VHDL 中的 3 位有限状态机

3-bit finite state machine in VHDL

entity project4 is
    Port ( clk : in  STD_LOGIC;
           reset : in  STD_LOGIC;
           x : in  STD_LOGIC_VECTOR (1 downto 0);
           myoutputs : out  STD_LOGIC_VECTOR (2 downto 0));
end project4;

architecture Behavioral of project4 is
type state_type is (s0,s1,s2,s3,s4,s5,s6,s7);
signal state: state_type;

begin
process1: process(clk,reset)
begin
     if (reset ='0') THEN state <= s0;
      myoutputs <= "000";
ELSE IF (clk'EVENT AND clk='1') THEN
    case state is
     when s0 =>
               if (x="00") THEN
                  state <= s1;
                  myoutputs <= "001";
                  ELSE IF (x="01") THEN
                  state <= s7;
                  myoutputs <= "111";
                  ELSE IF (x="10") THEN
                  state <= s2;
                  myoutputs <= "010";
                  ELSE
                  state <=s4;
                  myoutputs <= "100";
      END IF;

      when s1 =>
                if (x="00") THEN
                    state <= s2;
                    myoutputs <="010";
                    ELSE IF (x ="01") THEN
                    state <= s0;
                    myoutputs <= "000";
                    ELSE IF (x ="10") THEN
                    state <=s0;
                    myoutputs <= "000";
                    ELSE
                    state <= s0;
                    myoutputs <="000";
        END IF;

        when s2 =>
                  if (x="00") THEN
                     state <= s3;
                     myoutputs <="011";
                     ELSE IF (x="01") THEN
                     state <= s1;
                     myoutputs <="001";
                     ELSE IF (x="10") THEN
                     state <=s5;
                     myoutputs <="110";
                     ELSE
                     state <=s3;
                     myoutputs <="011";
        END IF;

        when s3 =>
                  if (x="00") THEN
                     state <=s4;
                     myoutputs <="100";
                     ELSE IF (x="01") THEN
                     state <= s2;
                     myoutputs <="010";
                     ELSE IF (x="10") THEN
                     state <= s1;
                     myoutputs <= "001";
                     ELSE
                     state <=s1;
                     myoutputs <= "001";
        END IF;

      when s4 =>
                if (x="00") THEN
                state <=s5;
                myoutputs <="101";
                     ELSE IF (x="01") THEN
                     state <= s3;
                     myoutputs <="011";
                     ELSE IF (x="10") THEN
                     state <= s5;
                     myoutputs <="101";
                     ELSE
                     state <= s5;
                     myoutputs <="101";
        END IF;

        when s5 =>
                  if (x="00") THEN
                     state <= s6;
                     myoutputs <="110";
                     ELSE IF (x="01") THEN
                     state <= s4;
                     myoutputs <= "100";
                     ELSE IF (x="10") THEN
                     state <= s7;
                     myoutputs <= "111";
                     ELSE
                     state <= s7;
                     myoutputs <= "111";
        END IF;

        when s6 =>
                  if (x="00") THEN
                     state <= s7;
                     myoutputs <= "111";
                     ELSE IF (x="01") THEN
                     state <= s5;
                     myoutputs <="101";
                     ELSE IF (x="10") THEN
                     state <= s4;
                     myoutputs <="100";
                     ELSE
                     state <= s2;
                     myoutputs <="010";
        END IF;

        when s7 =>
                  if (x="00") THEN
                     state <= s0;
                     myoutputs <="000";
                     ELSE IF (x="01") THEN
                     state <= s6;
                     myoutputs <="110";
                     ELSE IF (x="10") THEN
                     state <= s3;
                     myoutputs <="011";
                     ELSE
                     state <= s6;
                     myoutputs <= "110";
        END IF;
        end case;
        end process process1;

process2: process(state)
begin
      case state is
        when s0 => myoutputs <= "000";
        when s1 => myoutputs <= "001";
        when s2 => myoutputs <= "010";
        when s3 => myoutputs <= "011";
        when s4 => myoutputs <= "100";
        when s5 => myoutputs <= "101";
        when s6 => myoutputs <= "110";
        when s7 => myoutputs <= "111";
        end case;
end process process2;

end Behavioral;

Here's entire code.

谁能告诉我是什么原因导致的错误?我就是不明白。 ("when" 附近的语法错误。)

使用 elsif 而不是 else if

通过添加上下文子句从您的链接代码构建 Minimal, Complete, and Verifiable example

library ieee;
use ieee.std_logic_1164.all;

entity project4 is
    port ( 
        clk:        in  std_logic;
        reset:      in  std_logic;
        x:          in  std_logic_vector (1 downto 0);
        myoutputs:  out std_logic_vector (2 downto 0)
    );
end entity project4;

architecture behavioral of project4 is
    type state_type is (s0,s1,s2,s3,s4,s5,s6,s7);
    signal state: state_type;
begin
process1: 
    process (clk, reset)
    begin
    if reset ='0' then 
        state <= s0;
        myoutputs <= "000";
    else if clk'event and clk='1' then
        case state is
            when s0 =>
                if x = "00" then
                    state <= s1;
                    myoutputs <= "001";
                else if x = "01" then
                    state <= s7;
                    myoutputs <= "111";
                else if  x = "10" then
                    state <= s2;
                    myoutputs <= "010";
                else
                    state <= s4;
                    myoutputs <= "100";
                end if;
            when s1 =>
                if  x = "00" then
                    state <= s2;
                    myoutputs <= "010";
                else if  
                    x = "01" then
                    state <= s0;
                    myoutputs <= "000";
                else if  x = "10" then
                    state <= s0;
                    myoutputs <= "000";
                else
                    state <= s0;
                    myoutputs <= "000";
                end if;

            when s2 =>
                if  x = "00" then
                     state <= s3;
                     myoutputs <= "011";
                else if  x = "01" then
                     state <= s1;
                     myoutputs <= "001";
                else if  x = "10" then
                     state <= s5;
                     myoutputs <= "110";
                else
                     state <= s3;
                     myoutputs <= "011";
        end if;

            when s3 =>
                if  x = "00" then
                     state <= s4;
                     myoutputs <= "100";
                else if  x = "01" then
                     state <= s2;
                     myoutputs <= "010";
                else if  x = "10" then
                     state <= s1;
                     myoutputs <= "001";
                else
                     state <= s1;
                     myoutputs <= "001";
                 end if;

            when s4 =>
                if  x = "00" then
                    state <= s5;
                    myoutputs <= "101";
                else if  x = "01" then
                     state <= s3;
                     myoutputs <= "011";
                else if  x = "10" then
                     state <= s5;
                     myoutputs <= "101";
                 else
                     state <= s5;
                     myoutputs <= "101";
                 end if;

            when s5 =>
                if  x = "00" then
                    state <= s6;
                    myoutputs <= "110";
                else if  x = "01" then
                    state <= s4;
                    myoutputs <= "100";
                else if  x = "10" then
                    state <= s7;
                    myoutputs <= "111";
                else
                    state <= s7;
                    myoutputs <= "111";
                end if;

            when s6 =>
                if  x = "00" then
                     state <= s7;
                     myoutputs <= "111";
                else if  x = "01" then
                    state <= s5;
                    myoutputs <= "101";
                else if  x = "10" then
                    state <= s4;
                    myoutputs <= "100";
                else
                    state <= s2;
                    myoutputs <= "010";
                end if;

            when s7 =>
                if  x = "00" then
                    state <= s0;
                    myoutputs <= "000";
                else if  x = "01" then
                    state <= s6;
                    myoutputs <= "110";
                else if  x = "10" then
                    state <= s3;
                    myoutputs <= "011";
                else
                    state <= s6;
                    myoutputs <= "110";
                end if;
            end case;

    end process process1;

process2: 
    process(state)
    begin
        case state is
            when s0 => myoutputs <= "000";
            when s1 => myoutputs <= "001";
            when s2 => myoutputs <= "010";
            when s3 => myoutputs <= "011";
            when s4 => myoutputs <= "100";
            when s5 => myoutputs <= "101";
            when s6 => myoutputs <= "110";
            when s7 => myoutputs <= "111";
        end case;
    end process process2;
end behavioral;

并使用几个不同的 VHDL 工具:

ghdl -a project4.vhdl
project4.vhdl:39:13: 'end' is expected instead of 'when'
ghdl: compilation error

nvc -a project4.vhdl  
** Error: unexpected when while parsing if statement, expecting end  
  File project4.vhdl, Line 39  
                when s1 =>  
                ^^^^  
** Error: unexpected when while parsing if statement, expecting end  
  File project4.vhdl, Line 55  
                when s2 =>  
                ^^^^  
** Error: unexpected when while parsing if statement, expecting end  
  File project4.vhdl, Line 70  
                when s3 =>  
                ^^^^  
>...

解释问题所在。您使用的是 else if 而不是 elsif,这会导致错误数量的结束语句 (end if;)。

修复 else if 的 17 个实例,我们发现您遗漏了第一个 if 语句的末尾:

ghdl -a project4.vhdl
project4.vhdl:146:9: 'if' is expected instead of 'process'
ghdl: compilation error

在结束过程之前添加:

        end if; -- added
    end process process1;

以及您的设计分析。

您的代码是否有效由您决定。

(好的,还有另一个问题,你从两个进程驱动 myoutputs,这将导致 Xs,你应该删除第二个进程。分配信号的每个进程都有该信号的驱动程序,并且 std_logic 是一个已解析的类型,这意味着两个驱动程序值将提交给一个解析函数,对于包 std_logic_1164 将导致 Xs 两个驱动程序上的冲突值。 )

所以有 18 个语法错误,加上代码不起作用,我的输出有驱动程序冲突。

为了便于阅读,我删除了多余的括号并添加了空格和缩进。

所以添加一个小测试台:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity project4_tb is
end entity;

architecture foo of project4_tb is
    signal clk:        std_logic := '0';
    signal reset:      std_logic;
    signal x:          std_logic_vector (1 downto 0);
    signal myoutputs:  std_logic_vector (2 downto 0);
begin
DUT: 
    entity work.project4
        port map (
            clk => clk,
            reset => reset,
            x => x,
            myoutputs => myoutputs
        );

CLOCK:
    process
    begin
        wait for 5 ns;
        clk <= not clk;
        if now > 360 ns then
            wait;
        end if;
    end process;

STIMULI:
    process
    begin
        wait for 6 ns;
        reset <= '0';
        wait for 10 ns;
        reset <= '1';
        for i in 0 to 3 loop
            x <= std_logic_vector(to_unsigned(i,x'length));
            wait for 80 ns;
        end loop;
        wait;
    end process;
end architecture;

我们可以看到您的设计在仿真中做了什么: