I need to write this state machine to control a fifo datapath, yet syntax errors that seem to be ignored in other parts don't let me complete the state machine properly.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity FIFO_FSM is
Port ( CMD_WR_H : in STD_LOGIC;
CMD_RD_H : in STD_LOGIC;
SYS_CLK_H : in STD_LOGIC;
RST_H : in STD_LOGIC;
EMPTY_H : out STD_LOGIC;
FULL_H : out STD_LOGIC;
LD_EN_0_H : out STD_LOGIC;
LD_EN_1_H : out STD_LOGIC;
LD_EN_2_H : out STD_LOGIC;
LD_EN_3_H : out STD_LOGIC;
RD_EN_H : out STD_LOGIC;
WR_EN_H : out STD_LOGIC;
LD_RVR_H : out STD_LOGIC);
end FIFO_FSM;
architecture Behavioral of FIFO_FSM is
signal PresentState,Nextstate: integer := 0;
begin
process(PresentState,CMD_WR_H,CMD_RD_H,RST_H)
begin
case PresentState is
when 0 => -- empty state
LD_EN_0_H <='0';LD_EN_1_H <='0';LD_EN_2_H <='0';LD_EN_3_H <='0';
RD_EN_H<='0';WR_EN_H<='0';LD_RVR_H<='0';
EMPTY_H<='1';FULL_H<='0';
if(RST_H ='1') then Nextstate<=0;
elsif(((CMD_WR_H ='1' and CMD_RD_H='1') and ( RST_H='0'))) then Nextstate<=0;
elsif((((CMD_WR_H='0') and (CMD_RD_H='0' )) and ( RST_H='0')))then Nextstate<=0;
elsif(((CMD_WR_H='0' and (CMD_RD_H='1' )) and ( RST_H='0')))then Nextstate<=0;
elsif(((( CMD_WR_H='1') and CMD_RD_H='0') and ( RST_H='0')) )then Nextstate<=1;
end if;
when 1 => --loading Reg 0 transition state
LD_EN_0_H <='1';LD_EN_1_H <='0';LD_EN_2_H <='0';LD_EN_3_H <='0';
RD_EN_H<='0';WR_EN_H<='1';LD_RVR_H<='0';
EMPTY_H<='0';FULL_H<='0';
Nextstate<=2;
when 20=> -- unloading R0
LD_EN_0_H <='1';LD_EN_1_H <='1';LD_EN_2_H <='1';LD_EN_3_H <='1';
RD_EN_H<='1';WR_EN_H<='0';LD_RVR_H<='1';
EMPTY_H<='0';FULL_H<='0';
Nextstate<=0;
when 2=> -- Reg 0 stored
LD_EN_0_H <='0';LD_EN_1_H <='0';LD_EN_2_H <='0';LD_EN_3_H <='0';
RD_EN_H<='0';WR_EN_H<='0';LD_RVR_H<='0';
EMPTY_H<='0';FULL_H<='0';
if(RST_H ='1') then Nextstate<=0;
elsif(((CMD_WR_H ='1' and CMD_RD_H='1') and ( RST_H='0'))) then Nextstate<=2;
elsif((((CMD_WR_H='0') and (CMD_RD_H='0' )) and ( RST_H='0')))then Nextstate<=2;
elsif(((CMD_WR_H='0' and (CMD_RD_H='1' )) and ( RST_H='0')))then Nextstate<=20;
elsif(((( CMD_WR_H='1') and CMD_RD_H='0') and ( RST_H='0')) )then Nextstate<=3;
end if;
when 3=> --Load Reg 1 transition state
LD_EN_0_H <='0';LD_EN_1_H <='1';LD_EN_2_H <='0';LD_EN_3_H <='0';
RD_EN_H<='0';WR_EN_H<='1';LD_RVR_H<='0';
EMPTY_H<='0';FULL_H<='0';
Nextstate<=4;
when 42 => --unloading R1
LD_EN_0_H <='1';LD_EN_1_H <='1';LD_EN_2_H <='1';LD_EN_3_H <='1';
RD_EN_H<='1';WR_EN_H<='0';LD_RVR_H<='1';
EMPTY_H<='0';FULL_H<='0';
Nextstate<=2;
when 4=> --Reg 1 Stored
LD_EN_0_H <='0';LD_EN_1_H <='0';LD_EN_2_H <='0';LD_EN_3_H <='0';
RD_EN_H<='0';WR_EN_H<='0';LD_RVR_H<='0';
EMPTY_H<='0';FULL_H<='0';
if(RST_H ='1') then Nextstate<=0;
elsif(((CMD_WR_H ='1' and CMD_RD_H='1') and ( RST_H='0'))) then Nextstate<=4;
elsif((((CMD_WR_H='0') and (CMD_RD_H='0' )) and ( RST_H='0')))then Nextstate<=4;
elsif(((CMD_WR_H='0' and (CMD_RD_H='1' )) and ( RST_H='0')))then Nextstate<=42;
elsif(((( CMD_WR_H='1') and CMD_RD_H='0') and ( RST_H='0')) )then Nextstate<=5;
end if;
when 5=> --Load Reg 2 transition state
LD_EN_0_H <='0';LD_EN_1_H <='0';LD_EN_2_H <='1';LD_EN_3_H <='0';
RD_EN_H<='0';WR_EN_H<='1';LD_RVR_H<='0';
EMPTY_H<='0';FULL_H<='0';
Nextstate<=6;
when 64 -- unloading R2
LD_EN_0_H <='1';LD_EN_1_H <='1';LD_EN_2_H <='1';LD_EN_3_H <='1';
RD_EN_H<='1';WR_EN_H<='0';LD_RVR_H<='1';
EMPTY_H<='0';FULL_H<='0';
Nextstate<=4;
when 6=> -- Reg 2 Stored
LD_EN_0_H <='0';LD_EN_1_H <='0';LD_EN_2_H <='0';LD_EN_3_H <='0';
RD_EN_H<='0';WR_EN_H<='0';LD_RVR_H<='0';
EMPTY_H<='0';FULL_H<='0';
if(RST_H ='1') then Nextstate<=0;
elsif(((CMD_WR_H ='1' and CMD_RD_H='1') and ( RST_H='0'))) then Nextstate<=6;
elsif((((CMD_WR_H='0') and (CMD_RD_H='0' )) and ( RST_H='0')))then Nextstate<=6;
elsif(((CMD_WR_H='0' and (CMD_RD_H='1' )) and ( RST_H='0')))then Nextstate<=64;
elsif(((( CMD_WR_H='1') and CMD_RD_H='0') and ( RST_H='0')) )then Nextstate<=7;
end if;
when 7=> -- Load Reg 3 transition state
LD_EN_0_H <='0';LD_EN_1_H <='0';LD_EN_2_H <='0';LD_EN_3_H <='1';
RD_EN_H<='0';WR_EN_H<='1';LD_RVR_H<='0';
EMPTY_H<='0';FULL_H<='0';
Nextstate<=8;
when 86 -- unloading R3
LD_EN_0_H <='1';LD_EN_1_H <='1';LD_EN_2_H <='1';LD_EN_3_H <='1';
RD_EN_H<='1';WR_EN_H<='0';LD_RVR_H<='1';
EMPTY_H<='0';FULL_H<='0';
Nextstate<=6;
when 8=> -- Reg 3 Stored
LD_EN_0_H <='0';LD_EN_1_H <='0';LD_EN_2_H <='0';LD_EN_3_H <='0';
RD_EN_H<='0';WR_EN_H<='0';LD_RVR_H<='0';
EMPTY_H<='0';FULL_H<='1';
if(RST_H ='1') then Nextstate<=0;
elsif(((CMD_WR_H ='1' and CMD_RD_H='1') and ( RST_H='0'))) then Nextstate<=8;
elsif((((CMD_WR_H='0') and (CMD_RD_H='0' )) and ( RST_H='0')))then Nextstate<=8;
elsif(((CMD_WR_H='0' and (CMD_RD_H='1' )) and ( RST_H='0')))then Nextstate<=86;
elsif(((( CMD_WR_H='1') and CMD_RD_H='0') and ( RST_H='0')) )then Nextstate<=8;
end if;
end process;
process(CLK) -- State Register
begin
if CLK='1' and CLK'EVENT then -- rising edge of clock
PresentState <= Nextstate;
end if;
end process;
end Behavioral;
I get these errors:
ERROR:HDLCompiler:806 - "C:/Users/willow/workspaceVHDL/FSM/FIFO_FSM.vhd" Line 96: Syntax error near "<=".
ERROR:HDLCompiler:806 - "C:/Users/willow/workspaceVHDL/FSM/FIFO_FSM.vhd" Line 119: Syntax error near "<=".
ERROR:HDLCompiler:806 - "C:/Users/willow/workspaceVHDL/FSM/FIFO_FSM.vhd" Line 135: Syntax error near "process".
What I'm trying to ask is what is the error and how to fix it, because is saying like I can't use <=
to assign a value to my inputs and outputs but only in certain lines and not in others where it let's it be. The other error I get is near the end process line just before the process with sensitivity to the clock.
Firstly, you should really format your code to make it readable:
Your code may make sense to you now, but when you come back to this code in a few months, or if somebody else has to work with it, the benefit of well formatted code will quickly become apparent.
Your first and second errors are because you have e.g. when 64
, forgetting the =>
. It should say e.g. when 64 =>
.
The third error is because you have a case
statement, without a matching end case
. Your statement should look something like this:
case PresentState is
when 0 =>
-- do something
when 1 =>
-- do something else
end case;
The final line here is what you are missing.
Having resolved the case statement problems, the next issue is that your code uses CLK
, which is not an input to your entity.
The next problem is that your case statement doesn't cover all the possible cases. You can resolve this either by adding a final when others =>
case at the end of the case statement or by using an enumerated type for the case statement. The enumerated type would be my choice, to preserve readability:
type STATE_MACHINE_type is (IDLE, LOAD_DATA, RESET);
signal PresentState : STATE_MACHINE_type := IDLE;
...
case PresentState is
when IDLE =>
Nextstate <= LOAD_DATA;
when LOAD_DATA =>
Nextstate <= RESET;
when RESET =>
Nextstate <= IDLE;
end case;
If you decide to use the when others =>
approach, but have no code to put in this case, you can make this explicit using NULL
:
case PresentState is
when 0 =>
-- do something
when others =>
NULL;
end case;