100% found this document useful (1 vote)
848 views37 pages

Training On SV Assertions

This document provides an overview of SystemVerilog assertions. It defines assertions as pieces of code that describe expected system behavior, and notes they are used for design verification and formal verification. It describes different types of assertions like immediate assertions used in procedural blocks and concurrent assertions defined using the property keyword. It also discusses concepts like implication operators, timing specifications, disable iff, and consecutive repetition operators as they relate to defining assertions in SystemVerilog.

Uploaded by

Sam Honey
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
848 views37 pages

Training On SV Assertions

This document provides an overview of SystemVerilog assertions. It defines assertions as pieces of code that describe expected system behavior, and notes they are used for design verification and formal verification. It describes different types of assertions like immediate assertions used in procedural blocks and concurrent assertions defined using the property keyword. It also discusses concepts like implication operators, timing specifications, disable iff, and consecutive repetition operators as they relate to defining assertions in SystemVerilog.

Uploaded by

Sam Honey
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

Training on SystemVerilog

Assertions.
Venkat.
11th Sept 2009.
About SystemVerilog
• IEEE 1800 standard
– Extension to Verilog standard IEEE 1364 - 2005.
• Used for Design, Verification and assertion based formal verification.
• HDVL : Hardware Design and Verification Language.

• SystemVerilog constructs
– Design Constructs
– Testbench constructs
– Assertions
– API/DPI/PLI

LSI Proprietary 2
Introduction
• What is an Assertion?.
– Piece of code that describes the behavior a system.
– Mostly temporal in nature.
– Precise way of communicating the specification to verification tools.

• Assertions are not new.


– Designers frequently add verification code in RTL
// synopsys translate_off
if (full && new_req) $display(“Error : buffer overflow”);
// synopsys translate_on

• Examples
– Acknowledgement should be asserted by DUT when request comes.
– “data_ready” should be asserted within 4 clock cycles after read operation is
requested.

LSI Proprietary 3
Introduction cntd…
• Who writes the assertions?.
– Designers
• implementation specific.
• White box approach.
– Verification engineers
• independent to design implementation.
• Derived from specification.
• Black box approach

• Advantages
– Identify the problem at the root rather than tracing back from outputs.
– Communicate the specs across groups with out any ambiguity.
– Reusable: block  chip  system

• Assertions can be categorized in to two groups.


– Immediate Assertions
– Concurrent assertions

LSI Proprietary 4
Immediate Assertion
• Can only be used in procedural blocks.
• Expected to be TRUE always.
• Equivalent to an “if” statement with default “else” being $error.
• Syntax : assert (<expr>) <pass action block>
else <fail action block>

– Upon failure of the <expr>, by default, tool will print an error message in
addition to <fail action block>
– Default severity level can be changed using $warning/$info/$fatal in <fail
action block>.
• An example
always @(posedge clk)
begin : abc // naming a block/process
no_overflow = ….;
check_ovflw : assert (no_verflow) begin $display(“PASS”); end
else begin $display(“FAIL”); end
end : abc

LSI Proprietary 5
Concurrent assertions.
• Concurrent assertions are defined using the keyword property.
property <property_name> [(<arguments>)];
<sampling_event>
<property_expr>;
endproperty: [<property_name>];

module my_module (clk, ….); 1 2 3 4 5 6


input clk, ….;
output ….; clk
reg req, ack;

property p1(clk, a, b); req


@posedge (clk) ack
a |=> b;
endproperty: p1

check_req_ack : assert property (


p1(clk, req, ack)) $display(“PASS”);
else $display(“FAIL”);

endmodule

LSI Proprietary 6
Concurrent assertions cntd…
• Properties define the behavior of the design.
• Spawns over time.
• Can be declared in module/interfaces/program/package.
• Evaluation is either TRUE or FALSE.
• Signal values are sampled in preponed region. And that value would
be used in evaluation.
• Property must be instantiated. Otherwise it will not get executed.
• A property gets triggered only when the specified sampling event
occurs.
• Sampling event may not be a periodic event. It could be a named
event or implicit event.
• Formal verification tools use concurrent assertions. This is called static
ABV.

LSI Proprietary 7
Using properties
• A property definition on its own never gets evaluated.
• Properties can be used in various contexts/scenarios. Need to tell the
environment what to do with the property definition.
• Following are 3 ways of using properties.
– assert property
• acts as a checker, hence must evaluates to true at every sampling tick.
• Can have <pass action block> and <fail action block>
check_req_ack : assert property ( p1(clk, req, ack)) $display(“PASS”);
else $display(“FAIL”);
– cover property
• To score functional coverage.
• Simulator reports how many times property got evaluated to TRUE.
cover_req_ack : cover property (p1(clk, req, ack));
– assume property
• Used by formal verification tools as constarints and also in simulations.
assume_req_ack : assume property (p1(clk, req, ack));

LSI Proprietary 8
Implication operators
• Implication operators.
– Used to conditionally evaluate a property. Kind of if-else statement.
– Overlapped implication operator. |->
– Non-overlapped implication operator. |=>

• Usage of implication operators.


– <antecedent> |-> <consequent>
• <consequent> gets start evaluating in the same sampling event immediately
after the success of <antecedent>
– <antecedent> |=> <consequent>
• <consequent> gets start evaluating in the next sampling event after the
success of <antecedent>
– Every match of antecedent would invoke a separate thread
evaluating consequent.
– Real success : Antecedent is true, hence consequent also evaluated
to TRUE.
– vacuous success : Antecedent is not true, hence consequent would
not be evaluated. i.e “else” part is always TRUE.

LSI Proprietary 9
Timing specification in properties.
• Constant delay ##N Real success
• N must be constant. 1 2 3 4 5 6
hclk
property p1(hclk, addr_phase, hwrite,
hready); addr_phase
@posedge (hclk)
(addr_phase && ~hwrite) |-> ##1 hwrite
hready;
endproperty hready

property p1(hclk, addr_phase, hwrite,


hready);
@posedge (hclk)
(addr_phase && ~hwrite) |=>
hready;
endproperty
Vacuous success

The above two examples specifies the same behavior.

LSI Proprietary 10
Some more examples on constant delay.

1 2 3 4 5 6
clk

start
property p1(start, a, b, c);
@posedge (clk)
(start) |=> ##1 a ##2 b ##1 c; a
endproperty
b

LSI Proprietary 11
Specifying a delay range
• ##[min:max] Real success
1 2 3 4 5 6
property p1(hclk, addr_phase, hwrite,
hready); hclk
@posedge (hclk)
addr_phase
(addr_phase && ~hwrite) |-> ##[1:3]
hready;
hwrite
endproperty
hready
All these 3 scenarios would be TRUE.
Really, it starts 3 threads as below.
(addr_phase && ~hwrite) |-> ##1 hready hready
(addr_phase && ~hwrite) |-> ##2 hready
(addr_phase && ~hwrite) |-> ##3 hready
If any one of the above sequence matches
hready
then property would be TRUE.

• ##[N:$] : $ is used to specify the range until end of simulation.

LSI Proprietary 12
Things to remember about delays
• Specified by ##
• Should be specified in number of clock ticks on which property gets
evaluated.
• Absolute time can not be specified.
• Timing delay should be constant.

LSI Proprietary 13
Disable iff
• Terminates property evaluation in between on some condition.
– EX : When reset gets asserted property thread should be terminated.
1 2 3 4 5 6 7
property p1(hclk, addr_phase, hwrite, rst_n
hready); addr_phase
@posedge (hclk) disable iff(!rst_n)
(addr_phase && ~hwrite) |-> ##[2:4] hwrite
hready;
endproperty hready
p1
X
– Expressions in “disable iff” clause is evaluated on current values, not on
sampled values.
– On termination, property would be evaluated to TRUE.
– Almost every property which is temporal in nature would have “disable iff”.

LSI Proprietary 14
Consecutive repetition operator [*N]
• Expression must be true consecutively for specified number of clock
ticks.
• a[*3] means a ##1 a ##1 a.
1 2 3 4 5 6

property p1(start, a, b);


start
@posedge (clk)
(start) |=> ##2 a[*3] ##1 b; a
endproperty
b

property p1(start, a, b);


@posedge (clk) In this example “a” could be either 2 or
(start) |=> ##2 a[*2:3] ##1 b; 3 cycles wide consecutively followed by
endproperty “b” at least 1 clock cycle.

a ##1 a ##1 b
or
a ##1 a ##1 a ##1 b

LSI Proprietary 15
Go to repetition operator [->N]
• Expression must be true consecutively/non-consecutively for specified
number of clock ticks.
• Match ends on the last occurrence of sequence/expr
• a[->3] is equivalent to (!a[*0:$] ##1 a) [*3].

1 2 3 m n

start
property p1(start, a, end);
@posedge (clk) a
(start) |-> ##2 a[->3] ##1 end;
endproperty end

LSI Proprietary 16
Non-consecutive repetition operator [=N]
• Similar to go to repetition operator (->).
• Match doesn’t have to be end with last occurrence.
• a[=3] is equal to (!a[*0:$] ##1 a) [*3] ##1 !a[*0:$].
• a[=2:4]  Non-consecutive repetition with range.
1 2 3 m n

start
property p1(start, a, end);
@posedge (clk) a
(start) |=> ##2 a[=3] ##1 end;
endproperty end

“a” must be true non-consecutively


for only 3 clock ticks before “end”.
If “a” gets asserted for one more clock
before “end” occurs, then assertion fails.

LSI Proprietary 17
Sampled value functions.
• $rose, $fell, $change, $stable 3
1 2 4 5 6 7
– Based on previous and current values.
en
– These are system functions.
a
property p1;
@posedge (clk) p1
$rose(en) |=> a[*2:4] ##1 (!en);
endproperty p2

property p2; p1 triggers only once.


@posedge (clk) p2 triggers thrice.
en |=> a[*2:4] ##1 (!en);
endproperty
“a” must be stable until “en” goes low and also
$rose(en) |=> $stable(a)[*3:$] ##0 $fell(en); “a” should be stable for minimum 3 clocks. If
“en” goes low before 3 cycles, then propery
fails
posedge on “a” should occur with in
$change(en) |=> ##[0:5] $rose(a);
0 to 5 cycles for any change on “en”

What’s the difference between posedge and $rose?

LSI Proprietary 18
Sampled value fucntions cntd…
• $past
– Can return the value of a variable “n” cycles earlier.
– $past(expr1 [, number_of_ticks] [, gating_expr] [, clocking_event]
– Ex : “q_2d” lags “q” by 2 clock cycles.
clock is derived from property.
property p1; “number_of_ticks” should be >= 1. defaults to 1.
@posedge (clk) Could be used when there is a latency in pipeline.
(q_2d == $past(q, 2);
endproperty

• $countones
• $onehot
• $isunknown

LSI Proprietary 19
Sequences
• Sequences are defined using the keyword sequence
sequence <sequence_name> [<arguments>];
<sampling_event>
<sequence_expr>;
endsequence
module my_module (clk, ….); 1 2 3
input clk, ….; 4 5 6
output ….;
reg a, b, c, d;
sequence s1 (p, q); a
p ##1 q;
endsequence : s1
b
sequence s2 (r, s);
r ##2 s;
endsequence: s2 c

property p1(ck, a, b, c, d);


@posedge (ck) d
s1(a, b) |=> s2(c, d);
endproperty s1 s2
check_abcd : assert property (p1(clk, a, b, c, d));

endmodule

LSI Proprietary 20
About sequences
• Sequences could be used to build properties.
• This make the property expression more readable/manageable.
• Allows reuse across many property expressions.
• A sequence is a set of boolean expressions seperated by timing
information.
• For a sequnce to be true, every boolean expression in a sequence
should match in the increasing order of time specified.
• A boolean expression is a simple sequence with a time spawn of 1
clock cycle..
• Sequences can be declared in module/interface/program/package.
• Variables used in a sequence that are not formal arguments to the
sequence are resolved according to the scoping rules from the scope
in which the sequence is declared.
• Implication operators can not be used in sequences.
• Sequences can also have clocking information.

LSI Proprietary 21
Some more examples on sequences
module my_module (…);
• Points to observe here
– no arguments. Hence variables get logic start, a, b, c, d, end;
resolved in their scope.
– ##0 is sequence concatenation. So, sequence s1;
a[*3] ##1 b[->2];
“c” should be true on the second endsequence
occurrence of “b”
– Sequences derive clocks from the sequence s2;
properties in which they are used. c ##1 (c && d);
endsequence

property p1;
@posedge (clk)
(start) |=> s1 ##0 s2[*1:3] ##1end;
endproperty

check_p1 : assert property (p1);

endmodule

LSI Proprietary 22
Sequence operators.
• and
– Syntax : <seq1> and <seq2>
– Binary operator “and” specifies that both sequences must occur and start
at same time, but can end at any time.
– Composite sequence (seq1 and seq2) ends whenever both sequences
finish.
– Sequences could be simple boolean expressions.
• Ex : req and ack. Means req and ack should occur at same tick.

1 2 3 4 5 6 7
sequence s1; a ##1 b; endsequence start
end
sequence s2; c ##[2:4] d; endsequence a
b
property p1;
@posedge (clk) s1
$rose(start) |=> (s1 and s2) ##0 end ; c
endproperty d
s2
“d” and “end” should s1 and s2
occur at same tick p1

LSI Proprietary 23
Sequence operators cntd ...
• or
– Syntax : <seq1> or <seq2>
– Either seq1 or seq2 should match.
– Composite sequence (seq1 or seq2) ends whenever any sequences finish.

• intersect
– Syntax : <seq1> intersect <seq2>
– Both the sequences must occur;
– Start and end times should match exactly. i.e. lengths of both sequences
must be same.
– Only difference from “and” is the restriction on length of sequences.

LSI Proprietary 24
Sequence operators cntd ...
• first_match
– To find out first match out of multiple matches when range delay range is specified.
– Allows to ignore all subsequent matches.

sequence s1; a##[1:3] b; endsequence 1 2 3 4 5 6 7


a
property p1;
@posedge (clk) b
$first_match(s1)|=> c; c
endproperty p1

property p2; $first_match(s1) p2


@posedge (clk) p2
s1|=> c;
endproperty p2

LSI Proprietary 25
Sequence operators cntd ...
• throughout
– Used to check if a sequence holds hood during a window.
– Ex : “request” should not be asserted during a transaction.
property p1; 1 2 3 4 5 6 7
@posedge (clk) tr_window
$rose(tr_window) |->
(!req) throughout (tr_window[*1:$] ##1 req
$fell(tr_window));
endproperty

sequence s1; a ##1 b; endsequence


property p1; a
@posedge (clk)
$rose(tr_window) |-> b
s1 within (tr_window[*1:$] ##1 $fell(tr_window));
endproperty

• within
– A smaller sequence must occur during longer sequence.
– Ex 1: “data_valid” should be asserted sometime during a transaction.
– Ex2 : sequence, a ##1 b should occur during a transaction.

LSI Proprietary 26
Sequence methods
• ended
– To detect end point of a sequence.
– Syntax : <seq>.ended
– Evaluates to either TRUE or FALSE. And is available for only one clock
cycle.
– Does not depend on start point of sequence.
1 2 3 4 5 6 7
a
b
sequence s1; a ##[1:3] b ##1 c; endsequence c
property p1;
@posedge (clk) s1.ended
$rose(a) |-> ##2 p ##0 s1.ended ##1 q;
endproperty p

q
p1

LSI Proprietary 27
Sequence methods cntd…
• matched
– Is used for synchronization between clock domains.
– Similar to “ended” method.
– Only difference is that the result of sequence end point in source clock
domain would be available until the first clock tick in destination clock
domain.
– Sequences must have clocking event. 1 2 3
sequence s1; slow_clk
@(posedge fast_clk)
a ##[1:3] b ##1 c; 1 2 3 4 5 6 7
fast_clk
endsequence
a
property p1;
@posedge (slow_clk) b
(1) |-> ##1 p ##0 s1.matched ##1 q;
endproperty c
s1.ended
Source clock domain : fast_clk
Destination clock domain : slow_clk; s1.matched
s1 is ended at 4th clock in fast_clk domain.
S1.matched is used to convey this info to slow_clk domain.
S1.matched would be true until 2nd clock in slow_clk domain. This
is the first clock tick after s1 is ended.

LSI Proprietary 28
Supplementing assertions with verilog/SV code
• May need to write verilog/SV code that supplements an assertion.
module monitor ();
logic [31:0] mem [0:127];
logic [31:0] a;

function reg[31:0] read_data (logic[7:0] addr); Function “read_data” helps the


Function “read_data” helps the
read_data = mem(addr); assertion in verifying memory read op.
assertion in verifying memory read op.
endfunction

property p1(ck, a, d);


@posedge (clk)
(sel && read) |=> (d == read_data(addr));
endproperty

check_p1 : assert property (p1(clk, addr, data));

function int no_of_ones (bit[31:0] x);


no_of_ones = …; // counts how many bits are 1.
endfunction

check_p2 : assert property ( @(posedge clk) Checks at every clock cycle.


(no_of_ones(a) < 10) ); Checks at every clock cycle.

LSI Proprietary 29
Binding assertions to design
top
• “bind” statement
module A_ast(a, b, c); U_A1 chip
check1: assert property..
check2: assert property… A U_B
endmodule U_A_ast
B
bind A A_ast U_A_ast(a, b, c); U_A2
bind A:U_A2 A_ast U_A_ast(a, b, c);
A
bind top.chip.U_A1 A_ast U_A_ast(a, b,
c); U_A_ast
Ports would be resolved in the scope of module
“A”.
All port mapping rules applies as usual here. Assertion module “A_ast” would be instantiated
“.*” can be used to avoid lengthy list of ports. In module A. Hence every instance of module A
module B_ast(x, y, z); contains an instance of “A_ast”
check1: assert property..
check2: assert property… “A_ast” would only be part of instance “U_A2”
endmodule Binding an assertions module through
hierarchical path. Only instance U_A1 would
have “A_ast” instatiated.
• Example with implicit port mapping.
bind cpu: U_cpu1, U_cpu2 cpu_assert U_cpu_assert (. req(request), .intr(interrupt), .* );

LSI Proprietary 30
More on “bind”
• No need to change the design hierarchy.
• Allows the verification team to independently develop assertions.
• Assertions can also be written in “interface” and “program” and bind them
to modules/module_instances
• Equivalent to writing assertions outside modules using hierarchical path
names.
Hierarchical paths can also be passed through ports.
top

module B_ast(); U_A1 chip


//hierarchical paths
wire x = top.chip.U_B.x; A U_B
wire y = top.chip.U_B.y;
U_B_ast
wire z = top.chip.U_B.z;
B
U_A2
check1: assert property(..
check2: assert property(… Instantiate A
endmodule somewhere
in testbench

LSI Proprietary 31
Local variables in Assertions
• Required when there is a need to retain values for computation in later
stage.
– Ex: On every clock cycle, one memory read operation would be performed.
Output is being checked on output ports, where the latency is of 3 clocks.
logic [31:0] mem [0:127];
logic [31:0] a;
1 2 3 4 5 6 7
function reg[31:0] read_data (logic[7:0] addr); sel
read_data = mem(addr); read
endfunction
addr
property p1;
logic [6:0] addr_l; // Local variable.
@posedge (clk) data
((sel && read), addr_l = addr) |->
##3 (data== read_data(addr_l));
endproperty

check_p1 : assert property (p1(clk, addr, data));


The same example can be coded
property p1; using $past system function also.
@posedge (clk) It doesn’t mean that local variables can
(sel && read) |-> ##3 (data== be avoided completely.
read_data($past(addr,3));
endproperty
LSI Proprietary 32
Local variables in assertions cntd ….
• Needed for checking data in pipelined designs.
• For every evaluation thread, a new variable would created and deleted
as soon as the tread is finished. This is similar to variables in
automatic tasks.
• Local variables are assigned at the end point of
expression/subsequence match.
• Variables are strictly local to one property evaluation thread.
• Local variables can be assigned multiple times as the
expressions/sequences match with increasing order of time.

LSI Proprietary 33
Different ways of adding assertions

property p1(ck, a, b); check_p2 : assert property (


@posedge (clk) @(posedge clk)
a|=> b; req |=> ack;
endproperty );
check_p1 : assert property (
p1(clk, req, ack));

always @(posedge clk) begin


check_p3 : assert property (
req |=> ack;
);
end // always

LSI Proprietary 34
LSI Proprietary 35
• Gives a coverage that particular sequence of operations are exercized.
• Easily come to know if a corner case scenario is covered or not by writing assertion to that scenario.
• Is a part of functional coverage. 1.Data oriented 2.control oriented.
• Assertions can be put in interface too. Hence applies whereever interface is used.
• Its always best to regorously verify the asertion. By look it gives an impression that everything is correct. But there is a
very chance of holes in assertions.
• Use “adding assertions to your design” cadence/abv.pdf page no 27 to 33 worth adding in this presentation.
• Status of assertions
– Failing assertions
• indication of incorrect functional behavior
– Passing assertions
• indication a piece of the design has been exercised and is functioning properly.
• We can remove redundancy in test cases.
– Un-checked assertions
• indication that more testing is needed, Hence adding new test cases.

LSI Proprietary 36
1 2 3 4 5 6 7
en
a
p1

p2

LSI Proprietary 37

You might also like