Wednesday, September 3, 2008

VHDL Part 37 : Finite State Machine Sample Design Code

I had already illustrated the states I want my signals to go through. I have learned that to be able to design a state machine, I need one combinational and one sequential processes. So now I need to code it.

----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity fsm1 is
port(
clk : in std_logic;
rst : in std_logic;
cond_1 : in std_logic;
cond_2 : in std_logic;
block1_en : out std_logic;
block2_en : out std_logic;
block3_en : out std_logic;
block4_en : out std_logic);
end fsm1;

architecture Behavioral of fsm1 is

-- let me declare my states by enumeration; the present state and next states as signals, the
-- data type of which is my list of states (fsmState)

type fsmState is (idleState, state1, state2, state3, state4);
signal presentState, nextState : fsmState;

begin

-- here's my sequential process
seq_process : process (clk,rst)
begin

if rst = '1' then 

-- idleState is the default state
presentState <= idleState; 

elsif clk'event and clk = '1' then 

presentState <= nextState; 

end if
;
end process seq_process;

-- here's my combinational process
comb_process : process (presentState, cond_1, cond_2)
begin

case presentState is

when 
idleState =>

-- all my blocks are disabled
block1_en <= '0';
block2_en <= '0';
block3_en <= '0';
block4_en <= '0

-- at the next clock (as seen on the sequential process), my next state will be state 1
nextState <= state1; 

when 
state1 =>

-- enable only block1
block1_en <= '1';
block2_en <= '0';
block3_en <= '0';
block4_en <= '0'; 

-- conditions changed?
if ((cond_1 = '1') and (cond_2 = '0')) then

nextState <= state2;

elsif ((cond_1 = '0') and (cond_2 = '1')) then

nextState <= state3; 

else

nextState <= idleState; 

end if
;

when state2 =>

-- enable only block2
block1_en <= '0'; 
block2_en <= '1'; 
block3_en <= '0'; 
block4_en <= '0'; 

-- conditions changed?

if ((cond_1 = '1') and (cond_2 = '0')) then

nextState <= state4; 

else

nextState <= state2; 

end if
;

when state3 =>

-- enable only block3
block1_en <= '0'; 
block2_en <= '0'; 
block3_en <= '1'; 
block4_en <= '0'; 

-- conditions changed?
if ((cond_1 = '0') and (cond_2 = '1')) then

nextState <= state4; 

else


nextState <= state3; 

end if
;

when state4 =>

-- enable only block4
block1_en <= '0'; 
block2_en <= '0';
block3_en <= '0'; 
block4_en <= '1';

-- conditions changed?
if ((cond_1 = '1') and (cond_2 = '1')) then

nextState <= state1;

else

nextState <= state4; 

end if
;
end case;
end process comb_process;
end Behavioral;
----------------------------------------------------------------------------------

I did not have any warnings when I synthesized it. When I tried closing the cases in my case statement with

------------------------------
when others =>

nextState <= presentState;
------------------------------

I have the following warnings

------------------------------
WARNING:Xst:737 - Found 1-bit latch for signal . Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal . Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal . Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal . Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:1294 - Latch is equivalent to a wire in block .
WARNING:Xst:1294 - Latch is equivalent to a wire in block .
WARNING:Xst:1294 - Latch is equivalent to a wire in block .
WARNING:Xst:1294 - Latch is equivalent to a wire in block .
------------------------------

Ok. I had already completed my case statement with when others. Why is it that I still have
WARNING:Xst:737? After I read the warnings carefully, I noticed that ISE has given my outputs latch equivalents which I do not want because it seems to me that my outputs are not clocked. I tried adding the outputs to my when others like so

------------------------------
when others =>

block1_en <= '0'; block2_en <= '0'; block3_en <= '0'; block4_en <= '0'; nextState <= presentState;
------------------------------

The warnings then disappeared.

Yehey ;)

Reference:
(1) Pedroni, V., Circuit Design with VHDL, The MIT Press, 2004.



No comments: