|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



PHASE 6 RECEIVER




In this phase, we will write a receiver and use the receiver in environment class to collect the packets coming from the switch output_interface.

Receiver collects the data bytes from the interface signal. And then unpacks the bytes in to packet and pushes it into mailbox.

Receiver class is written in reveicer.sv file.


1) Declare a virtual output_interface. We will connect this to the Physical interface of the top module, same as what we did in environment class.


virtual output_interface.OP output_intf;


2) Declare a mailbox "rcvr2sb" which is used to send the packets to the score board


mailbox rcvr2sb;


3) Define new constructor with arguments, virtual input interface and a mail box which is used to send packets from the receiver to scoreboard.


function new(virtual output_interface.OP output_intf_new,mailbox rcvr2sb);
this.output_intf = output_intf_new ;
if(rcvr2sb == null)
begin
$display(" **ERROR**: rcvr2sb is null");
$finish;
end
else
this.rcvr2sb = rcvr2sb;
endfunction : new



4) Define the start method.

In start method, do the following

Wait for the ready signal to be asserted by the DUT.


wait(output_intf.cb.ready)


If the ready signal is asserted, then request the DUT to send the data out from the data_out signal by asserting the read signal. When the data to be sent is finished by the DUT, it will deassert the ready signal. Once the ready signal is deasserted, stop collecting the data bytes and deasseart the read signal.


output_intf.cb.read <= 1;
repeat(2) @(posedge output_intf.clock);
while (output_intf.cb.ready)
begin
bytes = new[bytes.size + 1](bytes);
bytes[bytes.size - 1] = output_intf.cb.data_out;
@(posedge output_intf.clock);
end
output_intf.cb.read <= 0;
@(posedge output_intf.clock);
$display(" %0d : Receiver : Received a packet of length %0d",$time,bytes.size);



Create a new packet object of packet.


pkt = new();


Then call the unpack method of the packet to unpacked the bytes and then display the packet content.


pkt.byte_unpack(bytes);
pkt.display();


Then send the packet to scoreboard.


rcvr2sb.put(pkt);


Delete the dynamic array bytes.


bytes.delete();

Receiver Class Source Code:

`ifndef GUARD_RECEIVER
`define GUARD_RECEIVER

class Receiver;

virtual output_interface.OP output_intf;
mailbox rcvr2sb;

//// constructor method ////
function new(virtual output_interface.OP output_intf_new,mailbox rcvr2sb);
this.output_intf = output_intf_new ;
if(rcvr2sb == null)
begin
$display(" **ERROR**: rcvr2sb is null");
$finish;
end
else
this.rcvr2sb = rcvr2sb;
endfunction : new

task start();
logic [7:0] bytes[];
packet pkt;
forever
begin
repeat(2) @(posedge output_intf.clock);
wait(output_intf.cb.ready)
output_intf.cb.read <= 1;
repeat(2) @(posedge output_intf.clock);
while (output_intf.cb.ready)
begin
bytes = new[bytes.size + 1](bytes);
bytes[bytes.size - 1] = output_intf.cb.data_out;
@(posedge output_intf.clock);
end
output_intf.cb.read <= 0;
@(posedge output_intf.clock);
$display(" %0d : Receiver : Received a packet of length %0d",$time,bytes.size);
pkt = new();
pkt.byte_unpack(bytes);
pkt.display();
rcvr2sb.put(pkt);
bytes.delete();
end
endtask : start

endclass

`endif



Now we will take the instance of the receiver in the environment class.



1) Declare a mailbox "rcvr2sb" which will be used to connect the scoreboard and receiver.


mailbox rcvr2sb;


2) Declare 4 receiver object "rcvr".


Receiver rcvr[4];


3) In build method, construct the mail box.


rcvr2sb = new();


4) In build method, construct the receiver object. Pass the output_intf and "rcvr2sb" mail box. There are 4 output interfaces and receiver objects. We will connect one receiver for one output interface.


foreach(rcvr[i])
rcvr[i]= new(output_intf[i],rcvr2sb);



5) To start collecting the packets from the DUT, call the "start" method of "rcvr" in the "start" method of Environment class.


task start();
$display(" %0d : Environment : start of start() method",$time);
fork
drvr.start();
rcvr[0].start();
rcvr[1].start();
rcvr[2].start();
rcvr[3].start();
join_any
$display(" %0d : Environment : end of start() method",$time);
endtask : start


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;

Receiver rcvr[4];

mailbox drvr2sb;

mailbox rcvr2sb;

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();

rcvr2sb = new();

drvr= new(input_intf,drvr2sb);

foreach(rcvr[i])
rcvr[i]= new(output_intf[i],rcvr2sb);

$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].cb.read <= 0;
output_intf[1].cb.read <= 0;
output_intf[2].cb.read <= 0;
output_intf[3].cb.read <= 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);
fork
drvr.start();

rcvr[0].start();
rcvr[1].start();
rcvr[2].start();
rcvr[3].start();

join_any
$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


(S)Download the phase 6 source code:


switch_6.tar
Browse the code in switch_6.tar


(S)Run the command:
vcs -sverilog -f filelist -R -ntb_opts dtm

Index
Introduction
Specification
Verification Plan
Phase 1 Top
Phase 2 Environment
Phase 3 Reset
Phase 4 Packet
Phase 5 Driver
Phase 6 Receiver
Phase 7 Scoreboard
Phase 8 Coverage
Phase 9 Testcase

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright 2007-2017 :: all rights reserved www.testbench.in::Disclaimer