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 ?