Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a FSM in VHDL

Tags:

fsm

vhdl

Just wondering if I'm implementing a finite state machine in VHDL whether or not I need to state what all of the outputs are in every possible state? Even if I know that some outputs won't change from one state to the other and I know that the order of the states will also be in the same order?

For example, in this (forced) example:

entity test is
    port (
        clk : in std_logic;
        a : in std_logic;
        b: out std_logic;
        c: out std_logic;
    );
end test;

architecture Behavioral of test is

type executionStage is (s1,s2,s3);
signal currentstate, nextstate: executionStage;

begin
    process (clk)
    begin
          if(rising_edge(clk)) then
                 currentstate <= nextstate;
          else 
                 currentstate <= currentstate;
          end if;
    end process;

    process(currentstate)
    begin
        case currentstate is
            when s1 =>
                if (a = '1') then
                    b <= '1';
                    c <= '0';
                else
                    b <= '1';
                    c <= '1';
                end if;

                nextstate <= s2;

            when s2 =>
                -- b doesnt change state from s1 to here, do I need to define what it is here?
                if (a = '1') then
                    b <= '1';
                    c <= '1';
                else
                    b <= '1';
                    c <= '0';
                end if;

                nextstate <= s3;

            when s3 =>
                if (a = '1') then
                    b <= '0';
                    c <= '0';
                else
                    b <= '1';
                    c <= '1';
                end if;

                nextstate <= s1;
        end case;
    end process;
end Behavioral;

From my understanding if I don't do this then latches are created?

It's not a big deal in something like that example but if I have a machine with more than 10 outputs and more than 10 states then my VHDL files start to look incredibly messy and I'm sure it must be bad practice to copy and paste the same thing over and over. Is there a better way of doing this?

edit: Can I define a 'default' state for an ouput? IE set b to be 1 outside of all the processes and then only define what it is in the case statements where it is 0? Would that work?

like image 845
Sam Avatar asked May 14 '11 09:05

Sam


People also ask

How do you implement a finite state machine in VHDL?

-- Architecture definition for the SimpleFSM entity Architecture RTL of SimpleFSM is TYPE State_type IS (A, B, C, D); -- Define the states SIGNAL State : State_Type; -- Create a signal that uses -- the different states BEGIN PROCESS (clock, reset) BEGIN If (reset = '1') THEN -- Upon reset, set the state to A State <= A ...

What is FSM implementation?

A finite state machine may be implemented through software or hardware to simplify a complex problem. Within an FSM, all states in consideration exist in a finite list and the abstract machine can only take on one of those states at a time.

What is FSM how it is used for FPGA?

If a system transits between finite number of such internal states, then finite state machines (FSM) can be used to design the system. The FSM designed can be classified as 'Moore machine' and 'Mealy machine' which are discussed in this chapter.

How do you define a state in VHDL?

A state machine is a sequential circuit that advances through a number of states. To describe a state machine in Quartus II VHDL, you can declare an enumeration type for the states, and use a Process Statement for the state register and the next-state logic.


3 Answers

Yes, you will infer latches if you only drive signals intended to be combinatorial in some branches of the process.

However, you can define a 'default' state for the signal simply by assigning a value to it before the case statement (but within the same process). For example:

process(currentstate, a)
begin
    b <= '1';
    c <= '1';
    case currentstate is
        when s1 =>
            if (a = '1') then
                c <= '0';
            end if;

            nextstate <= s2;

        when s2 =>
            -- b doesnt change state from s1 to here, do I need to define what it is here?
            if (a /= '1') then
                c <= '0';
            end if;

            nextstate <= s3;

        when s3 =>
            if (a = '1') then
                b <= '0';
                c <= '0';
            end if;

            nextstate <= s1;
    end case;
end process;
like image 197
Tomi Junnila Avatar answered Nov 15 '22 11:11

Tomi Junnila


Three problems with your example code:

The last port in your port list should not have a semicolon:

port (
    clk : in std_logic;
    a : in std_logic;
    b: out std_logic;
    c: out std_logic -- no semicolon here!!!
    );

In your register process, you should not have an "else" statement. While this will probably be accepted by the tools, it will confuse your fellow-VHDL designers.

process (clk)
begin
    if(rising_edge(clk)) then
        currentstate <= nextstate;
    end if;
end process;

In your combinational logic, the sensitivity list should contain all signals that you read: process(a, currentstate). In this particular case (again) things will probably work out fine, but you are bound to infer latches or cause other problems if your sensitivity list is not correct.

As for your question:

  1. Yes, you need to assign a value (for each state) to each signal in the combinational process.
  2. As Tomi mentions, you can easily do this by assigning a default value in the beginning of the process.
  3. But you can also write the entire state machine in one single synchronous process. This way, you do not have to assign a value to every signal in every state.
like image 44
Philippe Avatar answered Nov 15 '22 09:11

Philippe


Just a note to Philippe's response (can't comment on it directly?)..

I do prefer to write state machines in the two process style. It makes it very clear where you expect inferred flipflops and where you don't. It's also a bit more along the lines of describing the hardware - imagine building a state machine with board level logic for example. The registered device matches the state <= next_state process, and the case statement maps to the and/or array in front of the state register..

Having said that, I typically use one process state machines for small simple tasks, and move over to two process machines for bigger ones. I will even sometimes use a third process for organizing state outputs into different "task" groups.. but not often. A really large state machine tends to tell me the architecture needs work..

like image 29
Gord Wait Avatar answered Nov 15 '22 09:11

Gord Wait