Input Sampling for Clocking blocks

Hi ,

I was referring to LRM Section 14.14 Input Sampling .

It states the following ::


Upon processing its specified clocking event, a clocking block shall update its sampled values before
triggering the event associated with the clocking block name. This event shall be triggered in the Observed region. 
Thus, a process that waits for the clocking block itself is guaranteed to read the updated sampled values, 
regardless of the scheduling region in which either the waiting or the triggering processes execute.

For example:
clocking cb @(negedge clk);
  input v;  //  clockvar ' v ' 
endclocking


Wanted to ensure that I have a clear understanding of the above .

[Q1] On each clocking event i.e @( negedge clk ) , the clocking block internally updates the value of clockvar ’ v ’ at 1step ( default i/p skew ) before clocking event .
Then it triggers the event associated with the clocking block name in Observed Region .

**This  causes  events  like  @( cb )  to  unblock  in  Active  Region  due  to  implicit  triggering  in  Observed  Region ( i.e re-entrant triggering  from  Observed to Active Region )

 Is  my  understanding  correct ?**

LRM further says ::


 
always @(cb) $display(cb.v);
always @(negedge clk) $display(cb.v);

The preceding first always procedure is guaranteed to display the updated sampled value of signal v. 
In contrast, the second always exhibits a potential race and may display the old or the newly updated sampled value.

Assuming that DUT updates the value of signals on negedge of clk via Non - blocking assignment ( <= ) :

[Q2] How is that we observe updated value of signal v in 1st always block ?
Via the clocking block won’t be observe the value of signal ’ v ’ 1step before clock trigger i.e negedge clk i.e prior to DUT update ?

[Q3] In the 2nd always block , won’t we observe the preponed value i.e value of signal v prior to DUT update ?

[4] The following coding practice is used for Sampling signals driven from DUT via clocking block .


// GOOD testbench procedural code – Wait on clocking block event
@ simple_CB
 valid_result = simple_CB.from_DUT;
...
...
// BAD testbench procedural code – Wait on raw event
@(posedge clock) // DON’T DO THIS
 unreliable_result = simple_CB.from_DUT;

[Q4] When using the raw clocking event @( posedge clock ) won’t we observe the value prior to being driven by DUT ?

  @( posedge clock )  would  unblock  in  active  region  whereas  the  signal  driven  by  DUT  via  Non-Blocking  Assignment  would  be  updated  later  in  NBA  Region .
  Thereby  we  would  observe  the  previous  value  in  2nd  case  as  well .

 **However  if  the  DUT  were  to  drive  using  continuous  assign statement there  is  a  potential  race  condition**

i.e we could observe the previous value OR we could observe updated value

[5] I then tried the following code :: Code

DUT updates signal out at TIME : 20 , 30 , 40 to values 30 , 100 and 400 respectively .

Via always1 i.e using clocking event @( cb ) we observe the value of clockvar as 1step prior to negedge of clock
i.e value prior to being driven by DUT

Hence at TIME : 20 , 30 , 40 we observe values as 0 , 30 and 100 respectively .

[Q5] However via always2 I am not sure why values observed lag 1 clock behind the values observed via always1 ?

In reply to Have_A_Doubt:

You first statement is correct, but the rest might help by understanding there are actually three different values associated with a clocking block input signal.

  1. The raw signal value determined by what is driving the signal.
  2. The sampled signal value determined by the sampling skew.
  3. The clocking block variable (clockvar) that gets updated at the clocking event to the sampled value.

It’s possible for there to be three different values at a point in time. I think you are confused by the difference between the sampled value and the clocking block variable that gets updated to hold the sampled value.

Note that the LRM text you quoted has a number of clarifications in the next revision of the standard.

In reply to dave_59:

Hi Dave ,

[I] Regarding the mantispage :


  clocking cb @(posedge clk);
     ....
  endclocking

Wanted to confirm the following nomenclature ::

  • @( posedge clk ) is called as the clocking event
  • clocking block event which is triggered in Observed region is simply the name of the clocking block i.e ’ cb ’ without the @( … )

[QA] Is there a name for specifically @( cb ) ? i.e event which waits for clocking block event ?

 Would  calling  **@( cb ) as  Clocking  block's  named  event**  be  appropriate ?

[II] Having spent time referring LRM , SNUG Paper “Taming Testbench Timing Time’s Up for Clocking blocks Confusions” .

I believe I have clarity regarding [Q2] , [Q3] , [Q4] and [Q5] .

Please feel free to correct me ::

At a clocking event assume DUT updates it’s output signal from old_val to new_val .

At the very same clocking event the clocking block updates the clockvar with the value sampled at input skew time units before the clocking event .
Then after updating the input clockvar the clocking block triggers the event associated with it’s name in Observed Region .

Regarding [Q2] :
So when the 1st always block unblocks in Active region user is guaranteed to observe clocking block’s updated sampled value old_val which would be different than DUT’s updated value of new_val .

Regarding [Q3] and [Q4] :
Via the 2nd always block which uses the raw clock signal , there is a possible race condition i.e
We may observe clocking block’s updated sampled value OR we may observe the value of input clockvar prior to clocking block’s update .

I was confusing clocking block’s updated value ( i.e old_val ) with DUT’s updated value ( i.e new_val )

The LRM discusses sampling the updated values from clocking block’s perspective and not the DUT’s.

Regarding [Q5] :
Via 2nd always block which uses the raw clock @( negedge clk ) the clocking block hasn’t updated it’s input clockvar as a result we observe previous value of old_val