// DESIGN CODE — DUT
module add
(
input [3:0] a,b,
output reg [4:0] sum,
input clk
);
always@(posedge clk)
begin
sum <= a + b;
end
endmodule
// TRANSACTION CLASS -- Sends input to Generator
class transaction;
randc bit [3:0] a;
randc bit [3:0] b;
bit [4:0] sum;
function void display();
$display("a: %0d,\t b: %0d", a,b);
endfunction
//we are making a copy of transaction class instead of sending original transaction data
function transaction copy(); // creating same handler for class transaction and
function transaction cpy. Since it returns some
value, we didnt use any void
copy = new();
copy.a = this.a; //copying data members from class transaction to the
transaction copy() function.(deepcopy)
copy.b = this.b;
copy.sum = this.sum;
endfunction
endclass
/*GENERATOR CLASS -- Generator takes inputs (a,b) from transaction via mailbox
and sends inputs (a,b) to DRIVER */
class generator;
transaction trans; // trans is object which will store memory(packet) of
transaction data
mailbox #(transaction) mbx; // now putting the data of trasaction class in the
mailbox
event done; // indicating that certain stimulus operation is done
and will quit the loop
function new(mailbox #(transaction) mbx); // sets the connection (generator) to the
transaction
this.mbx = mbx; // this.mbx represents to class and = mbx represents the
arguement of function generator
trans = new();
endfunction
task run();
for(int i=0; i<20; i++) begin
assert(trans.randomize()) else $display(" randomization failed");
mbx.put(trans.copy); // The mbx.put() function stores the copied transaction
object(data will be inside the object) in the mailbox.
$display("[GEN] : DATA SENT TO DRIVER");
trans.display(); // will display the values of a and b values which will be sent to
driver via mailbox
#20; // Generating 2nd transaction after 10 nano seconds
end
-> done; // indicating that generator has succesfully generated the
stimuls
endtask
endclass
// INTERFACE -- declare I/O pins of design
interface add_if; // try to give similar name of design module
logic [3:0] a;
logic [3:0] b;
logic [4:0] sum;
logic clk;
endinterface
// DRIVER CLASS
class driver;
virtual add_if aif; // to connect driver to the interface we use -- "virtual" keyword
mailbox #(transaction) mbx;
transaction storage; // To store the transaction data which we receieve from that
class -- another handler of transaction class
event next;
// This allows the driver class to interact with the same mailbox that is used by other
parts of the design (like generator), enabling communication between them
function new(mailbox #(transaction) mbx);
this.mbx = mbx;
endfunction
task run();
forever begin // since we get values ocntinuosly
mbx.get(storage); // the data will be getting through mailbox from generator
@(posedge aif.clk);
aif.a <= storage.a; // the data in the storage is being sen to DUT (interface)
aif.b <= storage.b;
$display("[DRV]: Interface Trigger");
storage.display();
end
endtask
endclass
// TESTBENCH TOP
module tb;
add_if aif(); // connecting Testbench top to
generator gen;
driver drv;
mailbox #(transaction) mbx;
event done;
add dut(.a(aif.a), .b(aif.b), .sum(aif.sum), .clk(aif.clk)); // connecting dut with interface
initial begin
aif.clk <= 0;
end
always #10aif.clk <= ~aif.clk;
initial begin
mbx = new(); // The mailbox will hold transaction objects (like a postbox for
storing letters or packages). holds the data
gen = new(mbx); // The mbx (mailbox) is passed to the generator, so the generator
knows where to put the transactions it generates.
drv = new(mbx);
drv.aif = aif;
done = gen.done; // To connect this done to the above which is delared in
generator
end
initial begin
fork
gen.run();
drv.run();
join
wait(done.triggered);
$finish(); // exits the simulation
end
endmodule