SystemVerilog赋值异常求助:tr.decode_data始终为0的原因排查
vif.de_deq_data be assigned to tr.decode_data in my UVM monitor? This issue boils down to SystemVerilog's assignment timing and event region mechanics—the non-blocking assignment you're using and the immediate $display call are executing out of sync, so tr.decode_data hasn't been updated yet when you print it.
Let me break down what's happening in the SystemVerilog time step:
- When the
@(posedge vif.clk)trigger fires, we enter the Active execution region for this clock edge. - When you use the non-blocking assignment (
<=) to settr.decode_data <= vif.de_deq_data, the right-hand side value is captured, but the left-hand side variable isn't updated immediately. Instead, the update is queued to happen in the Non-Blocking Assignment (NBA) region, which only runs after all Active region code for the current time step completes. - Your
$displaycalls run right away in the Active region. At this point,tr.decode_datastill holds its default initial value (0, since it's declared as abittype), hence the 0 output. Meanwhile,vif.de_deq_datais referencing the valid value from the current clock edge, so it prints correctly.
Fixes to resolve this:
Fix 1: Switch to blocking assignments
In UVM monitor tasks, blocking assignments (=) are the standard for capturing data because they update the transaction variable immediately. Change your assignment (and the other non-blocking assignments incollect_one_pkt) to use=instead:tr.decode_data = vif.de_deq_data;This ensures
tr.decode_dataholds the correct value before your$displaycalls execute.Fix 2: Delay printing until after the NBA region
If you need to keep non-blocking assignments for some reason, add a#0delay to push the print statements into the Reactive region (after NBA updates are done):tr.decode_data <= vif.de_deq_data; #0; // Wait for NBA region to update tr.decode_data $display("tr.decode_data = %0h", tr.decode_data); $display("vif.de_deq_data = %0h", vif.de_deq_data);That said, blocking assignments are the cleaner, more idiomatic choice for monitor data collection.
You can also double-check that the width of tr.decode_data (9215:0) matches vif.de_deq_data (COLS-1:0 where COLS=9216)—which they do, so that's not the issue here.
内容的提问来源于stack exchange,提问作者Self-Motivated Wu

