Difference between output clockvar and raw signal

The difference between value of an input clockvar and the raw signal is straightforward ,
At each clocking event the input clockvar are internally updated by the clocking block . The DUT updates the raw signal on the same clocking event .
however I am trying to figure out difference between output clockvar and the raw signal since they are manually assigned / driven by DV owner

Consider the following code ::


 module  Top;

   bit  clk ;
   bit  [1:0]  to_DUT ;  //  Raw  signal  defaults  to  0

   clocking  cb @( posedge clk );
     default  input #1step output #2;
     output   to_DUT ;
   endclocking

   always  #5  clk  = !clk ;

   initial  begin

     #3  cb.to_DUT   <=  3 ;

   end

   initial  #20 $finish() ;

endmodule

From what I understand :

The raw signal ’ to_DUT ’ is scheduled to be driven in Re - NBA region of time 7 units ( clocking event at t : 5 + output skew of 2 units )

However the following isn’t clear :
When is the output clockvar ’ cb.to_DUT ’ driven ?
Is it driven in Re - NBA region as well ? Does the drive occur relative to clocking event and output skew ?

A colleague suggests that output clockvar ’ cb.to_DUT ’ is driven in Re - NBA region of time 3 units ( independent of clocking event and output skew ) ,
however I am not a 100% certain on it .

On adding ::

always @( cb.to_DUT ) $display(" Output  clockvar  cb.to_DUT  changes  at T:%2t ",$time);

I observe different results across tools .

One of the tool throws a compilation error ( maybe since output clockvar is being read )
2nd tool doesn’t throw compilation error and the display statement executes at T: 3 ( i.e same time as execution of the drive independent of clocking event and output skew )
3rd tool doesn’t throw compilation and the display statement executes at T: 7 ( i.e after clocking event and output skew )

In reply to Have_A_Doubt:

The LRM says: It shall be illegal to read the value of any clockvar whose clocking_direction is output.

Like a nonblocking assignment, the RHS expression of a clockvar output drive statement gets evaluated immediately in whatever region the process containing the drive statement is executing in.

In reply to dave_59:

Hi Dave ,

LRM 14.15 : “Explicit synchronization is done via the event control operator, @, which allows a process to wait for a particular signal value change or a clocking event.
The expression used with the event control can denote clocking block input (input or inout) or a slice thereof”

This too confirms that always@( cb.to_DUT ) is Illegal .

Like a nonblocking assignment, the RHS expression of a clockvar output drive statement gets evaluated immediately in whatever region the process containing the drive statement is executing in

So this tells me that the drive is essentially an non-blocking statement i.e if I were to add a display statement just after the drive , it would execute at t:3 units .

However I am still not clear on when the update to the output clockvar actually occurs

LRM 14.16 says :: “For clocking block outputs with nonzero skew, or drives with nonzero cycle delay, the corresponding signal shall be scheduled to change value in the Re-NBA region of a future time step.”

This means that the actual raw signal ’ to_DUT ’ is updated in Re - NBA region at output skew units after the clocking event i.e t:7 in above example .

I tried searching in the LRM but unfortunately couldn’t find anything regarding the update to the output clockvar .
Does the LRM clarify this ? OR Is it Implementation dependent ?

In reply to Have_A_Doubt:

The LRM only defines observable behavior. That is all that matters. Everything else is implementation dependent.