我需要编写这个状态机来控制fifo数据路径,但是在其他部分似乎忽略的语法错误不能让我正确地完成状态机。
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;
我收到这些错误:
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".
我想问的是错误是什么以及如何解决它,因为我说我不能使用<=
为我的输入和输出分配值,但仅限于某些行和不是在其他地方让它成为现实。我得到的另一个错误是在进程之前的结束进程线附近,对时钟敏感。
答案 0 :(得分:0)
首先,您应该格式化代码以使其可读:
您的代码现在可能对您有意义,但是当您在几个月内回到此代码时,或者如果其他人必须使用它时,格式良好的代码的好处将很快变得明显。
您的第一个和第二个错误是因为您有例如when 64
,忘记了=>
。它应该说例如when 64 =>
。
第三个错误是因为您有一个case
语句,没有匹配的end case
。你的陈述应该是这样的:
case PresentState is
when 0 =>
-- do something
when 1 =>
-- do something else
end case;
这里的最后一行是你缺少的。
解决了案例陈述问题后,下一个问题是您的代码使用CLK
,这不是您实体的输入。
下一个问题是您的案例陈述并未涵盖所有可能的案例。您可以通过在case语句的末尾添加最终when others =>
案例或使用case语句的枚举类型来解决此问题。为了保持可读性,我将选择枚举类型:
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;
如果您决定使用when others =>
方法,但在这种情况下没有代码,可以使用NULL
明确说明:
case PresentState is
when 0 =>
-- do something
when others =>
NULL;
end case;