0

I have created a testbench for a simple positive edge triggered d flip flop with synchronous active-low reset. In the testbench, the first case gives inputs at @(posedge clk), and in the second case, I am giving inputs based on #10ns statements.

In the first case, the output of the flop changes after 1 clock cycle, whereas in the second case, it changes immediately in the same clock cycle in the simulator.

Why?

I am simulating in the Quartus Simulator.

Code:

initial
begin
    //Case 1: Using Event Based statements
    n_reset = 1'b0;
    reset = 1'b1;
    d = 1'b0;
    repeat(2)@(posedge clk);
    n_reset = 1'b1;
    repeat(2)@(posedge clk);
    d = 1'b1;
    @(posedge clk);
    d = 1'b0;
    @(posedge clk);
    d = 1'b1;
    
    //Case 2: Using wait Statement
    #50ns;
    n_reset = 1'b0;
    reset = 1'b1;
    d = 1'b0;
    #50ns;
    n_reset = 1'b1;
    #20ns;
    d = 1'b1;
    #10ns;
    d = 1'b0;
    #10ns;
    d = 1'b1;
    #50ns;
    
end

Waveform of D FlipFlop with the testbench

toolic
  • 57,801
  • 17
  • 75
  • 117
Edwin Joseph
  • 41
  • 1
  • 5

2 Answers2

0

You see differences because there are simulation race conditions in the testbench.

Let's assume your flipflop uses the recommended coding style, something like this:

always @(posedge clk) q <= d;

q is the flipflop output. It is important to note that the flipflop uses a nonblocking assignment (<=).

The testbench code uses blocking assignments (=) everywhere. Let's also assume you are always changing d at the same time as the clk rising edge when you use # delays. When that is the case, you have a race condition no matter what type of timing control you are using (Case 1 or Case 2). Although you are seeing a difference between the two cases, there is no guarantee that you will see a difference because of the race.

Since the testbench uses blocking and the design (flipflop) use nonblocking, the value of d that is sampled inside the design is indeterminate.

The best way to avoid the race condition and to guarantee that the d input is synchronous to clk is to use nonblocking assignments in the testbench:

repeat(2) @(posedge clk);
d <= 1'b1;
@(posedge clk);
d <= 1'b0;
toolic
  • 57,801
  • 17
  • 75
  • 117
-1

Using wait Statement:

Delays the execution of a procedural statement by specific simulation time.

"#<_time> <_statement>;"

Using Event Based statements:

Delays execution of the next statement until the specified transition on a signal.

@ (< posedge >|< negedge > signal) < statement >;

Level-Sensitive Even Controls ( Wait statements ):

Delays execution of the next statement until < expression > evaluates to true

wait (< expression >) < statement >;

Now I think you are able to differentiate, Right?

Prakash Darji
  • 990
  • 6
  • 13