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. 我们一旦有基本逻辑时我们能够看清楚我们的测试基准程序在做什么,我们可以添加reset逻辑了。 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. 事件触发的方式。 | ||
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. | ||
Code of reset logic | ||
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 endYou could download file counter_tb4.v here | ||
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. 前面,我们添加产生测试用例的程序。 | ||
| ||
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. | ||
Test Case 1 - Asserting/ De-asserting reset | ||
In this test case, we will just trigger the event reset_trigger after 10 simulation units. | ||
1 initial 2 begin: TEST_CASE 3 #10 -> reset_trigger; 4 endYou could download file counter_tb5.v here | ||
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. | ||
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 endYou could download file counter_tb6.v here | ||
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. | ||
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 endYou could download file counter_tb7.v here | ||
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). | ||
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. | ||
1 event terminate_sim; 2 initial begin 3 @ (terminate_sim); 4 #5 $finish; 5 endYou could download file counter_tb8.v here | ||
The modified test case #2 would be like: | ||
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 13You could download file counter_tb9.v here | ||
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. |
the above original link:http://www.asic-world.com/verilog/art_testbench_writing3.html