Search code examples
system-veriloguvm

How to initialize clocking block signals at reset


I've been reading through UVM: illegal combination of driver and procedural assignment warning and paper attached in answer. (Please consider paper linked in the question mentioned)

However drivers are implemented to drive reset values on interface signals instead of on clocking block signals, the clock is not guaranteed to be running at reset.

So how can I go about this scenario if interface signals are declared wires.

for e.g. consider the code in linked question. General scenario would be

@(vif.cb); 
vif.cb.opcode <= value; 

This is correct even if opcode is declared net in interface cause clocking block will take care of correct assignment. However I can't say

@(vif.rst);
vif.cb.opcode <= init_value;

since I can't guarantee clock at reset. To accommodate this I'll have to change clock generation strategy.

Neither can I say

 vif.opcode <= init_value;

cause its illegal to use procedural assignment with net type signals

The other way is gating signals declared as net with reset but I think for that I'll have to declare temporary signals in interface. Can anyone elaborate how can I achieve driving nets at reset ?


Solution

  • While it's illegal to assign nets from procedural code, it's legal to force values onto them. You can do the following:

    @(negedge vif.rst);
    force vif.opcode = 0;
    

    Bonus: IMO you shouldn't have opcode defined as a wire. The illegal combination of procedural and continuous driver warning is wrong. The SV 2012 standard clearly states in 14.16.2 Driving clocking output signals:

    It is possible to use a procedural assignment to assign to a signal associated with an output clockvar. When the associated signal is a variable, the procedural assignment assigns a new value to the variable, and the variable shall hold that value until another assignment occurs (either from a drive to a clocking block output or another procedural assignment).