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.
//// 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.