You will want to create different clocking blocks for different functionality. The directionality of the signals is critical for correct functionality. For a driver clocking block, the signals like ‘addr’ will be outputs. For a monitor clocking block, the signals will all be inputs. Make sure you reference the correct clocking block in each component.
When using clocking blocks, all references need to be made using the clocking block (vif.cb.signal). Don’t refer to the signals directly (vif.signal).
Don’t use modports. They are design constructs and aren’t used for verification.
When assigning values to clocking block signals, you need to use non-blocking assignments.
Thanks for answering!
in the last point you raise you meant that in case of driving I need to use ‘<=’ instead of ‘=’?
If so, that’s exactly what I’m doing in my driver.
another question that I have regrading that(I saw different answer for this but I didn’t completely understood), why when we sampling we use blocking assignment and when we are driving we use non blocking assignments (I know it’s related to racing conditions but I can’t understand this completely, if you have some example I’d love to see it).
and last question regarding clocking block, when we sample a signal we sample it a bit before the clock edge, but what if in the signal’s value changes @(posedge)? it seems like we sample an old value of the signal, am I missing something?
You sample with blocking assignments as you are putting values into a testbench structure. You assign with non-blocking assignments as the clocking block uses the output skew to assign the clocking block values to the associated signals.
Clocking blocks are designed to prevent race conditions where signals change at the same time as the clock. You are correct that the input skew will sample all values prior to the clock edge. This ensures that you get the values for all signals correctly and don’t have a mismatch of some signals that have changed and some that haven’t.