Wednesday, February 27, 2019

systemverilog send packet from generator to driver using mailbox

How to send packet from generator to driver using mailbox?

Without UVM sequencer how to send packet from generator to driver?

Here is the answer for all the questions.

REQUIREMENT
When user start building SystemVerilog testbench without uvm there a requirement to generate the packet and send to driver. For packet creation/generation Generator will create a packet. Same packet need to transfer to Driver.

APPLICATION
Send packet from generator to driver
Send packet from one systemverilog component to another component

ANALOGY
Consider two water tanks are located in two different terrace. Now, there is a need to send water from one terrace to another terrace. To do the same thing source water tank need to connect with another water tank. To connect the both water tank we use the pipeline. So, water will flow from one terrace to another terrace through pipeline.

Similarly, we can correlate the same example with systemverilog based testbench source water tank is like generator, another or second water tank is like driver and pipline is like mailbox. Sending water from one tank to another tank is same as sending transaction instance or packet from generator to driver.



USER WANTS CODE




`timescale 1ns/1ps
// transaction class class trans; rand logic [8]data; rand logic [3]add; endclass // generator is like combination of sequence and sequencer
// which generate random data number and send it to driver
class generator; trans t1 = new; task generate_and_send_packet(mailbox m1,int no); repeat(no) begin if (t1.randomize) begin #1 // one clock cycle delay
m1.put(t1);// put the generated packet $display("@%0t data == %d add == %d malibox == %d ",
$realtime,t1.data,t1.add,m1.num); end else $display("randomization failed"); end endtask endclass

// driver will receive the packet from generator class driver; trans t2; task get_packet(mailbox m1,int no); repeat(no) #1.1 // delay begin if (m1.num >= 0) begin m1.get(t2); // get the packet $display("@%0t t222222222222222 data == %d
add == %d mailbox == %d ",$realtime,t2.data,t2.add,m1.num);
end end endtask endclass
// create object for generator and driver class env; generator g1; driver d1; function void build; g1 = new; d1 = new; endfunction task start(mailbox m1,int no);
// run both the process parallel fork g1.generate_and_send_packet(m1,no); d1.get_packet(m1,no); join_any endtask endclass
// main program block program main; env e1; mailbox m1; int number_of_packet; initial begin number_of_packet = $urandom_range(10,50); m1 = new; e1 = new; e1.build; e1.start(m1,number_of_packet); // control number of packets end endprogram

To run simulation click on below link.
Link: https://www.edaplayground.com/x/2Wdk 







1 comment:

  1. Why don't we use fork join_none instead of join_any. I think it would be better to run the tasks in parallel manner rather than using join_any.

    ReplyDelete