Below is some code from my interface and driver class definitions. When the code runs as-is, I never see the valid data cycle appear on the interface. I know that forks started inside of a for loop don’t actually start executing until the loop is done. But it seems that the for loop is advancing simulation time in such a way that when the threads start, I’ve already missed the posedge of my clocking block. If I throw “@this.vif.drv_cb” before the first interface assignment, I then see the valid cycle appear on my interface - but one cycle later than I want it. This adds a cycle before every valid transaction, making it impossible for me to drive back-toback valid transactions.
I have similar driver code for other agents that do not use forks. I’m able to drive back-to-back transactions on those interfaces just fine. So it seems almost certain the for-loop/fork combination is what’s causing my pain here.
Thanks in advance for any suggestions.
interface my_intf (input logic clk, input logic rst_n);
localparam WIDTH = 16;
localparam NUM_LANE = 8;
logic [NUM_LANE-1:0] vld;
logic [NUM_LANE-1:0] dat[WIDTH-1:0];
clocking drv_cb @(posedge clk);
output vld;
output data;
endclocking : drv_cb
clocking mon_cb @(posedge clk);
input rst_n;
input vld;
input data;
endclocking : mon_cb
endinterface : my_intf
class my_driver#(parameter NUM_LANE=1) extends uvm_driver #(my_item#(NUM_LANE));
...
virtual task run_phase(uvm_phase phase);
forever begin
this.seq_item_port.get_next_item(this.req);
this.drive_txn(this.req);
this.seq_item_port.item_done();
end
endtask : run_phase
task drive_txn(item_c#(NUM_LANE) _item);
for (int ii=0; ii<NUM_LANE; ii++) begin
// create a thread for each valid lane
if (_item.vld[ii] == 1'b1) begin
fork
automatic int unsigned jj = ii;
begin
this.vif.drv_cb.lane[jj].vld <= _item.vld;
this.vif.drv_cb.lane[jj].dat <= _item.data;
@this.vif.drv_cb;
this.vif.drv_cb.lane[jj].vld <= '0;
this.vif.drv_cb.lane[jj].dat <= 'x;
end
join_none
end // if vld
end // for num lanes
wait fork;
endtask : drive_txn
...
endclass : my_driver