Máquina de estados finitos, código Verilog

0

Lo tengo todo ahora mismo, pero la salida que deseo debería ser 00 00 11 00 00 00 00 00 00 00 00 cuando el reloj es 1 (z1z0). ¿Alguien puede decirme qué está mal con mi código? He revisado mi Kmap varias veces.

LosJKFFquedeboimplementarson:

module csm51a_proj3(
input r,
input x1,
input x0,
input clk,
output z0,
output z1
);

jkff i_jkff
( 
.r(r),
.x1(x1),
.x0(x0),
.clk(clk),
.z0(z0),
.z1(z1)
);  
endmodule

A continuación se muestra la implementación jkff:

    module jkff(
input clk, r, x1, x0,
output wire z1,z0
);
reg s0,s1;
initial begin s0<=1'b0; s1<=1'b0; end
assign z0=(x1&&!s0&&s1);
assign z1=(s1&&x0&&(!s0||x1));    

wire a1, a2, a3, J1, K1, J0, K0;
assign a1=(x1||s0);
assign J1=(a1&&x0);
assign a2=(x1||!s0);
assign K1=(x0&&a2);
assign a3=(x1||s1); 
assign J0=(x0&&!s1);
assign K0=(a3&&x0);

 always @(posedge clk or posedge r)
 begin
    if (r) begin
        s1<=0;
        s0<=0;
        end
    else begin
    case ({J1,K1})
    2'b00: s1<=s1;
    2'b01: s1<=1'b0;
    2'b10: s1<=1'b1;
    2'b11: s1<=~s1;
    endcase
    case ({J0,K0})
    2'b00: s0<=s0;
    2'b01: s0<=1'b0;
    2'b10: s0<=1'b1;
    2'b11: s0<=~s0;
    endcase
end
end
endmodule

A continuación se muestra el banco de pruebas

    module csm51a_proj3_tb(
    );

    reg reset, clk, x1, x0;
    wire z0, z1;
initial begin clk=0; end
always begin #5 clk=~clk; end
    csm51a_proj3 csm51a_proj3
    (
    .r(reset),
    .x1(x1),
    .x0(x0),
    .clk(clk),
    .z0(z0),
    .z1(z1)
    );
    initial begin
    reset=0;x1=1;x0=1;//clk=1;
    #10;
    reset=0;x1=0;x0=1;//clk=1;
    #10;
    reset=0;x1=1;x0=1;//clk=1;
    #10;
    reset=1;x1=0;x0=0;//clk=1;
    #10;
    reset=0;x1=0;x0=1;//clk=1;
    #10;
    reset=0;x1=0;x0=1;//clk=1;
    #10;
    reset=0;x1=0;x0=1;//clk=1;
    #10;
    reset=0;x1=0;x0=1;//clk=1;
    #10;
    reset=1;x1=0;x0=0;//clk=1;
    #10;
    reset=0;x1=1;x0=1;//clk=1;
    #10;
    reset=1;x1=0;x0=0;//clk=1;
    #10;
    end

endmodule
    
pregunta Kevin Lee

1 respuesta

1

En primer lugar, cuando se trata de crear instancias y conectarse a módulos, cualquier salida del módulo debe estar conectada a algo del tipo 'cable'. No puede asignar la salida a un 'reg'.

La regla para conectarse a un módulo es:

inputs can be fed with a 'reg' or 'wire' (includes constants)
outputs must be connected to a 'wire' (or unconnected)

Cuando se crea un módulo, sucede lo contrario:

an input can be of type 'wire'
an output can be of type 'reg' or 'wire'

En segundo lugar, no puede mezclar asignaciones de bloqueo y no bloqueo en un bloque siempre. Observe cómo en la cláusula de restablecimiento del registro s1, tiene la instrucción s1<=0 : esta es una asignación no bloqueante. Pero dentro de la declaración del caso, usa un s1=... que es una asignación de bloqueo.

Usa uno o el otro, no ambos. En la mayoría de los casos, debe usar una asignación '< =' sin bloqueo, ya que significa que si tiene varios registros asignados en el bloque siempre, todos se asignarán independientemente de los demás. Si usa una asignación de bloqueo, significa que puede encontrar que se inserta lógica adicional causando cosas que no pretende.

Por ejemplo, toma estos dos códigos:

//Code 1
reg a;
reg b;
wire c;
assign c = (a == b);
always @ (posedge clock) begin
    a <= ~a;
    b <= a;
end

//Code 2
reg a;
reg b;
wire c;
assign c = (a == b);
always @ (posedge clock) begin
    a = ~a;
    b = a;
end

En el primer ejemplo, 'b' es una versión canalizada de 'a'. Esto significa que el valor en 'b' siempre será el valor en 'a' pero un ciclo de reloj retrasado; esencialmente, el valor antiguo de 'a' se registrará en 'b' en cada borde del reloj. Lo que esto significa es que la variable 'c' en este ejemplo siempre será 0.

En el segundo ejemplo, 'b' y 'a' son siempre iguales. El valor '~ a' se asigna a 'a' en el borde del reloj, pero como la asignación está bloqueando, significa que el sintetizador después de debe calcular el valor que se asignará. para 'a' se ha hecho. Así que terminas con el nuevo valor que se asignará a 'a' y también se asignará a 'b'. Entonces, en este ejemplo, la variable 'c' siempre será 1. (Nota: en el código sintetizado a y b aún se asignarán en el mismo borde del reloj, no hay demora, esencialmente el ejemplo es idéntico a escribir b <= ~a; )

Observe cómo un pequeño cambio puede dar como resultado un comportamiento completamente diferente.

Editar:

Ahora que ha modificado la pregunta, la mayoría de los anteriores se han corregido. Pero todavía hay cosas que @Greg anotó correctamente en la sección de comentarios para corregir.

Tiene el problema de que aún no ha conectado correctamente su módulo de flip flop JK. En su código, usted crea una instancia de su flip flop como:

jkff i_jkff
( 
.s0(ss0),  
.s1(ss1)
);  

Pero usted declara el módulo como:

module jkff(
    input clk, r, x1, x0,
    output reg s0,
    output reg s1
);

Observe que la declaración del módulo tiene otras 4 entradas que no ha conectado en su creación de instancias. ¿Cómo se supone que tu módulo haga algo si no le das ninguna entrada?

Además, en su módulo de flip-flop JK tiene lógica para el registro de salida s1, un bloque siempre que le asigna un valor en cada flanco de reloj positivo. PERO no tiene ninguna lógica para el registro de salida s0. Entonces, ¿por qué esperas que s0 haga algo?

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas