quick.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

   

space.gif

   

space.gif

  ../images/main/bulllet_4dots_orange.gif Adding Reset Logic

Once we have the basic logic to allow us to see what our testbench is doing, we can next add the reset logic. If we look at the testcases, we see that we had added a constraint that it should be possible to activate reset anytime during simulation. To achieve this we have many approaches, but I am going to teach something that will go long way. There is something called 'events' in Verilog: events can be triggered, and also monitored, to see if an event has occurred.

   

space.gif

Let's code our reset logic in such a way that it waits for the trigger event "reset_trigger": when this event happens, reset logic asserts reset at negative edge of clock and de-asserts on next negative edge as shown in the code below. Also after de-asserting the reset, reset logic triggers another event called "reset_done_trigger". This trigger event can then be used somewhere else in the testbench to sync up.

   

space.gif

  ../images/main/bulllet_4dots_orange.gif Code of reset logic
   

space.gif


  1 event reset_trigger; 
  2   event  reset_done_trigger; 
  3     
  4   initial begin 
  5     forever begin 
  6       @ (reset_trigger); 
  7       @ (negedge clk); 
  8       reset = 1; 
  9       @ (negedge clk); 
 10       reset = 0; 
 11       -> reset_done_trigger; 
 12     end 
 13   end
You could download file counter_tb4.v here
   

space.gif

   

space.gif

  ../images/main/bulllet_4dots_orange.gif Adding test case logic

Moving forward, let's add logic to generate the test cases, ok we have three testcases as in the first part of this tutorial. Let's list them again.

   

space.gif

  • Reset Test : We can start with reset de-asserted, followed by asserting reset for few clock ticks and de-asserting the reset, See if counter sets its output to zero.
  • Enable Test : Assert/de-assert enable after reset is applied.
  • Random Assert/de-assert of enable and reset.
   

space.gif

Repeating it again: "There are many ways" to code a test case, it all depends on the creativity of the Test bench designer. Let's take a simple approach and then slowly build upon it.

   

space.gif

  ../images/main/bullet_star_pink.gif Test Case 1 - Asserting/ De-asserting reset

In this test case, we will just trigger the event reset_trigger after 10 simulation units.

   

space.gif


 1 initial  
 2   begin: TEST_CASE 
 3      #10  -> reset_trigger; 
 4   end 
You could download file counter_tb5.v here
   

space.gif

  ../images/main/bullet_star_pink.gif Test Case 2 - Assert/ De-assert enable after reset is applied.

In this test case, we will trigger the reset logic and wait for the reset logic to complete its operation, before we start driving the enable signal to logic 1.

   

space.gif


  1  initial  
  2   begin: TEST_CASE 
  3      #10  -> reset_trigger; 
  4     @ (reset_done_trigger); 
  5     @ (negedge clk); 
  6     enable = 1; 
  7     repeat (10) begin 
  8       @ (negedge clk); 
  9     end 
 10     enable = 0; 
 11   end   
You could download file counter_tb6.v here
   

space.gif

  ../images/main/bullet_star_pink.gif Test Case 3 - Assert/De-assert enable and reset randomly.

In this testcase we assert the reset, and then randomly drive values on to enable and reset signal.

   

space.gif


  1  initial  
  2   begin : TEST_CASE 
  3      #10  -> reset_trigger; 
  4     @ (reset_done_trigger); 
  5     fork  
  6       repeat (10) begin 
  7          @ (negedge clk); 
  8         enable = $random; 
  9       end	
 10       repeat (10) begin 
 11         @ (negedge clk); 
 12         reset = $random; 
 13       end 
 14     join 
 15   end 
You could download file counter_tb7.v here
   

space.gif

Well you might ask, do all this three test case exist in same file? Well, the answer is no. If we try to have all three test cases on one file, then we end up having race conditions due to three initial blocks driving reset and enable signal. So normally, once test bench coding is done, test cases are coded separately and included in testbench with `include directives as shown below. (There are better ways to do this, but you have to think how you want to do it).

   

space.gif

If you look closely at all the three test cases, you will find that even though test case execution is not complete, simulation terminates. To have better control, what we can do is adding an event like "terminate_sim" and execute $finish only when this event is triggered. We can trigger this event at the end of test case execution. The code for $finish now could look as shown below.

   

space.gif


 1   event terminate_sim;  
 2   initial begin  
 3   @ (terminate_sim); 
 4      #5  $finish; 
 5   end 
You could download file counter_tb8.v here
   

space.gif

The modified test case #2 would be like:

   

space.gif


  1 initial  
  2   begin: TEST_CASE 
  3      #10  -> reset_trigger; 
  4     @ (reset_done_trigger); 
  5     @ (negedge clk); 
  6     enable = 1; 
  7     repeat (10) begin 
  8       @ (negedge clk); 
  9     end 
 10     enable = 0; 
 11      #5  -> terminate_sim; 
 12   end 
 13 
You could download file counter_tb9.v here
   

space.gif

Second problem with the approach that we have taken till now is that we need to manually check the waveform and also the simulator output on the screen to see if the DUT is working correctly. Part IV shows how to automate this.

   

space.gif

   

space.gif

   

space.gif

   

space.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

  

Copyright 1998-2014

Deepak Kumar Tala - All rights reserved

Do you have any Comment? mail me at:deepak@asic-world.com