PHASE 5 DRIVER
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 [Link] 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 ( [Link]())
begin
$display (" %0d : Driver : Randomization Successes full.",$time);
...........
...........
else
begin
$display (" %0d Driver : ** Randomization failed. **",$time);
............
...........
Display the packet content.
[Link]();
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.
@(posedge input_intf.clock);
input_intf.cb.data_status <= 0;
input_intf.cb.data_in <= 0;
Send the packet in to mail "drvr2sb" box for scoreboard.
[Link](pkt);
If randomization fails, increment the error counter which is defined in [Link] file
$[Link]++;
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 ( [Link]())
begin
$display (" %0d : Driver : Randomization Successes full. ",$time);
//// display the packet content ///////
[Link]();
//// 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
//// deassert the data_status singal //////
@(posedge input_intf.clock);
input_intf.cb.data_status <= 0;
input_intf.cb.data_in <= 0;
//// Push the packet in to mailbox for scoreboard /////
[Link](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 ////////
$[Link]++;
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.
[Link]();
Environment Class Source Code:
`ifndef GUARD_ENV
`define GUARD_ENV
class Environment ;
virtual mem_interface.MEM mem_intf ;
virtual input_interface.IP input_intf ;
virtual output_interface.OP output_intf[4] ;
Driver drvr;
mailbox drvr2sb;
function new(virtual mem_interface.MEM mem_intf_new ,
virtual input_interface.IP input_intf_new ,
virtual output_interface.OP output_intf_new[4] );
this.mem_intf = mem_intf_new ;
this.input_intf = input_intf_new ;
this.output_intf = output_intf_new ;
$display(" %0d : Environment : created env object",$time);
endfunction : new
function void build();
$display(" %0d : Environment : start of build() method",$time);
drvr2sb = new();
drvr= new(input_intf,drvr2sb);
$display(" %0d : Environment : end of build() method",$time);
endfunction : build
task reset();
$display(" %0d : Environment : start of reset() method",$time);
// Drive all DUT inputs to a known state
mem_intf.cb.mem_data <= 0;
mem_intf.cb.mem_add <= 0;
mem_intf.cb.mem_en <= 0;
mem_intf.cb.mem_rd_wr <= 0;
input_intf.cb.data_in <= 0;
input_intf.cb.data_status <= 0;
output_intf[0].[Link] <= 0;
output_intf[1].[Link] <= 0;
output_intf[2].[Link] <= 0;
output_intf[3].[Link] <= 0;
// Reset the DUT
input_intf.reset <= 1;
repeat (4) @ input_intf.clock;
input_intf.reset <= 0;
$display(" %0d : Environment : end of reset() method",$time);
endtask : reset
task cfg_dut();
$display(" %0d : Environment : start of cfg_dut() method",$time);
mem_intf.cb.mem_en <= 1;
@(posedge mem_intf.clock);
mem_intf.cb.mem_rd_wr <= 1;
@(posedge mem_intf.clock);
mem_intf.cb.mem_add <= 8'h0;
mem_intf.cb.mem_data <= `P0;
$display(" %0d : Environment : Port 0 Address %h ",$time,`P0);
@(posedge mem_intf.clock);
mem_intf.cb.mem_add <= 8'h1;
mem_intf.cb.mem_data <= `P1;
$display(" %0d : Environment : Port 1 Address %h ",$time,`P1);
@(posedge mem_intf.clock);
mem_intf.cb.mem_add <= 8'h2;
mem_intf.cb.mem_data <= `P2;
$display(" %0d : Environment : Port 2 Address %h ",$time,`P2);
@(posedge mem_intf.clock);
mem_intf.cb.mem_add <= 8'h3;
mem_intf.cb.mem_data <= `P3;
$display(" %0d : Environment : Port 3 Address %h ",$time,`P3);
@(posedge mem_intf.clock);
mem_intf.cb.mem_en <=0;
mem_intf.cb.mem_rd_wr <= 0;
mem_intf.cb.mem_add <= 0;
mem_intf.cb.mem_data <= 0;
$display(" %0d : Environment : end of cfg_dut() method",$time);
endtask :cfg_dut
task start();
$display(" %0d : Environment : start of start() method",$time);
[Link]();
$display(" %0d : Environment : end of start() method",$time);
endtask : start
task wait_for_end();
$display(" %0d : Environment : start of wait_for_end() method",$time);
repeat(10000) @(input_intf.clock);
$display(" %0d : Environment : end of wait_for_end() method",$time);
endtask : wait_for_end
task run();
$display(" %0d : Environment : start of run() method",$time);
build();
reset();
cfg_dut();
start();
wait_for_end();
report();
$display(" %0d : Environment : end of run() method",$time);
endtask : run
task report();
endtask : report
endclass
`endif
Download the phase 5 source code:
switch_5.tar
Browse the code in switch_5.tar
Run the command:
vcs -sverilog -f filelist -R -ntb_opts dtm
Log file report.
******************* Start of testcase ****************
0 : Environment : created env object
0 : Environment : start of run() method
0 : Environment : start of build() method
0 : Environment : end of build() method
0 : Environment : start of reset() method
40 : Environment : end of reset() method
40 : Environment : start of cfg_dut() method
70 : Environment : Port 0 Address 00
90 : Environment : Port 1 Address 11
110 : Environment : Port 2 Address 22
130 : Environment : Port 3 Address 33
150 : Environment : end of cfg_dut() method
150 : Environment : start of start() method
210 : Driver : Randomization Successes full.
---------------------- PACKET KIND -------------------------
fcs_kind : BAD_FCS
length_kind : GOOD_LENGTH
-------- PACKET ----------
0 : 22
1 : 11
2 : 2d
3 : 63 4 : 2a 5 : 2e 6 : c 7 : a 8 : 14 9 : c1 10 : 14 11 : 8f 12 : 54 13 : 5d 14 : da 15 : 22 16 : 2c 17
: ac 18 : 1c 19 : 48 20 : 3c 21 : 7e 22 : f3 23 : ed 24 : 24 25 : d1 26 : 3e 27 : 38 28 : aa 29 : 54 30 :
19 31 : 89 32 : aa 33 : cf 34 : 67 35 : 19 36 : 9a 37 : 1d 38 : 96 39 : 8 40 : 15 41 : 66 42 : 55 43 :
b 44 : 70 45 : 35 46 : fc 47 : 8f
48 : cd
-----------------------------------------------------------
1210 : Driver : Finished Driving the packet with length 49
1270 : Driver : Randomization Successes full.
..................
..................
..................