A clocking block samples and drives interface signals relative to a clock. The TB talks to the clocking block, not raw wires — that removes NBA vs TB race bugs.
sequenceDiagram participant TB participant CB as clocking participant DUT Note over CB: @(cb) TB->>CB: cb.drv <= data CB->>DUT: after skew
clocking cb @(posedge clk);
default input #1step output #1;
output valid, data;
input ready;
endclocking
@(cb);
cb.valid <= 1;
cb.data <= payload;
Use ##n cycle delays in the clocking domain. Keep the DUT free of clocking blocks — they are a TB construct.
Wrong vs right
Wrong — @(posedge clk); vif.data = x; racing with DUT <=.
Right — drive through a clocking block (or a UVM driver that waits on the same edge, then <=).