When I use “exp_port.get(get_expect);” and “act_port.get(get_actual);”
It seems only the latest transaction popped out from the fifos.
I’ve tried to print out all packets written into the fifos and popped out from them. There is an evident difference between them.
It seems if the “get()” happens after any write(), it gets nothing but a future trans. The “get()” has to be earlier than “writes()”. Why does this happen? How to fix this?
Since you don’t show any code which relates to the writing/reading of your analysis ports, I’m going to guess that you don’t clone your transaction prior to writing. This results in re-using the same transaction handle which will overwrite your data.
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.
The analysis_export does n ozt have any storage capabilities, i.e. you see only the last transaction. You need analysis_fifos to store your transactions.
I retrieve data by “get()” from blocking_get_export of the fifo.
I already have write() to analysis_port in the monitor, but what’s wrong in my implement?
I do not really understand your architecture. Especially why you need the queue. You have already 2 tlm fifos in your environment.
BTW, they should be in the scoreboard, then your structure becomes more easy.
The process should be like this:
When you receive a transaction on your output side you have to make a get on the input tlm, retrieving a tarnsaction from there and providing this to your ref model. The output of your ref model delivers you an transaction of the same type as the output transaction has and you can make a compare.
If you could provide me a complete example I could help in some more detail. Currently it is more guessing what I do.
If you don’t want to share your code here publically you can send me an email christoph@christoph-suehnel.de
With the help of chr_sue, I find that in my reference model, before I write each trans into the analysis port which is finally connected to a fifo in the scoreboard, I forget to clone them. If I only write handles that points to the same object into a fifo, the content of the trans will be modified later. As they are already in the fifo, those changes will not be noticed, so the cause of the bug is very difficult to be found. The bug itself is even not obvious to be awared of.
Many thanks to chr_sue. He helps a lot.
Hi Leo,
I believe you are using expected as well as actual trans. By any chance, are you using a uvm_subscriber as well, as a part of your scoreboard architecture to put your reference model? If so, is it the recommended architecture?