Advance time in uvm_driver

Given the following code, located in the run_phase of a uvm_driver:


task get_and_drive();
    seq_item_port.get_next_item(trans);
    $display("DRIVER ISSUE: %p @%t", trans, $time);
    while(credits.is_available() == 0) begin
        @(vif.cb);
    end
    `uvm_info(get_type_name(), trans.sprint(), UVM_DEBUG)

    if (trans.valid == 1)
        credits.consume();
    vif.cb.valid <= trans.valid;
    vif.cb.instr <= trans.instr;
    vif.cb.data  <= trans.data;
    vif.cb.sb_id <= trans.sb_id;
    vif.cb.csr   <= trans.csr;
    test_valid = trans.valid

    $display("DRIVER ISSUE TEST VALID: %0d @%t", test_valid, $time);
    seq_item_port.item_done();

    @(vif.cb);
    vif.cb.valid <= 1'b0;
    test_valid = 0;
    $display("DRIVER ISSUE TEST VALID2: %0d @%t", test_valid, $time);
    trans = null;
endtask : get_and_drive

I would expect an output like:


# DRIVER ISSUE: '{m_leaf_name:"m_req", m_inst_id:3358, use_uvm_seeding:1, m_inst_count:3369, __m_uvm_status_container:@uvm_status_container@1, uvm_global_copy_map:'{ }, events:@uvm_object_string_pool__2@331, begin_event:@uvm_event__1@173, end_event:@uvm_event__1@174, m_transaction_id:8, begin_time:320000, end_time:18446744073709551615, accept_time:18446744073709551615, initiator:null, stream_handle:null, tr_recorder:null, m_sequence_id:8, m_use_sequence_info:1, m_depth:3, m_sequencer:@avispado_issue_sequencer@1, m_parent_sequence:@spike_seq@1, print_sequence_info:0, issued1:0, issued2:0, valid:1, instr:1577239255, data:1, sb_id:5, csr:139588599808, type_name:"avispado_issue_trans"} @320000

# DRIVER ISSUE TEST VALID: 1 @320000
# DRIVER ISSUE TEST VALID2: 0 @340000

But what I get is:


# DRIVER ISSUE: '{m_leaf_name:"m_req", m_inst_id:3358, use_uvm_seeding:1, m_inst_count:3369, __m_uvm_status_container:@uvm_status_container@1, uvm_global_copy_map:'{ }, events:@uvm_object_string_pool__2@331, begin_event:@uvm_event__1@173, end_event:@uvm_event__1@174, m_transaction_id:8, begin_time:320000, end_time:18446744073709551615, accept_time:18446744073709551615, initiator:null, stream_handle:null, tr_recorder:null, m_sequence_id:8, m_use_sequence_info:1, m_depth:3, m_sequencer:@avispado_issue_sequencer@1, m_parent_sequence:@spike_seq@1, print_sequence_info:0, issued1:0, issued2:0, valid:1, instr:1577239255, data:1, sb_id:5, csr:139588599808, type_name:"avispado_issue_trans"} @320000
# DRIVER ISSUE TEST VALID: 1 @320000
# DRIVER ISSUE TEST VALID2: 0 @320000

Instead if we do the following modification in the code:


$display("DRIVER ISSUE TEST VALID: %0d @%t", test_valid, $time);
seq_item_port.item_done();
@(vif.cb);
@(vif.cb);
vif.cb.valid <= 1'b0;
test_valid = 0;
$display("DRIVER ISSUE TEST VALID2: %0d @%t", test_valid, $time);

Note the second @(vif.cb)

The output generated is the following:


# DRIVER ISSUE: '{m_leaf_name:"m_req", m_inst_id:3358, use_uvm_seeding:1, m_inst_count:3369, __m_uvm_status_container:@uvm_status_container@1, uvm_global_copy_map:'{ }, events:@uvm_object_string_pool__2@331, begin_event:@uvm_event__1@173, end_event:@uvm_event__1@174, m_transaction_id:8, begin_time:320000, end_time:18446744073709551615, accept_time:18446744073709551615, initiator:null, stream_handle:null, tr_recorder:null, m_sequence_id:8, m_use_sequence_info:1, m_depth:3, m_sequencer:@avispado_issue_sequencer@1, m_parent_sequence:@spike_seq@1, print_sequence_info:0, issued1:0, issued2:0, valid:1, instr:1577239255, data:1, sb_id:5, csr:139588599808, type_name:"avispado_issue_trans"} @320000
# DRIVER ISSUE TEST VALID: 1 @320000
# DRIVER ISSUE TEST VALID2: 0 @360000

Do you have any hint on why the time with one @(vif.cb) do not advance but if we put two @(vif.cb) it does it twice ?

Thanks.
Salut!

In reply to Sustrak:

Without seeing the entire environment, it’s difficult to determine the exact issue. The get_next_item() call is blocking, so there may be something in the sequence that has a time delay or different block that waits until the same time slice as your vif. When the sequence_item is sent to the driver, the simulation is at time 320000, but the vif clocking block hasn’t been processed yet. You then wait for the vif clocking block (at the same time), which then occurs in the same time slice, hence the same simulation time displayed.

Look at the sequence and make sure that it is untimed or doesn’t have a different blocking mechanism.

In reply to cgales:

Thanks for the insight, indeed i was using in the sequence the #[time] construct to synchronize with the clock instead of using the @() notation. Once this was fixed the synchronization in the different parts of the UVM seems to follow a logical order.

Thanks.

Salut!

In reply to Sustrak:

As a follow-up, you should never have any timing constructs in your sequence. Timing events should only occur in your drivers.

In reply to cgales:

Agree but, for design reasons i need to have a forever loop in my sequence (in order to fetch instructions for my design) and I need to advance time there or the sequence will get stuck in a infinite loop.

In reply to Sustrak:

In reply to cgales:
Agree but, for design reasons i need to have a forever loop in my sequence (in order to fetch instructions for my design) and I need to advance time there or the sequence will get stuck in a infinite loop.

The sequence is an untimed construct and does not know anything about clock cycles and progressing time.