Sunday 8 December 2013

Using Clocking Blocks: Guidelines to follow

Clocking Blocks: Guidelines to follow

1.    When using a clocking block, the testbench must access only its clockvars and should never access the clocking signals directly.(CB_name.Clock_var_name)

clocking wr_cb@(posedge clock);
        default input #1 output #1;
  ============Clocking Var’s==============
        output wr_address;        
        output data_in;                  
        output write;             
endclocking: wr_cb

2.    Testbench code should synchronize itself to a clocking block’s clock event by waiting for the clocking block’s own named event, NOT by waiting for the raw clock event.

·         Testbench code that uses a clocking block should never synchronize itself to the raw clock event such as @(posedge clock). This would give rise to unexpected behavior of input sampling.

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

·         REASON 1: The name of a clocking block (and, therefore, of its named event) can be chosen to reflect the testbench-facing effect of the clock.
Eg. clocking video_pixel_clk @(negedge vClk);
·         The clocking block hides the clock’s edge polarity from the testbench. If the testbench carefully uses @video_pixel_clock everywhere, instead of @(negedge vClk), then future changes to the clock’s name or polarity can be accommodated simply by changing our clocking block’s definition.

3.    Write to output clockvars using the clocking drive operator <=. Never try to write an output clockvar using simple assignment =

·         Testbench obtains the values of the input clocking signals as they were at a time before the clock event, with the actual time specified by the clocking skew(input #1). The testbench can then use those “pre-clock” values to compute appropriate stimulus for the DUT.
·         After the clock event has already happened, we do not wish to risk hold time violations by applying new stimulus immediately. Instead, we apply our new stimulus some time after the clock event, so that it is stable and ready for the next clock.
·         simple_CB.to_DUT <= new_stimulus; // Clocking drive
·         Driving the output clocking var’s with use of NBA as actually known as clocking drive.
·         According to the SystemVerilog LRM, it is illegal to write to an output clockvar using the regular assignment operator =
·         The clocking block’s timing skews do not affect what happens if you access the original signals directly. Timing skews are relevant only when the testbench makes access through the clocking block’s clockvars.

4.    Use input#1step unless you have a special reason to do otherwise. It guarantees that your testbench sees sampled values that are consistent with the values observed by your SystemVerilog assertions, properties and sequences.

·         The default skew for clocking block input sampling, if no skew is explicitly specified, is input #1step.
·         Delay specification indicates that the signal’s value is to be sampled just before the simulation time at which the clock event occurs. “just before” means that the signal is sampled before any activity at the time of the clock event, but after any earlier simulation activity. For example, clock event occurs at time 15ns. Suppose, too, that there was some simulation activity (code execution, signal value changes, etc) at time 14.5ns, and nothing happened between those two times. input#1step sampling requires the simulator to report the value of our clocking block input signal as it was during that idle time between 14.5ns and 15.0ns.
·         input#1step yields exactly the same value as you would obtain by using the $sampled system function at the moment of the clock event. This is the same value that is sampled for the signal if it appears in a SVA property or sequence.

5.    Use non-zero output skew values in your clocking blocks to make waveform displays clearer, and to avoid problems caused by clock network delays in gate level simulation.

·       The default output skew for a clocking block is output#0.
·     This skew specification causes the driven signal to be updated during execution of the Re-NBA scheduling region of the same simulation timestep in which the clock event occurred.
·   This behavior is closely similar to the effect of an ordinary non-blocking assignment (NBA) executed on the clock event, but it will happen after all such NBAs have completed.

6.    Never use input#0 in your clocking blocks.

·    input#0 sampling delay specification causes the clocking block to sample an input signal in the Observed region of the SystemVerilog scheduler.
·     The Observed region occurs very late in the events queue, even later than the NBA region, and therefore input#0 sampling can see the new values of register outputs after they have been updated by NBA assignments executed at the clock edge.
·         input#0 sampling allows our testbench a “sneak preview” of the value of a signal after the effects of the current clock. Normally your testbench would not be able to see that new value until the next clock.

Notes:
·         If a clocking block output or inout drives a net, the driven value will automatically initialize to 'z (all high-impedance).
·         When a signal is driven by more than one clocking block output, that signal should be a variable.
·         Testbench code can read an input clockvar, but cannot write to it. Perhaps more surprisingly, testbench code can drive (write to) an output clockvar, but cannot read that clockvar to inspect its value.
·         When user code reads an inout clockvar it is in fact reading a corresponding input clockvar; by contrast, when user code drives an inout clockvar it is in fact driving a corresponding output clockvar.
·         Declare your clocking block in an interface. Expose the clocking block, and any asynchronous signals that are directly related to it, through a modport of the interface. In your verification code, declare a virtual interface data type that can reference that modport.
·         Use your clocking block to establish signal directions with respect to the testbench. Do not add the raw signals to a testbench-facing interface's modport.

modport master_mp(clocking master_cb, input RESET_async_n,
input READY, output VALID, DATA);               // WRONG – exposes raw signals

·         Clocking blocks should usually be accessed through a virtual interface variable pointing to a modport of the clocking block’s enclosing interface.
·         In that situation, each clockvar must be accessed using the three-part dotted name virtual_interface.clocking_block.clockvar

·         the class-based testbench code has no access to the interface's default clocking, and cannot safely use ##N procedural delays.


      
          View Maulik Suthar's profile on LinkedIn
        

   

------------------------------------------------------------------------------------------------

Reference: SNUG Austin 2012 "Taming Testbench Timing":
http://www.verilab.com/resources/papers-and-presentations/


   
         
     
   

No comments:

Post a Comment