In reply to cgales:
Sorry that I forgot to paste those parts.
In my monitor:
task out_monitor::main_phase(uvm_phase phase);
audio_transaction tr;
while(1) begin
collect_one_pkt(tr);
ap.write(tr);
end
endtask
task out_monitor::collect_one_pkt(output audio_transaction tr);
tr = new("tr");
tr.data_l = new[1];
tr.data_r = new[1];
`uvm_info("out_monitor", "begin to collect one pkt", UVM_HIGH);
@(posedge vif.AUD_DAT_VLD);
tr.data_l[0] = vif.AUD_DAT_L;
tr.data_r[0] = vif.AUD_DAT_R;
`uvm_info("out_monitor", "one pkt collected", UVM_HIGH);
// tr.print();
endtask
In my scoreboard:
task my_scoreboard::main_phase(uvm_phase phase);
audio_transaction get_expect, get_actual, tmp_tran;
bit result;
bit first_sample_f;
super.main_phase(phase);
first_sample_f = 1;
while (1)
// fork
begin
//expected trans
begin
exp_port.get(get_expect);
expect_queue.push_back(get_expect);
`uvm_info("my_scoreboard", "expect_queue push", UVM_HIGH)
`uvm_info("my_scoreboard", get_expect.sprint(), UVM_HIGH);
end
//actual trans
begin
act_port.get(get_actual);
if(first_sample_f)
begin
act_port.get(get_actual);
first_sample_f = 0;
end
//tailor the actual packet according to the stimulus
if(expect_queue.size() > 0)
begin
tmp_tran = expect_queue.pop_front();
if(tmp_tran.sample_width)
begin
get_actual.data_l[0][23:16] = 8'h0;
get_actual.data_r[0][23:16] = 8'h0;
end
if(~tmp_tran.channel[0]) get_actual.data_l.delete();
if(~tmp_tran.channel[1]) get_actual.data_r.delete();
result = get_actual.compare(tmp_tran);
if(result)
begin
`uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_HIGH)
end
else
begin
$display("the expect pkt is");
tmp_tran.print();
$display("the actual pkt is");
get_actual.print();
end
end
else
begin
`uvm_error("my_scoreboard", "Received from DUT, while Expect Queue is empty");
$display("the unexpected pkt is");
get_actual.print();
end
end
// join
end
endtask
The situation is that when I use “fork/join” in the scoreboard main_phase loop, since some unexpected actual trans may be got before the coresponding expected trans, one piece of error message will be printed; if I use “begin/end” instead, the “act_port” always gets the latest trans. As the “get()” occurs after the exp_port.get(), even if there’s any unexpected actual trans, they won’t be noticed.
The issue that you mentioned, that pointers refer to the same object written to the fifo, seems not the cause, as I have “new()” before each write.