In phase 5 we will write a driver and then instantiate the driver in environment and send packet in to DUT. Driver class is defined in Driver.sv file.
Driver is class which generates the packets and then drives it to the DUT input interface and pushes the packet in to mailbox.
1) Declare a packet.
packet gpkt;
2) Declare a virtual input_interface of the switch. We will connect this to the Physical interface of the top module same as what we did in environment class.
virtual input_interface.IP input_intf;
3) Define a mailbox "drvr2sb" which is used to send the packets to the score board.
mailbox drvr2sb;
4) Define new constructor with arguments, virtual input interface and a mail box which is used to send packets from the driver to scoreboard.
function new(virtual input_interface.IP input_intf_new,mailbox drvr2sb);
this.input_intf = input_intf_new ;
if(drvr2sb == null)
begin $display(" **ERROR**: drvr2sb is null");
$finish;
end else this.drvr2sb = drvr2sb;
5) Construct the packet in the driver constructor.
gpkt = new();
6) Define the start method.
In start method, do the following
Repeat the following steps for num_of_pkts times.
repeat($root.num_of_pkts)
Randomize the packet and check if the randomization is successes full.
if ( pkt.randomize())
begin $display (" %0d : Driver : Randomization Successes full.",$time);
...........
...........
else begin $display (" %0d Driver : ** Randomization failed. **",$time);
............
...........
Display the packet content.
pkt.display();
Then pack the packet in to bytes.
length = pkt.byte_pack(bytes);
Then send the packet byte in to the switch by asserting data_status of the input interface signal and driving the data bytes on to the data_in signal.
foreach(bytes[i])
begin @(posedge input_intf.clock);
input_intf.cb.data_status <= 1;
input_intf.cb.data_in <= bytes[i];
end
After driving all the data bytes, deassert data_status signal of the input interface.
Send the packet in to mail "drvr2sb" box for scoreboard.
drvr2sb.put(pkt);
If randomization fails, increment the error counter which is defined in Globals.sv file
$root.error++;
Driver Class Source Code:
`ifndef GUARD_DRIVER
`define GUARD_DRIVER
class Driver;
virtual input_interface.IP input_intf;
mailbox drvr2sb;
packet gpkt;
//// constructor method ////
function new(virtual input_interface.IP input_intf_new,mailbox drvr2sb);
this.input_intf = input_intf_new ;
if(drvr2sb == null)
begin $display(" **ERROR**: drvr2sb is null");
$finish;
end else this.drvr2sb = drvr2sb;
gpkt = new();
endfunction : new
/// method to send the packet to DUT ////////
task start();
packet pkt;
int length;
logic [7:0] bytes[];
repeat($root.num_of_pkts)
begin repeat(3) @(posedge input_intf.clock);
pkt = new gpkt;
//// Randomize the packet /////
if ( pkt.randomize())
begin $display (" %0d : Driver : Randomization Successes full. ",$time);
//// display the packet content ///////
pkt.display();
//// Pack the packet in tp stream of bytes //////
length = pkt.byte_pack(bytes);
///// assert the data_status signal and send the packed bytes //////
foreach(bytes[i])
begin @(posedge input_intf.clock);
input_intf.cb.data_status <= 1;
input_intf.cb.data_in <= bytes[i];
end
//// Push the packet in to mailbox for scoreboard /////
drvr2sb.put(pkt);
$display(" %0d : Driver : Finished Driving the packet with length %0d",$time,length);
end else begin $display (" %0d Driver : ** Randomization failed. **",$time);
////// Increment the error count in randomization fails ////////
$root.error++;
end end endtask : start
endclass
`endif
Now we will take the instance of the driver in the environment class.
1) Declare a mailbox "drvr2sb" which will be used to connect the scoreboard and driver.
mailbox drvr2sb;
2) Declare a driver object "drvr".
Driver drvr;
3) In build method, construct the mail box.
drvr2sb = new();
4) In build method, construct the driver object. Pass the input_intf and "drvr2sb" mail box.
drvr= new(input_intf,drvr2sb);
5) To start sending the packets to the DUT, call the start method of "drvr" in the start method of Environment class.