Comience ordenando el código. El espacio en blanco lo hace legible.
module CNT1 (Q, QN, To, CLK, D, L, RB, Ti);
output Q, QN, To;
input CLK, D, L, RB, Ti;
reg q, tout;
function mux;
input [3:0] in;
input [1:0] s;
begin
case(s)
2'b00: mux=in[0];
2'b01: mux=in[1];
2'b10: mux=in[2];
2'b11: mux=in[3];
endcase
end endfunction
always @(RB) begin
if (!RB) begin
assign q=1'b0;
end else begin
deassign q;
end
end
always @(posedge CLK) begin
q = mux({D,D,~q,q},{L,Ti});
end
always @(Ti or q) begin
tout = Ti&q;
end
assign To=tout;
assign Q=q;
assign QN=~q;
endmodule
A continuación puedes comenzar a descomponerlo. Veamos los tres bloques siempre primero. De abajo hacia arriba:
always @(Ti or q) begin
tout = Ti & q;
end
Eso es bastante sencillo. Solo una puerta AND Su diagrama lo identifica con éxito.
Siguiente:
always @(posedge CLK) begin
q = mux({D,D,~q,q},{L,Ti});
end
Ese es un poco más incómodo, ya que utiliza una función de llamada. Ahora, mirando la función, puede ver que no es más que un mux (como su nombre indica) que tiene 4 entradas de datos y una selección de 2 bits. Cada vez que hay un borde positivo del reloj, q
se actualiza con la salida del mux.
Este bloque es un lugar donde su diagrama sale mal. Tenemos las siguientes declaraciones de asignación:
assign Q = q;
assign QN = ~q;
Debido a que Q = q
, su salida Q
en su diagrama no debería ser no la salida mux, sino la salida del registro. Además, le falta la salida QN
, que es la inversa de q
.
Finalmente tenemos:
always @(RB) begin
if (!RB) begin
assign q=1'b0;
end else begin
deassign q;
end
end
Esto es feo en mi opinión. Está utilizando algo llamado "Asignación continua de procedimiento". Lo que el bloque está diciendo es que si RB
es 0
, fuerza la salida de q
a 0
. Cuando RB
va a 1
, libera la salida q
.
El término clave aquí es "liberar". Cuando se libera una señal, mantendrá su valor hasta que otro bloque la actualice .
Esto significa que es no inferir un mux, porque un mux cambiaría inmediatamente el valor a q
después de que se libere la señal, mientras que el comportamiento que necesitamos es mantener el valor actual hasta la próxima vez que se cambie q
.
Este comportamiento es en realidad una señal asincrónica de restablecimiento . El código equivalente para q
, que combina ambos bloques siempre para que sea mucho más legible, es:
always @(posedge CLK or negedge RB) begin
if (!RB) begin
q = 1'b0;
end else begin
q = mux({D,D,~q,q},{L,Ti});
end
end
Ahora debería poder corregir y completar su diagrama lógico.