VHDL Knight Rider

-2

Soy novato en VHDL. En mi código, todo parece correcto pero el código no funciona correctamente. No pude encontrar dónde está mi culpa. ¿Alguna solución?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Knight_Rider is
port    (
        in_CLK:  in     std_logic;
        out_LED: out    std_logic_vector(9 downto 0)
        );
end entity;

architecture Behavioral of Knight_Rider is

signal shift_reg:   std_logic_vector (9 downto 0):= "0000000001";
signal counter:     std_logic_vector (19 downto 0);
signal i:           integer range 0 to 9;
signal res:         std_logic:= '0';

begin 
CLOCK:process(in_CLK)
            begin
                if(rising_edge(in_CLK )) then
                        counter <= counter + 1;
                    end if;
                end process;
            process(counter(19))
                begin
                    if(rising_edge(counter(19)))then
                        if (res = '0') then
                            for i in 0 to 8 loop
                                shift_reg(i+1)<= shift_reg (i);
                                    res <= '1';
                            end loop;
                      else 
                            for i in 9 downto 1 loop
                             shift_reg(i-1) <=shift_reg(i);
                              res <= '0';
                    end loop;
                end if;
            end if;
        end process;
    out_LED <= shift_reg;
end architecture;

EDITAR: He cambiado el código un poco y ahora funciona perfectamente.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Karasimsek is

        Port (   CLK : in   STD_LOGIC;
                 LED : out  STD_LOGIC_VECTOR (9 downto 0));

end Karasimsek;

architecture Behavioral of Karasimsek is
         signal shift_reg: STD_LOGIC_VECTOR (9 downto 0) := "0000000001";
         signal sayac:      integer range 0 to 50000000;
         signal yonsec:     std_logic:= '0';
         signal pulse:     std_logic:= '0';
 begin

    process( CLK )

          begin
                if(rising_edge(CLK)) then 

                        if (sayac < 50000000) then 

                                sayac <= sayac + 1 ;
                        else

                                sayac <= 0;
                                          pulse <= '1';

                if (pulse = '1') then                         

                    if (yonsec = '0') then

                        shift_reg <= shift_reg (8 downto 0) & '0';

                        if (shift_reg(8) = '1') then

                            yonsec <= '1';

                            end if;

                    elsif (yonsec = '1') then

                        shift_reg <= '0' & shift_reg (9 downto 1);

                            if (shift_reg(1) = '1') then

                                yonsec <= not yonsec;

                        end if;

                    end if;

                end if;

            end if;

        end if;

    end process;

LED <= shift_reg;

end Behavioral;
    
pregunta Griffo

1 respuesta

1

Ha pasado un tiempo desde que uso VHDL, pero parece que su bucle if(res...)else simplemente rebota de un lado a otro. Piénsalo de esta manera,

1) Establezca su condición de inicio (lo hizo y se ve bien).

2) Usa res para cambiar la dirección del movimiento. Esto significa que no lo cambias cada vez que counter tiene un borde ascendente (esto está causando tu parpadeo). Lo cambia cuando el primer bit o el último bit de shift_reg es 1 . Su condición inicial es 0000000001 . Digamos que el primer bit a la izquierda (un cero) es "bit # 9" y el último bit a la derecha (a uno) es "bit # 0". res se debe establecer en 0 (mover el bit a la izquierda) cuando "bit # 0" es igual a 1 . Se debe establecer en 1 cuando "bit # 9" es igual a 1 . Probablemente no deberías establecer res en el bloque de desplazamiento. Lo configuré de forma independiente después de que se complete el turno.

3) Finalmente, debe asegurarse de que el último bit de cada dirección se alimente al primer bit. (Podría hacer esto mediante programación, pero un circuito real tendría que actuar de esta manera). Una vez más, su condición de inicio es 0000000001 , lo que significa que res debería ser cero. En cada flanco ascendente de counter , cambia todo a la izquierda un bit y cambia el último bit (bit # 9) al bit # 0. En la otra dirección, está cambiando el bit # 0 al bit # 9. Así es como mantienes tus ceros en su lugar. En otras palabras, almacene el bit 9, haga un bucle hacia arriba 0-8, luego asigne su bit almacenado 9 al bit 0. En la otra dirección: almacene el bit 0, haga un bucle hacia abajo 9-1, luego asigne el bit 0 al bit 9.

Sospecho que # 2 es tu mayor problema. Eso es lo que impide que el registro siga avanzando.

Finalmente, tome un momento a Google "VHDL Johnson Ring Counter". No es exactamente lo que estás tratando de hacer, pero es aproximadamente el 90% de eso. Le ayudará con su código porque muchos de los ejemplos imitan los diseños de registro de turnos reales, incluido el bucle de retroalimentación faltante.

    
respondido por el JBH

Lea otras preguntas en las etiquetas