Verilog to Logic Diagram

2

Estoy tratando de dibujar el diagrama lógico de este Código Verilog de un contador usando mux, d flip flop, nand, y.

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;
case(s)
2'b00: mux=in[0];
2'b01: mux=in[1];
2'b10: mux=in[2];
2'b11: mux=in[3];
endcase
endfunction
always @(RB) begin
if (!RB)
assign q=1'b0;
else
deassign q;
end
always @(posedge CLK) q=mux({D,D,~q,q},{L,Ti});
always @(Ti or q) tout=Ti&q;
assign To=tout;
assign Q=q;
assign QN=~q;
endmodule

He dibujado esto pero no estoy seguro. ¿Tiene alguna sugerencia relacionada con el diagrama lógico de este código?

    
pregunta bieaisar

1 respuesta

3

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.

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas