Chaitanya Chhichhia
Chaitanya Chhichhia

Reputation: 13

No response from uut in testbench

I am not getting any response from the uut in the testbench. The module exp2_up_down_counter works ok without testbench, but gives output as xxxx when instantiated in the testbench.

Here is the main module of the up-down counter:

`timescale 1ns/1ps
module exp2_up_down_counter (input clk, reset, mode, output reg [3:0] count);

  always @(posedge clk)

    if (reset == 1)
      count <= 0;   // reset the counter if reset is high
    else if (mode == 1)
      count <= count + 1; // works as up counter if mode pin is high
    else
      count <= count - 1; // works as down counter if mode pin is low

endmodule

Simulation without testbench:

simulation without testbench

Testbench for up-down counter

`timescale 1ns/1ps

module exp2_up_down_counter_tb;
  reg clk, reset, mode;
  wire [3:0] count;
  
  exp2_up_down_counter uut(.clk(clk), .reset(reset), .mode(mode), .count(count));
  initial begin
    clk = 1'b0;
  end
  
    always  @(*) #5 clk <= ~clk;
  initial begin
    // initializing the inputs
    reset = 1;
    mode = 0; 
    
    #5; 
    reset = 0;
    #10
    mode = 1;
    #5000 $finish;
  end
endmodule

Simulation with testbench:

simulation with testbench

Upvotes: 1

Views: 525

Answers (1)

toolic
toolic

Reputation: 62105

In exp2_up_down_counter, count is declared as a reg. This means that its default value is X at time 0. Since the reset signal is synchronous to the clock, you need to wait for the 1st posedge of clock before you release the reset. Currently, the reset is released at the 1st posedge of clock in the testbench, which is a race condition. Therefore, count does not get assigned the value of 0, and it retains the value of X for the whole simulation.

You need to delay the reset release. For example, change:

#5; 
reset = 0;

to:

#15; 
reset = 0;

However, it is better to drive your synchronous inputs in the testbench the same way you drive your signals in the design: using @(posedge clk) and using nonblocking assignments (<=):

  initial begin
    reset = 1;
    mode  = 0; 
    
    repeat (2) @(posedge clk);
    reset <= 0;
    repeat (1) @(posedge clk);
    mode <= 1;

    #5000 $finish;
  end

Also, this is a more standard way to drive the clock in the testbench:

always #5 clk = ~clk;

Upvotes: 1

Related Questions