VHDL - La simulación D flip flop va mal

2

Estoy tratando de simular un flip-flop D usando el código VHDL que compilo y ejecuto usando GHDL y luego trazo la forma de onda usando GTKwave.

El problema es que mi maestro me dijo que, al usar flip-flops D, si el reloj y la señal de datos aumentan al mismo tiempo, el estado del flip-flop no se actualiza hasta el siguiente flanco ascendente del reloj. Pero cuando simulo ese comportamiento en un banco de pruebas, obtengo esto:

Loqueparecefuncionarperfectamente,aexcepcióndelaúltimaseñalDenaumento,dondeQdeberíaactualizarseaALTOdespuésde10nanosegundos.Nosédóndeestáelproblemaypuededeberseaunacodificaciónincorrecta,porloqueledoymicódigosipuedeayudararesolverelproblema.

Dflip-flopmodule:

libraryIEEE;useIEEE.STD_LOGIC_1164.all;entityd_flip_flopisport(clk:inSTD_LOGIC;d:inSTD_LOGIC;reset:inSTD_LOGIC;q:outSTD_LOGIC);endentity;architectureasynchronousofd_flip_flopisbeginprocess(clk,reset)beginifreset='1'thenq<='0';elsifclk'eventandclk='1'thenq<=d;endif;endprocess;endarchitecture;

Dbancodepruebasflip-flop:

libraryIEEE;useIEEE.STD_LOGIC_1164.all;entityd_flip_flop_tbisendentity;architecturetestbenchofd_flip_flop_tbiscomponentd_flip_flopport(clk:inSTD_LOGIC;d:inSTD_LOGIC;reset:inSTD_LOGIC;q:outSTD_LOGIC);endcomponent;signalclk,d,reset,q:STD_LOGIC;beginuut:d_flip_flopportmap(clk,d,reset,q);processbeginclk<='0';waitfor5ns;clk<='1';waitfor5ns;endprocess;processbeginreset<='1';d<='1';waitfor12500ps;reset<='0';waitfor10ns;d<='0';waitfor12500ps;d<='1';waitfor20ns;assertfalsereport"End of simulation" severity failure;
        wait;
    end process;
end architecture;
    
pregunta Jaime_mc2

4 respuestas

3
  

El problema es que mi profesor me dijo que, al usar flip-flops D, si el reloj y la señal de datos aumentan al mismo tiempo, el estado del flip-flop no se actualiza hasta el siguiente flanco ascendente del reloj.

Esta es una descripción altamente idealizada, y ni siquiera una muy útil.

Un modelo mucho mejor para el comportamiento, que todavía es bastante simple, es que

  

Si la entrada es estable durante el borde del reloj, para un "tiempo de configuración" de antemano y un "tiempo de espera" después, ese mismo nivel estable emergerá de la salida después de un "tiempo de demora".

Y no se ofrecen garantías si, como en su simulación, la entrada está cambiando dentro de la ventana de configuración y retención.

En los circuitos reales, la distribución del reloj está diseñada para ser más rápida que la distribución de la señal, de modo que los cambios ocurren después del borde del reloj. Y el requisito de retención en la lógica moderna es casi cero. En tales casos las cosas funcionan.

Pero si los retrasos en la lógica que produce la entrada del flip-flop suman casi un ciclo completo de reloj, puede tener problemas con las infracciones de tiempo de configuración.

Y si está haciendo su propio diseño de PCB y no tiene cuidado de hacer que el reloj sea el rastro más corto, entonces las señales sincronizadas con el reloj en una parte del circuito pueden superarlo y verse como una transición en otra parte antes el borde del reloj, que también infringe el requisito de configuración y retención.

    
respondido por el Ben Voigt
0

El problema está en cómo estás conduciendo d en tu banco de pruebas.

Aunque en hardware, la lógica se ejecutaría simultáneamente, el simulador tiene que ejecutar una de las asignaciones antes que la otra como un paso de tiempo delta. Dado que el proceso en su banco de pruebas no es sensible a clk , la simulación tiene problemas para decidir si clk<='1' o d<='1' ocurren primero.

Mi solución preferida sería registrar el proceso en el banco de pruebas en lugar de confiar en las declaraciones wait for , pero si está buscando una solución de una línea, agregue wait until clk'event and clk='1'; entre la línea d<='0' y el d<='1' línea. Esto permitirá al simulador saber que el evento del reloj se produce antes de la transición d<='1' .

    
respondido por el ks0ze
0

Para esta simulación, asigna d a HIGH al mismo tiempo que aumenta el reloj.

La simulación toma ese valor y lo asigna a d. Al mismo tiempo, entra en su ruta elseif porque el reloj está alto y asigna el valor de D.

    
respondido por el zoder
0
  

... y puede deberse a una codificación incorrecta, por lo que le doy mi código si puede ayudar a resolver el problema.

Sí, es una codificación incorrecta, una codificación de banco de pruebas incorrecta.

Estás intentando configurar bordes para que sean simultáneos, lo que es una mala idea de todos modos. En la vida real, los bordes que son simultáneos (dentro de la definición de los tiempos de configuración y retención) son peligrosos. Podrían llegar en cualquier orden, o podrían hacer que la salida sea metaestable, lo que es incluso peor que no saber si se supone que la salida es 0 o 1.

Aparte de la conveniencia de producir cambios simultáneos, la forma en que lo has hecho no es la forma de hacerlo. Tiene dos procesos diferentes, uno múltiplos en espera de 5 nS, el otro espera 12.5nS, luego 10nS, luego 12.5nS, con la esperanza de que se alineen a 35nS.

Una forma bien conocida de hacer las cosas mal al computar es asumir que los números de punto flotante son exactos. Por ejemplo, 1.0 + 0.1 - 1.1 no es 0.0, de todos modos no se duplica en IEE754. Es probable que sus dos formas diferentes de llegar a 35nS sean diferentes, al menos en los pocos niveles de LSB.

Si aún desea probar cambios simultáneos, consulte la documentación del simulador VDHL para ver si los genera al mismo tiempo en el mismo proceso, los implementará simultáneamente o si aún se ordenarán.

    
respondido por el Neil_UK

Lea otras preguntas en las etiquetas