|
|||||||||||||||
Using SystemVerilog Assertions in RTL Code
By Michael Smith,
Doulos Ltd. Introduction SystemVerilog is a set of extensions to the Verilog hardware description language and is expected to become IEEE standard 1800 later in 2005. SystemVerilog Assertions (SVA) form an important subset of SystemVerilog, and as such may be introduced into existing Verilog and VHDL design flows. Assertions are primarily used to validate the behavior 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?"). You can add assertions to your RTL code as you write it " these form "active comments" that document what you have written and what assumptions you have made. Assertions may also be used as a formal specification language, making the requirements clear and unambiguous, and making it possible to automate validation of the design against the specification. SystemVerilog Assertions are not difficult to learn; in this tutorial, you will learn the basic syntax, so that you can start using them in your RTL code and testbenches. Properties and Assertions In SystemVerilog there are two kinds of assertion: 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, which are primarily used by formal tools. Finally, expect is a procedural statement that checks that some specified activity (property) occurs. The three types of concurrent assertion statement and the expect statement make use of sequences that describe the design"s temporal behavior " i.e. behavior over time, as defined by one or more clocks. Immediate Assertions 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"); You may omit the pass statement yet still include 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 the 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) The pass and fail statements can be any legal SystemVerilog procedural statement. They can be used, for example, to write out a message, set an error flag, increment a count of errors, or signal a failure to another part of the testbench. AeqB: assert (a == b) Concurrent Assertions "The Read and Write signals should never be asserted together." "A Request should be followed by an Acknowledge occurring no more than two clocks after the Request is asserted." Concurrent assertions are used to check behavior such as this. These are statements that assert that specified properties must be true. For example, assert property ( !(Read && Write) ); asserts that the expression Read && Write is never true at any point during simulation. Properties are often built using sequences. For example, assert property ( @(posedge Clock) Req |-> ##[1:2] Ack); where Req is a simple sequence (it"s just a boolean expression) and ##[1:2] Ack is a more complex sequence expression, meaning that Ack is true on the next clock, or on the one following (or both). |-> is the implication operator, so this assertion checks that whenever Req is asserted, Ack must be asserted on the next clock, or the following clock. Concurrent assertions like these are checked throughout simulation. They usually appear outside any initial or always blocks in modules, interfaces and programs. (Concurrent assertions may also be used as statements in initial or always blocks. A concurrent assertion in an initial block is only tested on the first clock tick.) The first assertion example above does not contain a clock. Therefore it is checked at every point in the simulation. The second assertion is only checked when a rising clock edge has occurred; the values of Req and Ack are sampled on the rising edge of Clock. Implication If there is no match of the antecedent sequence expression, implication succeeds vacuously by returning true. If there is a match, for each successful match of the antecedent sequence expression, the consequent sequence expression is separately evaluated, beginning at the end point of the match. There are two forms of implication: overlapped using operator |->, and non-overlapped using operator |=>. For overlapped implication, if there is a match for the antecedent sequence expression, then the first element of the consequent sequence expression is evaluated on the same clock tick. s1 |-> s2; In the example above, if the sequence s1 matches, then sequence s2 must also match. If sequence s1 does not match, then the result is true. For non-overlapped implication, the first element of the consequent sequence expression is evaluated on the next clock tick. s1 |=> s2; The expression above is basically equivalent to: "define true 1 where `true is a boolean expression, used for visual clarity, that always evaluates to true. Properties and Sequences property not_read_and_write; Complex properties are often built using sequences. Sequences, too, may be declared separately: sequence request property handshake; assert property (handshake); Assertion Clocking A clock tick is an atomic moment in time and a clock ticks only once at any simulation time. The clock can actually be a single signal, a gated clock (e.g. (clk && GatingSig)) or other more complex expression. When monitoring asynchronous signals, a simulation time step corresponds to a clock tick. The clock for a property can be specified in several ways, of which the most common are:
Handling Asynchronous Resets property p1; assert property (p1); The not negates the result of the sequence following it. So, this assertion means that if Reset becomes true at any time during the evaluation of the sequence, then the attempt for p1 is a success. Otherwise, the sequence (b ##1 c) must never evaluate to true. Sequences Here are some simple examples of sequences. The ## operator delays execution by the specified number of clocking events, or clock cycles.
The * operator is used to specify a consecutive repetition of the left-hand side operand.
The $ operator can be used to extend a time window to a finite, but unbounded range. a ##1 b [*1:$] ##1 c // E.g. a b b b b c The [-> or goto repetition operator specifies a non-consecutive sequence. a ##1 b[->1:3] ##1 c // E.g. a !b b b !b !b b c This means a is followed by any number of clocks where c is false, and b is true between one and three times, the last time being the clock before c is true. The [= or non-consecutive repetition operator is similar to goto repetition, but the expression (b in this example) need not be true in the clock cycle before c is true. a ##1 b [=1:3] ##1 c // E.g. a !b b b !b !b b !b !b c Putting It All Together "A request (req high for one or more cycles then returning to zero) is followed after a period of one or more cycles by an acknowledge (ack high for one or more cycles before returning to zero). ack must be zero in the cycle in which req returns to zero." assert property ( @(posedge clk) disable iff reset "After a request, ack must remain high until the cycle before grant is high. If grant goes high one cycle after req goes high then ack need not be asserted." assert property ( @(posedge clk) disable iff reset where $rose(req) is true if req has changed from 0 to 1. Summary and Conclusions Further Information Public Modular SystemVerilog classes are scheduled in the USA and Europe, and team-based training is available worldwide. Dates and locations currently scheduled are these: July 26 San Jose, CA, USA Doulos also publishes the SystemVerilog Golden Reference Guide, a comprehensive quick reference for the entire SystemVerilog language. A new SystemVerilog Assertions Golden Reference Guide will be available later in the year. About Michael Smith About Doulos Ltd. |
Home | Feedback | Register | Site Map |
All material on this site Copyright © 2017 Design And Reuse S.A. All rights reserved. |