salida extraña vhdl parpadeando con banco de pruebas

soy nuevo en vhdl y fpga. Actualmente estoy trabajando con una placa basys3 programada en vhdl usando vivado. Hice un decodificador de 3 (binario) a 8 (decimal) con un bucle for. Mi banco de pruebas también tiene un bucle for. Lo que ahora noto es una salida extraña que parpadea entre mis cambios de salida normales. ¿Alguien podría darme una razón para este problema?

principal:

entity bindec38 is
Port ( sw : in STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
       led : out STD_LOGIC_VECTOR (7 downto 0)  := (others => '0'));
end bindec38;

architecture Behavioral of bindec38 is
begin
process (sw)
variable int : integer := 0; 
begin

    int := to_integer(unsigned(sw));
    for j in 0 to 7 loop
        if (int = j) then
           led(int) <= '1'; -- correct schrijven deze led hoog
        else  
           led(j) <= '0'; -- schrijven de andere dan laag tijdens de loop
        end if;
    end loop;
end process;

end Behavioral;

Banco de pruebas:

entity simdec is
--  Port ( );
end simdec;

architecture Behavioral of simdec is

component bindec38 is
    Port ( sw : in STD_LOGIC_VECTOR (2 downto 0);
       led : out STD_LOGIC_VECTOR (7 downto 0));
end component bindec38;

-- input signal
signal sw : STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
-- output singal
signal led : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
begin

UUT: bindec38
Port Map (sw => sw, led => led);

-- sim process
sim_pro: process begin   
for i in 0 to 7 loop
sw <= std_logic_vector(to_unsigned(i, 3));
wait for 100 ns;    
end loop;

wait;
end process;            

end Behavioral;

vea el resultado de la simulación simulación, solo ocurre en 2 de 8 transiciones.

wow primera vez que veo este tipo de cosa en un simulador

Respuestas (2)

Ha diseñado un decodificador asíncrono de n y ha llevado a cabo una simulación posterior a la implementación o temporización.

Debido a que una simulación de temporización utiliza la temporización real de su diseño colocado y enrutado, cada señal tendrá una temporización ligeramente diferente, incluso si las señales son parte del mismo elemento lógico, por ejemplo, swen su caso.

Cualquiera que sea la lógica que use su FPGA para implementar el circuito, debido a que es asíncrono, si las señales llegan a la entrada de esa lógica en diferentes momentos, la salida pasará por estados intermedios en algunos casos cuando su elemento lógico solo haga la transición una vez. Como señala la otra respuesta, estas condiciones de carrera crean pulsos cortos en la salida.

Tomando como ejemplo la transición de swdesde 3a , las posibles transiciones en las señales binarias que representan este número, dependiendo del enrutamiento detallado de estas señales en la FPGA son:4

"011" > "111" > "110" > "100" = 3 > 7 > 6 > 4
"011" > "111" > "101" > "100" = 3 > 7 > 5 > 4
"011" > "010" > "110" > "100" = 3 > 2 > 6 > 5
"011" > "010" > "000" > "100" = 3 > 2 > 0 > 4
"011" > "001" > "000" > "100" = 3 > 1 > 0 > 4
"011" > "001" > "101" > "100" = 3 > 1 > 5 > 4
"011" > "101" > "100" = 3 > 5 > 4
"011" > "110" > "100" = 3 > 6 > 4
"011" > "100" = 3 > 4

Como puede ver, según el enrutamiento y el tiempo resultante, su decodificador uno de n podría ver una variedad de entradas durante la transición en sw, y así producir una variedad correspondiente de salidas. Tenga en cuenta que las transiciones intermedias ocurren en un espacio de tiempo muy corto, típicamente menos de 1 nanosegundo en un FPGA moderno.

Comparemos esto con una de las transiciones que no muestra runts en la salida, cuando swva de 4a 5. Las transiciones posibles son:

"100" > "101" = 4 > 5

Dado que solo cambia un bit, solo hay una transición posible. Como resultado, no verá ningún runter en esta transición, sin importar cómo se enruten las señales.

Ahora pensemos en cómo las herramientas realmente implementarán su circuito. Puede verificar el esquema implementado, pero cada ledsalida debe ser impulsada por un elemento de tabla de búsqueda (LUT) por separado. Puede usar las herramientas para ver la ecuación lógica de cada LUT, pero esencialmente buscarán ver si la swentrada de 3 bits corresponde a ese archivo led. Donde la otra respuesta es incorrecta es que solo porque la lógica se implementa en una sola LUT, no significa que estas condiciones de carrera sean solo un artefacto de simulación.

Relacionando esto con la transición 3a 4, debido a que cada ledsalida se implementa en una LUT diferente, el tiempo visto por cada LUT será diferente. Vemos pulsos cortos en las salidas 1, 2, 6y 7. De esto podemos deducir que la LUT para led(1)vio 3 > 1 > 0 > 4 o 3 > 1 > 5 > 4, led(2)vio 3 > 2 > 6 > 5 o 3 > 2 > 0 > 5, y así sucesivamente.

La forma común de evitar runts es usar un diseño síncrono, es decir, uno que use un reloj. Tenga en cuenta que para que esto funcione de manera confiable, la entrada ( swen este caso) también debe estar sincronizada con clk.

process(clk)
begin
  if (rising_edge(clk)) then
    led <= (others => '0');
    led(to_integer(unsigned(sw)) <= '1';
  end if;
end process;

Ahora, el decodificador de n aún verá las transiciones variables en las entradas de LUT y tendrá runts correspondientes en las salidas de LUT, pero estas salidas alimentarán un registro. Dado que en un sistema síncrono que ha cumplido con la temporización, todas las transiciones se habrán completado en el momento en que se produzca el flanco del reloj, la salida final no tendrá pulsos cortos.

Otra opción es decidir que no te importan estos pulsos pequeños. En un diseño que simplemente activa algunos LED, probablemente no le importe si existe la posibilidad de que el LED incorrecto se ilumine durante 0,5 nanosegundos.

El punto más importante de todo esto es que estos no son solo artefactos de simulación y podrían causar problemas del mundo real en un diseño.

Si en el panorama general, la cosa está siendo impulsada por un contador de alguna forma, a veces puede usar códigos Gray para evitar el problema con los retrasos de Fabric que causan este problema incluso en el caso de LUT único (@scary_jeff tiene razón en eso). El caso de LUT único elimina el retraso lógico de la imagen, pero deja los tiempos de propagación a través de la estructura.

Lo que dice es que ocurre solo cuando dos de las entradas cambian de estado simultáneamente...

Básicamente, al menos en lo que respecta al simulador, tiene una condición de carrera en la que la lógica que impulsa una salida tiene dos rutas diferentes con diferentes retrasos de propagación y, por lo tanto, obtiene un pulso corto hasta que el segundo conjunto de lógica se pone al día. Si tiene mucho en el esquema que produce su herramienta, debería ver esto.

Tenga en cuenta que esto puede suceder o no en un circuito sintetizado en una matriz de puerta real, ya que supongo que con solo 3 entradas en juego, todo colapsará a 1 LUT por salida, lo que claramente no tiene este problema.

Este es probablemente un artefacto de simulación (pero es algo que puede obtener en lógica asíncrona) en el sentido de que una ruta que conduce esas salidas tiene una puerta más con ciclos delta y luego otra para que vea la condición de carrera.