Following example is TestBench for ones counter. It has some verification components which are required, but not all the verification components discussed earlier. All the components implementation can be seen in further chapters with another protocol. Description of the language construct is discussed in further chapters, so don't pay attention to them. The intention of showing this example is to make you familiar with some steps required while building verification environment and to help you to understand the flow discussed above.
Specification:
Ones Counter is a Counter which counts the number of one's coming in serial stream. The Minimum value of the count is "0" and count starts by incriminating one till "15". After "15" the counter rolls back to "0". Reset is also provided to reset the counter value to "0". Reset signal is active negedge. Input is 1 bit port for which the serial stream enters. Out bit is 4 bit port from where the count values can be taken. Reset and clock pins also provided.
The following is the RTL code of onescounter with bugs.
This is a simple testplan. Features to be verified are
1) Count should increment from "0" to "15".( Coverage item)
2) Count should roolover to "0" after "15".(Coverage transition)
3) Reset should make the output count to "0", when the count values is non "0". ( Assertion coverage)
class stimulus;
randbit value;
constraint distribution {value dist { 0 := 1 , 1 := 1 }; }
endclass
Driver
This driver consists of reset and drive method. Reset method resets the DUT and drive method generates the stimulus and sends it to DUT. Driver also calculates the expected DUT output and stores in scoreboard. Coverage is also sampled in this component. Feature 1 and 2 which are mentioned in Testplan are covered in this cover group.
task drive(inputinteger iteration);
repeat(iteration)
begin sti = new();
@ (negedge intf.clk);
if(sti.randomize()) // Generate stimulus
intf.data = sti.value; // Drive to DUT
sb.store = sb.store + sti.value;// Cal exp value and store in Scoreboard
if(sti.value)
cov.sample();
end endtask endclass
Monitor
The monitor collects the DUT output and then gets the expected value from the score board and compares them.
class monitor;
scoreboard sb;
virtual intf_cnt intf;
The interface is declared and the test bench and DUT instances are taken. Testbench and DUT are connected using interfaces. Clock is also generated and connects it to DUT and testbench.
This coverage report will be different if you simulate in your tool.
To improve the coverage, than the 1st testcase , I wrote 2nd testcase with more input values and also logic related to 3 feature in the testplan.
program testcase(intf_cnt intf);
environment env = new(intf);
initial begin env.drvr.reset();
env.drvr.drive(100);
env.drvr.reset();
env.drvr.drive(100);
end endprogram