Implementing a FSM in VHDL

雨燕双飞 提交于 2019-12-12 08:02:33

问题


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?


回答1:


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;



回答2:


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.



回答3:


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




回答4:


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

Hi

the above process is problematic but not due to the sensitivity list. It is ok to only declare clk for sequential process. Both simulation and synthesis tools won't have problems with it. clk is the fastest changing/transitioning signal after all in your code.

However, you should use an (preferrably) asynchronous reset. Of course, vendors nowadays say that for FPGA design, resets are not even necessary; they happen at boot time. Or they propose a synchronous reset.

Still, an asynchronous reset is valuable for a board-based environment.

In short: add a reset to your design and fix its behavior properly.

Kind regards Nikolaos Kavvadias



来源:https://stackoverflow.com/questions/6001025/implementing-a-fsm-in-vhdl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!