Circuito Verilog no síncrono

1

Soy nuevo en Verilog y estaba tratando de hacer un contador de décadas. Simplemente tomé la referencia de un circuito real que implementa el contador de décadas utilizando JK-Flip Flops. Así que escribí un submódulo para JK-Flip Flop y un módulo superior que conectaría todos los Flip-Flops.

Aquí está mi código para el JK-Flip Flop:

module JK(
    input j,
    input k,
    input clk,
    input reset,
    output reg q
    );

initial q=0;

always @ (*)
    begin
        if (reset)
            q=0;
    end

always @ (negedge clk)
    begin
        if (~j&&k)
            q=0;
        else if (j&&~k)
            q=1;
        else if (j&&k)
            q=~q;
    end

endmodule

y mi código para el circuito:

module DECADECOUNTER(
    input clk,
    output q0,
    output q1,
    output q2,
    output q3
    );

JK jk0(1'b1,1'b1,clk,q1&q3,q0);
JK jk1(1'b1,1'b1,q0,q1&q3,q1);
JK jk2(1'b1,1'b1,q1,q1&q3,q2);
JK jk3(1'b1,1'b1,q2,q1&q3,q3);

endmodule

Entonces, la idea es que la última entrada sea un reinicio y borrará todos mis flip-flops si tanto q1 como q3 son 1 (1010).

Pero cuando intento simular el circuito en Xilinx, obtengo el siguiente resultado:

Esta pantalla es desde muy pronto que comienza la simulación. Como puede ver, q0 y q1 son 0 pero q2 y q3 no lo son. Mi conjetura es que después de restablecer q1, la condición q1 & q3 se volvió falsa y, por lo tanto, q2 y q3 se mantuvieron como 1. Esto parece como si el circuito fuera asíncrono. Pero esa no es la forma en que se supone que Verilog funciona, ¿verdad? Si hay algo presente en los puertos, lo ideal es que su valor se propague a otros puertos antes de que cambie. Porque así es como se supone que funciona un circuito del mundo real.

    
pregunta Chirag Arora

2 respuestas

1

Me di cuenta de que era mejor no intentar emular hardware usando código (ya que estaba tratando de emular un circuito de contador de décadas tradicional usando JK-Flip Flop). En su lugar, es mejor escribir un código que emule la salida. Y el resto se debe dejar a Xilinx para que sintetice y convierta el código en una pieza de hardware de trabajo.

Aquí está mi nuevo código para el contador de décadas:

module DecadeCounter(
     input clk,
     input reset,
     output q0,
     output q1,
     output q2,
     output q3
    );

reg [3:0]q;
initial q = 0;

assign q0 = q[0];
assign q1 = q[1];
assign q2 = q[2];
assign q3 = q[3];

always @ (posedge clk or posedge reset)
    begin
        if(reset||q[1]&&q[3])
            q <= 0;
        else
            q <= q + 1'b1;
    end

endmodule

Este código simula realmente bien y la mejor parte es que no viene con las sorpresas habituales y desagradables de Verilog. Es tan natural como escribir código en C / C ++.

    
respondido por el Chirag Arora
2

Dos problemas:

  1. En un bloque siempre secuencial (uno en el reloj) siempre use siempre la "asignación sin bloqueo", que parece ser un signo menor que / igual a (< =).

  2. Nunca asigne nunca a una señal de dos bloques siempre. Si desea que q se reinicie de forma asíncrona, haga que el bloque siempre sea sensible al reloj negativo o al reinicio de posición. A continuación, haga que se reinicie primero, seguido de else para las otras condiciones. Probablemente esto no esté causando su problema ahora, pero eventualmente causará problemas.

respondido por el Matt

Lea otras preguntas en las etiquetas