Now we’re truly going OO with this testbench. Up until this point, 2 classes (that did something useful) were added : driver and monitor. Adding more classes for generators, checkers, … should not be too much of a challenge, from a coding point-of-view.
The structure, however, should become clear by now:
To use the testbench in a generic way to enhance reusability, it is important that the generated testvectors are described in a generic form. Well … let’s use a class for that as well.
class transaction;
byte instruction;
function new();
this.instruction = 8'h8c;
endfunction : new
function string toString();
return $sformatf("Instruction: %08x", this.instruction);
endfunction : toString
endclass : transaction;
This class describes the transaction. It has only a single property: instruction
Upon construction, the value for this object’s instruction is fixed (for now) to 0x8C
(aka ADC H
`)
There is a function toString( ) that, as the name suggests, makes a sting from the object’s property values.
Make sure you spot the return-value type string in the toString( ) method.
The generator is the object that will create the aforementioned transactions. While making an object this class nothing else happens (for now).
Furthermore, it has a function run( ) which … well … generates a transaction and displays which instruction was generated. This is repeated for 10 times.
`include "transaction.sv"
class generator;
function new;
endfunction : new
task run;
transaction tra;
for(int i=0; i<10; i++)
begin
tra = new();
$display("%s", tra.toString());
end
endtask : run
endclass : generator
To glue everything together, a small test is set up which creates a generator and triggers it’s run( ) function. The result is shown below.
`include "generator.sv"
program test();
generator gen = new();
initial
begin
gen.run();
end
endprogram : test
Great !! Now you can generate all the testvectors that you want 😃 Only … they are all the same and only live within the generator. Let’s fix that with mailing transactions around.