I have a very simple Verilog code and it does not seem to work as expected:
Here is my code:
always @ (posedge clk, negedge resetn) begin
if (resetn == 1'b0) begin
var <= 1'b0;
end else begin
if (valid == 1'b1) begin
var<= 1'b1;
end else begin
var <= 1'b0;
end
end
end
I expected that assuming resetn is H all along
, when valid goes H
the var becomes H
in the next cycle. But in simulation, var becomes H in the same cycle. Why is that?
Here is a diagram as well:
next_state_d2 is my var
EDIT: Testbench code:
initial begin
gclk = 1'b1;
resetn = 1'b1;
div_valid=1'b0;
#40 div_valid = 1'b1;
#40 div_valid = 1'b0;
end
always
#20 gclk = ~ gclk;
Answer
This is actually quite similar to a question I answered previously, but I will try to build up a canonical answer for this somewhat common issue.
In a zero-delay simulation like this, the test flip-flop has a setup time and a hold time of zero:
\$ T_{setup} = T_{hold} = 0 \$
What this means is that the instant the sensitive clock edge occurs, the output is updated, regardless of what happened immediately before or after that instant. This is not like real hardware which would usually have a non-zero \$ T_{setup} \$ and \$ T_{hold} \$.
I ran your testbench, and the results are pretty clear. The valid signal changes at the same time the clock signal does. You have delayed them by precisely the same amount. So at the very edge when the clock is high, the valid signal has also changed:
Both the input (div_valid), and the clock (gclk) go high at the same time: 220 ns. Therefore, the DFF latches this new data, and the output changes instantly since there is also 0 propagation delay. This simulation would look less confusing if we just chose a different delay value for the input to the design:
In this case, we update the input on the falling edge of the clock (620 ns). It is much more clear now that the next clock edge (640 ns) will be when the DFF updates its output.
Here is the testbench code so you can see exactly how it works in your own simulator. Please update the design name as it wasn't clear what yours was named.
module scratch_tb;
reg gclk;
reg resetn;
reg div_valid;
wire data;
// instantiate design under test
scratch scratch (gclk, resetn, div_valid, data);
// generate stimulus
initial begin
gclk = 1'b1;
resetn = 1'b0;
div_valid = 1'b0;
#80 resetn = 1'b1;
// test 1: input switches on rising clock edge
#160 div_valid = 1'b1;
#40 div_valid = 1'b0;
#160 div_valid = 1'b0;
// test 2: input switches on falling clock edge
#180 div_valid = 1'b1;
#40 div_valid = 1'b0;
#2000 $finish;
end
always begin
#20 gclk = ~ gclk;
end
endmodule
No comments:
Post a Comment