Associative array of queues

Hi,

Could someone suggest an appropriate data structure to store information for scoreboarding purposes?

Problem I am trying to solve :

I have 3 masters that can read and write that send requests to the DUT to access the same DDR address space. DUT sends out data as AXI transactions.

I have sequences to send items on the 3 interfaces. I pop the wreq/wdata out of the corresponding TML fifos and packetize into AXI transaction type associative array, indexed by address and store the information.

Now, when 3 masters are accessing the same address, how can I keep track of the different accesses and how can I store information in the associative array that is indexed by address?

Should I have a queue for the accesses to the same address?


// Code your testbench here
// or browse Examples
///Class which contain the addr and data of the AXI transaction
class axi_tran;
  logic [31:0] data;
 
  //other methods
endclass : axi_tran
 
 
module my_prg;
 
  //Associative array of axi_tran type and int key/index type 
  // axi_tran axi_tran_arr[master_id][addr];
  axi_tran axi_tran_arr[int][int];
  int addr;
 
  initial begin
    for (int addr=0; addr<5; addr++)begin
      axi_tran a;

      a = new();
      a.data = $urandom();
      $display("Master : 0, AXI ADDR : %h, AXI DATA = %h", addr, a.data);
      //store the axi transaction in the associative array based on addr for specific master 
      axi_tran_arr[0][addr] = a;
      
      a = new();
      a.data = $urandom();
      $display("Master : 1, AXI ADDR : %h, AXI DATA = %h", addr, a.data);
      //store the axi transaction in the associative array based on addr for specific master 
      axi_tran_arr[1][addr] = a;
        
    end
 
    $display("*********** Checking  the DATA of the AXI transaction for specific master *********");
 
    addr = 1;
    $display("Master 0 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[0][addr].data);
    $display("Master 1 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[1][addr].data);
    
    //check addr = 2, data exist for master 0
    addr = 2;
    if(axi_tran_arr[0].exists(addr))
      $display("Master 0 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[0][addr].data);
    
  end
 
endmodule : my_prg


In reply to Rahul Patel:


// Code your testbench here
// or browse Examples
///Class which contain the addr and data of the AXI transaction
class axi_tran;
logic [31:0] data;
//other methods
endclass : axi_tran
module my_prg;
//Associative array of axi_tran type and int key/index type 
// axi_tran axi_tran_arr[master_id][addr];
axi_tran axi_tran_arr[int][int];
int addr;
initial begin
for (int addr=0; addr<5; addr++)begin
axi_tran a;
a = new();
a.data = $urandom();
$display("Master : 0, AXI ADDR : %h, AXI DATA = %h", addr, a.data);
//store the axi transaction in the associative array based on addr for specific master 
axi_tran_arr[0][addr] = a;
a = new();
a.data = $urandom();
$display("Master : 1, AXI ADDR : %h, AXI DATA = %h", addr, a.data);
//store the axi transaction in the associative array based on addr for specific master 
axi_tran_arr[1][addr] = a;
end
$display("*********** Checking  the DATA of the AXI transaction for specific master *********");
addr = 1;
$display("Master 0 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[0][addr].data);
$display("Master 1 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[1][addr].data);
//check addr = 2, data exist for master 0
addr = 2;
if(axi_tran_arr[0].exists(addr))
$display("Master 0 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[0][addr].data);
end
endmodule : my_prg

Thank you Rahul. Can I have two tasks(for two masters) write into the same associative array but with different index? One task writes to axi_tran_arr[0] and another to axi_tran_arr[1]?

In reply to UVM_learner6:

In reply to Rahul Patel:
Thank you Rahul. Can I have two tasks(for two masters) write into the same associative array but with different index? One task writes to axi_tran_arr[0] and another to axi_tran_arr[1]?

Yes


// Code your testbench here
// or browse Examples
// Code your testbench here
// or browse Examples
///Class which contain the addr and data of the AXI transaction
class axi_tran;
  logic [31:0] data;
 
  //other methods
endclass : axi_tran
 
 
module my_prg;
 
  //Associative array of axi_tran type and int key/index type 
  // axi_tran axi_tran_arr[master_id][addr];
  axi_tran axi_tran_arr[int][int];
  int addr;
 
  initial begin
    for (int addr=0; addr<5; addr++)begin
      axi_tran a;
 
      a = new();
      a.data = $urandom();
      $display("Master : 0, AXI ADDR : %h, AXI DATA = %h", addr, a.data);
      //store the axi transaction in the associative array based on addr for specific master 
      axi_tran_arr[0][addr] = a;
 
      a = new();
      a.data = $urandom();
      $display("Master : 1, AXI ADDR : %h, AXI DATA = %h", addr, a.data);
      //store the axi transaction in the associative array based on addr for specific master 
      axi_tran_arr[1][addr] = a;
 
    end
 
    $display("*********** Checking  the DATA of the AXI transaction for specific master *********");
 
    addr = 1;
    $display("Master 0 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[0][addr].data);
    $display("Master 1 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[1][addr].data);
 
    //check addr = 2, data exist for master 0
    addr = 2;
    if(axi_tran_arr[0].exists(addr))
      $display("Master 0 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[0][addr].data);
 
    master_1();
    master_2();
    $display("Master 0 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[0][15].data);
    $display("Master 1 : AXI ADDR : %h, AXI DATA = %h", addr, axi_tran_arr[1][16].data);
    
  end
  
  
  task master_1();
    axi_tran a1;
    addr = 15;
    a1 = new();
    a1.data = 16'h1234;
    axi_tran_arr[0][addr] = a1;
  endtask
  
  task master_2();
    axi_tran a2;
    addr =16;
    a2 = new();
    a2.data = 16'h5678;
    axi_tran_arr[1][addr] = a2;
  endtask
  
 
endmodule : my_prg

In reply to Rahulkumar Patel:

Thanks for helping on the multiple masters question.

If the same master writes different values to the same address (this is a valid scenario, though from RTL point of view it gets overwritten), the scoreboard fo some purpose, needs to keep track of all the writes to the same address. Which means I need to keep track of all the values pushed for the same address by storing in queue.

Can a queue be passed to an associative array? Is there an example you could please point me to?

In reply to UVM_learner6:


//associative array of queue.
axi_tran axi_tran_arr[int][int]  [$];

//OR 

typedef axi_tran axi_tran_q[$];
axi_tran_q axi_tran_arr[int][int];

Look like you are complicating the testbench.