<Previous
TOC
Next>
Boolean expressions
The expressions used in
sequences are evaluated over sampled values of the variables that appear
in the expressions. The outcome of the evaluation of an expression is
Boolean and is interpreted the same way as an expression is interpreted in
the condition of a procedural if statement. That is, if the
expression evaluates to X, Z, or 0, then it is interpreted as being false.
Otherwise, it is true. There are certain restrictions on the expressions
that can appear in concurrent assertions. The restrictions on operand
types, variables, and operators are specified in the following sections.
Expressions are allowed to
include function calls, but certain semantic restrictions are imposed.
Operand types
The following types are not
allowed:
Fixed size arrays, packed or
unpacked, can be used as a whole or as part selects or as indexed bit or
part selects. The indices can be constants, parameters, or variables. The
following example shows some possible forms of comparison of members of
structures and unions:
typedef int [4] array;
typedef struct { int a, b, c, d } record;
union { record r; array a; } p, q;
The following comparisons are
legal in expressions:
p.a == q.a
and
p.r == q.r
The following example
provides further illustration of the use of arrays in expressions.
logic [7:0] arrayA
[0:15], arrayB[0:15];
The following comparisons are
legal:
arrayA == arrayB;
arrayA != arrayB;
arrayA[i] >= arrayB[j];
arrayB[i][j+:2] ==
arrayA[k][m:2];
(arrayA[i] &
(~arrayB[j])) == 0; 
Variables
The variables that can appear
in expressions must be static design variables or function calls returning
values of types described in in the above section. Static variables
declared in programs, interfaces or clocking 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.
Operators
All operators that are valid
for the types described in the above section are allowed with the
exception of assignment operators and increment and decrement operators.
SystemVerilog includes the C assignment operators, such as +=, and
the C increment and decrement operators, ++ and . These
operators cannot be used in expressions that appear in assertions. This
restriction prevents side effects.
Sequential Expressions
Having defined the proper
sampling semantics for signals in assertions, SystemVerilog also includes
the ability to specify sequential expressions or sequences of
Boolean expressions with clear temporal relationships between them. To
determine a match of the sequence, the Boolean expressions are evaluated
at each successive sample point, defined by a clock that gets associated
with the sequence.
If all expressions are true,
then a match of the sequence occurs. The most basic sequential expression
is something like “a followed by b on the next clock” which is represented
in SystemVerilog as
a ##1 b
In this example, the “##1”
indicates a oneclock delay between successive Boolean expressions in the
sequence.
Notice the similarity between
the “##” cycle delay operator and the “#”
delay operator, which specifies a number of time units to delay. This
natural extension of an existing Verilog construct preserves the notion of
delay, as Verilog users are used to, and is used elsewhere in
SystemVerilog to indicate an explicit clockcycle delay. This is but one
instance where including the definition of assertions and sequences as
part of SystemVerilog allows for common concepts to use the same syntax
throughout different areas of the language.
It is important to understand
that in SystemVerilog, each element of a sequence may be either a Boolean
expression or another sequence. In terms of sequences, a Boolean
expression is simply the degenerate case of a sequence of length 1. Thus,
the expression
s1 ##1 s2
means that sequence s2
begins on the clock after sequence s1 ends.
s1
##1 s2
Figure: Sequence concatenation: Sequence s2 starts on the cycle after s1
sequence
s1
##0 s2
Figure: Sequence Overlap: Sequence s2 starts on the same cycle at
which s1 finishes
While sequential expressions
are useful for specifying temporal relationships between expressions, it
is important to be able to capture sequential expressions as elements in
the language so that they can be reused and referenced. SystemVerilog thus
introduces the notion of a sequence which can be declared and
reused elsewhere in the language, either to build other sequential
expressions or, as we shall see, as part of properties to be asserted.
Sequences are declared in
SystemVerilog using the following syntax:
sequence_declaration ::=
sequence name [ ( formal_item {,
formal_item } ) ] ;
{ assertion_variable_declaration }
sequence_spec ;
endsequence 
The optional list of formal
arguments allows for specification of sequences as a generic temporal
relationship that is applied to the actual arguments passed in when the
sequence is instantiated. For example, the sequence
sequence seq1 (a, b);
a ##2
b;
endsequence 
represents a sequence of two
expressions. When this sequence is instantiated as
seq1(e,f)
the actual arguments e and f
are substituted for the formal arguments (a and b, respectively) in the
sequence definition, so that the temporal relationship between e and f is
e ##2 f
