Vous êtes sur la page 1sur 12

11.

Aplicaciones Secuenciales en VHDL


Conceptos bsicos
Flip-Flops Contadores Secuenciadores Mquinas de Estado Registros

Saber Hacer
Describir en VHDL un sistema secuencial Simular el comportamiento del circuito

11.1 FLIP-FLOPS 11.1 Los procesos de VHDL


Los dispositivos de lgica secuencial necesitan todos para su implementacin del mecanismo del proceso (process) de VHDL. La forma general de un proceso en VHDL es la siguiente: PROCESS(lista de sensibilidad) Declaraciones de variables BEGIN Proposiciones secuenciales END PROCESS Un proceso se ejecuta cuando cualquiera de las seales incluidas en la lista de sensibilidad que v en el encabezado cambia. Dentro del cuerpo del proceso se puede manejar cual de las seales fue la que cambi por medio del atributo EVENT que se le puede agregar a una seal; por ejemplo, clockEVENT, es una condicin que se vuelve verdadera cuando la seal clock cambia de valor.

11.2 Los Flip-Flops


En el ejemplo que sigue incluimos varias implementaciones de flip-flops tipo D, para los cuales se ha seleccionado que el disparo se haga en el lado delantero del reloj. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DFFs IS PORT( D, Clock, Reset, Enable Q1, Q2, Q3, Q4 END DFFs;

: IN STD_LOGIC; : OUT STD_LOGIC);

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;

11.3 Registro 4 bits.


CLR 0 1 D * D Q 0 D Qn 1 Dn

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).

11.4 Contador binario de 4 bits.


clk Up/Down Q3 Q2 Q1 Q0

UP/DOWN 0 1

ACCION Cuenta ascendente Cuenta descendente

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;

11.5 Mquina de estados finita.

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;

11.6 Las luces del Ford.


Este ejemplo es tomado del libro de Wakerly. Se refiere al lector a dicho libro para ms detalles del problema. La mquina secuencial a desarrollar tiene 3 variables de entrada, denominadas left, right y haz, que corresponden a los controles de las seales de las luces direccionales. La mquina debe controlar seis luces de salida, tres a cada lado del vehculo en la parte trasera, de tal modo que cuando se seleccione la seal left, por ejemplo, las luces de salida deben mostrar primero 001000, luego 011000, luego 111000 y finalmente 000000, y reiniciar la secuencia. El diagrama de estados de la mquina pedida se muestra en la siguiente figura:

El programa correspondiente en VHDL se incluye a continuacin:


Library IEEE; use IEEE.std_logic_1164.all; entity vtbird is port ( CLOCK, RESET, LEFT, RIGHT, HAZ: in STD_LOGIC; LIGHTS: buffer STD_LOGIC_VECTOR (1 to 6) ); end;

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;