Estoy diseñando un contador asíncrono mod-3. Se espera que el circuito cuente de 0 a 2 y los flip flops se configuren tan pronto como q se convierta en 3.

0

module mod3counter(
input clk,
output [1:0] q
);

wire rst ;
nand a1(rst,q[0],q[1]);

tff t1(clk, rst, q[0]);
tff t2(q[0],rst,q[1]);

endmodule

module tff(
input clk,rst,
output reg q
);

initial q = 0 ;

always @(negedge clk or negedge rst) begin
    if(~rst) q <= 0;
    else    q <= ~q ;
end 
endmodule

El banco de pruebas es simplemente dos líneas de código que ejecutan el reloj.

    

1 respuesta

1

Dos grandes problemas:

  1. No reiniciar el flop de manera asíncrona. Esto incluía indirectamente a través de la lógica combinacional. Puede funcionar en la simulación (en su caso, parece que no es así), pero en FGPA / ASIC el pulso tiene un buen cambio de ser demasiado corto y puede tener metástasis. Agregar retrasos para crear un pulso más limpio es una curita; puede funcionar en las condiciones que intente y luego fallará inesperadamente con diferentes desvíos, parásitos u otras desviaciones. También es importante mantener todas las señales de configuración / reinicio asíncronas sin problemas, de lo contrario, corre el riesgo de configuración / reinicio involuntario o metastabilidad.

  2. No utilice contadores en cadena (donde el q de un flop funciona como el reloj de otro flop) no se recomienda para diseños reales. Pueden tener una mala sincronización y salidas con fallas. Los flops reales tienen retrasos de reloj a q, puede imitar el retraso en Verilog con un retraso sin bloqueo (por ejemplo, q <= #1 ~q; ). Une un montón de esto y verás que el valor tarda más en establecerse.
    Los contadores de cadena de margaritas son buenos para aprender, pero es mejor si todos los flops están controlados por el mismo reloj. A diferencia del punto 1, es poco probable que un pequeño contador en cadena tipo margarita cause problemas importantes, pero es mejor no ponerse en práctica en su uso.

Mantenga el diseño síncrono en un dominio de reloj. Ejemplo:

always @(negedge clk or negedge rst) begin
  if (!rst) begin
    q <= 2'b00;
  end
  else if (q < 2) begin
    q <= q + 2'b01;
  end
  else begin
    q <= 2'b00;
  end
end
    
respondido por el Greg

Lea otras preguntas en las etiquetas