Wednesday, August 8, 2018

Avoiding race around in Assertions

I have been coding assertions a lot recently to verify certain functionality at SOC/block level. I ended up with some false failures in regressions mainly due to Systemverilog race around and I could not find good online guidelines to avoid such conditions. After researching, I am putting up some learnings here and many of these directions are directly coming from CummingsSNUG2006Boston_SystemVerilog_Events paper.

Broadly assertions can be classified into 2 categories
  1. Concurrent Assertions – describes logic behavior of signals that spans over time
  2. Immediate Assertions – describes logic behavior of signals at an instant of time
Understanding SystemVerilog Scheduling semantics is crucial to understand simulation induced Race around conditions. I am summarizing some important aspects below:

Simulators simulate the Testbench based on IEEE Scheduling Semantics of SystemVerilog. A single and smallest timeslot can be visualized to have many regions as shown below 
Event Regions Diagram in SV(Picture taken from CummingsSNUG2006Boston_SystemVerilog_Events Paper)

Each of the regions(like preponed, active, observed, reactive) is associated with specific functionality.


Assertions are passive and they do not drive any stimulus into the design. If proper coding guidelines for RTL/Testbench are followed, we should not see any race around conditions.

Race around in Concurrent Assertions

All the signals in concurrent assertions are sampled in the preponed region before the clocking event. Values do not change in the preponed region(Read-only region) and hence sampled values of signals do not change during that particular time step of evaluation(in the observed region) multiple times. Hence if RTL/Testbench guidelines are followed, there is no special care to be taken while writing concurrent assertions as it is inherently protected.

Also, note that if ‘event.triggered’ is used in assertion then the current value(during that timestep) of the event is used for evaluation in the observed region. ‘triggered’ is a property of an event – evaluation do not happen until the statement is executed. If the event is getting updated in active region then triggered property will be a new value when evaluated in the observed region


Race around in Immediate Assertions

Simple immediate assertions are part of sequential statements (Ex part of ‘always’ construct) and their sampling & triggering depends on where they get executed.

If you observe the Event region, certain signals may get evaluated twice or more depending on when/if the value gets updated and hence might result in simulator seeing 2 or more values in one single time step although one values eventually settles. This could be one source of a possible misfire of immediate assertion. Signal value getting updated twice in a single step and during these scenarios $display prints 2 values of the same variable while $monitor/$strobe which executes in Postponed region prints only one value.


Looking at the possibility of assertions action block triggering twice or more than in immediate assertion, Systemverilog committee came up with a "final" deferred assertion to execute in the "postponed" region which is the last region before advancing time and all the values are settled to their final value. 

There 2 kinds of deferred assertions in SystemVerilog

1.  Observed deferred assertion –
·         Evaluation of immediate assertion is postponed to observed region.
·         Problem of glitch still exists if one decides to use program block which might      trigger loop back from reactive to active and multiple execution
·         Use #0 after assert keyword

Ex
assert_check: assert #0 (cs == 2'b00 && enable==1’b1) else $error ("cs and enable are in wrong combination");

2. Final deferred assertion
·         Evaluation of immediate assertion is postponed to postponed region
·         Works for all kinds of situation and most recommended
·         Use final keyword after assert keyword
Ex:
assert_check: assert final (cs == 2'b00 && enable==1’b1) else $error ("cs and enable are in wrong combination");


No comments:

Post a Comment