1 votos

Error de sintaxis en el código VHDL

Estoy tratando de implementar el módulo controlador como un FSM utilizando VHDL, a continuación es 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"

Me da error de sintaxis al compilar. He puesto la descripción del error como un comentario en el código. ¿Puede alguien ayudarme a corregirlo?

Gracias por las aportaciones. Hice la corrección como se sugirió. Ahora ya no me salen esos errores, en cambio me salen otros y los he corregido todos, pero siguen saliendo dos errores más. Abajo está 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 he rascado mucho la cabeza pero sigue sin funcionar. 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;

2voto

En general, un error de análisis está asociado a una línea de su descripción de diseño VHDL. Los comentarios que se acercan no son suficientes 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 hiciste hay al menos un error más con la declaración del caso, en que todas las opciones deben ser representadas te falta representar los estados ADD y BYPASS:

Si la expresión es el nombre de un objeto cuyo subtipo es localmente estático, ya sea un tipo escalar o un tipo array, entonces cada valor del subtipo debe representarse una y sólo una vez en el conjunto de opciones de la sentencia case, y no se permite ningún otro valor;...
(Del LRM)

No sé lo suficiente sobre la intención de su diseño para añadir ramas de estados ADD y BYPASS .

Comenta el when others => y ghdl nos dice directamente que se representan dos enumeraciones de estado entre las opciones:

ghdl -a controlador.vhdl
controller.vhdl:34:13: no hay opciones para añadir a la derivación
ghdl: error de compilación

Los mensajes de error no están estandarizados en VHDL, ghdl apuntaba a la línea en la que comienza la sentencia case pero sí especificaba el rango de valores que faltaban en las opciones especificadas.

Obsérvese 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 de índices de 3 a 0. Los operadores aritméticos escalares tienen su significado matemático convencional, mientras que la evaluación de b_n(i) se someterá a una comprobación de límites que podría dar lugar a un error en tiempo de ejecución si b_n(i) ser evaluado y i como un índice y caen fuera del rango del índice del subtipo.

Los resultados de la aritmética de enteros pueden estar fuera de rango para su uso como índice de b_n. Sólo se utiliza + por lo que sólo hay que limitar i a 3 ( b_n'LEFT ).

Si se sintetiza el diseño se querrá restringir el rango i para especificar el número de bits necesarios para implementar i (como contador en este caso).

Limitación del alcance i para la síntesis implica evaluar para 3 antes de asignar el nuevo i para evitar un error de fuera de rango. Si i = 3, se establece i a 0 en su lugar, de lo contrario añada 1 a `i1.

En lugar de i := i+1; utilice

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

Para la síntesis declarar el rango de i:

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

si b_n'LEFT fueran el resultado de una declaración y uso genérico o constante podrías utilizarlo 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 i := i+1; en su código original utilice

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

Anexo

Su código modificado tenía un else if en lugar de elsif donde se evaluaba 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 utilizando se quejaba de que debía haber if siguiendo end en lugar de procesar (por encima de end behavioral ). Muestra, entre otras cosas, el valor de la legibilidad, además de incluir los mensajes de error reales:

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

Obsérvese que el número de línea : la posición de los caracteres no era especialmente útil más que para decirnos que faltaba algo más que encerrar end declaración. Si no me equivoco, este es el mismo problema que Vladimir Craver señaló en su respuesta, que yo utilicé como punto de partida.

Sugiero que se haga una pregunta aparte si se necesita ayuda con los resultados de la simulación.

Ahora que la descripción de su diseño para el controlador de la entidad debe analizar tal vez usted podría hacer una pregunta separada en caso de tener problemas con la funcionalidad.

He reformateado tu segunda publicación de código para que el error aparezca un poco más fácilmente. A través de la indentación no vemos ningún nivel perdido de end if que deja un error de sintaxis que implica la necesidad de otro nivel. else y if en

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

implica una end if para el else y if .

1voto

Sammo034 Puntos 26

Ese es un truco que me atrapó a mí también.

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

Lo que estás haciendo en realidad es algo así:

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!    

O bien arreglas tu código añadiendo algunos if's finales o bien (sabia elección) utilizas la palabra clave elsif.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X