D es esc r i pc pc i o n d e ma q u i n a s d e est a d o en v h d l • Una máquina máquina de estados estados está definida definida por dos funciones; funciones; una que que calcula el el estado siguiente en el que se encontrará la máquina y la otra que calcula la salida. •Máquina de Mealy: Mealy: la salida salida depende depende de las entradas entradas y del del estado presente presente •Maquina de Moore: la salida depénde sólo del estado presente. •En VHDL se pueden describir tanto máquinas de Mealy como máquinas de Moore. Las máquinas de estado se modelan con una parte secuencial y otra combinacional.
Una máquina de estados en VHDL tiene: • Una lógica que permite pasar de estado. • Una lógica de salida • una memoria
Mealy Machine Model Primary Inputs
Output Combinational Logic
Moore Machine Model Primary Outputs
Primary Inputs
Next State Combinational Logic Present State
y r o m e M
Output Combinational Logic
Primary Outputs
Next State Combinational Logic Next State
Present State
y r o m e M
Next State
Co d if i c ac io n d e est ad o s Se utiliza el tipo enumerado para codificar los estados posibles: TYPE state_type IS (idle,init,test,add,shift);
SIGNAL present_state, next_state : state_type;
Co d i f ic ac i o n d e l a t r an si c io n d e est ad o s (MEMO RIA) Signal estado: state_type; PROCESS(reloj, entradas_asíncronas) BEGIN IF entradas_asincronas THEN estado <= estado_inicial; ELSIF clk’event AND clk = ‘1’ THEN CASE estado IS WHEN estado1 => Calculo_estado_en _función de entradas WHEN estado2 => Calculo_estado_en _función de entradas WHEN estado3 =>
Calculo_estado_en _función de entradas ... WHEN estadon => Calculo_estado_en _función de entradas END CASE; END IF; END PROCESS;
Ejemplo: clocked : PROCESS(clk, reset) BEGIN IF (reset = '0') THEN present_state <= idle; ELSIF (clk'EVENT AND clk = '1') THEN present_state <= next_state; END IF; END PROCESS clocked;
nextstate : PROCESS(present_state,start,q0) BEGIN CASE present_state IS WHEN idle => IF(start='1') THEN next_state <= init; ELSE next_state <= idle; END IF; WHEN init => next_state <= test; WHEN test => IF(q0='1') THEN next_state <= add; ELSIF(q0='0') THEN next_state <= shift; ELSE next_state <= test; END IF; WHEN add => next_state <= shift; WHEN shift => next_state <= test; END CASE; END PROCESS nextstate;
Co d if i c ac io n d e l a sal i d a El proceso de salida obtiene las salidas basandose en el estado presente y en las entradas (máquina de Mealy) o sólo en el estado presente (máquina de Moore) Mealy:PROCESS(estado, entradas) BEGIN CASE estado IS WHEN estado1 => Cálculo_de_salidas_en_función_del_estado; WHEN estado2 => Cálculo_de_salidas_en_función_del_estado; WHEN estado3 => Cálculo_de_salidas_en_función_del_estado; ..... WHEN estadon => Cálculo_de_salidas_en_función_del_estado; END CASE; END PROCESS;
Moore:PROCESS(estado) BEGIN CASE estado IS WHEN estado1 => Salidas <= valor; WHEN estado2 => Salidas <= valor; WHEN estado3 => Salidas <= valor; ..... WHEN estadon => Salidas <= valor; END CASE; END PROCESS;
Ejemplo: output : PROCESS(present_state,start,q0) BEGIN -- Default Assignment a_enable <= '0' after delay; a_mode <= '0' after delay; c_enable <= '0' after delay; m_enable <= '0' after delay; -- State Actions CASE present_state IS WHEN init => a_enable <= '1' after delay; c_enable <= '1' after delay; m_enable <= '1' after delay; WHEN add => a_enable <= '1' after delay; c_enable <= '1' after delay; m_enable <= '1' after delay; WHEN shift => a_enable <= '1' after delay; a_mode <= '1' after delay; m_enable <= '1' after delay; WHEN OTHERS => NULL; END CASE; END PROCESS output;
La máquina completa es: LIBRARY LIBRARYieee ieee; ; USE USEieee.std_logic_1164.all; ieee.std_logic_1164.all; USE USEieee.numeric_std.all; ieee.numeric_std.all; ENTITY ENTITYcontrol_unit control_unitIS IS PORT(clk PORT(clk : :IN IN std_logic; std_logic; q0 : :IN q0 IN std_logic; std_logic; reset reset : :IN IN std_logic; std_logic; start start : :IN IN std_logic; std_logic; a_enable a_enable: :OUT OUTstd_logic; std_logic; a_mode a_mode : :OUT OUTstd_logic; std_logic; c_enable c_enable: :OUT OUTstd_logic; std_logic; m_enable m_enable: :OUT OUTstd_logic); std_logic); END ENDcontrol_unit; control_unit;
ARCHITECTURE ARCHITECTUREfsm fsmOF OFcontrol_unit control_unitIS IS CONSTANT CONSTANTdelay delay: :time time:= :=55ns ns; ; TYPE TYPEstate_type state_typeIS IS( (idle, idle,init, init,test, test,add, add,shift); shift); SIGNAL SIGNALpresent_state, present_state,next_state next_state: :state_type state_type; ; BEGIN BEGIN clocked clocked: :PROCESS(clk, PROCESS(clk,reset) reset) BEGIN BEGIN IF IF(reset (reset=='0') '0')THEN THEN present_state present_state<= <=idle; idle; ELSIF ELSIF(clk'EVENT (clk'EVENTAND ANDclk clk=='1') '1')THEN THEN present_state present_state<= <=next_state; next_state; END ENDIF; IF; END ENDPROCESS PROCESSclocked; clocked;
nextstate nextstate: : PROCESS(present_state,start,q0) PROCESS(present_state,start,q0) BEGIN BEGIN CASE CASEpresent_state present_stateIS IS WHEN idle => WHEN idle => IF(start='1') IF(start='1')THEN THEN next_state <= next_state <=init; init; ELSE ELSE next_state next_state<= <=idle; idle; END IF; END IF; WHEN WHENinit init=> => next_state next_state<= <=test; test; WHEN test => WHEN test => IF(q0='1') IF(q0='1')THEN THEN next_state next_state<= <=add; add; ELSIF(q0='0') THEN ELSIF(q0='0') THEN next_state next_state<= <=shift; shift; ELSE ELSE next_state next_state<= <=test; test; END IF; END IF; WHEN WHENadd add=> => next_state next_state<= <=shift; shift; WHEN shift => WHEN shift => next_state next_state<= <=test; test; END CASE; END CASE; END ENDPROCESS PROCESSnextstate; nextstate;
output output: :PROCESS(present_state,start,q0) PROCESS(present_state,start,q0) BEGIN BEGIN ----Default DefaultAssignment Assignment a_enable <= a_enable <='0' '0'after afterdelay; delay; a_mode <= '0' after delay; a_mode <= '0' after delay; c_enable c_enable<= <='0' '0'after afterdelay; delay; m_enable <= '0' after delay; m_enable <= '0' after delay; ----State StateActions Actions CASE present_state CASE present_stateIS IS WHEN init => WHEN init => a_enable a_enable<= <='1' '1'after afterdelay; delay; c_enable <= '1' after delay; c_enable <= '1' after delay; m_enable m_enable<= <='1' '1'after afterdelay; delay; WHEN add => WHEN add => a_enable a_enable<= <='1' '1'after afterdelay; delay; c_enable <= '1' after delay; c_enable <= '1' after delay; m_enable m_enable<= <='1' '1'after afterdelay; delay; WHEN shift => WHEN shift => a_enable a_enable<= <='1' '1'after afterdelay; delay; a_mode <= '1' after delay; a_mode <= '1' after delay; m_enable m_enable<= <='1' '1'after afterdelay; delay; WHEN OTHERS => WHEN OTHERS => NULL; NULL; END ENDCASE; CASE; END PROCESS END PROCESSoutput; output; END fsm;
Ejemplo de una máquina de Moore
entity MOORE is -- Moore machine port(X, CLOCK: in BIT; Z: out BIT); end MOORE; architecture BEHAVIOR of MOORE is type STATE_TYPE is (S0, S1, S2, S3); signal CURRENT_STATE, NEXT_STATE: STATE_TYPE; begin -- Process to hold synchronous elements (flip-flops) SYNCH: process begin wait until CLOCK’event and CLOCK = ’1’; CURRENT_STATE <= NEXT_STATE; end process SYNCH;
-- Process to hold combinational logic COMBIN: process(CURRENT_STATE, X) begin case CURRENT_STATE is when S0 => Z <= ’0’; if X = ’0’ then NEXT_STATE <= S0; else NEXT_STATE <= S2; end if; when S1 => Z <= ’1’; if X = ’0’ then NEXT_STATE <= S0; else
NEXT_STATE <= S2; end if; when S2 => Z <= ’1’; if X = ’0’ then NEXT_STATE <= S2; else NEXT_STATE <= S3; end if; when S3 => Z <= ’0’; if X = ’0’ then NEXT_STATE <= S3; else NEXT_STATE <= S1; end if; end case; end process COMBIN; end BEHAVIOR;
Máquina de Mealy
entity MEALY is -- Mealy machine
NEXT_STATE <= S0;
port(X, CLOCK: in BIT;
else
Z: out BIT);
Z <= ’1’;
end MEALY;
NEXT_STATE <= S2;
architecture BEHAVIOR of MEALY is
end if;
type STATE_TYPE is (S0, S1, S2, S3);
when S1 =>
signal CURRENT_STATE, NEXT_STATE: STATE_TYPE;
if X = ’0’ then
begin -- Process to hold combinational logic. COMBIN: process(CURRENT_STATE, X) begin case CURRENT_STATE is when S0 => if X = ’0’ then Z <= ’0’;
Z <= ’0’; NEXT_STATE <= S0; else Z <= ’0’; NEXT_STATE <= S2; end if; when S2 => if X = ’0’ then Z <= ’1’; NEXT_STATE <= S2; else Z <= ’0’;
NEXT_STATE <= S3; end if; when S3 => if X = ’0’ then Z <= ’0’; NEXT_STATE <= S3; else Z <= ’1’; NEXT_STATE <= S1; end if; end case; end process COMBIN; -- Process to hold synchronous elements (flip-flops) SYNCH: process
begin wait until CLOCK’event and CLOCK = ’1’; CURRENT_STATE <= NEXT_STATE; end process SYNCH; end BEHAVIOR;