Mailbox

class stimulus;
  logic [2:0]opcode;
  logic [7:0] op1,op2;
 task gen;
    
    op1 = $random;
    op2 = 'd8;
    opcode = $random;

    #1 stimulus_vectors();
    op1 = 0;
    op2 = $random;
   opcode = opcode + 1'b1;

    
    #1 stimulus_vectors();
    op1 = $random;
    op2 = ~op1;
   opcode = 3;
 
    
    #1 stimulus_vectors();
    
    op1 = $random;
    op2 = $random;
    opcode = $random;
 
    #1 stimulus_vectors();
 endtask 
   
   
     task stimulus_vectors();
    $display("stimulus vector is : at %g",$time);
    $display("[Stimulus]:stimulus is generated :: op1 = %d , op2 = %d , opcode = %d",op1,op2,opcode);
  endtask
  
  

endclass

i want to put the messages in the mailbox for all the changes in the inputs.

i .e. i m changing my inputs for every #1 so i want to put these in mailbox.

i have tried like this below code, where my last value is put in the mailbox :

(i’m unable to break the gen task in between to access my mailbox. can we do this ? if so how can this be done)

class generator;
  
stimulus sti;
  
mailbox m_box;
  
  function new(mailbox m_box);
    this.m_box = m_box;
  endfunction
  
  
  task  run();
    repeat(5) begin
     
      sti = new();
      sti.gen();
      m_box.put(sti);
      $display("message is put into mailbox at %g %d",$time,m_box.num());
 
    end
      
  endtask
endclass

have u tried by declaring mailbox of stimulus class type? if not please try it and let me know.

In reply to shreebamnikar:

how can i do that ? can you please guide me

*In reply to sreelaxmi:*You should always parameterize your mailbox with the type of item being put/get.

mailbox #(stimulus) m_box;
  function new(mailbox  #(stimulus) m_box);
    this.m_box = m_box;
  endfunction
 

But this is not your problem. You need to show us what you expect to happen to your inputs and you need to show who does the get(). What you are doing does not make much sense. Normally, your class ‘stimulus’ represents one set of values for (opcode,op1,o2) and create an class object for each set. The each object goes onto the mailbox.

In reply to sreelaxmi:

You want something like this?

class stimulus;
  logic [2:0]opcode;
  logic [7:0] op1,op2;

  //Store messages here
  string message;

  //Create constructor and pass mailbox
  //...
  mailbox#(string) msg_mbx;
  //..

  task gen;
 
    op1 = $random;
    op2 = 'd8;
    opcode = $random;
 
    #1 stimulus_vectors();
    op1 = 0;
    op2 = $random;
   opcode = opcode + 1'b1;
 
 
    #1 stimulus_vectors();
    op1 = $random;
    op2 = ~op1;
   opcode = 3;
 
 
    #1 stimulus_vectors();
 
    op1 = $random;
    op2 = $random;
    opcode = $random;
 
    #1 stimulus_vectors();
 endtask //gen
 
 
  task stimulus_vectors();
    $display("stimulus vector is : at %g",$time);
    $display("[Stimulus]:stimulus is generated :: op1 = %d , op2 = %d , opcode = %d",op1,op2,opcode);

    //Store message into mailbox
    message = $sformatf("[Stimulus]:stimulus is generated :: op1 = %d , op2 = %d , opcode = %d",op1,op2,opcode);
    msg_mbx.put(message);
  endtask //stimulus_vectors
 
endclass //stimulus

In reply to dave_59:

i’m learning how mailboxes work so as an example i have considered an alu block and by using mailbox im accessing the inputs.
is it right way to do ?

i want to access my mailbox everytime my inputs(opcode op1,op2 ) changes at #1 time .

class driver;
  stimulus sti;
  mailbox m_box;
  
  //constructor, getting mailbox handle
  function new(mailbox m_box);
    this.m_box = m_box;
  endfunction
  
  task run;
    repeat(5) begin
      m_box.get(sti); //getting stimulus from mailbox
      $display("Driver:: stimulus is received at %g",$time);
      $display("[Driver]:stimulus is generated :: op1 = %d , op2 = %d , opcode = %d %d",sti.op1,sti.op2,sti.opcode,m_box.num());
     
    end
  endtask
endclass

In reply to mayurkubavat:

In reply to sreelaxmi:
You want something like this?

class stimulus;
logic [2:0]opcode;
logic [7:0] op1,op2;
//Store messages here
string message;
//Create constructor and pass mailbox
//...
mailbox#(string) msg_mbx;
//..
task gen;
op1 = $random;
op2 = 'd8;
opcode = $random;
#1 stimulus_vectors();
op1 = 0;
op2 = $random;
opcode = opcode + 1'b1;
#1 stimulus_vectors();
op1 = $random;
op2 = ~op1;
opcode = 3;
#1 stimulus_vectors();
op1 = $random;
op2 = $random;
opcode = $random;
#1 stimulus_vectors();
endtask //gen
task stimulus_vectors();
$display("stimulus vector is : at %g",$time);
$display("[Stimulus]:stimulus is generated :: op1 = %d , op2 = %d , opcode = %d",op1,op2,opcode);
//Store message into mailbox
message = $sformatf("[Stimulus]:stimulus is generated :: op1 = %d , op2 = %d , opcode = %d",op1,op2,opcode);
msg_mbx.put(message);
endtask //stimulus_vectors
endclass //stimulus

class type doesnot allow string type message

In reply to dave_59:

*In reply to sreelaxmi:*You should always parameterize your mailbox with the type of item being put/get.

mailbox #(stimulus) m_box;
function new(mailbox  #(stimulus) m_box);
this.m_box = m_box;
endfunction

But this is not your problem. You need to show us what you expect to happen to your inputs and you need to show who does the get(). What you are doing does not make much sense. Normally, your class ‘stimulus’ represents one set of values for (opcode,op1,o2) and create an class object for each set. The each object goes onto the mailbox.

stimulus vector is : at 1
[Stimulus]:stimulus is generated :: op1 = 36 , op2 = 8 , opcode = 1
stimulus vector is : at 2
[Stimulus]:stimulus is generated :: op1 = 0 , op2 = 9 , opcode = 2
stimulus vector is : at 3
[Stimulus]:stimulus is generated :: op1 = 99 , op2 = 156 , opcode = 3
stimulus vector is : at 4
[Stimulus]:stimulus is generated :: op1 = 13 , op2 = 141 , opcode = 5
message is put into mailbox at 4 0
Driver:: stimulus is received at 4
[Driver]:stimulus is generated :: op1 = 13 , op2 = 141 , opcode = 5 0
stimulus vector is : at 5
[Stimulus]:stimulus is generated :: op1 = 18 , op2 = 8 , opcode = 1
stimulus vector is : at 6

i want my driver output to work at every #1

In reply to sreelaxmi:

then u have to create one diver handle and call driver run task . in initial block like drv.run.

In reply to shreebamnikar:


`timescale 1 ns/ 100 ps
//`include "test.sv" 
`include "stimulu.sv"
`include "generator.sv"
`include "driver.sv"

module test_top();
 
  generator gen;
  mailbox #(stimulus)m_box;
  driver dri;
    
  initial begin
    m_box = new();
    gen = new(m_box);
    dri = new(m_box);
    
    fork
      gen.run();
      dri.run();
    join
  
    #1000 $finish ;
  end
  
endmodule:test_top


hi,
how can we use mailbox concept between generator module block and driver module block?
my example code is here… please anyone explain me.

module tbtop;
wire clk;
  wire [319:0]driver_out;
  wire [255:0]pkt1;
 
  reg rst_n;
  initial
    begin
      rst_n = 0 ;
      #5ns;
      rst_n =1  ;
    end
  clkgen cg(.clk(clk));

  driver drvr(.clk(clk),.pkt1(pkt1),.driver_out(driver_out));
  generator gen(.clk(clk),.pkt1(pkt1));
  endmodule

// clock generator

module clkgen(clk); 
output reg clk;
initial begin
clk = 0;
end
always #5 clk = ~clk;

endmodule

// Code your design here
module driver(clk,pkt1,driver_out); 
  input clk;
 // bit trans;
  input [255:0]pkt1;
  output reg [319:0]driver_out;
  bit [15:0]pkt_length;
  bit [255:0]ipv4_pkt;
  bit [255:0]ipv6_pkt;
  bit [255:0]vlan_pkt;
  bit [31:0]outcrc1;
  bit [1:0]pkt_type;
  bit [55:0]preamble ='h5a5a5a5a5a5a5a; 
  bit [7:0]spd = 'h5d;
 reg [319:0]dri_out;
  int i;
 generator g1();
  mailbox mbx = new();
    
initial begin     // trans =1;
    g1.gen_pkt(0);
 // mbx.get(pkt1);
  $display("pkt1=%h",g1.pkt1);   
  dri_out = {preamble[55:0],spd[7:0],g1.pkt1[255:0]};
    $display("dri_out=%0h",dri_out);

  for (i=0;i<40;i=i+1) begin
 @(posedge clk)   driver_out = dri_out[i*8 +: 7];
    $display("driver_out=%0h",driver_out);
      
end
end
 endmodule



module generator(clk,pkt1);
  input clk;
  output reg [255:0]pkt1;
  bit[255:0] pkt;
 

   bit[15:0]pkt_length;

   bit[255:0]ipv4_pkt;

   bit[255:0]ipv6_pkt;

   bit[255:0]vlan_pkt;

  bit [31:0]outcrc1;
  bit [1:0]pkt_type;
  
  //mailbox mbx = new();
    //  mbx.put(pkt1);

  task gen_pkt(input [1:0]pkt_type);

    case(pkt_type)

    'd0 : begin

             pkt_length = 'h256;

      for(int i=0; i<256; i++) begin

        ipv4_pkt[i*8 +: 7] = $random;

             end

             pkt[255:0] ={pkt_length, ipv4_pkt[239:0]};
            $display("value of pkt=%0h",pkt);
      
            outcrc1 = gen_crc(pkt_length,pkt);

             pkt1[255:0] = {pkt_length, pkt[207:0], outcrc1};
      $display("value of pkt1=%0h",pkt1);
           end

      'd1 : begin
            
            pkt_length = 'h256;
        for(int i=0; i<256; i++) begin
          ipv6_pkt[i*8 +: 7] = $random;
            end
            pkt[255:0] = {pkt_length, ipv6_pkt[239:0]};
            $display("value of pkt=%0h",pkt);
        
        
            outcrc1 = gen_crc(pkt_length,pkt);
        pkt1[255:0] = { pkt_length,pkt[207:0],outcrc1};
        $display("value of pkt1=%0h",pkt1);
            end


      'd2 : begin

            pkt_length = 'h256;
        for(int i=0; i<256; i++) begin
          vlan_pkt[i*8 +: 7] = $random;
            end
            pkt[255:0] = {pkt_length, vlan_pkt[239:0]};
            $display("value of pkt=%0h",pkt);
        
             outcrc1 = gen_crc(pkt_length,pkt);
            pkt1[255:0] = {pkt_length, pkt[207:0],outcrc1};
        $display("value of pkt1=%0h",pkt1);
           
      end
    endcase

  endtask

 function [31:0] gen_crc(input [15:0]length,input [255:0]pkt);

 bit [7:0] d;

 bit [31:0] crc, c, temp_crc;

 int i;

for (i=0; i<length; i++) begin

  d = pkt[i*8 +: 7];

crc[0] = d[6] ^ d[0] ^ c[24] ^ c[30];

crc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31];

crc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31];

crc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31];

crc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30];

crc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31];

crc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31];

crc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31];

crc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28];

crc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29];

crc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29];

crc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28];

crc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30];

crc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31];

crc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31];

crc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31];

crc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29];

crc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30];

crc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31];

crc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31];

crc[20] = d[4] ^ c[12] ^ c[28];

crc[21] = d[5] ^ c[13] ^ c[29];

crc[22] = d[0] ^ c[14] ^ c[24];

crc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30];

crc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31];

crc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27];

crc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30];

crc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31];

crc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30];

crc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31];

crc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31];

crc[31] = d[5] ^ c[23] ^ c[29];

$display("the value of CRC result crc = %h",crc);

 c = crc;

end

 gen_crc = c;

endfunction
 


endmodule

Sir,
i want to implement mailbox with randomize function.i used to put 10 write data for every 10ns delay but automatic read data to get for every put write data.but output here not put and get 10write and read data same data value is repeated.

fork
  //begin
  producer.fifo_if.write();
  consumer.fifo_if.read();
  //end
  join


task write();
    //a=1;
    //fork
    begin
    int i;
    i++;
    for(i=0;i<10;i++)begin
    #10ns;
    fifo_if=new();
    void'(fifo_if.randomize());
    mbx.put(fifo_if);
    $display("write data=%0d",fifo_if);
   // #10ns;
     end
   end

endtask
 // join
task read();
  int a;
  //if(a===1)
  //fifo_if.write=1;
  while(1)begin
  mbx.get(fifo_if);
  $display("read data=%0d",fifo_if);
  end
endtask

output

write data=5
read data=5
write data=6
read data=6
write data=5
read data=5
write data=6
read data=6
write data=5
read data=5
write data=6
read data=6
write data=5
read data=5
write data=6
read data=6
write data=5
read data=5
write data=6
read data=6