Error de sintaxis en el código VHDL

1

Estoy intentando implementar el módulo del controlador como un FSM usando VHDL, a continuación está el código

entity controller is
    Port ( 

           reset : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           ring_k_1 : in  STD_LOGIC;
           b_n : in  STD_LOGIC_vector(3 downto 0);
           start : in  STD_LOGIC;
           STOP : out  STD_LOGIC;
           LOAD_CMD : out  STD_LOGIC;
           ADD_CMD : out  STD_LOGIC;
           BYPASS_CMD : out  STD_LOGIC);
end controller;

architecture Behavioral of controller is

--declare states

type state_typ is (IDLE, INIT, TEST, ADD, BYPASS);

signal  state : state_typ;


begin


process(reset,clk)

  variable i : STD_LOGIC := '0';

  begin

    if reset = '0' then
       state <= IDLE;

     else if clk'event and clk = '1' then

        case state is 

          when IDLE =>
            if START = '1' then
             state <= INIT;
             else
             state <= IDLE;
             end if;

          when INIT =>
            state <= TEST;

          when TEST =>
            if ring_k_1 = '1' then
             state <= IDLE;
             else if ring_k_1 = '0' and b_n(i) = '0' then
             state <= BYPASS;
             i <= i+1;
             else if (ring = '0' and b_n(i) = '1') then
             state <= ADD;
             i <= i+1;
          end if;

        end case; --Syntax error near "case".

     end if; --end for the clock event

    end process; --Syntax error near "process".

    STOP <= '1' when state = IDLE else '0';
    ADD_CMD <= '1' when state = ADD else '0';
    BYPASS_CMD <= '1' when state = BYPASS else '0';
    LOAD_CMD <= '1' when state = INIT else '0';

end Behavioral; --Syntax error near "Behavioral"

Recibo un error de sintaxis cuando se compila. He puesto la descripción del error como un comentario en el código. ¿Puede alguien ayudarme en cuanto a lo que debería ser la corrección?

Gracias por las entradas. Hice la corrección según lo sugerido. Ahora no estoy obteniendo esos errores, en lugar de eso, recibí algunos errores más y los corregí todos, pero aún obtengo dos errores más. A continuación se muestra el código modificado

entity controller is
     Port ( 
reset : in  STD_LOGIC;

       clk : in  STD_LOGIC;

       ring_k_1 : in  STD_LOGIC;

       b_n : in  STD_LOGIC_vector(3 downto 0);

       start : in  STD_LOGIC;

       STOP : out  STD_LOGIC;

       LOAD_CMD : out  STD_LOGIC;

       ADD_CMD : out  STD_LOGIC;

       BYPASS_CMD : out  STD_LOGIC);

end controller;

architecture Behavioral of controller is

--declare states

  type state_typ is (IDLE, INIT, TEST, ADD, BYPASS);

  signal  state : state_typ;


  begin


  process(reset,clk)

    variable i : natural := 0;

    begin

      if reset = '0' then

         state <= IDLE;

         STOP <= '1';

       else if clk'event and clk = '1' then

    case state is 

      when IDLE =>

        if START = '1' then

         state <= INIT;

         STOP <= '1';

         else

         state <= IDLE;

         STOP <= '0';

         end if;

      when INIT =>

       LOAD_CMD <= '1';

        state <= TEST;

      when TEST =>

        if ring_k_1 = '1' then

         state <= IDLE;

         elsif ring_k_1 = '0' and b_n(i) = '0' then

         state <= BYPASS;

         BYPASS_CMD <= '1';

         i := i+1;

         elsif (ring_k_1 = '0' and b_n(i) = '1') then

         state <= ADD;

         ADD_CMD <= '1';

         i := i+1;
      end if;

    end case;

   end if; --end for the clock event

end process; --Syntax error near "process".(error 1)

 -- STOP <= '1' when state = IDLE else '0';

 -- ADD_CMD <= '1' when state = ADD else '0';

 -- BYPASS_CMD <= '1' when state = BYPASS else '0';

  --    LOAD_CMD <= '1' when state = INIT else '0';



end Behavioral; --Expecting type  void for <behavioral>.(error 2)

He escrito error 1 y error2 en el comentario para señalar el error. Por favor, sugiera la corrección, ya que soy novato en la codificación vhdl.

Después de una nueva modificación, obtengo el siguiente error. ¡Me rasqué mucho la cabeza pero aún no uso! Aquí está el código modificado y el error es

ERROR: HDLParsers: 164 - "D: /programs_xlinx/BZFAD/controller.vhd" Línea 123. error de análisis, PROCESS inesperado, esperando IF

CÓDIGO:

entity controller is

    Port ( reset : in  STD_LOGIC;

          clk : in  STD_LOGIC;

           ring_k_1 : in  STD_LOGIC_vector(3 downto 0);

           b_n : in  STD_LOGIC_vector(3 downto 0);

           start : in  STD_LOGIC;

           STOP : out  STD_LOGIC;

           LOAD_CMD : out  STD_LOGIC;

           ADD_CMD : out  STD_LOGIC;

           BYPASS_CMD : out  STD_LOGIC);

end controller;

architecture Behavioral of controller is

--declare states

type state_typ is (IDLE, INIT, TEST, ADD, BYPASS);

signal  state : state_typ;


begin


process(reset,clk)

  --variable i : natural := 0;

  variable i : integer range b_n'RIGHT to b_n'LEFT := b_n'RIGHT; -- 3 downto 0

  begin

        if reset = '1' then

       state <= IDLE;

           STOP <= '1';

    else if clk'event and clk = '1' then

        case state is 

          when IDLE =>

                       if START = '1' then

                       state <= INIT;

               else

                       state <= IDLE;

                       STOP <= '1';

                       end if;

          when INIT =>

                  LOAD_CMD <= '1';

                  state <= TEST;

          when TEST =>

                       if ring_k_1(3) = '1' then

                         state <= IDLE;

                             STOP <= '1';
--          


            elsif ring_k_1(3) = '0' and b_n(i+1) = '0' then

                             state <= BYPASS;

                             BYPASS_CMD <= '1';

                -- i := i+1;

                             if i = b_n'LEFT then 

                             i := 0;   

                             else 

                             i:= i + 1; 

                             end if;

            elsif (ring_k_1(3) = '0' and b_n(i+1) = '1') then

                             state <= ADD;

                             ADD_CMD <= '1';

                 if i = b_n'LEFT then 

                             i := 0;           -- or use i := b_n'RIGHT;

                             else 

                             i:= i + 1; 

                             end if;

         end if;


        when BYPASS =>

                state <= TEST;

        when ADD =>

                state <= TEST;


        end case;

     end if; --end for the clock event

end process;



end Behavioral;
    
pregunta user40295

2 respuestas

2

En general, un error de análisis está asociado con una línea de su descripción de diseño de VHDL. Los comentarios que están cerca realmente no lo cortan y el mensaje de error real puede ser significativo.

library ieee;
use ieee.std_logic_1164.all;

entity controller is
    Port ( 
        reset:      in  std_logic;
        clk:        in  std_logic;
        ring_k_1:   in  std_logic;
        b_n:        in  std_logic_vector(3 downto 0);
        start:      in  std_logic;
        STOP:       out std_logic;
        LOAD_CMD:   out std_logic;
        ADD_CMD:    out std_logic;
        BYPASS_CMD: out std_logic
    );
end controller;

architecture Behavioral of controller is

    --declare states
    type state_typ is (IDLE, INIT, TEST, ADD, BYPASS);

    signal  state : state_typ;

begin


    process(reset,clk)
        variable i : natural := 0; 
    begin
        if reset = '0' then
            state <= IDLE;
        elsif clk'event and clk = '1' then
            case state is 
                when IDLE =>
                    if START = '1' then
                        state <= INIT;
                    else
                        state <= IDLE;
                    end if;
                when INIT =>
                    state <= TEST;
                when TEST =>
                    if ring_k_1 = '1' then
                        state <= IDLE;
                    elsif ring_k_1 = '0' and b_n(i) = '0' then
                        state <= BYPASS;
                        i := i+1;
                    elsif ring_k_1 = '0' and b_n(i) = '1' then
                        state <= ADD;
                        i := i+1;  
                        -- How do you prevent b_n(i) from going outside of 3 downto 0?
                    end if;
                when others =>  -- when ADD, when BYPASS  must have all states

            end case; 
        end if;
    end process;

    STOP <= '1' when state = IDLE else '0';
    ADD_CMD <= '1' when state = ADD else '0';
    BYPASS_CMD <= '1' when state = BYPASS else '0';
    LOAD_CMD <= '1' when state = INIT else '0';

end Behavioral;

Además de las correcciones que hizo, hay al menos un error más con la declaración del caso, en el sentido de que todas las opciones deben estar representadas, le falta representación para los estados ADD y BYPASS:

  

Si la expresión es el nombre de un objeto cuyo subtipo es localmente   estática, ya sea un tipo escalar o un tipo de matriz, entonces cada valor de la   El subtipo se debe representar una vez y solo una vez en el conjunto de opciones   de la declaración del caso, y no se permite ningún otro valor; ...
  (Desde el LRM)

No sé lo suficiente sobre la intención de su diseño para agregar sucursales de los estados ADD y BYPASS .

Comente el when others => y ghdl nos dice directamente que dos enumeraciones de estado están representadas entre las opciones:

  

ghdl -a controller.vhdl
  controller.vhdl: 34: 13: no hay opciones para agregar a omitir
  ghdl: error de compilación

Los mensajes de error no están estandarizados en VHDL, ghdl señaló la línea en la que comienza la declaración del caso, pero sí especificó el rango de valores que faltan en las opciones especificadas.

Note que el mecanismo simple utilizado para permitir que el análisis se complete con éxito no maneja las transiciones de estado y probablemente debería hacerlo.

Tampoco hay nada aparente que mantenga a b_n (i) dentro del rango del índice 3 hasta 0. Los operadores aritméticos escalares tienen su significado matemático convencional, mientras que la evaluación de b_n (i) se verificará en los límites, lo que podría generar un error en el tiempo de ejecución. ser evaluados y b_n(i) como índice y caer fuera del rango del índice de subtipo.

Los resultados aritméticos de enteros pueden estar fuera de rango para su uso como un índice para b_n. Solo está utilizando i , así que solo debe limitar + a i ( 3 ).

Si sintetiza el diseño, desearía variar la restricción b_n'LEFT para especificar la cantidad de bits necesarios para implementar i (como un contador en este caso).

La restricción del rango i para la síntesis implica evaluar el i antes de asignar el nuevo valor 3 para evitar un error fuera del rango. Si i = 3, establezca i a i en su lugar, de lo contrario agregue 0 a 'i1.

En lugar de 1 use

if i=3 then 
    i := 0; 
else 
    i:= i+1; 
end if;

Para síntesis declare el rango de i:

variable i : integer range 0 to 3 := 0; 

si i := i+1; fue el resultado de una declaración constante o genérica y podría usar eso en lugar de 3:

variable i : integer range b_n'RIGHT to b_n'LEFT := b_n'RIGHT; -- 3 downto 0

o

variable i : integer range b_n'RANGE := b_n'RIGHT; -- where b_n'RIGHT = 0

Y en lugar de b_n'LEFT en su uso del código original

if i = b_n'LEFT then 
    i := 0;           -- or use i := b_n'RIGHT;
else 
    i:= i + 1; 
end if;

Addendum

Tu código modificado tenía un i := i+1; en lugar de else if donde se estaba evaluando el reloj:

library ieee;
use ieee.std_logic_1164.all;

entity controller is
    port ( 
        reset:      in  std_logic;
        clk:        in  std_logic;
        ring_k_1:   in  std_logic_vector(3 downto 0);
        b_n:        in  std_logic_vector(3 downto 0);
        start:      in  std_logic;
        STOP:       out std_logic;
        LOAD_CMD:   out std_logic;
        ADD_CMD:    out std_logic;
        BYPASS_CMD: out std_logic
    );
end controller;

architecture behavioral of controller is
--declare states
    type state_typ is (IDLE, INIT, TEST, ADD, BYPASS);
    signal  state : state_typ;

begin

    process(reset,clk)
        --variable i : natural := 0;
        variable i : integer range b_n'RIGHT to b_n'LEFT := b_n'RIGHT; -- 3 downto 0
    begin
        if reset = '1' then
            state <= IDLE;
            STOP <= '1';
        elsif clk'event and clk = '1' then  -- else if
            case state is 
                when IDLE =>
                    if START = '1' then
                        state <= INIT;
                    else
                        state <= IDLE;
                        STOP <= '1';
                    end if;
                when INIT =>
                    LOAD_CMD <= '1';
                    state <= TEST;
                when TEST =>
                    if ring_k_1(3) = '1' then
                        state <= IDLE;
                        STOP <= '1';
                    elsif ring_k_1(3) = '0' and b_n(i+1) = '0' then
                        state <= BYPASS;
                        BYPASS_CMD <= '1';
                    -- i := i+1;
                        if i = b_n'LEFT then 
                            i := 0;   
                        else 
                            i:= i + 1; 
                        end if;
                    elsif (ring_k_1(3) = '0' and b_n(i+1) = '1') then
                        state <= ADD;
                        ADD_CMD <= '1';
                        if i = b_n'LEFT then 
                            i := 0;           -- or use i := b_n'RIGHT;
                        else 
                            i:= i + 1; 
                        end if;
                    end if;
                when BYPASS =>
                    state <= TEST;
                when ADD =>
                    state <= TEST;
            end case;
         end if; --end for the clock event
    end process;

end behavioral;

El analizador que estaba usando se quejó de que debería haber elsif después de if en lugar del proceso (arriba de end ). Muestra, entre otras cosas, el valor de la legibilidad, así como la inclusión de los mensajes de error reales:

cont_mod.vhdl:72:9: 'if' is expected instead of 'process'  
ghdl: compilation error  

Tenga en cuenta el número de línea: la posición del carácter no fue particularmente útil, además de decirnos que a otra persona le faltaba una declaración de end behavioral adjunta. Si no me equivoco, este es el mismo problema que Vladimir Craver señaló en su respuesta, que usé como punto de partida.

Yo sugeriría que una pregunta separada podría estar en orden si necesita ayuda con los resultados de la simulación.

Ahora que debe analizar su descripción de diseño para el controlador de entidad, quizás pueda hacer otra pregunta si tiene problemas con la funcionalidad.

Reformateé tu segunda publicación de código para permitir que el error se muestre un poco más fácil. A través de la sangría no vemos ningún nivel faltante de end , lo que deja un error de sintaxis que implica la necesidad de otro nivel. end if y else in

    else if clk'event and clk = '1' then

implica un if separado para end if y else .

    
respondido por el user8352
1

Eso es un problema que me atrapó también.

en vhdl la sentencia "else if" es elsif y NO else if.

Lo que estás haciendo en realidad es algo como:

if <condition> then
    statement1;
    statement2;
else  --the then after the else is implied
    if <condition> then
        --this actually is an if annidated in the outer one
        statement3;
        statement4;
    end if;
--missing end if for the first if!    

Ya sea que corrijas tu código agregando un final si es tuyo (o, si lo prefieres, usa la palabra clave elsif).

    
respondido por el Vladimir Cravero

Lea otras preguntas en las etiquetas