I have a monitor and a scoreboard connected through uvm_analysis_port/imp. I am sampling some values in the monitor and using the write function to transport those to the scoreboard. The scoreboard is also getting those values as reflected in the info statement and putting it in a queue. However, when I am reading the queue in check_phase, all the entries in the queue have the same value equal to the last value written in the queue. please help debug.
class my_scoreboard extends uvm_scoreboard;
`uvm_component_utils(my_scoreboard)
my_sequence_item tr_q[$];
my_sequence_item tr1;
logic [7:0] prev_a;
logic [7:0] prev_b;
uvm_analysis_imp#(my_sequence_item, my_scoreboard) ai;
function new(string name="scoreboard",uvm_component parent);
super.new(name,parent);
ai=new(name,this);
endfunction
function void write(my_sequence_item tr_c);
`uvm_info("",$sformatf("writing to queue a-%d, b-%d",tr_c.a,tr_c.b),UVM_LOW); //printing correct values
tr_q.push_back(tr_c);
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
//write match logic here
phase.drop_objection(this);
endtask
function void check_phase(uvm_phase phase);
super.check_phase(phase);
tr1 = my_sequence_item::type_id::create("tr1");
foreach(tr_q[i]) $display(tr_q[i].a); //printing all same values, unintended
while(tr_q.size()) begin
$display("tr_q.size-%d",tr_q.size); //prints correct queue size
tr1=tr_q.pop_front();
if(tr1.doAdd) begin
if(!(tr1.result===(prev_a+prev_b)))
`uvm_info("",$sformatf("add result-%d,a-%d,b-%d",tr1.result,prev_a,prev_b), UVM_LOW);
end
else begin
if(!(tr1.result===(prev_a-prev_b)))
`uvm_info("",$sformatf("sub result-%d,a-%d,b-%d",tr1.result,prev_a,prev_b), UVM_LOW);
end
prev_a=tr1.a;
prev_b=tr1.b;
end
endfunction
endclass
class my_monitor extends uvm_monitor;
`uvm_component_utils(my_monitor)
my_sequence_item tr_m;
virtual add_sub_if vif;
uvm_analysis_port#(my_sequence_item) ap;
function new(string name,uvm_component parent);
super.new(name,parent);
ap=new(name,this);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
//if(!uvm_config_db#(virtual add_sub_if)::get(this,"","add_sub_if",vif))
// `uvm_error("","Error in Monitor");
endfunction
task run_phase(uvm_phase phase);
tr_m=my_sequence_item::type_id::create("tr_m");
forever begin
@(vif.cb);
tr_m.a=vif.a;
tr_m.b=vif.b;
tr_m.doAdd=vif.doAdd;
tr_m.result=vif.cb.result;
ap.write(tr_m);
`uvm_info(get_name(),$sformatf("a-%d, b-%d, doAdd-%d, result-%d",tr_m.a,tr_m.b,tr_m.doAdd,tr_m.result),UVM_LOW);
end
endtask
endclass
class my_agent extends uvm_agent;
`uvm_component_utils(my_agent);
my_driver drv;
my_sequencer sqr;
my_monitor mon;
my_scoreboard scbd;
virtual add_sub_if vif;
function new(string name="agent", uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
//build driver, monitor, scoreboard here
super.build_phase(phase);
drv=my_driver::type_id::create("drv",this);
sqr=my_sequencer::type_id::create("sqr",this);
mon=my_monitor::type_id::create("mon",this);
scbd=my_scoreboard::type_id::create("scbd",this);
if(!uvm_config_db#(virtual add_sub_if)::get(this,"","add_sub_if",vif))
`uvm_error(get_name(),"Error getting vif")
endfunction
function void connect_phase(uvm_phase phase);
//connect driver, sequencer here
drv.seq_item_port.connect(sqr.seq_item_export);
mon.ap.connect(scbd.ai);
drv.vif=this.vif;
mon.vif=this.vif;
endfunction
endclass: my_agent
Please reply if you need the complete code to help debug.