Section 17.4.2

LRM-137

Change (changes in red and blue):

The variables that can appear in expressions must be static design variables or function calls returning values of types described in Section 17.4.1. The functions should be automatic (or preserve no state information) and pure (no output arguments, no side effects). Static variables declared in programs, interfaces or clocking domains blocks can also be accessed. If a reference is to a static variable declared in a task, that variable is sampled as any other variable, independent of calls to the task.

Section 17.5

LRM-129 LRM-133

Change in Syntax 17-2 (changes in red and blue):

sequence_expr ::=                                                                                // from Annex A.2.10

  cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }

| sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }

| expression expression_or_dist { , variable_assignment } [ boolean_abbrev ]

| ( expression expression_or_dist {, variable_assignment } ) [ boolean_abbrev ]

| sequence_instance [ sequence_abbrev ]

| ( sequence_expr {, variable_assignment } ) [ sequence_abbrev ]

| sequence_expr and sequence_expr

| sequence_expr intersect sequence_expr

| sequence_expr or sequence_expr

| first_match ( sequence_expr )

| expression throughout sequence_expr

| sequence_expr within sequence_expr

LRM-133

Change in Syntax 17-2 (changes in red and blue):

actual_arg_expr ::=

  event_expression

| $

LRM-133

Change in Syntax 17-2 (changes in red and blue):

cycle_delay_const_range_expression ::=

  constant_expression : constant_expression

| constant_expression : $

 

expression_or_dist::=

  expression

| expression dist { dist_list }

Section 17.6

LRM-137

Change (changes in red and blue):

      a clocking domain block as a clocking_item

LRM-131

Change in Syntax 17-4 (changes in red and blue):

multi_clock_sequence::=

clocked_sequence { ## clocked_sequence }

  sequence_expr

| clocking_event multi_clock_sequence

| ( multi_clock_sequence )

| multi_clock_sequence ## multi_clock_sequence

 

clocked_sequence ::=

clocking_event sequence_expr

LRM-135

Change in Syntax 17-4 (changes in red and blue):

actual_arg_expr ::=

  event_expression

| $

LRM-135

Change (changes in red and blue):

An actual argument can replace an:

 

      identifier

 

      expression

 

      event control expression

 

      upper range as $

Section 17.7.1

LRM-131

Change in Table 17-1 (changes in red and blue):

SystemVerilog expression operators

Associativity

, (for assignment)

left

[*] [*=] [*->]

left ----

##

left

and throughout

left right

or within

left

throughout intersect

left

within and

left

## or

left

Section 17.7.2

LRM-129 LRM-133

Change in Syntax 17-5 (changes in red and blue):

sequence_expr ::=                                                                                                // from Annex A.2.10

| expression expression_or_dist { , variable_assignment } [ boolean_abbrev ]

| ( expression expression_or_dist {, variable_assignment } ) [ boolean_abbrev ]

| sequence_instance [ sequence_abbrev ]

| ( sequence_expr {, variable_assignment } ) [ sequence_abbrev ]

Section 17.7.3

LRM-134

Change (changes in red and blue):

17.7.3 Value change Sampled value functions

 

This section describes the system functions available for accessing sampled values of an expression. These functions include the capability to access current sampled value, access sampled value in the past, or detect changes in sampled value of an expression. Sampling of an expression is explained in Section 17.3. Following functions are provided.

 

Three functions are provided to detect changes in values between two adjacent clock ticks: $rose, $fell and $stable.

 

$sampled(expression [ , clocking_event])

 

$rose ( expression [ , clocking_event])

 

$fell ( expression [ , clocking_event])

 

$stable ( expression [ , clocking_event])

 

$past (expression1 [,number_of_ticks][,expression2][,clocking_event] )

 

A value change expression at a clock tick detects the change in value of an expression from the value of that expression at the previous clock tick. The result of a value change expression is true or false and can be used as a boolean expression. At the first clock tick after the assertion is started, the result of these functions are computed by comparing the current value to ‘x’.

 

The use of these functions is not limited to assertion features; they can be used as expressions in procedural code as well. The clocking event, although optional as an explicit argument to the functions, is required for their semantics. The clocking event is used to sample the value of the argument expression.

 

The clocking event must be explicitly specified as an argument, or inferred from the code where it is used. The following rules are used to infer the clocking event:

 

if used in an assertion, the appropriate clocking event from the assertion is used.

 

if used in an action block of a singly clocked assertion, the clock of the assertion is used.

 

if used in a procedural block, the inferred clock, if any, for the procedural code (Section 17.12.2) is used.

 

Otherwise, default clocking (Section 15.11) is used.

 

When these functions are used in an assertion, the clocking event argument of the functions, if specified, shall be identical to the clocking event of the expression in the assertion. In the case of multi-clock assertion, the appropriate clocking event for the expression where the function is used, is applied to the function.

 

Function $sampled returns the sampled value of the expression with respect to the last occurrence of the clocking event. When $sampled is invoked prior to the occurrence of the first clocking event, the value of X is returned. The use of $sampled in assertions, although allowed, is redundant, as the result of the function is identical to the sampled value of the expression itself used in the assertion.

 

Three functions are provided to detect changes in sampled values: $rose, $fell and $stable.

 

A value change function detects the change in the sampled value of an expression. The clocking event is used to obtain the sampled value of the argument expression at a clock tick prior to the current simulation time unit. Here, the current simulation time unit refers to the simulation time unit in which the function is evaluated. This sampled value is compared against the value of the expression determined at the prepone time of the current simulation time unit. The result of a value change expression is true or false and can be used as a boolean expression.

 

$rose returns true if the least significant bit of the expression changed to 1. Otherwise, it returns false.

 

$fell returns true if the least significant bit of the expression changed to 0. Otherwise, it returns false.

 

$stable returns true if the value of the expression did not change. Otherwise, it returns false.

 

When these functions are used at the first clock tick, determined by the clocking event, or before the first clock tick, the result of these functions are computed by comparing the current sampled value of the expression to X.

 

Figure 17-3 illustrates two examples of value changes:

 

— Value change expression e1 is defined as $rose(req)

 

— Value change expression e2 is defined as $fell(ack)

 

INSERT FIGURE 17-3

 

The clock ticks used for sampling the variables are derived from the clock for the property, which is different from the simulation ticks. Assume, for now, that this clock is defined elsewhere. At clock tick 3, e1 occurs because the value of req at clock tick 2 was low and at clock tick 3, the value is high. Similarly, e2 occurs at clock tick 6 because the value of ack was sampled as high at clock tick 5 and sampled as low at clock tick 6.

 

The example below illustrates the use of $rose in SystemVerilog code outside assertions.

 

always @(posedge clk)

reg1 <= a & $rose(b);

 

In this example, the clocking event (posedge clk) is applied to $rose. $rose is true whenever the sampled value of b changed to 1 from its sampled value at the the previous tick of the clocking event.

 

In addition to accessing value changes, the past values can be accessed with the $past function. The following three optional arguments are provided:

 

expression2 is used as a gating expression for the clocking event

 

number_of_ticks specifies the number of clock ticks in the past

 

clocking_event specifies the clocking event for sampling expression1

 

expression1 and expression2 can be any expression allowed in assertions.

 

number_of_ticks must be one or greater. If number_of_ticks is not specified, then it defaults to 1. $past returns the sampled value of the expression that was present number_of_ticks prior to the time of evaluation of $past. A clock tick is based on clocking_event. If the specified clock tick in the past is before the start of simulation, the returned value from the $past function is a value of X.

 

The optional argument clocking_event specifies the clock for the function. The rules governing the usage of clocking_event are same as those described for the value change function.

 

When intermediate optional arguments between two arguments are not needed, a comma must be placed for each ommited argument. For example,

 

$past(in1, , enable);

 

Here, a comma is specified to omit number_of_ticks. The default of one is used for the empty number_of_ticks argument. Note that a comma for the ommited clocking_event argument is not needed, as it does not fall within the specified arguments.

 

$past can be used in any System Verilog expression. An example is shown below.

 

always @(posedge clk)

reg1 <= a & $past(b);

 

In this example, the clocking event (posedge clk) is applied to $past. $past is evaluated in the current occurrence of (posedge clk), and returns the value of b sampled at the previous occurrence of (posedge clk).

 

When expression2 is specified, the sampling of expression is performed based on its clock gated with expression2. For example,

 

always @(posedge clk)

if (enable) q <= d;

 

always @(posedge clk)

assert (done |=> (out == $past(q, 2,enable)) ;

 

In this example, the sampling of q for evaluating $past is based on the clocking expression

 

posedge clk iff enable

Section 17.7.10

LRM-128

Change (changes in red and blue):

ended can be used directly on sequences that do not have formal arguments. To use ended on a sequence with arguments, first define a sequence without formal arguments that instantiates the sequence with actual arguments. For example, For example with the definitions

 

sequence e2(a,b,c);

@(posedge sysclk) $rose(a) ##1 b ##1 c;

endsequence

sequence e2_instantiated;

e2(ready,proc1,proc2);

endsequence

sequence rule2;

@(posedge sysclk) reset ##1 inst ##1 e2_instantiated.ended e2(ready,proc1,proc2).ended ##1 branch_back;

endsequence

 

rule2 is equivalent to rule2a below:

 

sequence e2_instantiated;

   e2(ready,proc1,proc2);

endsequence

sequence rule2a;

   @(posedge sysclk) reset ##1 inst ##1 e2_instantiated.ended ##1 branch_back;

endsequence

 

There are additional restrictions on passing local variables into an instance of a sequence to which ended is applied. See Section 17.8.

Section 17.7.11

LRM-131

Change (changes in red and blue):

 

The implication construct allows a user to monitor sequences properties based on satisfying some criteria. Most common uses are to attach a precondition to a sequence, where the evaluation of the sequence is based on the success of a condition.

LRM-131

Change in Syntax 17-12 (changes in red and blue):

property_expr ::=

| sequence_expr |-> [ not ] sequence_expr property_expr

| sequence_expr |=> [ not ] sequence_expr property_expr

 

multi_clock_property_expr ::=

| multi_clock_sequence |-> multi_clock_property_expr

| multi_clock_sequence |=> [ not ] multi_clock_sequence multi_clock_property_expr

LRM-131

Change (changes in red and blue):

This clause is used to precondition monitoring of a sequence property expression and is allowed at the property level. The result of the implication is either true or false. The left-hand side operand sequence_expr is called the antecedent, while the right-hand side operand sequence_expr property_expr is called the consequent.

 

The following points should be noted for |-> implication:

 

      antecedent sequence_expr can result in multiple successful sequences.

 

      From a given start point, the antecedent sequence_expr can have zero, one, or more than one successful match.

 

      If there is no match of the antecedent sequence_expr from a given start point, then evaluation of the implication from that start point succeeds vacuously by returning and returns true.

 

      For each successful match of antecedent sequence_expr, the consequent sequence_exp property_expr is separately evaluated, beginning at the end point of the match. That is, the end point of matching sequence from antecedent sequence_expr overlaps with start point of the consequent sequence_expr. The end point of the match of the antecedent sequence_expr is the start point of the evaluation of the consequent property_expr.

 

      From a given start point, evaluation of the implication succeeds and returns true iff for every match of the antecedent sequence_expr beginning at the start point, the evaluation of the consequent property_expr beginning at the endpoint of the match succeeds and returns true.

 

      All matches of antecedent sequence_expr must satisfy consequent sequence_expr. The satisfaction of the consequent sequence_expr means that there is at least one match of the sequence_expr.

 

      Nesting of implication is not allowed.

 

Two forms of implication are provided: overlapped using operator |->, and non-overlapped using operator |=>. For overlapped implication, if there is a match for the antecedent sequence_expr, then the first element of the consequent sequence_expr is evaluated on the same clock tick end point of the match is the start point of the evaluation of the consequent property_expr. For non-overlapped implication, the first element of the consequent sequence_expr is evaluated on the next clock tick start point of the evaluation of the consequent property_expr is the clock tick after the end point of the match. Therefore:

 

sequence_expr |=> [not] sequence_expr property_expr

 

is equivalent to:

 

sequence_expr ##1 ‘true |-> [not] sequence_expr property_expr

 

If not is used on the consequent, the result of consequent sequence_expr is reversed.

 

The use of implication when multi-clock sequences and properties are involved is explained in Section 17.11.

LRM-131

Change (changes in red and blue):

Generally, assertions are associated with preconditions so that the checking is performed only under certain specified conditions. As seen from the previous example, the |-> operator provides this capability to specify preconditions with sequences that must be satisfied before continuing to match those sequences evaluating their consequent properties. The next example modifies the preceding example to see the effect on the results of the assertion by removing the precondition for the sequence consequent. This is shown below, and illustrated in Figure 17-15.

LRM-131

Change (changes in red and blue):

property p16;

(write_en & data_valid) ##0

(write_en && (retire_address[0:4]==addr)) [*2] |->

##[3:8] write_en && !data_valid &&(write_address[0:4]==addr);

endproperty

 

This property can be coded alternatively as a nested implication:

 

property p16_nested;

   (write_en & data_valid) |->

      (write_en && (retire_address[0:4]==addr)) [*2] |->

         ##[3:8] write_en && !data_valid && (write_address[0:4]==addr);

endproperty

Section 17.8

LRM-129

Change in Syntax 17-13 (changes in red and blue):

sequence_expr ::=                                                                                                // from Annex A.2.10

| expression { , variable_assignment } [ boolean_abbrev ]

| ( expression expression_or_dist {, variable_assignment } ) [ boolean_abbrev ]

| ( sequence_expr {, variable_assignment } ) [ sequence_abbrev ]

LRM-129

Change (changes in red and blue):

The type of variable is explicitly specified. The variable can be assigned anywhere in the sequence and reassigned later in the sequence.. at the end point of any syntactic subsequence by placing the subsequence, comma separated from the sampling assignment, in parentheses.  For example, if in

 

a ##1 b[*->1] ##1 c[*2]

 

it is desired to sample x = e at the match of  b, the sequence expression can be rewritten as

 

a ##1 (b[*->1], x = e) ##1 c[*2]

 

The local variable can be reassigned later in the sequence, as in

 

a ##1 (b[*->1], x = e) ##1 (c[*2], x = x + 1)

 

For every attempt, a new copy of the variable is created for the sequence. The variable value can be tested like any other SystemVerilog variable.

LRM-128

Change (changes in red and blue):

To access a local variable of a sub-sequence, a local variable must be declared and passed to the instantiated sub-sequence through an argument. An example below illustrates this usage.

 

sequence sub_seq2(lv);

a ##1 !a, lv = data_in ##1 !b*[0:$] ##1 b && (data_out == lv);

endsequence

sequence seq2;

int v1;

c ##1 sub_seq2(v1) ##1 (do1 == v1); // v1 is now bound to lv

endsequence

 

Local variables can be passed into an instance of a defined sequence to which ended is applied and accessed in a similar manner.  For example

 

sequence seq2a;

   int v1; c ##1 sub_seq2(v1).ended ##1 (do1 == v1); // v1 is now bound to lv

endsequence

 

There are additional restrictions when passing local variables into an instance of a defined sequence to which ended is applied: 

 

1.        Local variables can be passed in only as entire actual  arguments, not as proper subexpressions of actual arguments.

2.        In the declaration of the defined sequence, the formal argument to which the local variable is bound must not be referenced before it is sampled.

 

The second restriction is met by sub_seq2 because the sampling lv = data_in occurs before the reference to lv in data_out == lv.

 

If a local variable is sampled before being passed into an instance of a defined sequence to which ended is applied, then the restrictions prevent this sampled value from being visible within the defined sequence.  The restrictions are important because the use of ended means that there is no guaranteed relationship between the point in time at which the local variable is sampled outside the defined sequence and the beginning of the match of the instance.

 

A local variable that is passed in as actual argument to an instance of a defined sequence to which ended is applied will flow out of the application of ended to that instance provided both of the following conditions are met:

 

1.        The local variable flows out of the end of the defined sequence instance, as defined by the local variable flow rules for sequences.  (See below and Annex G.)

2.        The application of ended to this instance is a maximal boolean expression.  In other words, the application of ended cannot have negation or any other expression operator applied to it.

 

Both conditions are satisfied by sub_seq2 and seq2a. Thus, in seq2a the value in v1 in the comparison do1 == v1 is the value sampled into lv in sub_seq2 by the assignment lv = data_in. However, in

 

sequence seq2b;

   int v1; c ##1 !sub_seq2(v1).ended ##1 (do1 == v1); // v1 undefined

endsequence

  

the second condition is violated because of the negation applied to sub_seq2(v1).ended. Therefore, v1 does not flow out of the application of ended to this instance, and so the reference to v1 in do1 == v1 is to an unsampled variable.

           

In a single cycle, there can be multiple matches of a sequence instance to which ended is applied, and these matches can have different valuations of the local variables.  The multiple matches are treated semantically the same way as matching both disjuncts of an or (see below).  In other words, the thread evaluating the instance to which ended is applied will fork to account for such distinct local variable valuations.

Section 17.9

LRM-134

Change (changes in red and blue):

In addition to accessing values of signals at the time of evaluation of a boolean expression, the past values can be accessed with the $past function.

 

$past ( expression [ , number_of_ticks] )

 

The optional argument number_of_ticks specifies the number of clock ticks in the past. If number_of_ticks is not specified, then it defaults to 1. $past returns the sampled value of the expression that was present number_of_ticks prior to the time of evaluation of $past.

Section 17.10

LRM-137

Change (changes in red and blue):

a clocking domain block as a clocking_item

LRM-131

Change in Syntax 17-14 (changes in red and blue):

property_spec ::=

  [clocking_event ] [ disable iff ] ( expression ) ] [ not ] property_expr

| [ disable iff ( expression ) ] [ not ] multi_clock_property_expr

 

property_expr ::=

  sequence_expr

| ( property_expr )

| not property_expr

| property_expr or property_expr

| property_expr and property_expr

| sequence_expr |-> [ not ] sequence_expr property_expr

| sequence_expr |=> [ not ] sequence_expr property_expr

| if  ( expression ) property_expr [ else property_expr ]

| property_instance

| ( property_expr )

 

multi_clock_property_expr ::=

  property_expr

| multi_clock_sequence

| clocking_event multi_clock_property_expr

| ( multi_clock_property_expr )

| not multi_clock_property_expr

| multi_clock_property_expr or multi_clock_property_expr

| multi_clock_property_expr and multi_clock_property_expr

| multi_clock_sequence |-> multi_clock_property_expr

| multi_clock_sequence |=> [ not ] multi_clock_sequence multi_clock_property_expr

| if  ( expression ) multi_clock_property_expr  [ else multi_clock_property_expr ]

| property_instance

| ( multi_clock_property_expr )

LRM-131

Change (changes in red and blue):

The result of property evaluation is either true or false. There are two kinds of property: sequence, and implication. If the property is just a sequence, the result of a sequence for every evaluation attempt is true or false. This is accomplished by implicitly transforming sequence_expr to first_match(sequence_expr). That is, as soon as a match of sequence_expr is determined, the result is considered to be true, and no other matches are required for that evaluation attempt. However, if the property is an implication, then the semantics of implication determine whether the property is true or false.

 

The disable iff clause allows asynchronous resets to be specified. For a particular attempt, if the expression of the disable iff becomes true at any time during the evaluation of the attempt, then the attempt for the property is considered to be a success. Other attempts are not affected by the evaluation of the expression for an attempt.

 

The not clause states that the property_expr associated with the property must never evaluate to true. Effectively, it negates property_expr. For each attempt, property_expr results in either true or false, based on whether there is a match for the sequence. The not clause reverses the result of property_expr. It should be noted that there is no complementation or any form of negation for the sequence in property_expr.

 

The result of property evaluation is either true or false. There are seven kinds of properties: sequence, negation, disjunction, conjunction, if-else, implication, and instantiation.

 

1.        A property that is a sequence evaluates to true if and only if  there is a match of the sequence.  Since there is a match if and only if there is a first match, evaluation of such a property is the same as implicitly transforming its sequence_expr to first_match(sequence_expr). As soon as a match of sequence_expr is determined, the evaluation of the property is considered to be true, and no other matches are required for that evaluation attempt.

 

2.        A property is a negation if it has the form

 

not property_expr

 

For each evaluation attempt of the property, there is an evaluation attempt of property_expr.  The keyword not states that the evaluation of the property returns the opposite of the evaluation of the underlying property_expr.  Thus, if  property_expr evaluates to true, then not property_expr evaluates to false, and if property_expr evaluates to false, then not property_expr evaluates to true.

 

3.        A property is a disjunction if it has the form

 

property_expr1 or property_expr2

 

The property evaluates to true if and only if at least one of  property_expr1 and property_expr2 evaluates to true.

 

4.        A property is a conjunction if it has the form

 

property_expr1 and property_expr2

 

The property evaluates to true if and only if both property_expr1 and property_expr2 evaluate to true.

 

5.        A property is an if-else if it has either the form

 

if (expression) property_expr1

 

or the form

 

if (expression) property_expr1  else  property_expr2

 

A property of the first form evaluates to true if and only if either expression evaluates to false or property_expr1 evaluates to true.  A property of the second form evaluates to true if and only if either expression evaluates to true and property_expr1 evaluates to true or expression evaluates to false and property_expr2 evaluates to true.

 

6.        A property is an implication if it has either the form

 

sequence_expr |-> property_expr

 

or the form

 

sequence_expr |=> property_expr

 

The meaning of implications has already been discussed in 17.7.11.

 

7.        An instance of a defined property can be used as a property_expr or property_spec.  In general, the instance is legal provided the body property_spec of the defined property can be substituted in place of the instance, with actual arguments substitited for formal arguments, and result in a legal property_expr or property_spec, ignoring local variable declarations.  Thus, for example, if an instance of a defined property is used as a property_expr operand for any property-building operator, then the defined property must not have a disable iff clause.  Similarly, clock events in a defined property must conform to the rules of multiple clock support when the property is instantiated in a property_expr or property_spec that also involves other clock events.

 

 

The following table lists the property operators from highest to lowest precedence and shows the associativity of the non-unary operators.

 

Table 17-2 Property operator precedence and associativity

SystemVerilog property operators

Associativity

not

----

and

left

or

left

if…else

right

|-> |=>

right

 

A disable iff clause can be attached to a property_expr to yield a property_spec

 

disable iff (expression) property_expr

 

The expression of the disable iff is called the reset expression.  The disable iff clause allows asynchronous resets to be specified.  For an evaluation of the property_spec, there is an evaluation of the underlying property_expr.  If during that evaluation the reset expression becomes true, then the overall evaluation of the property_spec is true.  Otherwise, the evalution of the property_spec is the same as that of the property_expr.  The reset expression is tested independently for different evaluation attempts of the property_spec.  Nesting of disable iff clauses, explicitly or through property instantiations, is not allowed.

LRM-131

Change (changes in red and blue):

Property rule2 negates the result of the implication (a |-> b ##1 c ##1 d) for every attempt. clkev specifies the clock for the property.

 

property rule3;

   @(posedge clk) a[*2] |-> ((##[1:3] c) or (d |=> e));

endproperty

 

Property rule3 says that if a holds and a also held last cycle, then either c must hold at some point 1 to three cycles after the current cycle, or, if d holds in the current cycle, then e must hold one cycle later.

 

property rule4;

   @(posedge clk) a[*2] |-> ((##[1:3] c) and (d |=> e));

endproperty

 

Property rule4 says that if a holds and a also held last cycle, then c must hold at some point 1 to three cycles after the current cycle, and if d holds in the current cycle, then e must hold one cycle later.

 

property rule5;

   @(posedge clk)

   a ##1 (b || c)[*->1] |->

      if (b)

         (##1 d |-> e)

      else // c

         f ;

endproperty

 

Property rule5 has a followed by the first match of either b or c as its antecedent.  The consequent uses if-else to split cases on which of b or c is matched first.

 

property rule6(x,y);

   ##1 x |-> y;

endproperty

property rule5a;

   @(posedge clk)

   a ##1 (b || c)[*->1] |->

      if (b)

         rule6(d,e)

      else // c

         f ;

endproperty

 

Property rule5a is equivalent to rule5, but it uses an instance of rule6 as a property expression.

Section 17.10.1 (New)

LRM-130

Add (changes in red and blue):

17.10.1  Recursive properties

SystemVerilog allows recursive property definitions.  A defined property is recursive if its declaration involves an instantiation of itself.  Recursion provides a flexible framework for coding properties to serve as ongoing assumptions, checkers, or coverage monitors.

 

For example,

 

property prop_always(p);

   p and (1’b1 |=> prop_always(p));

endproperty

 

is a recursive property that says that the formal argument property p must hold at every cycle.  This example is useful if the ongoing requirement that property p hold applies after a complicated triggering condition encoded in sequence s:

 

property p1(s,p);

   s |=> prop_always(p);

endproperty

 

As another example, the recursive property

 

property prop_weak_until(p,q);

   q or (p and (1’b1 |=> prop_weak_until(p,q)));

endproperty

 

says that formal argument property p must hold at every cycle up to but not including the first cycle at which formal argument property q holds.  Formal argument property q is not required ever to hold, though.  This example is useful if p must hold at every cycle after a complicated triggering condition encoded in sequence s, but the requirement on p is lifted by q:

 

property p2(s,p,q);

   s |=> prop_weak_until(p,q);

endproperty

 

More generally, several property definitions can be mutually recursive.  For example

 

property check_phase1;

   s1 |-> (phase1_prop and (1’b1 |=> check_phase2));

endproperty

property check_phase2;

   s2 |-> (phase2_prop and (1’b1 |=> check_phase1));

endproperty

 

There are three restrictions on recursive property definitions.

 

RESTRICTION 1:  The negation operator not cannot be applied to any property expression that instantiates a recursive property.  In particular, the negation of a recursive property cannot be asserted or used in defining another property.

 

Here are examples of illegal property definitions that violate Restriction 1:

 

property illegal_recursion_1(p);

   not prop_always(not p);

endproperty

 

property illegal_recursion_2(p);

   p and (1’b1 |=> not illegal_recursion_2(p));

endproperty

 

RESTRICTION 2:  The operator disable iff cannot be used in the definition of a recursive property.  This restriction is consistent with the restriction that disable iff cannot be nested.

 

Here is an example of an illegal property definition that violates Restriction 2:

 

property illegal_recursion_3(p);

   disable iff (b)

   p and (1’b1 |=> illegal_recursion_3(p));

endproperty

 

The intent of illegal_recursion_3 can be written legally as

 

property legal_3(p);

   disable iff (b) prop_always(p);

endproperty

 

since legal_3 is not a recursive property.

 

RESTRICTION 3:  If p is a recursive property, then, in the definition of p, every instance of p must occur after a positive advance in time.  In the case of mutually recursive properties, all recursive instances must occur after positive advances in time.

 

Here is an example of an illegal property definition that violates Restriction 3:

 

property illegal_recursion_4(p);

   p and (1’b1 |-> illegal_recursion_4(p));

endproperty

 

If this form were legal, the recursion would be stuck in time, checking p over and over again at the same cycle.

 

Recursive properties can deal with complicated requirements, such as those associated with varying numbers of data beats, out-of-order completions, retries, etc.  Here is an example of using a recursive property to check complicated conditions of this kind.

 

EXAMPLE:  Suppose that write data must be checked according to the following conditions:

 

·         Acknowledgment of a write request is indicated by the signal write_request together with write_request_ack.  When a write request is acknowledged, it gets a 4-bit tag, indicated by signal write_reqest_ack_tag.  The tag is used to distinguish data beats for multiple write transactions in flight at the same time. 

 

·         It is understood that distinct write transactions in flight at the same time must be given distinct tags.  For simplicity, this condition is not a part of what is checked in this example.

 

·         Each write transaction can have between 1 and 16 data beats, and each data beat is 8 bits.  There is a model of the expected write data that is available at acknowledgment of a write request.  The model is a 128 bit vector.  The most significant group of 8 bits represents the expected data for the first beat, the next group of 8 bits represents the expected data for the second beat (if there is a second beat), and so forth.

 

·         Data transfer for a write transaction occurs after acknowledgment of the write request and, barring retry, ends with the last data beat.  The data beats for a single write transaction occur in order.

 

·         A data beat is indicated by the data_valid signal together with the signal data_valid_tag to determine the relevant write transaction.  The signal data is valid with data_valid and carries the data for that beat.  The data for each beat must be correct according to the model of the expected write data. 

 

·         The last data valid is indicated by signal last_data_valid together with data_valid and data_valid_tag.  For simplicity, this example does not represent the number of data beats and does not check that last_data_valid is signaled at the correct beat.

 

·         At any time after acknowledgement of the write request, but not later than the cycle after the last data valid, a write transaction can be forced to retry.  Retry is indicated by the signal retry together with signal retry_tag to identify the relevant write transaction.  If a write transaction is forced to retry, then its current data transfer is aborted and the entire data transfer must be repeated.  The transaction does not re-request and its tag does not change.

 

·         There is no limit on the number of times a write transaction can be forced to retry.

 

·         A write transaction completes the cycle after the last data valid provided it is not forced to retry in that cycle.

 

Here is code to check these conditions:

  

property check_write;

  

   [0:127] expected_data;  // local variable to sample model data

   [3:0] tag;              // local variable to sample tag

  

   disable iff (reset)

   (

      write_request && write_request_ack,

      expected_data = model_data,

      tag = write_request_ack_tag

   )

   |=>

   check_write_data_beat(expected_data, tag, 4'h0);

 

endproperty

  

property check_write_data_beat

(

   expected_data, // [0:127]

   tag,           // [3:0]

   i              // [3:0]

);

 

   first_match 

   (

      ##[0:$]

      (

         (data_valid && (data_valid_tag == tag))

         ||

         (retry && (retry_tag == tag))

      )

   )

   |->

   (

      (

         (data_valid && (data_valid_tag == tag)

         |->

         (data == expected_data[i*8+:8])

      )

      and

      (

         if (retry && (retry_tag == tag))

         (

            1’b1 |=> check_write_data_beat(tag, expected_data, 4’h0)

         )

         else if (!last_data_valid)

         (

            1’b1 |=> check_write_data_beat(tag, expected_data, i+4’h1)

         )

         else

         (

            ##1 (retry && (retry_tag == tag))

            |=>

            check_write_data_beat(tag, expected_data, 4'h0)

         )

      )

   );

  

endproperty

Section 17.11

LRM-131

Change in Syntax 17-15 (changes in red and blue):

multi_clock_sequence::=

clocked_sequence { ## clocked_sequence }

  sequence_expr

| clocking_event multi_clock_sequence

| ( multi_clock_sequence )

| multi_clock_sequence ## multi_clock_sequence

 

clocked_sequence ::=

clocking_event sequence_expr

 

multi_clock_property_expr ::=

  property_expr

| multi_clock_sequence

| clocking_event multi_clock_property_expr

| ( multi_clock_property_expr )

| not multi_clock_property_expr

| multi_clock_property_expr or multi_clock_property_expr

| multi_clock_property_expr and multi_clock_property_expr

| multi_clock_sequence |-> multi_clock_property_expr

| multi_clock_sequence |=> [ not ] multi_clock_sequence multi_clock_property_expr

| if  ( expression ) multi_clock_property_expr  [ else multi_clock_property_expr ]

| property_instance

| ( multi_clock_property_expr )

LRM-131

Change (Note this change adds Section 17.11.1 through 17.11.4 The examples at the end of 17.11 are moved to be part of 17.11.4 with changes given there) (changes in red and blue):

Two cases are allowed:

 

1) Concatenation of two sequences, where each sequence can have a different clock

 

2) The antecedent of an implication on one clock, while the consequent is on another clock

 

The multi-clock concatenation operator ## synchronizes between the two clocks.

 

@(posedge clk0) sig0 ## @(posedge clk1) sig1

 

When signal sig0 matches at clock clk, ## moves the time to the nearest clock tick of clk1 after the match. At the first clock tick of clk1, it matches sig1. If the two clocks, clk0 and clk1, are identical, then the above sequence is equivalent to:

 

@(posedge clk0) sig0 ##1 sig1

 

For two sequences, such as

 

@(posedge clk0) s0 ## @(posedge clk1) s1

 

For every match of s0 at clock clk0, ## moves the time to the first clock tick of clk1. From that first tick of clk1, s1 is matched.

 

Multi-clock implication is only allowed with the non-overlapping implication. The semantics are similar to the sequence concatenation with ##. Whenever there is a match of the antecedent sequence, time is advancedto the nearest clock tick of the clock of the consequent sequence. The consequent is then evaluated for satisfaction.

17.11.1 Multiply-clocked sequences

Multiply-clocked sequences are built by concatenating singly-clocked subsequences using the multi-clock concatenation operator ##.  This operator is non-overlapping and synchronizes between the ending clock tick of the left hand sequence and the strictly subsequent starting clock tick of the right hand sequence.

 

For example, consider

 

@(posedge clk0) sig0 ## @(posedge clk1) sig1

 

A match of this sequence starts with a match of sig0 at posedge clk0.  Then ## moves the time to the nearest strictly subsequent posedge clk1, and the match of the sequence ends at that point with a match of sig1.  If clk0 and clk1 are not identical, then the clocking event for the sequence changes after ##.  If clk0 and clk1 are identical, then the clocking event does not change after ## and the above sequence is equivalent to

 

@(posedge clk0) sig0 ##1 sig1

 

When using the multi-clock concatenation operator ##, both operands are required to admit only non-empty matches.  Thus, if s1, s2 are sequence expressions with no clocking events, then the multiply-clocked sequence

 

@(posedge clk1) s1 ## @(posedge clk2) s2

 

is legal only if neither s1 nor s2 can match the empty word.  The clocking event posedge clk1 applies throughout the match of s1, while the clocking event posedge clk2 applies throughout the match of s2.  Since the match of s1 is non-empty, there is an end point of this match at posedge clk1.  The ## synchronizes between this end point and the first occurrence of posedge clk2 strictly after it.  That occurrence of  posedge clk2 is the start point of the match of s2.

 

The restriction to operands that do not match the empty word when using ## ensures that any multiply-clocked sequence has well-defined starting and ending clocking events and well-defined clock changes.  If clk1 and clk2 are not identical, then the following sequence

 

@(posedge clk0) sig0 ## @(posedge clk1) sig1[*0:1]

 

is illegal because of the possibility of an empty match of sig1[*0:1], which would make ambiguous whether the ending clocking event is posedge clk0 or posedge clk1.

 

Differently-clocked or multiply-clocked sequence operands cannot be combined with any sequence operators other than the multi-clock concatenation operator ##.  For example, the following is illegal:

 

(@(posedge clk1) x ##1 y) intersect (@(posedge clk2) z[*1:$])

17.11.2 Multiply-clocked properties

As in the case of singly-clocked properties, the result of evaluating a multiply-clocked property is either true or false.  Multiply-clocked properties can be formed in a number of ways.

 

Multiply-clocked sequences are themselves multiply-clocked properties.  For example,

 

@(posedge clk0) sig0 ## @(posedge clk1) sig1

 

is a multiply-clocked property.  If a multiply-clocked sequence is evaluated as a property starting at some point, the evaluation returns true if and only if there is a match of the multiply-clocked sequence beginning at that point.

 

The boolean property operators (not, and, or) can be used freely to combine singly- and multiply-clocked properties.  The meanings of the boolean property operators are the usual ones, just as in the case of singly-clocked properties.  For example,

 

(@(posedge clk0) sig0) and (@(posedge clk1) sig1)

 

is a multiply-clocked property, but it is not a multiply-clocked sequence.  This property evaluates to true at a point if and only if the two sequences

 

@(posedge clk0) sig0

 

and

  

@(posedge clk1) sig1

 

both have matches beginning at the point.

 

The non-overlapping implication operator |=> can be used freely to create a multiply-clocked property from an antecedent sequence and a consequent property that are differently- or multiply-clocked.  The meaning of multiply-clocked non-overlapping implication is similar to that of singly-clocked non-overlapping implication.  For example, if s0, s1 are sequence expressions with no clocking event, then in

 

@(posedge clk0) s0 |=> @(posedge clk1) s1

 

|=> synchronizes between posedge clk0 and posedge clk1.  Starting at the point at which the implication is being evaluated, for each match of s0 clocked by clk0, time is advanced from the end point of the match to the nearest strictly future occurrence of posedge clk1, and from that point there must exist a match of s1 clocked by clk1.

 

The non-overlapping implication operator |=> can synchronize between the ending clock event of its antecedent and several leading clock events for subproperties of its consequent.  For example, in

 

@(posedge clk0) s0 |=> (@(posedge clk1) s1) and (@(posedge clk2) s2)

 

|=> synchronizes between posedge clk0 and both posedge clk1 and posedge clk2.

 

Since synchronization between distinct clocks always requires strict advance of time, the two property building operators that require special care with multiple clocks are the overlapping implication |-> and if/if-else.

 

Since |-> overlaps the end of its antecedent with the beginning of its consequent, the clock for the end of the antecedent must be the same as the clock for the beginning of the consequent.  For example, if clk0 and clk1 are not identical and s0, s1, s2 are sequence expressions with no clocking events, then

 

@(posedge clk0) s0 |-> @(posedge clk1) s1 ## @(posedge clk2) s2

 

is illegal, but

 

@(posedge clk0) s0 |-> @(posedge clk0) s1 ## @(posedge clk2) s2

 

is legal.

 

The if/if-else operators overlap the test of the boolean condition with the beginning of the then clause property and, if present, the else clause property.  Therefore, whenever using if or if-else, the then and else clause properties must begin on the same clock as the test of the boolean condition.  For example, if clk0 and clk1 are not identical and s0, s1, s2 are sequence expressions with no clocking events, then

 

@(posedge clk0) if (b) @(posedge clk0) s1

 

is legal, but

 

@(posedge clk0) if (b) @(posedge clk0) s1 else @(posedge clk1) s2

 

is illegal because the else clause property begins on a different clock than the if condition.

17.11.3 Clock flow

Throughout this subsection, c, d denote clocking event expressions and v, w, x, y, z denote sequence expressions with no clocking events.

 

Clock flow allows the scope of a clocking event to extend in a natural way through various parts of multiply-clocked sequences and properties and reduces the number of places at which the same clocking event must be specified.

 

Intuitively, clock flow provides that in a multiply-clocked sequence or property the scope of a clocking event flows left-to-right across linear operators (e.g., repetition, concatenation, negation, implication) and distributes to the operands of branching operators (e.g., conjunction, disjunction, intersection, if-else) until it is replaced by a new clocking event.   

 

For example,

 

@(c) x |=> @(c) y ## @(d) z

 

can be written more simply as

 

@(c) x |=> y ## @(d) z

 

because clock c is understood to flow across |=>. 

 

Clock flow eliminates the need to write clocking events in positions where the clock is not allowed to change.  For example,

 

@(c) x |-> @(c) y ## @(d) z

 

can be written as

 

@(c) x |-> y ## @(d) z

 

to reinforce the restriction that the clock not change across |->.  Similarly,

 

@(c) if (b) @(c) w ## @(d) x else @(c) y ## @(d) z

 

can be written as

 

@(c) if (b) w ## @(d) x else y ## @(d) z

 

to reinforce the restriction that the clock not change from the boolean condition b to the beginnings of the then and else clause properties.

 

Clock flow also makes the adjointness relationships between concatenation and implication clean for multiply-clocked properties:

 

@(c) s1 ##1 s2 |=> @(d) s

 

is equivalent to

 

@(c) s1 |=> s2 |=> @(d) s

 

and

 

@(c) s1 ##0 s2 |=> @(d) s

 

is equivalent to

 

@(c) s1 |-> s2 |=> @(d) s

 

The scope of a clocking event flows into parenthesized subexpressions and, if the subexpression is a sequence, also flows left-to-right across the parenthesized subexpression.  However, the scope of a clocking event does not flow out of enclosing parentheses.

 

For example, in

 

@(c) w ## (x ## @(d) y) |=> z

 

w, x, z are clocked at c and y is clocked at d.  Clock c flows across ##, across the parenthesized sub-sequence (y ## @(d) z), and across |=>.  Clock c also flows into the parenthesized sub-sequence, but it does not flow through @(d). Clock d does not flow out of its enclosing parentheses.

 

As another example, in

 

@(c) v |=> (w ## @(d) x) and (y ## z)

 

v, w, y, z are clocked at c and x is clocked at d.  Clock c flows across |=>, distributes to both operands of the and (which is a property conjunction due to the multiple clocking), and flows into each of the parenthesized subexpressions.  Within (w ## @(d) x), c flows across ## but does not flow through @(d).  Clock d does not flow out of its enclosing parentheses.  Within (y ## z), c flows across ##.

 

Similarly, the scope of a clocking event flows into an instance of a defined sequence or property, and, if the instance is a sequence, also flows left-to-right across the instance.  However, a clocking event in the definition of a sequence or property does not flow out of an instance of that sequence or property.

 

Note that juxtaposing two clocking events nullifies the first of them:

 

@(d) @(c) x

 

is equivalent to

 

@(c) x

 

because the flow of clock d is immediately overridden by clock c.

17.11.4 Examples

The following are examples of multiple-clock specifications:

LRM-131

Change (changes in red and blue):

6) property with implication, where antecedent and consequent are named multi-clocked sequences

 

property mult_p6;

mult_s |=> mult_s;

endproperty

 

7)       property using clock flow and overlapped implication:

 

property mult_p7;

             @(posedge clk) a ##1 b |-> c ## @(posedge clk1) d;

   endproperty

 

Here, a, b, and c are clocked at posedge clk.

 

8)       property using clock flow and if-else:

 

property mult_p8;

   @(posedge clk) a ##1 b |->

if (c)

   (1 |=> @(posedge clk1) d)

else

   e ## @(posedge clk2) f ;

   endproperty

 

Here, a, b, c, and e are clocked at posedge clk.

Section 17.11.1

LRM-128

Change (Note this will become Section 17.11.5 due to LRM-131) (changes in red and blue):

Like ended, matched can be used directly on sequences that do not have formal arguments.

 

An example is shown below:

 

sequence e1(a,b,c);

@(posedge clk) $rose(ready a) ##1 proc1 b ##1 proc2 c ;

endsequence

sequence e2;

@(posedge sysclk)

reset ##1 inst ##1 e1(ready,proc1,proc2).matched [*->1] ##1 branch_back;

endsequence

 

In this example, source sequence e1 is evaluated at clock clk, while the destination sequence e2 is evaluated at clock sysclk. In e2, the end point of the instance e1(ready,proc1,proc2) is tested to occur sometime after the occurrence of inst. Notice that method matched only tests for the end point of e1(ready,proc1,proc2) and has no bearing on the starting point of e1(ready,proc1,proc2).

 

Local variables can be passed into an instance of a defined sequence to which matched is applied.  The same restrictions apply as in the case of ended. Values of local variables sampled in an instance of a defined sequence to which matched is applied will flow out under the same conditions as for ended.  See Section 17.8.

 

As with ended, a sequence instance to which matched is applied can have multiple matches in a single cycle of the destination sequence clock. The multiple matches are treated semantically the same way as matching both disjuncts of an or. In other words, the thread evaluating the destination sequence will fork to account for such distinct local variable valuations.

Section 17.12

LRM-133

Change (changes in red and blue):

      assert to specify the property as a checker to ensure that the property holds for the design

 

      assume to specify the property as an assumption for the environment

 

LRM-133

Change in Syntax 17-16 (changes in red and blue):

procedural_assertion_item ::=                                           // from Annex A.6.10

  assert_property_statement

| cover_property_statement

| immediate_assert_statement

| assume_property_statement

LRM-131 LRM-133

Change in Syntax 17-16 (changes in red and blue):

assert_property_statement::=

  assert property ( property_spec ) action_block

| assert property ( property_instance ) action_block

 

assume_property_statement::=

  assume property ( property_spec )

 

cover_property_statement::=

  cover property ( property_spec ) statement_or_null

| cover property ( property_instance ) statement_or_null

Section 17.12.1/17.12.2 (New)

LRM-133

Change (Renumber following sections) (changes in red and blue):

The assert, assume or cover statements can be referenced by their optional name. A hierarchical name can be used consistent with the SystemVerilog naming conventions. When a name is not provided, a tool shall assign a name to the statement for the purpose of reporting. Assertion control tasks are described in Section 23.8.

 

17.12.1 assert statement

 

The assert statement is used to enforce a property as a checker. When the property for the assert statement is evaluated to be true, the pass statements of the action block are executed. Otherwise, the fail statements of the action_block are executed. For example,

 

property abc(a,b,c);

disable iff (a==2) not @clk (b ##1 c);

endproperty

env_prop: assert property (abc(rst,in1,in2)) pass_stat else fail_stat;

 

When no action is needed, a null statement (i.e.;) is specified. If no statement is specified for the else, then $error is used as the statement when the assertion fails.

 

The action_block shall not include any concurrent assert, assume, or cover statement. The action_block, however, can contain immediate assertion statements.

 

Note: The pass and fail statements are executed in the Reactive region. The regions of execution are explained in the scheduling semantics section, Section 14.

 

17.12.2 assume statement

 

The purpose of the assume statement is to allow properties to be considered as assumptions for formal analysis as well as for dynamic simulation tools. When a property is assumed, the tools constrain the environment so that the property holds.

 

For formal analysis, there is no obligation to verify that the assumed properties hold. An assumed property can be considered as a hypothesis to prove the asserted properties.

 

For simulation, the environment must be constrained such that the properties that are assumed shall hold. Like an assert property, an assumed property must be checked and reported if it fails to hold. There is no requirement on the tools to report successes of the assumed properties.

 

Additionally, for random simulation, biasing on the inputs provides a way to make random choices. An expression can be associated with biasing as shown below

 

expression dist { dist_list } ;                              // from Annex A.1.9

 

The operator dist and the production dist_list is explained in Section 12.4.4.

 

The biasing feature is only useful when properties are considered as assumptions to drive random simulation. When a property with biasing is used in an assertion or coverage, the dist operator is equivalent to inside operator, and the weight specification is ignored. For example,

 

a1:assume property @(posedge clk) req dist {0:=40, 1:=60} ;

property proto

@(posedge clk) req |-> req[*1:$] ##0 ack;

endproperty

 

This is equivalent to:

 

a1_assertion:assert property req inside {0, 1} ;

property proto_assertion

@(posedge clk) req |-> req[*1:$] ##0 ack;

endproperty

 

In the above example, signal req is specified with distribution in assumption a1, and is converted to an equivalent assertion a1_assertion.

 

It should be noted that the properties that are assumed must hold in the same way with or without biasing. When using an assume statement for random simulation, the biasing simply provides a means to select values of free variables, according to the specified weights, when there is a choice of selection at a particular time.

 

Consider an example specifying a simple synchronous request - acknowledge protocol, where variable req can be raised at any time and must stay asserted until ack is asserted. In the next clock cycle both req and ack must be deasserted.

 

Properties governing req are:

 

property pr1;

@(posedge clk) !reset_n |-> !req; //when reset_n is asserted (0),keep req 0

endproperty

property pr2;

@(posedge clk) ack |=> !req; // one cycle after ack, req must be deasserted

endproperty

property pr3;

@(posedge clk) req |-> req[*1:$] ##0 ack; // hold req asserted until

 // and including ack asserted

endproperty

 

Properties governing ack are:

 

property pa1;

@(posedge clk) !reset_n || !req |-> !ack;

endproperty

property pa2;

@(posedge clk) ack |=> !ack;

endproperty

 

When verifying the behavior of a protocol controller which has to respond to requests on req, assertions assert_req1 and assert_req2 should be proven while assuming that statements a1, assume_ack1, assume_ack2 and assume_ack3 hold at all times.

 

a1:assume property @(posedge clk) req dist {0:=40, 1:=60} ;

assume_ack1:assume property (pr1);

assume_ack2:assume property (pr2);

assume_ack3:assume property (pr3);

 

assert_req1:assert property (pa1)

else $display("\n ack asserted while req is still deassrted");

assert_req2:assert property (pa2)

else $display("\n ack is extended over more than one cycle");

 

Note that assume does not provide an action block, as the actions for an assumption serve no purpose.

 

17.12.3 cover statement

 

To monitor sequences and other behavioral aspects of the design for coverage, the same syntax is used with the cover statement. The tools can gather information about the evaluation and report the results at the end of simulation. When the property for the cover statement is successful, the pass statements can specify a coverage function, such as monitoring all paths for a sequence. The pass statement shall not include any concurrent assert, assume or cover statement.

 

The assert or cover statements can be referenced by their optional name. A hierarchical name can be used consistent with the SystemVerilog naming conventions. When a name is not provided, a tool shall assign a name to the statement for the purpose of reporting.

 

Assertion control tasks are described in Section 23.8.

 

Coverage results are divided into two: coverage for properties, coverage for sequences.

 

For sequence coverage, the statement appears as:

 

cover property ( sequence_spec ) statement_or_null

 

The identifier of a particular attempt is called attemptId, and the clock tick of the occurrence of the match is called clock step.

 

The results of coverage statement for a property shall contain:

 

      Number of times attempted

 

      Number of times succeeded

 

      Number of times failed

 

      Number of times succeeded because of vacuity

 

      Each attempt with an attemptID and time

 

      Each success/failure with an attemptID and time

 

In addition, statement_or_null is executed every time a property succeeds.

 

Vacuity rules are applied only when implication operator is used. A property succeeds non-vacuously only if the consequent of the implication contributes to the success.

 

Results of coverage for a sequence shall include:

 

      Number of times attempted

 

      Number of times matched (each attempt can generate multiple matches)

 

      Each attempt with attemptId and time

 

      Each match with clock step, attemptID, and time

 

In addition, statement_or_null gets executed for every match. If there are multiple matches at the same time, the statement gets executed multiple times, one for each match.

Section 17.13 (New)

LRM-137

Change (changes in red and blue):

— clocking domain block, for example:

LRM-137

Change (changes in red and blue):

For a multi-clocked assertion, the clocks are explicitly specified. No default clock or inferred clock is used. In addition, multi-clocked properties are not allowed to be defined within a clocking domain block.

LRM-137

Change (changes in red and blue):

Sequences and properties specified in clocking domains blocks resolve the clock by the following rules:

 

1) Event control of the clocking domain block specifies the clock.

 

2) No explicit event control is allowed in any property or sequence declaration.

 

3) If a named sequence that is defined outside the clocking domain block is used, its clock, if specified, must be identical to the clocking domain’s block’s clock.

LRM-137

Change (changes in red and blue):

— default clock can be specified using default clocking domain block

Section 17.13.1 (New)

LRM-131

Add new Section (changes in red and blue):

17.13.1  Clock resolution in multiply-clocked properties

Throughout this subsection, s, s1, s2 denote sequence expressions without clocking events; p, p1, p2 denote property expressions without clocking events; m, m1, m2 denote multiply-clocked sequences, q, q1, q2 denote multiply-clocked property expressions; and c, c1, c2 denote non-identical clocking event expressions.

 

Due to clock flow, juxtaposition of two clocks nullifies the first.  This and the nesting of clocking events within other property building operators mean that there are subtleties in the general interpretation of the restrictions about where the clock can change in multiply-clocked properties.  For example,

 

@(c) s |-> @(c) (p and @(c1) p1)

 

appears legal because the antecedent is clocked by c and the consequent begins syntactically with the clocking event @(c).  However, the consequent sequence is equivalent to

 

(@(c) p) and (@(c1) p1)

 

and |-> cannot synchronize between clock c from the antecedent and clock c1 from the second conjunct of the consequent.  Similarly,

 

@(c) s |-> @(c1) (@(c) p)

 

appears illegal due to the apparent clock change from c to c1 across |->.  However, it is legal, although arguably misleading in style, because the consequent property is equivalent to @(c) p.

 

This subsection gives a more precise treatment of the restrictions on multiply-clocked use of |-> and if/if-else than the intuitive discussion in Section 17.11.  The present treatment depends on the notion of the set of semantic leading clocks for a multiply-clocked sequence or property. 

 

Some sequences and properties have no explicit leading clock event.  Their initial clocking event is inherited from an outer clocking event according to the flow of clocking event scope.   In this case, the semantic leading

clock is said to be inherited.  For example, in the property

 

@(c) s |=> p and @(c1) p1

 

the semantic leading clock of the subproperty p is inherited since the intial clock of p is the clock that flows across |=>.

 

A multiply-clocked sequence has a unique semantic leading clock, defined inductively as follows.

 

·         The semantic leading clock of s is inherited. 

 

·         The semantic leading clock of @(c) s is c.

 

·         If inherited is the semantic leading clock of m, then the semantic leading clock of @(c) m is c.  Otherwise, the semantic leading clock of @(c) m is equal to the semantic leading clock of m.

 

·         The semantic leading clock of (m) is equal to the semantic leading clock of m.

 

·         The semantic leading clock of m1 ## m2 is equal to the semantic leading clock of m1.

 

The set of semantic leading clocks of a multiply-clocked property is defined inductively as follows.

 

·         The set of semantic leading clocks of m is {c}, where c is the unique semantic leading clock of m.

 

·         The set of semantic leading clocks of p is {inherited}. 

 

·         If inherited is an element of the set of semantic leading clocks of q, then the set of semantic leading clocks of @(c) q  is obtained from the set of semantic leading clocks of q by replacing inherited by c.  Otherwise, the set of semantic leading clocks of @(c) q is equal to the set of semantic leading clocks of q.

 

·         The set of semantic leading clocks of (q) is equal to the set of semantic leading clocks of q.

 

·         The set of semantic leading clocks of not q is equal to the set of semantic leading clocks of q.

 

·         The set of semantic leading clocks of q1 and q2 is the union of the set of semantic leading clocks of q1 with the set of semantic leading clocks of q2.

 

·         The set of semantic leading clocks of q1 or q2 is the union of the set of semantic leading clocks of q1 with the set of semantic leading clocks of q2.

 

·         The set of semantic leading clocks of m |-> p  is equal to the set of semantic leading clocks of m.

 

·         The set of semantic leading clocks of m |=> p  is equal to the set of semantic leading clocks of m.

 

·         The set of semantic leading clocks of if (b) q is {inherited}. 

 

·         The set of semantic leading clocks of if (b) q1 else q2  is {inherited}.

 

·         The set of semantic leading clocks of a property instance is equal to the set of semantic leading clocks of the multiply-clocked property obtained from the body of its definition by substituting in actual arguments.

 

For example, the multiply-clocked sequence

 

@(c1) s1 ## @(c2) s2

 

has c1 as its unique semantic leading clock, while the multiply-clocked property

 

not (p1 and (@(c2) p2)

 

has {inherited, c2} as its set of semantic leading clocks.

 

In the presence of an incoming outer clock, the inherited semantic leading clock is always understood to refer to the incoming outer clock.  On the other hand, if a property has only explicit semantic leading clocks, then the incoming outer clock has no effect on the clocking of the property since the explicit clock events replace the incoming outer clock.  Therefore, the clocking of a property q in the presence of incoming outer clock c is equivalent to the clocking of the property @(c) q.

 

The rules for using multiply-clocked overlapping implication and if/if-else in the presence of an incoming outer clock can now be stated more precisely.

 

1.        Multiply-clocked overlapping implication.

 

Let c be the incoming outer clock.  Then the clocking of m |-> q is equivalent to the clocking of  @(c) m |-> q

 

In the presence of the incoming outer clock, m has a well-defined ending clock, and there is a well-defined clock that flows across |->.  The multiply-clocked overlapped implication m |-> q is legal for incoming clock c if and only if the following two conditions are met:

 

a.        Every explicit semantic leading clock of q is identical to the ending clock of m.

 

b.       If inherited is a semantic leading clock of q, then the ending clock of m is equal to the clock that flows across |->.

 

For example

 

@(c) s |-> p1 or @(c2) p2

 

is not legal because the ending clock of the antecedent is c, while the consequent has c2 as an explicit semantic leading clock.

 

Also,

 

@(c) s ## (@(c1) s1) |-> p

 

is not legal because the set of semantic leading clocks of p is {inherited}, the ending clock of the antecedent is c1, and the clock that flows across |-> and is inherited by p is c.

 

On the other hand,

 

@(c) s |-> p1 or @(c) p2

 

and

 

@(c) s ## @(c1) s1 |-> p1 or @(c1) p2

 

are both legal.

 

1.        Multiply-clocked if/if-else

 

Let c be the incoming outer clock.  Then the clocking of if (b) q1 [ else q2 ]  is equivalent to the clocking of

 

@(c) if (b) q1 [ else q2 ]

 

The boolean condition b is clocked by c, so the multiply-clocked if/if-else if (b) q1 [ else q2 ]  is legal for incoming clock c if and only if the following condition is met:

 

o        Every explicit semantic leading clock of q1 [ or q2 ] is identical to c.

 

For example,

 

@(c) if (b) p1 else @(c) p2

 

is legal, but

 

@(c) if (b) @(c) (p1 and @(c2) p2)

 

is not.

Section 17.15

LRM-136

Change in Syntax 17-18 (changes in red and blue):

statement_item ::=

...

| expect ( property_spec ) [ action_block ]

| expect ( property_instance ) [ action_block ]

 

expect_property_statement ::=

                                expect ( property_spec ) action_block