Data Types

 

Integer data types

Type Description
bit 2-state data type, user-defined vector size representing unsigned data
byte 8 bit 2-state integer representing signed data or ASCII character
shortint 16 bit 2-state integer representing signed data
int 32 bit 2-state integer representing signed data
longint 64 bit 2-state integer representing signed data
logic 4-state data type, user-defined vector size, unsigned data
reg 4-state data type, user-defined vector size, unsigned data
wire Used to connect different elements in a design. They can be read or assigned, but no values can be stored in them.
integer 32 bit 4-state integer representing signed data
time 64 bit 4-state integer representing signed data

 

Real data types

Type Description
shortreal 32 bit, single-precision, floating-point number
real 64 bit, single-precision, floating-point number
realtime 64 bit, single-precision, floating-point number

 

Enum data types

Declares a user-defined enumerated type having a set of explicitly named values. Syntax:

enum data_type {item[0], item[1], ...} enum_type_name;

 

Defaults Description
data_type If not specified data type defaults to int.

 

Example:

 bit[1:0], int, byte etc
item[0] value If not specified the first item in an enumerated list will be represented as 0
item[n] value If not specified the n-th item in an enumerated list will be represented as item[n-1] + 1

 

Method Description
first() Returns the first value of an enumeration
last() Returns the last value of an enumeration
next(N) Return the N-th next value, wrapping to the beginning if needed. Default N = 1.
prev(N) Return the N-th previous value, wrapping to the end if needed. Default N = 1.
num() Returns the number of values in the enum

 

Struct data types

Type Description
Unpacked (default) Syntax:

 

struct
{
   type1 field_name1;
   type2 field_name2;
   ....

} <struct_name>;

Access to a certain field: <struct_name>.<field_name>

Packed Syntax:

 

struct packed
{
   type1 field_name1;
   ....

}<struct_name>;

Members of a packed structure can be accessed either by their name, or by indexing a vector. By default the first field will be the leftmost item in the vector:

Example:

struct packed 
{
   bit id;
   int addr;
   bit[7:0] data;

}my_struct;

In this case my_struct[0] is my_struct.data[0]
Example Packet Struct Data Type

 

Dynamic array

 

A dynamic array is an unpacked array whose size can be set or changed at runtime. Syntax:

type array_name[];

array_name = new[expression1](expression2);

expression2 is an optional initialization of the array

Method Description
new[expression] Constructor that sets the size of the dynamic array and initializes its elements

 

Example:

int my_array[];

my_array = new[10];           //an array of 10 elements

my_array = new[20];           //doubles the array size, discarding previous values

my_array = new[20](my_array); //doubles the array size, preserving previous values
size() Returns the current size or 0 if the array is not created or if it was deleted.
Example:

 

int array_size;

array_size = my_array.size();
delete() Empties the array, resulting in a zero-sized array

 

Example:

my_array.delete();

Queue data type

Syntax:

 

<type> my_queue[$:max_size]; //where max_size is optional

Example:

int q_int[$];

my_class my_q[$:5]; // accepts maximum 6 elements
Method Description
size() Returns current size of the queue
insert(i,d) Inserts item d at index i
delete(i) Deletes item at index i, if index is omitted, deletes queue
pop_front() Reads and removes the item from the front of the queue
pop_back() Reads and removes the item from the back of the queue
push_front(d) Adds item d to front of the queue
push_back(d) Adds item d to back of the queue

 

Casting

 

Static Cast

In a static cast, if the expression is assignment compatible with the casting type, then the cast shall return the value of a variable of the casting type. Syntax:

casting_type‘(expression)

Example 1:

shortint a;
int b;
b = int’(a);

Example 2:

logic[7:0] register;
register = signed’(4’b1100) // register = -4

Example 3:

shortint a;
int b;
b = a; // implicit cast

 

Dynamic Cast

Used to assign values to variables that might not ordinarily be valid because of differing data types. Syntax:

function int $cast(destination, source)

task $cast(destination, source)

If the assignment is invalid, a task will generate a runtime error, while the function will return 0.

typedef enum(idle,busy,pause,done) state;
state current_state;

if(!$cast(current_state,6)
   $display(“Error in cast”);

 

Classes

Class Declaration Syntax:

class my_class;
   constructor
   local/static/protected items
   Methods/method prototypes
endclass

Class Instance Syntax:

my_class obj; // declare an object of class my_class

Obj = new();  // initialize variable to a new allocated object of class my_class

 

Relevant keywords

Keyword Description
static A static class field shares its value with all instances of the class
A static method can only access static properties, but it can be called even when no class instances exist by using class name and the scope resolution operator.
Example:

 

class my_class;
   static int number_of_instances = 0;

   function new();
      ++number_of_instances;
   endfunction

   static function int get_count()
      return number_of_instances;
   endfunction

endclass
instances_count = my_class::get_count();
this The this keyword gives unambiguous access to members of the current class instance

 

Example:

class  my_class;
   int x;

   function new(int x);
      this.x = x;
   endfunction

endclass
super The super keyword gives unambiguous access to members of the parent class of the calling object.

 

Example:

class parent;
   //constructor
   string name = “parent”;
endclass

class child extends parent;
   //constructor
   string name = “child”;  //override
   function void get_parent_name();
      return super.name;
   endfunction
endclass

child c = new();

initial begin
   $display(c.name);            // child
   $display(c.get_parent_name); // parent
   ...
end
virtual A virtual class is an abstract class which can only be inherited, but not instantiated.
const Class properties can be made read-only by using a const declaration.

 

Example:

class my_class;
   const int id;
endclass

 

Encapsulation

Keyword Description
local Used to specify that class members are only visible within the class where they were declared.

 

class my_class;
   //constructor;
   local int private;
   function void set_private(int x);
      private = x;
   endfunction
endclass

my_class  instance = new();
initial begin
   instance.private = 1;    // ERROR
   instance.set_private(1); // OK
   ...
end
protected Used to specify that class members are only visible within the class where they were declared and any subclasses.

 

class my_class;
   //constructor;
   protected int private;
endclass

class my_extended_class extends my_class
   //constructor;
   function void set_private(int x);
      private = x;
   endfunction
endclass

my_extended_class  instance = new();
initial begin
   instance.private = 1;      // ERROR
   instance.set_private(1);   // OK
   ...
end

 

Inheritance

Keyword Description
extends It is used to create a new class that inherits the members of a base class.

 

class base_calculator;
   int result;
   function void sum(int a, int b)
      result = a + b;
   endfunction
endclass

class smart_calculator extends base_calculator;
   function void mul(int a, int b)
      result = a * b;
   endfunction
endclass

 

Polymorphism

Keyword Description
virtual Virtual (class method) is used to define basic polymorphic constructs. A virtual method is used to override a method in all of its base classes.

 

class base_class;
   int A = 1;
   int B = 2;
   function void printA();
      $display(“A from base: %d”, A)
   endfunction
   virtual function void printB();
      $display(“B from base: %d”, B)
   endfunction
endclass

class extended_class extends base_class;
   int A = 3;
   int B = 4;
   function void printA();
      $display(“A from extended: %d”, A)
   endfunction
   virtual function void printB();
      $display(“B from extended: %d”, B)
   endfunction
endclass

base_class base = new();
extended_class child = new();
initial begin
   base.printA;  // A from base 1
   base.printB;  // B from base 2
   base = child;
   base.printA;  // A from base 1
   base.printB;  // B from extended 4
   child.printA;  // A from extended 3
   child.printB;  // B from extended 4
end

 

Parameterized classes

Class implementation can be customized by using class parameters. Example:

class vector#(int size  = 1)
   bit [size -1 : 0] a;
endclass

class stack#(type T  = int)
   local T items[];
   ...
endclass

Instantiation:

vector#(10) a = new();
stack#(real) b = new();

 

Interface class

The interface class is a class that can be viewed as having a common set of behaviours. An interface class shall contain only pure virtual methods, type declarations and parameter declaration, all other blocks and declarations shall not be allowed.

Syntax:

interface class class_name [extends interface_class_type]
   // pure virtual methods
   // parameters
   // type declarations
endclass

A class may implement one or more interface classes.
Example:

interface class set_data#(type SET_TYPE = logic)
   pure virtual function void set(SET_TYPE a);
endclass

interface class get_data#(type GET_TYPE = logic)
   pure virtual function void get();
endclass

class my_queue#(type T =logic, DEPTH = 1);
   T q[$:DEPTH - 1]
   virtual void function delete_queue();
      q.delete();
   endfunction
enclass

class fifo (type T = logic, DEPTH = 1)
   extends my_queue#(T, DEPTH)
   implements set_data#(T), get_data#(T);
   virtual function void set(T a);
      q.push_back(a);
   endfunction
   virtual function void get();
      q.pop_front();
   endfunction
endclass

 

Copy-Constructor

The copy constructor is a constructor which creates an object by initializing it with an object of the same class, which has been created previously. Example:

 

class my_class;
   int x,y;
   function new();
      // simple constructor
   endfunction
   function new(my_class obj);
      this.x = obj.x;
      this.y = obj.y;
   endfunction
endclass

 

Operators

Symbol Description
= Binary assignment operator
+=  -= /=  *= Binary arithmetic assignment operator
%= Binary arithmetic modulus assignment operator
&=     |= ^= Binary bitwise assignment operator
>>=    <<= Binary logical shift assignment operator
>>>=      <<<= Binary arithmetic shift assignment operator
+  - *   / ** Binary arithmetic operators
% Binary arithmetic modulus operators
&    | ^ Binary bitwise operators
>>     << Binary shift operators
! Unary logical negation operator
~   & ~&
  | ~|

 

^  ~^

Unary logical reduction operator

 

Example:

&y will return the result of an AND operation between all the bits of y

&&      || Binary logical operations
<  > <=  >= Binary relational operation
==     != Binary logical equality operators
   ===
!==
Binary case equality operators.

 

Unlike logical equality operator, this operators can identify x and z.

++       -- Unary increment/decrement operation

 

Package

package my_pacakge;
   //classes
   //variables
   //functions
   //structs
   //etc..
endpackage

Wildcard import - Imports all symbols within the package

import my_package::*; 

Explicit import - Imports only the mentioned symbol from the package

import my_package::my_symbol;

 

Processes

Parallel processes:

 

fork
   begin
      //Task 1
   end
   begin
      //Task 2
   end
   begin
      //Task n
   end
join_keyword
join_keyword Description
join The fork completes when all tasks complete
join_any The fork completes when the first task is completed
join_none The fork completes immediately

 

Verification Features

 

Randomizations

Declaration Description
rand Used in class declaration to specify that a class property is a random variable with an uniform distribution

 

rand int variable_name;
randc Used in class declaration to specify that a class property is a random variable with an cyclic distribution

 

randc bit [1:0] x;

X can take on values in rage of 0 to 3. Randomize will compute an initial random permutation of the range values and return them in order on successive calls.

Initial permutation 0,2,1,3

next permutation 2,3,0,1

The values will be generated in the following order  0,2,1,3,2,3,0,1.

 

Function Description
std::randomize() It is a built-in function used to randomize local variables or class properties

 

rand int random_value;
if(randomize(random_value))
   $display(“Successful randomization”);

The randomize function will return 1 if the randomization was successful or 0 otherwise.

randomize(class method) Built-in method used to randomize all properties declared with rand and randc. The properties that are not declared rand or randc can still be randomized if they are passed as arguments.

 

Cannot be overridden!

class my_class;
   rand int random_value1, random_value2;
   int value;
enclass
my_class rand_obj;

obj.randomize(); // will randomize rand_value1 and rand_value2
obj.randomize(value) // will randomize value as declared as a rand property
pre_randomize() Built-in method that is called by the randomize() method before the objects are randomized.

 

class my_class
rand bit[27:0] data;
bit[3:0] crc;
constraint data_constraint{ data <= 32000}
function void pre_randomization()
   //disable constraint before randomization
   data_constraint.constraint_mode(0);
endfunction
endclass
post_randomize() Built-in method that is called by the randomize() method after the objects are randomized.

 

class my_class;
rand bit[27:0] data;
bit[3:0] crc;
function void post_randomization()
   crc = compute_crc(data);
endfunction
endclass

 

Constraint

Used in class-based randomization, restricting values to specific ranges.

 

Syntax:

constraint name_c {<constraint_item>;}
class my_class;
   rand int random_value;
   constraint random_value_c{
      random_value >= 0;
      random_value <= 15;
   }
endclass
Constraint item Description
solve..before... Defines the order of generation for multiple values

 

Syntax:

solve rand_variable1 before rand_variable2

Example without solve...before...:

class  latch;
   rand bit set,reset;
   constraint random_value_c{
      set == 1 -> reset == 0;
   }
endclass
// ”->” will be explained in the next section

In this case we have three possible combinations (set,reset) = {(0,0);(0,1);(1,0)} each having a 33% chance of occurring.

Example with solve...before...:

class  latch;
   rand bit set,reset;
   constraint random_value_c{
      set == 1 -> reset == 0;
      solve set before reset;
   }
endclass

In this case set is solved first, so (set,reset) = (1,0) has a 50% chance of occurring, instead of 33%.

foreach Used to specify constraints over the elements of an array

 

class my_class;
rand int my_array[100];
constraint my_constraint
{
   foreach(my_array[i])
   my_array[i] < 100;
}
endclass
soft Designates a constraint that is to be satisfied unless contradicted by another constraint with an higher priority.

 

class my_class;
rand int my_int;
constraint my_constraint
{
   soft my_int < 100;
}
endclass

my_class  rand_int = new();
rand_int.randomize() with { my_int >1000; }
Keyword Description
inside Comparison operator which is true if an expression is contained within a specific list

 

class my_class;
   rand int random_value;
   constraint random_value_c{
      random_value  inside {[0:15]};
   }
endclass
dist Used to define weighted distributions

 

Syntax:

variable_name dist {<range> <operator> <weight>};

The operator is one of the following

  • := attributes the range a specific weight
  • :/ equally divides the specified weight to all members of the range

Example:

class my_class;
   rand int random_value;
   constraint random_value_c{
      random_value  dist {
      0:=20,
      [1:10] :/ 80};
   }
endclass
with Used to specify in-line constraints for randomization.

 

Syntax:

randomize([properties]) [with {<constraints>};]

rand int random_value;
if(randomize(random_value) with {random_value < 50;})
   $display(“Successful randomization”);
Operators and methods Description
-> Implication operator used for conditional constraints. It is similar to the if construct.

 

Syntax:

boolean_statement -> constraint_item

Similar to:

if(boolean_statement)
   constraint_item
constraint_mode() task Used to enable and disable class constraints.

 

Syntax:

//[enables|disable] all class constraints
object.constraint_mode([1|0])
//[enables|disable] a certain constraint
objects.constraint_name.constraint_mode([1|0])
constraint_mode() function Returns the current status of a constraint

 

Syntax:

objects.constraint_name.constraint_mode()

 

Functional Coverage

 

 

Covergroups

Defines probes that sample relevant information from functional coverage and defines how coverage results will be reported.

 

covergroup name_cg <coverage event>
   //coverpoints
   //cross
endgroup

<coverage event> could be:

  • @(block_event) example: @(posedge clk)
  • with function sample([port_list])

Initialization code:

name_cg = new();
name_cg.set_inst_name(“my_name”);

 

 

Coverpoints

Identifies a variable that will be tracked for coverage

 

Syntax:

coverpoint variable  [iff (boolead_expresion)]
{ /* bins */ }

If no bins are defined , the coverpoint creates an automatic bin for every value of the variable.

covergroup my_cg with function sample(bit[31:0] addr)
coverpoint addr iff(rst_n);
{
   bins null_addr = {0};
   bins valid_addr = {[2:20]};
}
endgroup

 

 

Cross

Correlates bins from two or more coverpoints so that an inter-variable value relationship can be explored.

 

Syntax:

cross expression1 , expression2, … expression n [iff (boolean expression)];

// or

cross expression1 , expression2, … expression n [iff (boolean expression)]
{ /* user defined cross coverage bins; */ }

covergroup my_cg with function sample(bit signal1,bit signal2)
   coverpoint signal1;
   coverpoint signal2;
   cross signal1, signal2;
endgroup

 

Transitions

 

Type Description
Sequence A transition from valueA to valueB is defined as such:
valueA => valueB 0 => 1
Set Syntax:

 

range_list1 => range_list2
1,2 => 3,4
// This is equivalent to : (1 => 3), (1 => 4), (2 => 3), (2 => 4)
Consecutive repetitions [*n] Syntax:

 

transition_item[*repeat_range]
1[*3] is equivalent to 1 => 1 => 1
Range of repetitions [*n:m] Syntax:

 

transition_item[* low_limit:high_limit]

Example:

1[*2:3] is equivalent to (1 => 1), (1 => 1 => 1)
Goto repetition[->n] Syntax:

 

transfer_item[->repeat_range]

Examples:

1[->3] is equivalent to …=>1 … =>1 …=>1

Where … is any transition that does not contain the value 1

0 => 1[->3] => 0 // is equivalent to 0=>=>1 … =>1 …=>1=>0

Notice that the last transition happens immediately after the second 1 to 1 transition.

Nonconsecutive repetition[=n] Syntax:

 

transfer_item[=repeat_range]

Example:

1[->3] is equivalent to …=>1 … =>1 …=>1...

Where … is any transition that does not contain the value 1

0 => 1[->3] => 0 is equivalent to 0=>…=>1 … =>1 …=>1...=>0

Notice that the transition following the nonconsecutive repetition may occur after any number of transition as long as the value 1 doesn’t occur again.

 

Bins

Type of bins Description
bins Allows explicit named coverage bins to be defined and a range of values to be tracked for each bins.

 

bins name = {range};
wildcard bins Allows x,z and ? as wildcard values in bins definition

 

wildcard bins name = {‘b11xx};
illegal_bins Identifies that a certain range of values are illegal.
ignore_bins Identifies that a certain range of values are excluded from coverage.
default Default bins are used for all values not covered in other bin ranges.
Default bins are not tracked in cross-coverage.

 

coverpoint addr iff(rst_n);
{
   bins null_addr = {0};
   bins valid_addr = {[10:20]};
   bins invalid_addr = default;
}

Assertions

Type Description
Immediate assertions Syntax:

 

[label:]assert (boolean_expresion)
   // pass block
else
   //fail block
SIGNAL_ASSERTED_ERR: assert(signal) // pass block omitted
            else $error(“Assertion failed”);
Concurrent assertions Are SVA directives used to verify that a property holds.
Syntax:

 

[label:] assert property (property_name);
property my_property;
   @(posedge clk) (rst_n !== x && rst_n != Z)
endproperty
assert property (my_property);
Cover Is SVA directive used to verify that a property occurs during simulation.
Syntax:

 

[label:] cover property (property_name);
property my_property;
   @(posedge clk) (rst_n !== x && rst_n != Z)
endproperty
cover property (my_property);

 

SVA Syntax

 

Sequences

Sequence Type Description
Temporal delay ## with integer
signal_1 ##1 signal_2

 
Example Temporal delay ## with integer

Temporal delay ## with range
signal_1 ##[0:2] signal_2 

 
      delay = 0
Example Temporal Delay with range 1

 
      delay = 1
Example Temporal Delay with range 2

 
      delay = 2
Example Temporal Delay with range 3

Consecutive repetition [*m] or range [*n:m] Where n,m re natural numbers, m>n>=1. The $ sign can be used to represent infinity
 

 

signal_1[*1:2] ##1 signal_2

 
      The length of signal1 is 1 clock cycle
Example Consecutive repetitions sequence 1
      The length of signal1 is 2 clock cycle
Example Consecutive repetitions sequence 2

Non-consecutive repetition [=n], [=n:m] Example 1:

 

signal_1[=2]

This is a shortcut for the following sequence

!start[*0:$] ##1 start ##1 !start[*0:$] ##1 start ##1 !start[*0:$] 

Example 2:

signal_1[=2] ##1 signal_2

 
Example Non consecutive repetition

Goto non-consecutive repetition [->n], [->n:m] Example 1:

 

signal_1[->2]

The difference between the two non-consecutive repetition is that the pattern
matching is finished after the last active pulse. This is a shortcut for the following sequence:

!start[*0:$] ##1 start ##1 !start[*0:$] ##1 start ##1

Observe that signal_1 is matched before returning to the LOW state.

Example 2:

signal_1[=2] ##1 signal2

 
Example GOTO non consecutive Repetition

 

Properties

Operator Description
Overlapping sequence implication operator |-> Syntax:

 

sequence_1 |-> sequence_2

sequence_2 will start in the same clock cycle in which sequence_1 will end

Example:

signal_1 ##1 signal_2 |-> signal_3 ##1 signal_4

Example Overlapping Sequence Implication Operator

Non-overlapping sequence implication operator |=> Syntax:

 

sequence_1 |=> sequence_2

sequence_2 will start one clock cycle after sequence_1 has ended
Example Non Overlapping Sequence Implication Operator
Example:

signal_1 ##1 signal_2 |=> signal_3 ##1 signal_4

Observation!
Seq1 |=> Seq2 is the same as Seq1 |-> ##1 Seq2

 

System functions

 

 

 

 

 

 

 

Function Description
$onehot(signal) Returns true if only one bit of the signal HIGH
$onehot0(signal) Returns true if only one bit of the signal is LOW
$isunknown(signal) Returns true if at most one bit of the signal is X or Z
$rose(signal) Returns true if the signal has changed value to 1 in the current evaluation cycle
$fell(signal) Returns true if the signal has changed value to 0 in the current evaluation cycle
$stable(signal) Returns true if the signal has the same value as it had in the previous evaluation cycle
#past(signal, number_of_cc) Returns the value of the signal at a previous evaluation cycle specified through the number_of_cc argument

 

Design and Verification Blocks

 

 

 

Block Description
Module Syntax:

 

module my_module (input input_signal1,
                  input input_signal2,
                  output reg output_signal1);
   //module logic
endmodule
 
reg input1, input2;
wire output;
my_module module_name (.input_signal1(input1),
                       .input_signal2(input2)
                       .output_signal1(output))
Interface Syntax:

 

interface my_interface(port1, port2...)
   //<parameters>
   //<modports>
endinterface

An interface can have different views by defining modports.

interface my_interface(input clk,
                       input rst);
   logic input_signal1, input_signal2, output_signal1;
 
   modport  transmit (
      input input_signal1, input_signal2,
      output output_signal1);
 
   modport receive (
      output input_signal1, input_signal2,
      input output_signal1);
endinterface

Module declaration:

module my_module (my_interface.transmit my_name);
Virtual Interface A virtual interface is a variable that represents an interface instance, providing a mechanism of separating abstract models from the actual RTL implementation.
Syntax:

 

virtual intarface_name virtual_interface_name;
 
interface my_interface(input logic clk, input logic rst_n)
   logic signal;
endinterface
   
class my_class;
virtual my_interface my_virtual_interface;
   //...
endclass

 

SystemVerilog Assertions

 

Type Description
Immediate assertions Syntax:

 

[label:] assert (boolean_expresion)
   // pass block
else
   //fail block
   
SIGNAL_ASSERTED_ERR: assert(signal) // pass block omitted
         else $error(“Assertion failed”);
Concurrent assertions Are SVA directives used to verify that a property holds. Syntax:

 

[label:] assert property (property_name);
 
property my_property;
   @(posedge clk) (rst_n !== x && rst_n != Z)
endproperty
   
assert property (my_property); 
Cover Is a SVA directive used to verify that a property occurs during simulation. Syntax:

 

[label:] cover property (property_name);
 
property my_property;
   @(posedge clk) (rst_n !== x && rst_n != Z)
endproperty
 
cover property (my_property);

SVA Syntax

 

Property

Declaration:

 

property my_property[(port0, port1, ...)];
   //assertion variable declarations
   // property_statement
endproperty
Operator Description
Overlapping sequence implication operator |-> Syntax:

 

sequence1 |-> sequence2

sequence2 will start in the same clock cycle in which sequence1 will end
 
Example:

signal1 ##1 signal2 |-> signal3 ##1 signal4
    //Antecedent         //Consequent

Example Signals Overlapping sequence implication

Non-overlapping sequence implication operator |=> Syntax:

 

sequence1 |=> sequence2

sequence2 will start one clock cycle after sequence1 has ended
 
Example:

signal1 ##1 signal2 |=> signal3 ##1 signal4

Example Signals Non Overlapping sequence implication
 
Observation!
Seq1 |=> Seq2 is the same as Seq1 |-> ##1 Seq2

not Syntax:

 

not my_property;

 
It is not recommended to negate properties that contain an implication operator. The result of such a negation might be hard to predict.
 
Example:

property my_propery;
   @(posedge clk)
   signal1 |-> signal2;
endproperty

not my_propery is equivalent to signal1 && !signal2
The correct negation should be signal1 |-> not signal2

and Syntax:

 

property my_property;
   property1 and property2;
endproperty

 
Both properties should start at the same evaluation time and may end at different cycles. The assertion will pass only if both properties hold.

or Syntax:

 

property my_property;
   property1 or property2;
endproperty

 
Both properties should start at the same evaluation time and may end at different cycles. The assertion will pass only if at least one property holds.

until Syntax:

 

property my_property;
   property1 until property2;
endproperty

 
my_property evaluates to true if property1 evaluates to true for every clock cycle beginning with the starting point, and finishing one clock cycle before property2 starts to evaluate to true.
 
Example:

property my_property;
   req |=> busy until ready;
endproperty

Example Property Until SVA

until_with Syntax:

 

property my_property;
   property1 until_with property2;
endproperty

my_property evaluates to true if property1 evaluates to true for every clock cycle beginning with the starting point, and finishing the same cycle when property2 starts to evaluate to true.

Example:

property my_property;
   req |=> busy until_with ready;
endproperty

Example Property Until With SVA

disable iff Syntax:

 

property my_property;
   disable iff(boolean_condition)
   //property_statement
endproperty

Causes the assertion checking to be terminated if the boolean condition is evaluated to TRUE.
 
Example:

property my_property(input rst_n);
   @(posedge clk)
      disable iff(rst_n == 0)
      signal1 |=> signal2;
endproperty

 

Sequences

Declaration:

 

sequence my_sequence [(port0, port1, ...)]
   //assertion variable declarations
   //sequence expressions
endsequence
Operator Description
Temporal delay ## with integer
signal1 ##1 signal2

Example Temporal Delay with integer

Temporal delay ## with range
signal1 ##[0:2] signal2

   Delay = 0
Example Temporal Delay with range 1
   Delay = 1
Example Temporal Delay with range 2
   Delay = 2
Example Temporal Delay with range 3

Consecutive repetition [*m] or range [*n:m], [*],[+] Where n,m are natural numbers, m>n>=1. The $ sign can be used to represent infinity.
 
Example:

 

signal1[*1:2] ##1 signal2

The length of signal1 is 1 clock cycle
Example Sequences Consecutive Repetitions 1

 
The length of signal1 is 2 clock cycle
Example Sequences Consecutive Repetitions 2

Abbreviations:

  • [*] is the same as [*0:$]
  • [+] is the same as [*1:$]
Non-consecutive repetition [=n], [=n:m] Example 1:

 

signal1[=2]

This is a shortcut for the following sequence
 

!start[*0:$] ##1 start ##1 !start[*0:$] ##1 start ##1 !start[*0:$]

Example 2:

signal1[=2] ##1 signal2

Example Sequences Non Consecutive Repetitions

Goto non-consecutive repetition [->n], [->n:m] Example 1:

 

signal1[->2]

The difference between the two non-consecutive repetition is that the pattern matching is finished after the last active pulse.

signal1[->2] is a shortcut for the following sequence:

!start[*0:$] ##1 start ##1 !start[*0:$] ##1 start ##1

Observe that signal1 is matched before returning to the LOW state

Example 2:

signal1[=2] ##1 signal2

Example Sequences Goto Non Consecutive Repetitions

and Syntax:

 

seq1 and seq2

Example:

(signal1 ##[1:8] signal2) and (signal3 ##[0:$] signal4)

Example Sequences AND

The evaluation starts at the same clock time (if each sequence has it’s own clock, then the AND starts at the first clocking event of each sequence), but it is not necessary to finish at the same time. The and sequence fails to match when any of the sequences fail to match.

or Syntax:

 

seq1 or seq2

Example:

(signal1 ##1 signal2) or (signal3 ##1 signal4)

Example Sequences OR

The result of OR-ing two sequence is a match when at least one of the two sequences is a match.

intersect It is similar to the and operator, except that the the two sequences must end at the same time.
Syntax:

 

seq1 intersect seq2

Example:

(signal1 ##[1:8] signal2) intersect (signal3 ##[0:$] signal4)

Example Sequences INTERSECT

within Syntax:

 

seq1 within seq2

Example:

signal3 ##1 signal4[*2] within signal1 ##[4:6] signal2

Example Sequences WITHIN

A match must satisfy the following conditions:

  • The starting point of seq1 must be after or at the same time as the starting point of seq2.
  • The ending point of seq1 must be before or at the same time as the ending point of seq2.
throughout The throughout operator specifies that a signal must hold throughout a sequence.
Syntax:
signal throughout seq
Example:

 

R/~W throughout (starting_bit ##[3:7] ending_bit)

Example Sequences throughout

Method Description
first_match Used to specify that only the first sequence match is considered from a range of possible matches, the rest being discarded. Syntax:

 

first_match(seq);

Example:

sequence my_seq
   signal1 ##[1:$] signal2;
endsequence

property
   @(posedge clk)
   first_match(my_seq) |=> signal3
endproperty

my_seq generates an infinite number of threads and an infinite number of matches. To prevent unexpected errors the first_match  method is used to ensure that only the first of multiple matches is considered.

Implicit first_match:

  • When a sequence is treated as a property (no implication operator in the property)

          Example:assert property @ (posedge clk) signal1 ##[1:2] signal2
          
          Possible match1
          
Example Sequences Method first match 1

          Possible match2
          
Example Sequences Method first match 2
          For the assertion of a sequence to be successful it is sufficient to have one matched thread.

  • When a sequence is used as a consequent

          The first match of a consequent causes the property to hold and to successfully complete the
          assertion.
          Example:assert property @ (posedge clk)  signal1 |->signal2 ##[1:$] signal3
          
Example Sequences Method first match 3

Required first match:

  • When a sequence is used as an antecedent.

          Each thread generated by an antecedent must match to cause the property to hold. If a thread
          fails to match, the assertion fails.
          Example:
          assert property @ (posedge clk) first_match( signal1 ##[1:2] signal2) |->signal3

          Successful assertion with first_match
          Option1:
          
Example Sequences Method first match 4
          Option2:
          
Example Sequences Method first match 5
          Successful assertion without first_match:
          
Example Sequences Method first match 6
          Failed assertion without first_match:
          
Example Sequences Method first match 7

triggered Used to test if the end point of a sequence was reached. An end point is a boolean expression that represents the evaluation of a thread at its last clock cycle. Syntax:

 

My_seq.triggered

Example:

sequence my_seq;
   signal2 ##2 signal3;
endsequence
   
sequence my_new_seq;
   signal1 ##1 my_seq.triggered ##1 signal4;
endsequence

Example Sequences Method Trigerred

 

Variables

Declaration of a sequence:

sequence my_sequence[(Formal arguments)]
   //Assertion Variable Declaration
endsequence
Types Description
Legal Types Legal local variable types

 

bit          byte          shortint          integer
logic          struct          int          time
reg          enum          longint          untyped

 
Typed formal arguments that are are not local variables

  • sequence
  • event
llegal types Illegal local variable types

 

shortreal          string          Associative arrays
real          class          Dynamic arrays
realtime          chandle  
Initialization Rules:

 

  • Formal Arguments are initialized before assertion variables
  • Local variables are initialized with a nonlocal variable, using the value from the time slot in which the evaluation attempt begins.
  • Non-initialized local variables are unassigned and have no default values.

 
Example:

sequence my_sequence( //FA
               local logic fa_signal = signal1;
               );
   // Assertion Variables Declaration
   logic avd_ signal = 1;
endsequence

Fa_signal will be initialized first with the preponed value of signal1, then avd_signal will be initialized.

Initialization of Formal Arguments:

  • Only local arguments of input direction can be initialized.
  • inout, output and event cannot be declared as local.
Assignments Local variables can be assigned within the sequence matched item list, each variable being separated from each other by using comma in the parentheses.
 
The variables are assigned in order of appearance.
 
Non-local variables cannot be directly assigned in a sequence, it is necessary to assigned them through function calls.
 
Example:

 

sequence my_sequence( //FA
               local logic fa_signal = signal1;
               );
   // Assertion Variables Declaration
logic avd_ signal = 1;
(signal1,fa_signal=1) ##1 (signal2,avd_signal=!signal2) ##1 ($fall(signal3),set_flag());
endsequence

// flag and set_flag function are declared in the module
function void set_flag()
   flag <= 1;
endfunction

Assignments can be used in repetitions:

(signal1, counter = 0) ##1 (signal2, counter += 1)[*10] ##1 counter == 10
User-defined repetitions Local variables cannot be used in temporal ranges, but they can be used as counters for user-defined repetitions or delays.
 
Illegal use of local variables

 

$rose(signal1) ##1 signal2[0:MAX] ##1 signal3

Legal use of local variables

local int count;
($rose(signal1), count = 0) ##1 (signal2, count += 1)[0:$] ##1 (signal3 && count < MAX)
Passing and binding Local Variables to instance of a subsequence Method 1: Using an untyped formal argument

 

sequence binded_seq(signal)
   signal3 ##1 (signal1, s = signal2);
endsequence

sequence my_seq
   local logic s;
   signal2 ##1 binded_seq(s) ##1 signal4 == s;
endsequence

my_seq is equivalent to:

signal2 ##1 signal3 ##1 (signal1, s = signal2) ##1 signal4 == s

   

Method 2: Using a typed formal argument

sequence binded_seq(local output logic signal)
   signal3 ##1 (signal1, s = signal2);
endsequence

sequence my_seq
   local logic s;
   signal2 ##1 binded_seq(s) ##1 signal4 == s;
endsequence

   
Method 3: Using triggered

sequence binded_seq(local output logic signal)
   signal3 ##3 (signal1, s = signal2);
endsequence

sequence my_seq
   local logic s;
   signal2 ##1 binded_seq(s).triggered ##1 signal4 == s;
endsequence

In this case the end point of binded_seq(s) must occur 1 clock cycle after signal2 was asserted. The starting point of binded_seq(s) is before signal2 is asserted.

Using and, or, intersect with local variables Using local variables on parallel “or” Threads.
The or operand generates two concurrent threads, each thread having separate copies of the local variables. If a local variable is set on one thread, the other thread wouldn’t be able to access it.
 
Example Sequences Variables Using AND or INTERSECT
Using local variables on parallel “and”/”intersect” Threads.
The and/intersect operands generate two concurrent threads, each having separate copies of the local variables. At the end of the evaluations, the two threads are merged into one. This will create problems when a local variable is assigned in both threads, and later used after the threads are merged.

 

Example:

//illegal sequence
sequence my_sequence;
   int signal_cp;
   ((signal1 ##1 (signal2, signal_cp = signal3)) and (signal3 ##1 (signal4, signal_cp = signal4))) ##1 (signal1 == signal_cp);
endsequence

In this case we have an illegal assignment of signal_cp in both threads.
 

// legal sequence
sequence my_sequence;
   int signal_cp1;
   int signal_cp2;
   ((signal1 ##1 (signal2, signal_cp1 = signal3)) and (signal3 ##1 (signal4, signal_cp2 = signal4))) ##1 (signal1 == signal_cp1);
endsequence

 
Example Sequences Variables Using AND or INTERSECT 2

 

System functions

Function Description
$onehot(signal) Returns true if only one bit of the signal HIGH
$onehot0(signal) Returns true if only one bit of the signal is LOW
$isunknown(signal) Returns true if at most one bit of the signal is X or Z
$rose(signal) Returns true if the signal has changed value to 1 in the current evaluation cycle
$fell(signal) Returns true if the signal has changed value to 0 in the current evaluation cycle
$stable(signal) Returns true if the signal has the same value as it had in the previous evaluation cycle
$past(signal, number_of_cc) Returns the value of the signal at a previous evaluation cycle specified through the number_of_cc argument