[Edit of Image1]
Introduction
Hey it's a me again @drifter1!
Today we continue with the Logic Design series on SystemVerilog in order to talk about Constraints and Randomization.
So, without further ado, let's get straight into it!
Testing and Verification
Initially, design testing and verification was done through something known as a verification plan. Such verification is more direct as independent scenarios target particular features of a design. But, as the complexity of the designs increased, many such scenarios lead to the introduction of randomized testing. This allowed for a better identification of corner cases that may "slip" using the traditional direct approach.
Random Variables
In Verilog, the only way of randomizing is the build-in system task $random
, which returns a "random" 32-bit integer. Of course, this is not sufficient for object randomization, which is needed in the context of SystemVerilog's OOP. Therefore, SystemVerilog introduces Constraints, which are a compact way of specifying the legal values that will be used by the solver / tester. These values are given to specially-declared Random Variables.
Standard Random Variables
Any normal variable, array, dynamic array or queue can be declared random by adding the keyword rand
. This specifies a standard random variable, where the values are uniformly distributed.
For example:
rand integer num;
Random-Cyclic Variables
It's also possible to declare a random variable using the randc
keyword. This leads to something known as cyclic randomization, where no value is repeated within a given iteration. Additionally, such variables are limited to a maximum of 16-bits (which means that the maximum range is 0 to 65535) and can only be of integer, reg and enumerated types.
Randomize Method
In order to randomize the random variables declared in a class, the randomize()
method has to be called on an instance (or object) of that class. Of course, objects are not randomized automatically.
The randomize()
method returns 1 when the randomization is successful, otherwise it returns 0. This can be used for a success check as shown below.
className instance;
if (instance.randomize())
// success
else
// failure
Randomization Methods
By default, constraints are used for the purpose of randomization. So, all constraints are initially active.
Constraint Mode
Deactivating constraints is a simple as calling the constraint_mode()
method on each constraint.
instance.constraintName.constraint_mode(val);
where a value of 1 activates the constraint, and a value of 0 deactivates it.
Random Mode
Additionally, it's also possible to activate and deactivate the "randomness" of the random variables by calling the random_mode()
method on them. By default, all random variables are active.
instance.randomVariable.rand_mode(val);
Here a value of 1 specifies that the random variable will be randomized, and 0 that it will not be randomized when calling randomize()
.
Pre / Post Randomize
When calling randomize()
the built-in pre_randomize()
and post_randomize()
functions are called automatically, before and after the randomization correspondingly. Similar to randomize()
these are also recursively called on each object member of the object that calls randomize()
.
Of course, these functions are initially empty. So, it's possible to override them in order to add custom code before and after randomization.
Note that the randomize()
task cannot be overridden!
RESOURCES:
References
- https://www.chipverify.com/systemverilog/systemverilog-tutorial
- https://www.asic-world.com/systemverilog/tutorial.html
Images
Block diagrams and other visualizations were made using draw.io
Previous articles of the series
Verilog
- Introduction → Basic Syntax, Data Types, Operators, Modules
- Combinational Logic → Assign Statement, Always Block, Control Blocks, Gate-Level Modeling and Primitives, User-Defined Primitives
- Combinational Logic Examples → One Circuit - Four Implementations, Encoder, Decoder, Multiplexer
- Sequential Logic → Procedural Blocks (Initial, Always), Blocking and Non-Blocking Assignments, Statement Groups
- Sequential Logic Examples → Flip Flops (DFF, TFF, JKFF, SRFF), N-bit Counter, Single-Port RAM
- Finite-State Machines → Finite-State Machine (FSM), FSM Types, State Encoding, Modeling FSMs in Verilog
- Finite-State Machine Examples → Moore FSM Example (1 and 2 always blocks), Mealy FSM Example (1, 2 and 3 always blocks)
- Testbenches and Simulation → Testbenches (DUT / UUT, Syntax, Test Cases), System Tasks, Simulation Tools
- Combinational Logic Testbench Example → Half Adder Implementation, Testbench and Simulation
- Sequential Logic Testbench Example → Sequence Detector FSM Implementation, Testbench and Simulation
- Functions and Tasks → Function and Task Syntax, Calling, Rules, Examples
- Module Parameters and Generate Block → Parameterized Module (Parameters, Instantiation and Overriding Parameters), Generate Blocks (For, If, Case)
- Compiler Directives → Summary of Verilog's Compiler Directives (Include, Macros, Timescale, Conditional Compilation, etc.)
- Switch Level Modeling → Transistors, Switch Primitives (NMOS, PMOS, CMOS, Bidirectional, Resistive), Signal Strengths
SystemVerilog
- From Verilog To SystemVerilog → Data Types, Arrays, Structures, Operators and Expressions
- Control Flow → Additional Procedural Blocks, Loops, Conditional Statements, Functions and Task Features
- Processes → Fork - Join in Verilog and SystemVerilog, Process Control (wait fork, disable fork)
- Events → Interprocess Communication, Events (Definition, Triggering, Waiting, Sequencing, Merging, as Arguments)
- Semaphores and Mailboxes → Semaphores (Creation, Methods), Mailboxes (Definition, Methods)
- Interfaces (part 1) → Interfaces (Definition, Port and Signal Lists, Instantiation), Modports
- Interfaces (part 2) → Parameters, Tasks and Functions (Importing, Exporting), Clocking Blocks (Input and Output Skews)
- Classes (part 1) → Classes (Definition, Constructor Function, Creating Objects, Accessing Class Members, Static and Constant Class Members, Arrays)
- Classes (part 2) → Copying Objects (Shallow and Deep Copy), Inheritance, Polymorphism, Virtual Methods
- Classes (part 3) → Parameterized Classes, Out-of-Block Method Declaration, Data Accessibility, Abstract / Virtual Classes
- Program Blocks → Design and Testbench, Program Block (Reactive Region, Allowed Constructs)
- Packages → Design Hierarchy, Packages (Definition, Importing, Definition Collision)
Final words | Next up
And this is actually it for today's post!
Next time we will continue on with more on Constraints...
See Ya!
Keep on drifting!