Question

The following code is meant to output a 1 in the case of wires S1 and X being asserted and wire S0 being deasserted. However, when I run the wave form, the output is constantly 0.

The logic equations governing the wires are:

S1 = (S0 & ~X) | (S1 & ~S0 & X)

S0 = X

O = (S1 & S0)

Is there a problem with my code:

module Dff1(D, clk, Q, Qbar);
input D, clk;
output reg Q;
output Qbar;

initial begin
Q = 0;
end

assign Qbar = ~Q;
always @(posedge clk)
Q = D;
endmodule

module Mod1 (clk, X, O);
input clk, X;
output O;
wire S1, S0, Q1, Q0, Q1bar, Q0bar;

assign S1 = (S0 & ~X) | (S1 & ~S0 & X);
Dff1 C1(S1, clk, Q1, Q1bar);

assign S0 = X;
Dff1 C0(S0, clk, Q0, Q0bar);

assign O = (S1 & S0);
endmodule

module test_bench ();

wire clk;
reg osc;

reg [1:0] R;
reg Seqinput;
integer num;

initial begin
osc = 0;
num = 0;
Seqinput = 0;
end

initial begin
$dumpfile("dump.vcd");
$dumpvars;
#20000 $finish;
end

always begin
#10 osc = ~osc;

num = (num >= 7) // counter incremented by 1 from 0..7
? 0 : (num + 1);

if ((num % 2) == 0) begin // every other time step

R = $random % 2; // $random generates a 32-bit signed
                 // random number
                 // -1 <= $random % 2 <= 1
if (R > 0)
Seqinput = 1; // input is 1
else
Seqinput = 0; // input is 0
end
end

assign clk=osc;

wire Out1;
Mod1 Mod1instance(clk, Seqinput, Out1);

endmodule
Was it helpful?

Solution

Explained with substitution:

S1 = (S0 & ~X) | (S1 & ~S0 & X)      sub S0 with X
S1 = ((X) & ~X) | (S1 & ~(X) & X)    X & ~X == 0
S1 = ( 0 ) | ( S1 & 0 )              S1 & 0 == 0;
S1 = ( 0 ) | ( 0 )
S1 = 0

Since the assignment of S1 dependent on its current value, it is considered asynchronous feedback logic. This is normally something you don't want to do. I believe the real equation you want is:

S1 = (Q0 & ~X) | (Q1 & ~Q0 & X)

This makes the code synchronous and predictable. Q1 and Q0 are the previous clocked values of S1 and S0 respectively.

Also, it is important to use non-blocking assignments when assigning (<=) flops. Verilog is a non-determent simulator. This means operations scheduled in the same region can happen in any order. Using non-blocking on a flop moves the assignment to the NBA region while its evaluation in kept in the active region.

always @(posedge clk)
    Q <= D;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top