Search code examples
vhdlstatemodelsimfsmquartus

start from a specific stat in the FSM


I have a specific FSM that works just fine. but I want to start from a specific state in the FSM, I was wondering if I can do it using an event that only happens once in the circuit but I can't do it because all the events I think of keeps the circuit in the same state

library ieee;
use ieee.std_logic_1164.all;
use work.all;

entity ELEVAR is
port(
clk, rst: in std_logic;
NF,status : in std_logic_vector(2 downto 0);
output: out std_logic_vector(2 downto 0));
end ELEVAR;

architecture struct of ELEVAR is
type state is(S,S0,S1,S2,S3,S4,S5,S6,S7,S8,HI);
signal current_state, next_state:state; 
signal output22 : std_logic_vector(2 downto 0);

begin 
    process(clk, rst)
    begin
            if(rst='1')then
                current_state<=S0;

            elsif(rising_edge(clk))then


            else
                    null;
            end if;

    end process;




    process(current_state)

    begin

            case current_state is

                when S8=>next_state<=S7;
                            output<="111";

 output22<="111";
    if (NF=output22) then
    next_state<=HI;
    output<="111";
    end if;

                when S7=>next_state<=S6;
                            output<="110";

 output22<="110";
    if (NF=output22) then
    next_state<=HI;
    output<="110";
    end if;
                when S6=>next_state<=S5;
                            output<="101";

 output22<="101";
    if (NF=output22) then
    next_state<=HI;
    output<="101";

    end if;
                when S5=>next_state<=S4;
                            output<="100";

 output22<="100";
    if (NF=output22) then
    next_state<=HI;
                output<="100";
    end if;
                when S4=>next_state<=S3;
                            output<="011";

 output22<="011";
    if (NF=output22) then
    next_state<=HI;
    output<="011";
    end if;
                when S3=>next_state<=S2;
                            output<="010";

 output22<="010";
    if (NF=output22) then
    next_state<=HI;
        output<="010";
    end if;
                when S2=>next_state<=S1;
                            output<="001";

 output22<="001";
    if (NF=output22) then
    next_state<=HI;
            output<="001";
    end if;
                when S1=>next_state<=S0;
                            output<="000";

 output22<="000";
    if (NF=output22) then
    next_state<=HI;
        output<="000";
    end if;

                 when others => next_state<=HI;
                            null;


            end case;
    end process;

  end struct;

-- this code selects the state I want to start from but I don't know --- where should I place it in my code.

   current_state<=next_state;
                elsif status = "000" then 
                current_state<=S0;
                elsif 
                status = "001" then 
                current_state<=S1;
                elsif 
                status = "010" then 
                current_state<=S2;
                elsif 
                status = "011" then 
                current_state<=S3;
                elsif 
                status = "100" then 
                current_state<=S4;
                elsif 
                status = "101" then 
                current_state<=S5;
               elsif 
                status = "110" then 
                current_state<=S6;
                elsif 
                status = "111" then 
                current_state<=S7;

Solution

  • Signals get initialized by default with the left-most value of the range of that signal's subtype, if no initial value is provided. In your case the type is State and it's left-most value is S. Thus your initial state is S.

    You can assign an initial value to while declaring the signal:

    signal current_state : State := S4;
    signal next_state    : State;
    

    Now, the initial value is S4 and the start state is also S4.

    Please note, an FSM can have different start and reset states. (Not saying it's always clever.) It depends on the underlying technology (FPGA, Xilinx, Altera, ASIC, ...) if the reset state can differ from initial state.


    Other hints:

    • Do not enumerate identifiers like S1, S2!
      Use proper state names.
    • If you need to check status for multiple different values, use a case statement, but no if/elsif decision-tree.
    • You process' sensitivity list is incomplete.
    • Don't use asynchronous resets.