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.