3-битный конечный автомат в 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;

Вот весь код.

Может ли кто-нибудь сказать мне, что вызывает ошибку? Я просто не понимаю. (Синтаксическая ошибка рядом с «когда».)


person Jack    schedule 11.04.2016    source источник
comment
Код в ссылке Весь код на самом деле неполный.   -  person mcleod_ideafix    schedule 12.04.2016
comment
В какой строке вы получаете синтаксическую ошибку?   -  person mcleod_ideafix    schedule 12.04.2016
comment
Ваш код не является минимальным, полным и проверяемым примером, и должен присутствовать полный код (включая предложение контекста), позволяющий тиражирование проблемы. Ваш связанный код может исчезнуть со временем, что уменьшит ценность вашего вопроса для будущих читателей.   -  person    schedule 12.04.2016


Ответы (1)


Используйте elsif, а не else if

Создание минимального, полного и проверяемого примера из связанного кода путем добавления предложения контекста:

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: ожидается "конец" вместо "когда"
ghdl: ошибка компиляции

а также

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

Исправляем эти 17 экземпляров else if, и мы обнаруживаем, что вы пропустили конец if для первого оператора if:

ghdl -a project4.vhdl
project4.vhdl:146:9: ожидается 'if' вместо 'process'
ghdl: ошибка компиляции

Добавление этого прямо перед конечным процессом:

        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;

Мы можем увидеть, что ваш дизайн делает в моделировании:

project4_tb.png

person Community    schedule 11.04.2016