Cómo decide Verilog en eventos simultáneos

1

Digamos que tenemos una función, tan simple como f(x) = x . Supongamos que tenemos un reloj que marca cada 20 nanosegundos y decimos que cambiamos x como deseemos.

Diga que hay una marca de reloj por venir, en t = 20ns exactamente (lo que sea que signifique) Digamos que x había sido 0 desde el t = 0ns desde entonces, y de alguna manera cambiamos el x en 1 nuevamente exactamente t = 20ns .

Ahora describe este escenario en Verilog. La pregunta es, ¿qué sería f en t = 21ns ?

Aquí están los códigos Verilog que había escrito, junto con la captura de pantalla de la ventana de simulación de Xilinx ISim.

El circuit.v

module circuit(f, x, clk, rst);

    output f;
    input x, clk, rst;

    wire d, q;

    d_flip_flop flipper (q, d, clk, rst);

    assign f = q;
    assign d = x;

endmodule

El d_flip_flop.v

module d_flip_flop(q, d, clk, rst);

    output reg q;
    input d, clk, rst;

    always @(posedge clk, posedge rst)
    begin
        if (rst)
            q <= 1'b0;
        else
            q <= d;
    end

endmodule

Y los pruebo con este tester.v

module tester;

    reg x, clk, rst;
    wire f;

    circuit uut (f, x, clk, rst);

    initial clk <= 0;
    always #10 clk <= ~clk;

    initial
    begin
        x <= 0;
        rst <= 0;

        rst <= #2 1;
        rst <= #4 0;

        #10 x <= 1;
    end

endmodule

Y aquí está la forma de onda que obtengo:

¿Es este un comportamiento definido de Verilog para realizarlo? En caso afirmativo, ¿cómo decide qué es lo primero que debe aparecer en tales circunstancias?

Los asistentes me dijeron el curso que lo que realmente debería estar viendo es realmente lo opuesto, por supuesto, y debo estar haciendo algo mal si veo lo contrario. Me gustaría saber qué estoy haciendo mal, necesito ayuda, y no me brindan esta ayuda en particular. ¿Alguien aquí podría ayudar?

    
pregunta ThoAppelsin

2 respuestas

2

El estándar Verilog garantiza que todos los eventos dentro de un bloque begin..end programado para el mismo tiempo de simulación se procesarán en el orden en que se declaran. Aparte de este escenario específico, cualquier otro evento puede ser retirado de la cola en cualquier orden.

Dicho esto, se puede esperar cualquier comportamiento porque ambos eventos están programados para el mismo tiempo de simulación en diferentes bloques de código. Sin embargo, el comportamiento que tiene es lo que generalmente se acepta como correcto, porque los datos no se muestrean en el mismo tiempo de simulación en que se generan.

Cosas que podrías hacer para mejorar la previsibilidad:

  1. Genera tu reloj usando una asignación de bloqueo.

    always #10 clk = ~clk;
    
  2. Generar estímulos en eventos de reloj.

    initial
    begin
        repeat (2) @(posedge clk)
            x <= 1;
    end
    

Esta codificación garantizará, en general, que la simulación RTL se comportará como la lista de red final a nivel de gatillo sin necesidad de demoras en los datos. En una simulación RTL, los datos no se deben generar y muestrear en el mismo tiempo de simulación.

    
respondido por el Vitor
-1

En lugar de usar d_flip_flop flipper (q, d, clk, rst); use d_flip_flop flipper (q, x, clk, rst); en el módulo de nivel superior.

    
respondido por el Jithin

Lea otras preguntas en las etiquetas