This action might not be possible to undo. Are you sure you want to continue?
Assertions are primarily used to validate the behaviour of a design. ("Is it working correctly?") They may also be used to provide functional coverage information for a design ("How good is the test?"). Assertions can be checked dynamically by simulation, or statically by a separate property checker tool – i.e. a formal verification tool that proves whether or not a design meets its specification. Such tools may require certain assumptions about the design’s behaviour to be specified. In SystemVerilog there are two kinds of assertions: immediate (assert) and concurrent (assert property). Coverage statements (cover property) are concurrent and have the same syntax as concurrent assertions, as do assume property statements. Another similar statement – expect – is used in testbenches; it is a procedural statement that checks that some specified activity occurs. The three types of concurrent assertion statement and the expect statement make use of sequences and properties that describe the design’s temporal behaviour – i.e. behaviour over time, as defined by one or more clocks.
Immediate assertions are procedural statements and are mainly used in simulation. An assertion is basically a statement that something must be true, similar to the if statement. The difference is that an if statement does not assert that an expression is true, it simply checks that it is true, e.g.: if (A == B) ... // Simply checks if A equals B
assert (A == B); // Asserts that A equals B; if not, an error is generated If the conditional expression of the immediate assert evaluates to X, Z or 0, then the assertion fails and the simulator writes an error message. An immediate assertion may include a pass statement and/or a fail statement. In our example the pass statement is omitted, so no action is taken when the assert expression is true. If the pass statement exists: assert (A == B) $display ("OK. A equals B"); it is executed immediately after the evaluation of the assert expression. The statement associated with an else is called a fail statement and is executed if the assertion fails: assert (A == B) $display ("OK. A equals B"); else $error("It's gone wrong"); Note that you can omit the pass statement and still have a fail statement: assert (A == B) else $error("It's gone wrong"); The failure of an assertion has a severity associated with it. There are three severity system tasks that can be included in the fail statement to specify a severity level: $fatal, $error (the default severity) and $warning. In addition, the system task $info indicates that the assertion failure carries no specific severity. Here are some examples: ReadCheck: assert (data == correct_data) else $error("memory read error"); Igt10: assert (I > 10) else $warning("I has exceeded 10");
end Concurrent Assertions The behaviour of a design may be specified using statements similar to these: "The Read and Write signals should never be asserted together. for each successful match of the antecedent sequence expression. interfaces and programs. (Concurrent assertions may also be used as statements in initial or always blocks. to write out a message. $error("A should equal B"). Ack must be asserted on the next clock." Concurrent assertions are used to check behaviour such as this. then the result is true. . assert property (@(posedge Clock) Req |-> ##[1:2] Ack). |-> is the implication operator. if the sequence s1 matches. They can be used. while the right-hand side is called the consequent sequence expression.) The first assertion example above does not contain a clock. Implication The implication construct (|->) allows a user to monitor sequences based on satisfying some criteria. A concurrent assertion in an initial block is only tested on the first clock tick." "A Request should be followed by an Acknowledge occurring no more than two clocks after the Request is asserted. increment a count of errors. if there is a match for the antecedent sequence expression. The left-hand side operand of the implication is called the antecedent sequence expression. assert property (!(Read && Write)).g. asserts that the expression Read && Write is never true at any point during simulation. the consequent sequence expression is separately evaluated. The second assertion is only checked when a rising clock edge has occurred. set an error flag. for example. the values of Req and Ack are sampled on the rising edge of Clock. or signal a failure to another part of the testbench. If there is a match.The pass and fail statements can be any legal SystemVerilog procedural statement. then the first element of the consequent sequence expression is evaluated on the same clock tick. or the following clock. For overlapped implication. If sequence s1 does not match. There are two forms of implication: overlapped using operator |->. They usually appear outside any initial or always blocks in modules. Therefore it is checked at every point in the simulation. AeqB: assert (a == b) else begin error_count++. Concurrent assertions like these are checked throughout simulation. Properties are built using sequences. For example. For non-overlapped implication. beginning at the end point of the match. the first element of the consequent sequence expression is evaluated on the next clock tick. or on the one following (or both). meaning that Ackis true on the next clock. In the example above. implication succeeds vacuously by returning true. If there is no match of the antecedent sequence expression. attach a precondition to a sequence and evaluate the sequence only if the condition is successful. and non-overlapped using operator |=>. then sequence s2 must also match. where Req is a simple sequence (it’s just a boolean expression) and ##[1:2] Ack is a more complex sequence expression. These are statements that assert that specified properties must be true. For example. s1 |-> s2. e. so this assertion checks that whenever Req is asserted.
Assertion Clocking Concurrent assertions (assert property and cover property statements) use a generalised model of a clock and are only evaluated when a clock tick occurs. the properties being asserted are specified in the assert property statements themselves. endproperty assert property (handshake). endsequence property handshake. used for visual clarity. @(posedge Clock) request |-> acknowledge. Sequences. for example: property not_read_and_write. . Complex properties are often built using sequences. (In fact the values of the variables in the property are sampled right at the end of the previous time step. Properties and Sequences In these examples we have been using. Properties may also be declared separately. too.) Everything in between clock ticks is ignored. not (Read && Write). that always evaluates to true. endproperty assert property (not_read_and_write). The expression above is basically equivalent to: ‘define true 1 s1 ##1 ‘true |-> s2. This model of execution corresponds to the way a RTL description of a design is interpreted after synthesis.s1 |=> s2. where `true is a boolean expression. endsequence sequence acknowledge ##[1:2] Ack. may be declared separately: sequence request Req.
The clock for a property can be specified in several ways: o Explicitly specified in a sequence: sequence s. property p. endproperty assert property (p). a gated clock (e.g. (clk && GatingSig)) or other more complex expression. a simulation time step corresponds to a clock tick. o From a clocking block (see the Clocking Blocks tutorial): clocking cb @(posedge clk). endproperty always @(posedge clk) assert property (p). @(posedge clk) a ##1 b. a ##1 b. endsequence property p. o Explicitly specified in the concurrent assertion: assert property (@(posedge clk) a ##1 b).A clock tick is an atomic moment in time and a clock ticks only once at any simulation time. When monitoring asynchronous signals. o Inferred from a procedural block: property p. The clock can actually be a single signal. @(posedge clk) a ##1 b. o Explicitly specified in the property: property p. a |-> s. endproperty endclocking . a ##1 b. endproperty assert property (p).
The expressions used in sequences are interpreted in the same way as the condition of a procedural ifstatement. So. The ## operator delays execution by the specified number of clocking events. this assertion means that if Reset becomes true at any time during the evaluation of the sequence. Sequences A sequence is a list of boolean expressions in a linear order of increasing time. the disable iff clause allows an asynchronous reset to be specified. or clock cycles. The sequence is true over time if the boolean expressions are true at the specific clock ticks.p). property p1. Otherwise. endproperty assert property (p1).assert property (cb. Here are some simple examples of sequences. a ##1 b [*3] ##1 c (a ##2 b) [*2] (a ##2 b)[*1:3] // Equiv. the sequence b ##1 c must never evaluate to true. to (a ##2 b ##1 a ##2 b) // Equiv. o From a default clock (see the Clocking Blocks tutorial): default clocking cb. then the attempt for p1 is a success. to a ##1 b ##1 b ##1 b ##1 c // Equiv. The not negates the result of the sequence following it. to (a ##2 b) // or (a ##2 b ##1 a ##2 b) . a ##1 b // a must be true on the current clock tick // and b on the next clock tick a ##N b a ##[1:4] b // Check b on the Nth clock tick after a // a must be true on the current clock tick and b // on some clock tick between the first and fourth // after the current clock tick The * operator is used to specify a consecutive repetition of the left-hand side operand. @(posedge clk) disable iff (Reset) not b ##1 c. Handling Asynchronous Resets In the following example.
g. The end time of the end operation is the end time of the sequence that terminates last. the expression above succeeds if both s1 and s2 are evaluated to be true. a ##1 b [=1:3] ##1 c // E. The sequence matches whenever at least one of the operands is evaluated to true. This allows all subsequent matches to be discarded from consideration. a !b b b !b !b b !b !b c Combining Sequences There are several operators that can be used with sequences: The binary operator and is used when both operand expressions are expected to succeed. . but the expression (b in this example) need not be true in the clock cycle before c is true. A sequence succeeds (i. The [= or non-consecutive repetition operator is similar to goto repetition.g. first_match(s1 ##[1:2] s2). s1 and s2 // Succeeds if s1 and s2 succeed.e. the last time being the clock before c is true. and the end times of the operand expressions must be the same. is true over time) if the boolean expressions containing it are true at the specific clock ticks. but the end times of the operand expressions can be different. In this example: sequence fms.// or (a ##2 b ##1 a ##2 b ##1 a ##2 b) The $ operator can be used to extend a time window to a finite. The binary operator intersect is used when both operand expressions are expected to succeed. The end time is the // end time of the sequence that terminates last If s1 and s2 are sampled booleans and not sequences. a ##1 b[->1:3] ##1 c // E. a !b b b !b !b b c This means a is followed by any number of clocks where c is false. a b b b b c The [-> or goto repetition operator specifies a non-consecutive sequence. s1 intersect s2 // Succeeds if s1 and s2 succeed and if end time of s1 is // the same with the end time of s2 The operator or is used when at least one of the two operand sequences is expected to match.g. s1 or s2 // Succeeds whenever at least one of two operands s1 // and s2 is evaluated to true The first_match operator matches only the first match of possibly multiple matches for an evaluation attempt of a sequence expression. and b is true between 1 and three times. a ##1 b [*1:$] ##1 c // E. but unbounded range.
The within construct is an abbreviation for writing: (1[*0:$] ##1 SeqExpr1 ##1 1[*0:$]) intersect SeqExpr2 i. Expression throughout SequenceExpr means that Expression must evaluate true at every clock tick during the evaluation ofSequenceExpr. A common use for this occurs in pipelines: `define true 1 property p_pipe. . The syntax of these is the same as that of assert property. bit X. @(posedge clk) X ##1 Y. This can be used to determine whether or not certain aspects of the designs functionality have been exercised. cover property statements can be used.v=DataIn) ##5 (DataOut === v). module Amod2(input bit clk). and the sequence expression and variable assignment are enclosed in parentheses. logic v. @(posedge clk) (`true.endsequence whichever of the (s1 ##1 s2) and (s1 ##2 s2) matches first becomes the result of sequence fms. The throughout construct is an abbreviation for writing: (Expression) [*0:$] intersect SequenceExpr i. DataOut is expected to equal the assigned value.e. Y. Notice the syntax: the assignment to v is separated from a sequence expression by a comma. endproperty In this example. Each invocation of the property (here there is one invocation on every clock) has its own copy of v. Coverage Statements In order to monitor sequences and other behavioural aspects of a design for functional coverage. endsequence CovLavel: cover property (s1).e. sequence s1. Five clocks later. SequenceExpr1 within SequenceExpr2 means that SeqExpr1 must occur at least once entirely within SeqExpr2 (both start and end points of SeqExpr1 must be between the start and the end point of SeqExpr2 ). The simulator keeps a count of the number of times the property in the cover property statement holds or fails. Variables in Sequences and Properties Variables can be used in sequences and properties. the variable v is assigned the value of DataIn unconditionally on each clock.
The system functions $onehot and $onehot0 are used for checking one-hot encoded signals. For example... asserts that if in changes from 0 to 1 between one rising clock and the next. There are other system functions. For example.. states that q increments. sequences and assertions for the module can be written in a separate program: . Binding We have seen that assertions can be included directly in the source code of the modules in which they apply. $onehot0(expr) returns true if at most one bit of expr is high. states that data shouldn’t change whilst enable is 0. which can be used in assertions.. The system function $past returns the value of an expression in a previous clock cycle. Alternatively. for example. verification code can be written in a separate program. suppose there is a module for which assertions are to be written: module M (. endmodule SystemVerilog also includes covergroup statements for specifying functional coverage. They can even be embedded in procedural code. provided reset is low and enable is high. Assertion System Functions SystemVerilog provides a number of system functions. $rose. These are introduced in the Constrained-Random Verification Tutorial. assert property (@(posedge clk) enable == 0 |=> $stable(data)). // The design is modelled here endmodule The properties. and that program can then be bound to a specific module or module instance. For example. This assertion.. assert property (@(posedge clk) $rose(in) |=> detect). assert property (@(posedge clk) disable iff (reset) enable |=> q == $past(q+1)). detect must be 1 on the following clock.). assert property (@(posedge clk) $onehot(state)). $onehot(expr) returns true if exactly one bit of expr is high. $fell and $stable indicate whether or not the value of an expression has changed between two adjacent clock ticks.
The syntax and meaning of M_assertions is the same as if the program were instanced in the module itself: module M (. endmodule .).)...)...).. // sequences... // The design is modelled here M_assertions M_assertions_inst (. assertions for M go here endprogram This program can be bound to the module M like this: bind M M_assertions M_assertions_inst (. properties..program M_assertions(.
This action might not be possible to undo. Are you sure you want to continue?
We've moved you to where you read on your other device.
Get the full title to continue reading from where you left off, or restart the preview.