Logic Design - Constraint Blocks (SystemVerilog)

in STEMGeeks10 months ago

[Edit of Image1]


Hey it's a me again @drifter1!

Today we continue with the Logic Design series on SystemVerilog in order to talk about Constraint Blocks.

Let's note that we will not cover the various constraint types, but only how a constraint can be defined - the syntax, rules, internal / external, static, etc.

So, without further ado, let's get straight into it!

Constraint Blocks

A constraint block is a class member with a unique identifier, where various conditions are defined for the purpose of limiting the range of random variables.


More specifically, the conditions of the solver are specified within curly brackets ({}) and each condition expression ends with a semicolon (;).

constraint <identifier> { expr1; expr2; ... exprN; }

Because they are basically declarations only {} can be used, instead of the typical begin end that we saw in other blocks.


The expressions listed within a single constraint don't have to refer to every variable of the class, nor do they have to be limited to a single variable. However, conflicting constraints are forbidden, and have to be spread out to different constraint blocks. Which of the conflicting constraint should be used, will have to be specified using the constraint_mode() method.

External Constraints

Constraints can also be defined outside of classes and be accessed using the scope resolution operator (::) for the purpose of declaration. Additionally, external constraints can also be declared in an implicit or explicit way.


An explicit external constraint is defined by adding the keyword extern to the constraint name. In this case, if no constraint block is defined outside of the class then an error will occur.

class className;


    extern constraint c_explicit;


constraint  className::c_explicit { ... };


An implicit external constraint is defined when no extern keyword is added. The remaining syntax is basically the same. The only difference is that no error will occur, but there may be issued a warning by the simulator.

class className;


    constraint c_implicit;


constraint  className::c_implicit { ... };

Static Constraints

Similar to static variables, constraints can also be declared as static by adding the static keyword to the definition. That way, they will be shared across all class instances, allowing every instance of the class to be affected, when they are turned on or off using the constraint_mode() method.

static constraint <identifier> { ... }

Soft Constraints

By default, all constraints are hard, which means that they are mandatory for the solver and have to be satisfied. If no solution can be found for them the randomization will fail.

To improve the flexibility of constraints and basically add priorities to them, some of the conditions can be declared as soft. That way, when contradicting conditions are specified, the soft ones will be of lower priority than the hard ones.

constraint <identifier> { soft expr; ... }

In-Line Constraints

Suppose a class with well-written constraints. Some additional constraints / conditions may have to be added without affecting it when randomizing some instance of it. For that purpose, SystemVerilog allows for the declaration of in-line constraints. These are added by using the with construct when calling the randomize() method, and are considered along the original constraints.

className instance;

instance.randomize() with { ... };

Of course, providing some conflicting in-line constraint will cause the randomization to fail.



  1. https://www.chipverify.com/systemverilog/systemverilog-tutorial
  2. https://www.asic-world.com/systemverilog/tutorial.html


  1. https://www.flickr.com/photos/creative_stock/5227842611

Block diagrams and other visualizations were made using draw.io

Previous articles of the series



  • 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)
  • Constraints and Randomization → Testing and Verification, Random Variables (Standard, Random-Cyclic), Randomize Method (Constraint and Random Mode, Pre / Post Randomize)

Final words | Next up

And this is actually it for today's post!

Next time we will cover the various types of constraints...

See Ya!

Keep on drifting!

Posted with STEMGeeks