Capitulo 11
Capitulo 11
Capitulo 11
Saber Hacer
Describir en VHDL un sistema secuencial Simular el comportamiento del circuito
ARCHITECTURE behavior OF DFFs IS BEGIN -- Flip flop D PROCESS BEGIN WAIT UNTIL (Clock'EVENT AND Clock='1'); Q1 <= D; END PROCESS; -- Flip-Flop D con reset sincrnico PROCESS BEGIN WAIT UNTIL (Clock'EVENT AND Clock='1'); IF reset = '1' THEN Q2 <= '0'; ELSE Q2 <= D; END IF; END PROCESS; -- Flip-Flop D con reset asincrnico PROCESS (Reset,Clock) BEGIN IF reset = '1' THEN Q3 <= '0'; ELSIF (clock'EVENT AND clock='1') THEN Q3 <= D; END IF; END PROCESS; -- Flip-Flop D con reset y habilitacin asincrnicos PROCESS (Reset,Clock) BEGIN IF reset = '1' THEN Q4 <= '0'; ELSIF (clock'EVENT AND clock='1') THEN IF Enable = '1' THEN Q4 <= D; END IF; END IF; END PROCESS; END behavior;
Como
puede
observase
en
la
tabla
que
describe
el
comportamiento del circuito, si CLR = 0, las salidas Q adoptan el valor de 0; pero si CLR = 1, toman el valor de las entradas D0, D1, D2 y D3. El cdigo del programa se observa en el siguiente listado.
library ieee; use ieee.std_logic_1164.all; entity reg4 is port( D : in std_logic_vector (3 downto 0); CLR, CLK : in std_logic; Q, Qn : inout std_logic_vector (3 downto 0)); end reg4; architecture a_reg4 of reg4 is begin process (CLK, CLR) begin if (CLK'event and CLK = '1') then if (CLR = '1') then Q <= D; Qn <= not Q; else Q <= "0000"; Qn <= "1111"; end if; end if; end process; end a_reg4;
Las variables sensitivas que determinan el comportamiento del circuito se encuentran dentro del proceso (CLR y CLK).
UP/DOWN 0 1
La seal de control Up/Down permite definir si el conteo se realiza en sentido ascendente o descendente. En este caso, un cero aplicado a esta seal determina una cuenta ascendente: del 0 al 15. De esta forma, el funcionamiento del circuito queda determinado por dos seales: el pulso de reloj (clk) y la seal Up/Down, como se muestra en el siguiente programa.
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_signed.all; entity contador is port( clk : in std_logic; up : in std_logic; Q : inout std_logic_vector(3 downto 0)); end contador; architecture a_contador of contador is begin process (up, clk) begin if (clk'event and clk = '1') then if (up = '0') then Q <= Q + 1 ; else Q <= Q - 1; end if; end if; end process; end a_contador;
En la figura se puede observar que el circuito pasa al estado q1 con el primer 1 de entrada (x) y al estado q2 con el segundo. Las salidas (z) asociadas con estas dos entradas son 0, segn se seala. La tercera entrada consecutiva de 1 genera un 1 en la salida y hace que el circuito pase al estado q3. Una vez que se encuentre en q3, el circuito permanecer en este estado, emitiendo salidas O. Las ideas nuevas de VHDL, provienen de usar estructuras case when y tipo de datos enumerados, que en este caso contiene los cinco estados (q0, q1, q2, q3 y q4) que componen el diagrama. El listado correspondiente al programa se encuentra a
continuacin.
library ieee; use ieee.std_logic_1164.all; entity diag is port( clk, x : in std_logic; z : out std_logic); end diag;
architecture a_diag of diag is type estados is (q0, q1, q2, q3, q4); signal estado_presente, estado_futuro : estados; begin proceso1: process (estado_presente, x) begin case estado_presente is when q0 => z <= '0'; if x = '0' then estado_futuro <= q4; else estado_futuro <= q1; end if; when q1 => z <= '0'; if x = '0' then estado_futuro <= q4; else estado_futuro <= q2; end if; when q2 => if x = '0' then estado_futuro <= q4; z <= '0'; else estado_futuro <= q3; z <= '1'; end if; when q3 => z <= '0'; if x = '0' then estado_futuro <= q3; else estado_futuro <= q3; end if; when q4 => z <= '0'; if x = '0' then estado_futuro <= q4; else estado_futuro <= q1; end if; end case; end process proceso1; proceso2: process (clk) begin if (clk'event and clk = '1') then estado_presente <= estado_futuro; end if; end process proceso2; end a_diag;
architecture vtbird_arch of vtbird is constant IDLE: STD_LOGIC_VECTOR (1 to 6) := "000000"; constant L3 : STD_LOGIC_VECTOR (1 to 6) := "111000"; constant L2 : STD_LOGIC_VECTOR (1 to 6) := "110000"; constant L1 : STD_LOGIC_VECTOR (1 to 6) := "100000"; constant R1 : STD_LOGIC_VECTOR (1 to 6) := "000001"; constant R2 : STD_LOGIC_VECTOR (1 to 6) := "000011"; constant R3 : STD_LOGIC_VECTOR (1 to 6) := "000111"; constant LR3 : STD_LOGIC_VECTOR (1 to 6) := "111111"; begin process (CLOCK) begin if CLOCK'event and CLOCK = '1' then if RESET = '1' then LIGHTS <= IDLE; else case LIGHTS is when IDLE => if HAZ='1' or (LEFT='1' and RIGHT='1') then LIGHTS <= LR3; elsif LEFT='1' then LIGHTS <= L1; elsif RIGHT='1' then LIGHTS <= R1; end if; when L1 => if HAZ='1' then LIGHTS <= LR3; else LIGHTS <= L2; end if; when L2 => if HAZ='1' then LIGHTS <= LR3; else LIGHTS <= L3; end if; when L3 => LIGHTS <= IDLE; when R1 => if HAZ='1' then LIGHTS <= LR3; else LIGHTS <= R2; end if; when R2 => if HAZ='1' then LIGHTS <= LR3; else
LIGHTS <= R3; end if; when R3 => LIGHTS <= IDLE; when LR3 => LIGHTS <= IDLE; when others => null; end case; end if; end if; end process; end vtbird_arch;
11.7 Semforo.
Este ejemplo es tomado del libro de Floyd en el numeral 6.11, a donde puede referirse el lector para obtener ms detalles sobre el problema. A continuacin se muestra el programa VHDL de sta aplicacin:
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY semaforos IS PORT (sensor,reset,clk: IN std_logic; semcamin,semcarr: OUT std_logic_vector(0 TO 2)); END semaforos; ARCHITECTURE descripcion OF semaforos IS TYPE estado IS (PrimerEstado, SegundoEstado, TercerEstado, CuartoEstado); CONSTANT verde: std_logic_vector(0 TO 2):="001"; CONSTANT amarillo: std_logic_vector(0 TO 2):="010"; CONSTANT rojo: std_logic_vector(0 TO 2):="100"; SIGNAL presente: estado:=PrimerEstado; SIGNAL rescont: boolean:=false; -- Pone a cero la cuenta SIGNAL fin_largo,fin_corto: boolean; -- Indica fin de cuenta SIGNAL cuenta: integer RANGE 0 TO 63; BEGIN -- Definimos la mquina de estados: maquina: PROCESS(clk,reset) BEGIN IF reset='1' THEN
presente<=PrimerEstado; ELSIF clk='1' AND clk'event THEN CASE presente IS WHEN PrimerEstado=> IF sensor='1' and fin_largo THEN presente<=SegundoEstado; END IF; WHEN SegundoEstado=> IF fin_corto THEN presente<=TercerEstado; END IF; WHEN TercerEstado => IF sensor = 0 or not fin_largo THEN presente<=CuartoEstado; END IF; WHEN CuartoEstado => IF fin_corto THEN presente<=PrimerEstado; END IF; END CASE; END IF; END PROCESS maquina; salida: PROCESS(presente) -- No depende de las entradas BEGIN CASE presente IS WHEN PrimerEstado=> semcarr<=verde; semcamin<=rojo; rescont<=true; WHEN SegundoEstado=> semcarr<=amarillo; semcamin<=rojo; rescont<=true; WHEN TercerEstado=> semcarr<=rojo; semcamin<=verde; rescont<=false; WHEN CuartoEstado=> semcarr<=rojo; semcamin<=amarillo; rescont<=true; END CASE; END PROCESS salida; -- El siguiente proceso define el contador: contador: PROCESS(clk) BEGIN
IF clk='1' THEN IF rescont THEN cuenta<=0; ELSE cuenta<=cuenta+1; END IF; END IF; END PROCESS contador; -- Deteccin de los tiempos largos y cortos: fin_largo<=true WHEN cuenta=29 ELSE false; fin_corto<=true WHEN cuenta=9 ELSE false; END descripcion;