[go: up one dir, main page]

0% found this document useful (0 votes)
163 views413 pages

System Verilog Full Notes

The document provides an overview of VLSI design, detailing the front-end and back-end processes, verification methodologies, and the importance of verification in ensuring design correctness. It highlights the various technologies and approaches used in verification, including simulation, formal verification, and the Universal Verification Methodology (UVM). Additionally, it discusses the challenges in the verification process and the need for a structured verification plan to manage complexity and ensure quality in design outcomes.
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
0% found this document useful (0 votes)
163 views413 pages

System Verilog Full Notes

The document provides an overview of VLSI design, detailing the front-end and back-end processes, verification methodologies, and the importance of verification in ensuring design correctness. It highlights the various technologies and approaches used in verification, including simulation, formal verification, and the Universal Verification Methodology (UVM). Additionally, it discusses the challenges in the verification process and the need for a structured verification plan to manage complexity and ensure quality in design outcomes.
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/ 413

VLSI Design – An Overview

VLSI
DESIGN

FRONT
BACK END CAD
END

Design/Arch Design Synthesis + P&R Layout


RTL Design Tools Flow Methodology
Specification Verification flow Verification

Ckt Design, STA, Process


Computer Arch, C++, Verilog, System Verilog, System Process Technology, Design
Technology, Scripting (TCL,
Digital Design Verilog, Digital Design Verilog, Digital Design Rules, Scripting (TCL)
Perl)
HDL

Digital
PLD
Design

EDA
OOP
Tools
Major Industry Components

Design Wafer Wafer Assembly &


Mask Making
Services Manufacturing Test Final Test
Market Trends

• Companies
• Product based
• Service based
• Designer to Verification Engineers Ratio
• Increase in demand with complexity due to data boom
Learning Outcomes

Verification….why, how and what?

Verification options, methodologies, approaches and plan

Test Bench Fundamentals

Writing your SystemVerilog code

Various SystemVerilog Data Types including User Defined Data Types

Procedural Statements and Flow Control Statements

Interface Concepts

Examples to practice on verification tool EDA Playground


Verification Engineer Skillset
 Language knowledge of
 System Verilog, UVM
 System Verilog Assertions (Formal + Simulation)
 VHDL (preferred for Designs)
 Digital Design and Computer Architecture Concepts
 Knowledge of Industry Standard Protocols like AXI, HDMI, PCI, USB
 Knowledge of Processors, System On Chip, FPGAs, Caches, Memories.
 Tools used for Debug Experience :
 Cadence : NCSIM, IEV
 Synopsys : VCS(Verdi) , Jasper
 Code Repository Systems like Perforce, CVS, ClearCase
 Scripting languages like Perl, Python
Web References

 https://www.chipverify.com
 https://testbench.in
 http://www.asicguru.com
 http://www.asic-world.com
 https://verificationguide.com/
Need of Verification

• To match the design with the intent and specs


• Unexpected behavior of design
• Incorrect interaction between IPs/ sub systems
• Cost of re spin runs into millions of $$
• 70-80% of design time and resources spent on verification

To build confidence and stay in business


 Verification became the main bottleneck in the
design process.
 The functional verification bottleneck is an effect
of rising the design abstraction level.
 Majority of ASICs require at least one re-spin with
71% of re-spins are due to functional bugs.
Marketing Requirements Document (MRD)

Architecture Specification

Design Specification

RTL Design

Synthesis
Verification Plan
Physical Design

Timing Analysis

Tape Out
Design Specifications
Front End
Design Entry (Schematic/HDL)
Back End

Functional Verification & Power Analysis


Floor
Planning Technology
Logic & Test Synthesis
Library

Static Gate
Formal Power
Timing Level
Verification Estimation
Analysis Simulation

Floor Planning & CTS

Layout Design

Placement & Routing


SDF &
Parasitics Physical Verification

6/21/2020 Tapeout
Verification with System Verilog 4
Example of coding error
Why Verify?
The later in the product cycle a bug is found the more costly it is.

Cost
of Bug

Block Subsystem System Post Field


Level Level Level Silicon
Product Cycle
FPGAs Need Verification!
Case Study 1:
LOA Technology
2 fully custom FPGA’s

45 man weeks of verification effort 131 bugs found


10 man-weeks of lab debug 9 bugs found
100% statement coverage
Source: Chris Spear: System Verilog for Verification
FPGAs Need Verification!

Case Study 2:
•Fore River Group
•Hardware acceleration for network security.
•Existing testbench with 100 directed tests.
•Shipping to customers.
•7 man-months of effort.
•Using random verification found 40 bugs

Case Study 3:
•Fore River Group
•Packet Switching device
•Verification considered complete
•6 man-months of effort.
•Using random verification found 42 bugs
Source: Chris Spear: System Verilog for Verification
Block Diagram of Typical SoC
USB
UART I2 C GPIO UART2 USB Host 2.0
PHY
Flash USB
USB OTG2.0
MPEG PHY
Interface
How to verify
S/PDIF all the top-level
10/100
Ethernet Graphics CPU Cluster 1 connectivity is
Processor SATA 1/2 correct?

DDR2/3 CPU Cluster 2


SD/MMC 4-ch

Embedded JEPEG Codec


PCI Audio
Memories Audio Codec
Graphics SubSystem
Camera Processor
Interface General Touch Screen
MIPI CSI-2 MIPI DSI HDMI TX
Purpose ADC Controller
Smart Phone SoC
• System On Chip (SOC) is equivalent to Computer motherboard for phone.
• A typical SOC includes
• CPU - multi-core
• GPU - multi-core
• ISP (Image Signal Processor)
• Video Encoders/Decoders
• Memory & caches
• Miscellaneous components..
• A typical design cycle of around 2 years
• Involves multiple vendors supplying Design
IPs & services creating inter-dependencies.
Functional Verification
Functional Verification
 Process to demonstrate functional correctness of the design
 Accounts for 60 – 80% efforts of ASIC design cycle
 Logic Simulation using System Verilog UVM
 Random Testing – scenarios engineer cannot anticipate
 Functional Testing – scenarios defined by engineer
 Corner Case Testing – Hard to hit scenarios defined
 Regression Testing – Automated combination of all of above with repetitive runs
 Formal Verification using System Verilog Assertions
 Immediate Assertions (similar to if statements)
 Concurrent Assertions (Behavior spans across multiple clock cycles)
 Cover Properties (identify hitting scenarios)
 Emulation Testing – Mimic HW to test real life scenarios
Metric Driven Verification
• A clear and un-ambiguous specification is used to create a Verification Plan
– defines what to test & how.
• Plan defines Test cases, Coverage and Checker model
• Verification Environment consists of:
– Monitors, Drivers, Scoreboards, Stimulus generator , coverage Model
• Stimulus generation is random, automated & user constrained to drive legal stimulus
• Verification is signed-off when all verification goals are met (100%)
Universal Verification Methodology
 UVM is a standard verification methodology from
the Accellera Systems Initiative that was developed
with support from multiple vendors: Aldec,
Cadence, Mentor Graphics, and Synopsys.
 It is designed to enable creation of robust, reusable,
interoperable verification IP and testbench
components
 Includes a Reference Guide, a Reference
Implementation in the form of a System Verilog base
class library, and a User Guide.
 First version UVM 1.0 released in 2011
 Supports Object Oriented Programming (OOPS)
concepts
Why are Methodologies Needed?
Vertical and horizontal Reuse
Standardized architecture across teams
Automation
Upgradation
Consistent approach – naming conventions
Coding guidelines
Controllability
Vendor Dependence
What is Verification?
Verification ensures that the RTL performs the correct function.

What defines the correct function of the RTL?


Verification Specification Design

What is the format of the specification?


1. paper document
2. Executable spec
1. SystemC
2. C++
3. Matlab
4. etc.
The Verification Process

Specification

Verifier interprets the spec Designer interprets the spec

Verifier creates a verification plan Designer creates a design spec

Verifier creates tests Designer creates the logic


BUGS!
The Verification Process

A hardware design mostly consists of several Verilog (.v) files with


one top module, in which all other sub-modules are instantiated to
achieve the desired behavior and functionality.

An environment called testbench is required for the verification of a


givenVerilog design and is usually written in SystemVerilog.

The idea is to drive the design with different stimuli to observe its
outputs and compare it with expected values to see if the design is
behaving the way it should.
The Verification Process

In order to do verification, the top level design module is instantiated


within the testbench environment and design input/output ports are
connected with the appropriate testbench component signals.

The inputs to the design are driven with certain values for which we
know how the design should operate.

The outputs are analyzed and compared with the expected values to
see if the design behavior is correct.
How to Verify the Design?

Compare DUT output with expected result.

Reference Compare
Model Logic

Apply input Design Under Test Get the


stimulus (DUT) Output
Design Test Bench
Technology Challenges

 Timing closure
 Capacity
 Physical properties
Technology Challenges
Technology Challenges
 Design Productivity Gap
Technology Challenges

 Time-to-Market Trends
 These technology and market
challenges are having a dramatic
impact on verification methodologies
and tools

• SOC Technology
 design disciplines coexisting
within a single design

topographical representation of Bluetooth design


Why GPU in Phone?
• Graphics Processing Units (GPU) are designed to
accelerate the large number of multiply and add
computations performed in graphics rendering.
• Mobile gaming global revenue is increasing day by day
• These feature rich, high resolution games look
pleasant to eyes but are extremely ‘hardware hungry’.
• A single game scene rendering(drawing) on screen
involves complex memory-intensive geometric and
arithmetic operations.
• Graphics Processor Unit (GPU) is a dedicated
hardware to offload CPU of these efforts.
Graphics Processor Pipeline
Application running on CPU defines/modifies a scene based on UI
Inputs/animation to GPU.
• Geometry Transformation
• Camera Transformation
• Lighting
• Clipping
• Viewport Transformation
• Rasterization
Types of Verification

• Simulation based Pre-Si


• Formal Equivalence
• Post Silicon
• HW – SW Co sim
Verification Technology Options
 The goal of verification is to ensure that the design meets the functional
requirements as defined in the functional specification.
 Verification of SOC devices takes anywhere from 40 to 70 percent of the
total development effort for the design.

Classification:
1. Simulation Technologies
2. Static Technologies
3. Formal Technologies
4. Physical Verification and Analysis
Verification Technology Options

 Simulation Technologies
 Event-based Simulators
 Cycle-based Simulators
 Transaction-based Verification
 Code Coverage
 HW/SW Co-verification
 Emulation Systems
 Rapid Prototyping Systems
 Hardware Accelerators
 AMS Simulation
Verification Technology Options

 Static Technologies: Does not require testbench or test vectors for


carrying out the verification

 Lint Checking

 Static TimingVerification
Verification Technology Options

 Formal Technologies: To detect bugs that depend on specific sequences of events.

 Theorem Proving Technique

 Formal Model Checking

 Formal Equivalence Checking


Formal Verification
Formal Verification
 Formal Analysis exhaustively verifies assertions and reachability of covers in context of
design and constraints
 Why Formal ?
Consider comparing 2 input buses(32 bit wide) for equality. An exhaustive verification
via simulation requires 2^64 bit vectors, and at the rate of 1 M vectors/s , it requires
500k + years to simulate. Formal can exhaustively verify it in 0.05 s (CPU time)
 Engineers build mathematical models of system so they can predict their properties
through the power of calculation
 Formal Tools provide proprietary formal algorithm engines which attempt to prove
each defined property as a mathematical proof rather than actually driving the
stimulus.
Formal Flow
 Properties are statements about the behavior of a design and its environment.
 Assertions express desired behavior of the Design Under Verification (DUV)
 Constraints express behavior of the environment
 Cover Statements express desired reachability of states of the DUV and the
environment
 Proving a property is showing that it holds for all possible input combinations ,
across all execution paths.
 Uses Formal Engines or algorithms to prove/disprove property.
 IFV engines : Sword , Dagger , Bow , Saber , Hammer
 Different Engines have wildly different performance for different properties.
 Multiple Engines can run in parallel provided we have enough CPUs and memory.
 Proving runs until a time/system limit reached or Fail/Pass result found for every
assertion.
 Fail : DUV violates the assertion (tool provides a failure trace).
 Pass : DUV satisfies the assertion with the constraints.
 Explored : DUV does not violate the assertion up to a particular depth and
Time/System limit has been reached. Requires modifications to get it passed
Verification Technology Options

 PhysicalVerification and Analysis:


All electrical issues and processes must be considered

To understand and fix the effects of interconnect parasitics.

The issues that are to be analyzed and fixed are timing, signal integrity,
crosstalk, IR drop, electromigration, power analysis, process antenna effects,
phase shift mask, and optical proximity correction.
Verification Technology Options

 Which Is the Fastest/Best Option


 Event based: suited for asynchronous design
(both function and timing), small designs
 Cycle based: only function; no timing, medium
designs
 Formal: smaller designs
 Emulation: higher speed, very large designs
 Rapid prototyping: developing s/w for product
Verification Methodology

System-Level Verification
SOC Hardware RTL Verification
SOC Software Verification
Netlist Verification
Physical Verification
Device Test
Verification Approaches

 Top-Down Design and Verification Approach


 Bottom-Up Verification Approach
 Platform-based Verification Approach
 System Interface-driven Verification Approach
Verification Plan
Verification Plan

 Plan helps verification engineer to understand how the verification should be done.
 Plan illustrate road map for how do achieve the goal, it is a living document.
 Plan includes, introduction, assumptions, list of test cases, list of features to be
tested, approach, deliverables, resources, risks and scheduling, entry and exit
criteria.
 Plan could be a spreadsheet, a document or a simple text file.
 Sometimes, plan simply reside in the engineer's head which is dangerous in which
the process cannot be properly measured and controlled.
 Plan also contains the descriptions of TestBench architecture and description of each
component and its functionality.
Verification Plan

Generally Verification plan development is divided in two steps:


What to verify and How to verify?

Step one: What to Verify?


List of clearly defined features-to-verify. This is called feature extraction phase.

Step two: How to Verify?


After defining what exactly need to be verified, define how to verify them.
Evolution of the Verification Plan

Continuously
updated

Design and Verification follow the “Waterfall” flow


From all the information sources

Start writing a verification plan

Write feature extraction plan

Stimulus generation plan Coverage plan Checker plan

Create stimulus generator/driver Implement Coverage Checkers/monitors

Integrate all the components and DUT

Do the random testing

Constraint random testing

Analyze the coverage

Directed testing to fill coverage holes


Verification Plan Primarily Contains The Following

Test Bench
Feature List
Architecture

Stimulus Coverage Monitor/


Plan Plan Checker Plan
The Verification Plan

 Project Functional Overview (design functionality, defines all external interfaces,


and lists the major blocks to be used)
 Verification Approach
 Abstraction Levels (behavioral, functional, gate level, and switch level)
 Verification Technologies
 Abstraction Level for Intent Verification (functional equivalence to the model)
 Test Application Approach (approach for applying functional tests to the design)
 Results Checking (selfchecking techniques, golden model (reference model)
comparison, or comparing expected results files.)
 Functional Verification Flow
The Verification Plan

 Test Definitions
 Testbench Requirements
 Models (Model sources, Existing models, Derived models, Authored models)
 Testbench Elements (Checkers, Transaction verification modules, Stimulus)
 Verification Metrics (Capacity metrics, Quality metrics)
 Regression Testing (overnight, continuously, triggered by change levels and so on )
 Issue Tracking and Management
 Resource Plan (human resources, machine resources, and software tool resources.)
 Project Schedule (key benchmarks and completion dates)
The Verification Plan
1. Binds a requirement in the specification to the test(s)
Specification: Test Plan:
The I2C bus will read/write the • Check reset values
config registers •Write a writable config reg
•Write a read-only config reg
2. Technique for testing feature
• Read a config reg
a. Block, hybrid, or System level
• Read a memory mapped input
b. Directed or random
• Stall an I2C transaction
c. Assertions
d. Emulation (FPGA, accelerator, etc)
e. Verification IP
f. Self checking or visual

Source: Chris Spear: System Verilog for Verification


TestBench Components
Design and Testbench
• “Design” ….HDL code….converted as RTL……goes into IC or SoC
• Design Engineer
• “Test Bench” or “TB” ….HDL (or any other) code…used to verify design
• Verification Engineer
• For Design Engineer….Verilog and SystemVerilog is same
• SystemVerilog is preferred by Verification Engineer
• SystemVerilog = Verilog + A lot of verification supporting features.
• The design code might contain hierarchical level of modules.
• There will be always a top level module in the design which instantiate the
hierarchical modules.
• The Test Bench is again another ‘module’ in SV.
• The ‘Top-level module’ of the design will be instantiated in the TB module.
Design and Testbench

module a(); module soc_top(); module test_bench();


endmodule: a cluster cluster1(.*) soc_top soc_top1(.*);
a a1(.*)
module b(); b b1(.*) //TB Functionality
endmodule:soc_top endmodule: test_bench
endmodule: b

module c();
OR
endmodule: c module test_bench();
//TB Functionality
module d(); endmodule: test_bench
endmodule: d
module top();
module cluster(); soc_top soc_top1(.*);
c c1(.*) test_bench test_bench1(.*);
d d1(.*) endmodule: test_bench
endmodule: cluster
What is DUT?

DUT
Linear Testbench

 Linear TestBench is the simplest, fastest and easiest way of writing


testbenchs.
 This became novice verification engineer choice.
 It is also slowest way to execute stimulus.
 Typically, linear testbenchs are written in the VHDL or Verilog. In
this TestBench, simple linear sequence of test vectors is mentioned.
 Stimulus code is easy to generate.
 Small models like simple state machine or adder can be verified with
this approach.
SystemVerilogTestbench Features

 Constrained random generation – built on class infrastructure


 Universal randomize() method
 In-line random generation (randomize() with)
 Spawn threads (fork….join/join_any/join_none)
 Control threads (process class methods)
 Inter-process communication (mailboxes, semaphores etc)
Basic TestBench Functionality
Basic TestBench Functionality

1. Generate stimulus
2. Apply stimulus to DUT
3. Capture the responses
4. Check for correctness
5. Measure progress
Test Bench

Input Pattern Design Under Test Output


(Stimulus) (DUT) (Response)

Self Checking Test Bench Results


Expected
Output Compare

Input Pattern Design Under Test Output


(Stimulus) (DUT) (Response)
Self Checking Testbench

Stimulus Driver DUT Monitor

Require considerably more effort during the initial test bench


creation phase
This technique can dramatically reduce the amount of effort needed
to re-check a design after a change has been made to the DUT.
Debugging time is significantly shortened by useful error-tracking
information that can be built into the TestBench to show where a
design fails.
Self Checking Testbench

Self
checking
Techniques for Testbench Creation

 Testbench in HDL (smaller designs)


 Testbench in Programmable Language Interface (PLI)
 Waveform-based
 Transaction-based
 Specification-based
How to Check Results

How does a Verification engineer check whether the results obtained


from the simulation match the original specification of the design?
1. output is displayed in waveform window OR
2. messages are sent to terminal for visual checking.
Directed Testing
Most (all) probably specified directed testing in their test plan
• Steady progress
• Little up-front infrastructure development
• Small design changes could mean massive test changes

100%

Test Plan
Completion

Time
Testing Methodology

Our verification environments will use the following principles


1. Constrained random stimulus
2. Functional coverage
3. Layered testbench using transactors
4. Common testbench for all tests
5. Test-specific code kept separate from testbench
Simulation 1
Testcase 1 DUT

Simulation 2
Testcase 2 DUT

Solution Space
Random
Number
Constraints Generator DUT
Specification
Constraint
Stimulus/
Solver
Scenario
Random Testing
It reduces the efforts.
100%
Random
Testing Directed tests take long
time to develop because
Test Plan Directed
Completion Testing you have to think about all
possible scenarios to verify
different features.

Time

The main disadvantage of random testing is that we never know what random
values are generated and it may waste simulation cycles by generating same
values again and again.
Layered TestBench
Flat testbench Layered testbench
//Write 32’hFFFF to 16’h50 task write(reg[15:0] addr,
@(posedge clk); reg [31:0] data);
PAddr <= 16’h50;
PWData <= 32’hFFFF; @(posedge clk);
PWrite <= 1’b1; PAddr <= addr;
PSel <= 1’b1; PWData <= data;
PWrite <= 1’b1;
// Toggle PEnable PSel <= 1’b1;
@(posedge clk);
PEnable <= 1’b1; // Toggle PEnable
@(posedge clk); @(posedge clk);
PEnable <= 1’b0; PEnable <= 1’b1;
@(posedge clk);
PEnable <= 1’b0;
endtask
Source: Chris Spear: System Verilog for Verification
Layered TestBench

Test

Functional Coverage
Scenario Generator Environment

Functional Agent Scoreboard Checker

Command Driver Assertions Monitor

Signal DUT

Source: Chris Spear: System Verilog for Verification


TestBench Hierarchy

Test

Environment

Generator Generator Generator Scoreboard


Transaction Transaction Transaction
Driver Driver Driver
Monitor Monitor Monitor
agent-1 agent-2 agent-n
SystemVerilogTestBench Architecture
Test
Environment
Scoreboard
agent
Generator
Transaction Transaction
Monitor Driver

Interface
DUT
Component Description
Generator Generates different input stimulus to be driven to DUT

Interface Contains design signals that can be driven or monitored

Driver Drives the generated stimulus to the design


Monitor the design input-output ports to capture design
Monitor activity
Scoreboard Checks output from the design with expected behavior

Environment Contains all the verification components mentioned above


Contains the environment that can be tweaked with
Test different configuration settings
Simulation Environment Phases
• Build
• Generate DUT configuration and environment
configuration
• Build testbench environment
• Reset the DUT
• Configure the DUT
• Run
• Start environment
• Run the test
•Wrap-up
• Sweep
• Report
Maximum Code Reuse

• Put your effort into your testbench not into your tests.
• Write 100’s or 1000’s of directed tests or far fewer
random tests.
• Use directed test to cover missed functional coverage
TestBench Performance

 Directed tests run quicker than random tests


 Random testing explores a wide range of the state space
 Simulation time is cheap
 Your time is not
 Avoid visually verified tests
 Test maintenance can be a huge effort
Verification Languages
 Enhanced productivity

 Specman Elite hardware verification language


 generating functional tests, checking verification results, coverage analysis and
easy verification testbench reuse

 Vera hardware verification language


 creates target model environments, automatic stimulus generation, self-
checking tests with error indication, coverage analysis capabilities and easy
verification testbench reuse

 Verilog, VHDL, PLI, or C++ languages


System Level Languages
Java-Based JAVA

Entirely New SUPERLOG


Language
SLDL
Higher-Level
Language SDL
System-Lvel Modeling
Language AMS
VHDL/Verilog
Replacements
SystemVerilog

Handle-C

C/C++ Based SoC++

SystemC
1985 –Verilog Introduced by Gateway Design Automation
1990 – Open Verilog International Formed
1990 – OVI released Verilog 1.0
1993 – OVI released Verilog 2.0
1995 – IEEE1364-1995
2002- IEEE 1364-2001
2002 – Extension of Verilog IEEE 1364-2001 with the same name SystemVerilog 3.0
2003 – SystemVerilog 3.1
2005 – IEEE 2005
2009- merged with Verilog IEEE 1364-2005 and formed IEEE 1800-2009
2012- IEEE 1800-2012 corrections of IEEE 1800-2009
2017- IEEE 1800-2017 release as updation of IEEE 1800-2012
What is SystemVerilog?

As designs started to grow rapidly at the beginning of the 21st century,


classical Verilog users realized that the language had come deficiencies in
modeling area, and serious deficiencies in verification area.

Some independent efforts targeted improvement of Verilog (e.g. Superlog) or


creation of verification languages (Vera, e).
SystemVerilog project was sponsored by Accellera and planned to extend
Verilog-2001 using both original work and Superlog and OpenVera donations.
Accellera’s SystemVerilog 3.1a was passed to IEEE and approved as IEEE Std
1800-2005 standard.
What is SystemVerilog?

SystemVerilog is a Hardware Description and Verification


Language(HDVL)
SystemVerilog is an extensive set of enhancements to IEEE 1364
Verilog-2001 standards
It has features inherited from Verilog HDL,VHDL,C,C++
System verilog is the superset of Verilog therefore it supports all
features of verilog plus add on features
+ More additional features
Why SystemVerilog is required when other languages
like Verilog, Vera and e are there?

Verilog is primarily a designer language with less features for verification. Verilog
is good for designs that were small, not very complex and has less features.
Complex designs require better tools to verify it. SV is far superior to Verilog
because of its ability to perform constrained random stimuli, use OOP features
in testbench construction, function coverage, assertions among many others.

SV is much powerful as compared to Vera, e and other similar HVL. Also SV


supports OOP which makes verification of designs at a higher level of abstraction
possible. SV can be considered as an extension of Verilog and therefore it makes
sense to verify a Verilog design in SV.
Why SystemVerilog?

•Gains in productivity/maintainability/thoroughness
•Automatic generation and direction of stimulus
•Functional Coverage
•Higher level RTL
•Required for complex designs
Current Version of Verilog/SystemVerilog

•Last Verilog standard is IEEE Std 1364-2005


•Verilog (1364-2005) and SystemVerilog (1800) merged to create
IEEE Std 1800-2009
•Verilog RTL synthesis standard is IEEE 1364.1-2005
•Current version of SysemVerilog is IEEE 1800-2017 an updated
version of IEEE 1800-2012
SystemVerilog - Evolution

TestBench Assertions

Verilog – IEEE 1364-2001

Coverage C and C++ DPI


SystemVerilog - Evolution
SystemVerilog - Evolution
SystemVerilog – User View

SVD- SystemVerilog for Design


 Synthesizable, useful for circuit modeling
SVA- SystemVerilog for Assertions
 Better verification, increased design quality
SVTB- SystemVerilogTestbench
 High level verification, new methodologies
SV-API- Application Programming Interface
 DPI- new, direct interface to C/C++
 VPI/PLI- interface to C/C++ inherited from Verilog
 Assertion API, Coverage API- extensions of VPI
Tool support for SystemVerilog
•Cadence
•Minimum is Incisive Design Team Simulator
•Much better SystemVerilog support
•Xcelium
•Mentor
•ModelSim SE or PE does not fully support SystemVerilog
•Minimum is QuestaSim
•Synopsys
•VCS
•Aldec
•Riviera
•Synthesis of SystemVerilog supported in Xilinx ISE 12.1
•Synplicity and Precision support is limited but improving
Tool support for SystemVerilog
EDA Playground

https://www.youtube.com/user/edaplayground/videos
First SystemVerilog Program
First SystemVerilog Program
First SystemVerilog Program
Module Port List
Name

a[7:0]
sum [7:0]
b[7:0] Adder
cout
cin Port
Declaration

Internal
‘assign’ infers a Signals
combinational Description of
circuit the
functionality
Built-in Functions (Tasks)

Starts with a $ symbol


$display E.g.: $display(“Hello, value in decimal is %d”, var_a);
$finish, $stop, $exit
$time E.g. $display(“Simulation error at time %t in output a
with value = %d”, $time, out_a);
$random
SystemVerilog Operators
SystemVerilog Operators
SystemVerilog Operators
Operator Operator Name Operator Operator Name Operator Operator Name
- Unary arithmetic (negative) ! Logical negation << Logical left shift
+, -, *, / Binary arithmetic && Logical and >> Logical right shift
% Modulus || Logical or <<< Arithmetic left shift
** Power operator -> Logical implication >>> Arithmetic right shift
<-> Logical equivalence

Operator Operator Name Operator Operator Name


& Unary and ~ Bitwise negation (Unary)
~& Unary nand & Bitwise and (binary)
| Unary or &~ Bitwise nand (binary)
~| Unary nor | Bitwise or (binary)
^ Unary exclusive or |~ Bitwise nor (binary)
~^ Unary exclusive ^ Bitwise exclusive or (binary)
^~, ~^ Bitwise exclusive nor (binary)
SystemVerilog Operators

Operator Operator Name Definition


a==b Logical equality a equal b, result can be unknown
a!=b Logical inequality a not equal to b, result can be unknown
a ===b Case equality a equal b, including x and z
a!==b Case inequality a not equal b, including x and z
a==?b Wildcard equality a equals b, X and Z values in act as wildcards
a!=?b Wildcard inequality a does not equal b. X and Z values in b act as wildcards
The Logic Type
•Verilog has 2 data types
• wire
• reg
•SystemVerilog introduces the logic data type
• Still 4-value
• Replaces both wire and reg
• Cannot have multiple drivers
•For a bidirectional bus use the wire type.
logic reset;
logic [15:0] data;
SystemVerilog - Data Types

Enhanced data types:


 2-state (bit)
 logic- the best of reg and wire
Potential memory & run time improvement (2-state)
High level models benefit from 2-state types.
logic provides clearer descriptions: a Verilog reg is NOT necessarily a
“register”
With logic, you don’t have to think “should I use wire or reg here?”
2-State Data Types

•Why?
•Faster simulation and less memory than 4-state logic
•Easier to interface to C/C++ functions
• bit byte shortint int longint
bit [15:0] my_reg;
shortint my_reg2;

•Caveats
•bit is not signed
•byte, shortint, int, longint are signed
•Initial value is 0
• X’s and Z’s resolve to a 0
2-State Data Types

• 4-state logic types are x at beginning of simulation


• 2-state logic types are 0 at beginning of simulation
• Can assign 4-state to 2-state.
• Can use $isunknown to check for x or z
if ($isunknown(iport) == 1)
$display("@%0t: 4-state value detected on
iport %b", $time, iport);
2-State Data Types: Example
What is the range of values my_byte can take?
byte my_byte; What is the value of:
integer my_integer = 32’b000_1111_xxxx_zzzz;
int my_int = my_integer; my_int in hex?
bit [15:0] my_bit = 16’h8000; my_bit in decimal
shortint my_short_int1= my_bit;
shortint my_short_int2 = my_short_int1-1; my_short_int1 in decimal
my_short_int2 in decimal

my_byte ranges from -128 to 127


my_int is 32’h0000_0F00
my_bit is 32768
my_short_int1 is -32768
my_short_int2 is 32767
Type 2-state/ Signed/ Number SystemVerilog/
4-state Unsigned of bits Verilog
logic 4 Unsigned >=1 SystemVerilog
bit 2 Unsigned >=1 SystemVerilog
byte 2 Signed 8 SystemVerilog
shortint 2 Signed 16 SystemVerilog
Int 2 Signed 32 SystemVerilog
longint 2 Signed 64 SystemVerilog
reg 4 Unsigned >=1 Verilog
wire 4 Unsigned >=1 Verilog
integer 4 Signed >=32 Verilog
real Verilog
shortreal SystemVerilog
realtime Verilog
time 4 Unsigned 64 Verilog
How to write floating point and exponential numbers ?
Void Data Type
Logic Data Type

Default value of logic type is X


Bit Data Type
Assign new values and display the variable to see
Default value of bit type is 0
that it gets the new values

If a "bit" type variable is assigned with a value greater than it can


hold the left most bits are truncated. In this case, b can hold only
4 bits and hence 'h100 gets truncated leaving b with only 'ha;

With ‘b’ as bit type

With ‘b’ as logic type

If a logic type or any 4-state variable assigns its value to a


"bit" type variable, then X and Z get converted to zero
Signed Integer
By default int data types are signed which means that MSB is the sign bit and the integer variables can also store negative numbers

Assign the maximum value for


each of the variables. MSB of
When added a 1, the Print initial values of the integer variables each variable represents the sign
sign changes to negative bit and is set to 0. Rest of the
because this is a signed bit positions are filled with 1
variable and hence you get the
maximum value that these
variables can hold
Rollover observe
change from + sign Start a monitor to print out values of each variables as they change
to - sign
Unsigned Integer
MSB no longer holds the sign information and hence these variables can only
store positive values
Byte Data Type
By default byte type is signed
Assign the "assumed" maximum value to both variables

Increment by 1, and see that s_byte rolled


over to negative because byte is signed by
default. u_byte keeps increasing because it is
unsigned and can go upto 255
Assign 255 (8'hFF) to u_byte, the max value it
can hold and add 1 to see that it rolls over to 0
How to write comments ?
SystemVerilog Array

An array is a collection of variables, all of the same type, and accessed


using the same name plus one or more indices.
e.g reg [7:0] ABC [1:256]; // [7:0] is the vector width, [1:256] is the array size

Fixed Size Arrays


Dynamic Arrays
Associative arrays
Queues
Fixed-Size Arrays
•C-style array declaration
int lo_hi[0:15];
int c_style_lo_hi[16];
bit [7:0] my_bitmem [128];
logic [3:0] my_logicmem [64];

•Out of bounds writes ignored


• Out of bounds read:
• For 4-state returns an X
• For 2-state returns a 0
The Array Literal
•Verilog 2001
• Could not initialize arrays at declaration
• No way to set default value of array
• SystemVerilog
• Initialize with apostrophe (‘)
int ascend[4] = ‘{0,1,2,3};
ascend[0:2]=‘{5,6,7};

• Replicate values with replication operator


ascend = ‘{4{8}};
• Specify defaults
ascend = ‘{default:-1};
• Print using %p format specifier
$display(“%p”, ascend);
Example
int array1 [6]; //fixed size single dimension array
int array2 [5:0]; //fixed size single dimension array
int array3 [3:0][2:0]; //fixed size multi dimension array
bit [7:0] array4[2:0]; //unpacked array declaration
bit [2:0][7:0] array5; //packed array declaration
bit [2:0][7:0] array6 [3]; //mixed packed and unpacked array
//multi dimensional array
byte fixed_array[10]; int array [2:0] [3:0];
Element
Fixed Index (at 4th index)

0 1 2 3 4 5 6 7 8 9 0 1 2 3
0

Length of array 10 1
2
Fixed Size Array: Example
Example
Given the following code sample:
bit [7:0] my_mem [3] = '{default:8'hA5};
logic [3:0] my_logicmem [4] = '{0,1,2,3};
logic [3:0] my_logic = 4’hF;

Evaluate in order: my_mem = {A5, A5, 0}


my_logic = x
my_mem[2] = my_logicmem[4];
my_logicmem= {0,1,2,0}
my_logic = my_logicmem[4];
my_logicmem[3] = my_mem[3]; my_mem does not change
my_mem[3] = my_logic; my_logic = 1
my_logic = my_logicmem[1]; my_logic = 4’h5
my_logic = my_mem[1]; my_logic = x
my_logic = my_logicmem[my_logicmem[4]];
Basic Array Ops – for/foreach
• For loop
• Declare index local to loop
• use $size function to return size of the array
initial begin
bit [31:0] src[5];
for (int i=0; i<$size(src); i++)
src[i]=i;
end
• Foreach loop
• Simply loops through each item of array
• Index variable is automatically declared
initial begin
bit [31:0] dst[5];
foreach(dst[j])
dst[j]=j*2;
end
Multi-dimensional arrays
md[0][0] md[0][2] md[1][0] md[1][2]
• Initialization:
int md[2][3] = ‘{‘{0,1,2}, ‘{3,4,5}};

• Foreach loop
• Loop through every element
foreach (md[i,j]) $display(“%d “, md[i][j]);

• Loop through the first dimension


foreach (md[i]) $display(“%d “, md[i][0]);

• Loop through the 2nd dimension


foreach (md[,j]) $display(“%d “, md[1][j]);
Basic array ops – Copy and Compare
• Comparison and copy only
• No arithmetic
initial begin
bit [31:0] src[5] = ‘{0,1,2,3,4},
dst[5] = ‘{5,4,3,2,1};
if(src==dst)
$display(“src==dst”);
else
$display(“src!=dst”);
dst=src;
src[0]=5;
if(src[1:4]==dst[1:4])
$display(“src==dst”);
else
$display(“src!=dst”);
end
Bit and Array Subscripts

• Illegal in Verilog-1995 to select a bit from an element in an array


• New capability in Verilog 2001. Supported in SystemVerilog
bit [31:0] src[5] = '{5{5}};
$displayb(src[0],, src[0][0],, src[2][2:1]);

# 00000000000000000000000000000101 1 10

src src[0][0]=1

0 00000000000000000000000000000101 src[0]=5
1 00000000000000000000000000000101
2 00000000000000000000000000000101 src[2][2:1]=10
3 00000000000000000000000000000101
4 00000000000000000000000000000101

32bits
Example of Static Array
A vector or 1D packed array

Assign a value to the vector

Iterate through each bit of


the vector and print value
Array Slice and Part Select
Slice is a selection of one or more contiguous elements of an array, whereas part
select is a selection of one or more contiguous bits of an element.
Part select operates on bits of an element, whereas slice operates on elements of
an array.
SystemVerilog uses the term part select to refer to a selection of one or more
contiguous bits of a single dimension packed array.
Fixed size arrays - unpacked arrays
•Unpacked arrays
• Store byte, shortint, int in a single 32-bit word
• Identified by the declaration. Depth is declared after the variable
bit [7:0] up_array[3];
unused space

up_array[0]
7 6 5 4 3 2 1 0
Unpacked arrays may
up_array[1]
be fixed-size, dynamic,
up_array[2] associative or queue.
Total memory consumed = 3*32 = 96 bits
• Can consider up_array only as an array of bytes.
$displayh(up_array); Will not compile
• Cannot trigger an event on up_array
always @(up_array); Will not compile
wait(up_array); Will not compile
Unpacked array Examples
real A1 [7:0];
logic B1 [9:0];

bit [7:0] ABC[2:0];


7 6 5 4 3 2 1 0 ABC[0];
7 6 5 4 3 2 1 0 ABC[1];
7 6 5 4 3 2 1 0 ABC[2];
Unpacked array 1D Example
Unpacked array Multidimentional Example
Packed Arrays
•Stored as contiguous bits
• Identified by the declaration. Size is declared before the variable
bit [3:0][7:0]bytes = 32’hcafe_dada;
ca fe da da

Total memory consumed = 3*8 = 32 bits

•Array bytes can be considered as a 32-bit word or 4 bytes


$displayh(bytes,, bytes[3],, bytes[3][7]);
# cafedada ca 1
• However, cannot fully consider array bytes as a 32-bit word
$displayb(bytes[31]);

• Can trigger an event on bytes


always @(bytes);
wait(bytes);
Packed array Examples

bit [3:0] A1;


bit [7:0] B1;

bit [2:0] [7:0]ABC;


7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0

ABC[2] ABC[1] ABC[0]


Packed Array Example
bit [1:0] [2:0] [3:0] barray;
barray = '{'{4’h6, 4’h5, 4’h4}, '{4’h3, 4’h2, 4’h1}};
$displayh(barray,, barray[1],, barray[1][2],, barray[1][2][3]);

barray 4'b0110 4'b0101 4'b0100 4'b0011 4'b0010 4'b0001

# 654321 654 6 0
Packed array 1D Example
Packed array Multidimensional Example
Packed array 3D Example
Mixing Packed and Unpacked Dimensions
• Dimensions of the array declared before the variable are packed
• Dimensions of the array declared after the variable are unpacked

bit [3:0] [7:0] barray [3];

packed unpacked
barray[0][3] barray[0][1][6]

barray[0] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0
barray[1] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0
barray[2] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0
Indexing Mixed Arrays
•Unpacked dimensions are referenced first from the left-most to the
right-most dimension
•Packed dimensions are referenced second from the left-most dimension
to the right-most dimension
packed dimensions unpacked dimensions

logic [3:0][7:0] mixed_array [0:7] [0:7] [0:7];

mixed_array [0] [1] [2] [3] [4] = 1’b1;

unpacked indexes packed indexes


Mixed Array Example

bit [1:3] [1:6] face [1:7] [1:8]; bit [1:3] [1:6] face [1:7] [1:8];

face [a]=0; face [a][b]=0;

bit [1:3] [1:6] face [1:7] [1:8]; bit [1:3] [1:6] face [1:7] [1:8];

face [a][b][c]=0; face [a][b][c][d]=0;


Mixed Array Example
Dynamic Arrays

• Fixed-size array size is set at compile time


• Dynamic array size is set at run-time (is not known at compile time)
• Can be allocated and resized during simulation
• Declared with empty subscripts [ ] bit [7:0] stack []; // A dynamic array of 8-bit vector
int mem[], dyn[], d2[]; string names []; // A dynamic array that can contain strings
• new[] operator allocates space, passing the number of entries
dyn = new[5];
• Can also pass name of an array to copy values
dyn=new[20](dyn);
dyn=new[100];
• Mixing fixed/dynamic – only unpacked dimensions can be dynamic
reg [7:0][3:0] b_reg_array []; OK
reg [][3:0] b_reg_array2 [4:0]; Not OK
Source: Chris Spear: System Verilog for Verification
Dynamic Arrays
•When is this useful?
• Creating a random # of transactions using an array
•You don’t feel like counting the # of elements you put in an array.
bit [7:0] mask[] = ’{8’h12, 8’h23, 8’h45};
•Built-in methods
•size
$size(mask);
mask.size();
•delete
mask.delete();
• Assignment
• Between fixed-size and dynamic elements if base type is the same
• dynamic to fixed-size if current size is the same
• fixed-size to dynamic if current size is the same: new[] is called.
Source: Chris Spear: System Verilog for Verification
Dynamic Arrays

Dynamic arrays are fast and variable size is possible with a call to new ()
function.

In dynamic size array :


1.Similar to fixed size arrays but size can be given in the run time
2.Dynamic arrays can have only single dimension and it can not be packed
3.Out of bound error in dynamic arrays causes run time error.
Dynamic Arrays

Two dynamic arrays


Make array with 5 elements
Initialize

Copy a dynamic array

See both values (0 & 5)

Expand and copy

Allocate 100 new integers. Old values are lost

Delete all elements


Dynamic Arrays

// dynamic array declaration


bit [7:0] ABC[ ];
int ABC[ ]; 0 1 2 3 Indices

//memory allocation
ABC = new[4]; //dynamic array of 4 elements
0 1 2 3 Indices
//array initialization
ABC = {0,1,2,3}; 0 1 2 3 Elements

foreach(ABC[j]) ABC[j] = j;
Dynamic Arrays
// dynamic array declaration
bit [7:0] ABC[ ]; 0 1 2 3 Indices
int ABC[ ];
//memory allocation
0 1 2 3 Indices
ABC = new[4];
0 1 2 3 Elements
//array initialization
ABC = {0,1,2,3};
0 1 2 3 4 5 6 7 8 9
//Increasing the size by overriding the old values
ABC=new[10];
//Increasing the size by retaining the old values 0 1 2 3 4 5 6 7 8 9
ABC=new[10](ABC);
0 1 2 3
Dynamic Array Example
Dynamic Array Methods Example
Dynamic Arrays

How to add new items to a dynamic array ?

int array [];


array = new [10];

// This creates one more slot in the array, while keeping old contents
array = new [array.size() + 1] (array);
Dynamic Array Example
Dynamic array….. adding elements

Grow size by 1 and copy existing


elements to the new dyn array "id"

Assign value 6 to the newly added


location [index 5]
Dynamic Arrays

module dynamic_array();
dyna[ ]
integer dyna[];
initial begin
dyna=new[4]; 10
$display(dyna.size); RESULT
dyna[1]=10; 100 #4
dyna[3]=100; #8
dyna=new[8][dyna]; #0
$display(dyna.size);
dyna.delete;
$display(dyna.size);
end
endmodule
Queues
• A Queue is a variable size ordered collection of homogeneous objects (same data type).
• Provides easy sorting, searching and inserting elements
• Can add and remove elements from anywhere
• A queue can have variable length, including a length of zero.
• Can dynamically grow and shrink. No new[].
• Can copy contents of fixed or dynamic arrays to the queue
•Constant time to read, write, and insert at front & back
•Out of bounds access causes run-time error
Queues

The other advantage of having a queue is that, it provides a way to


emulate both Last In First Out (LIFO) and First In First Out (FIFO)
behavior that are required in so many ordered transactions.
At the same time a queue still allows you to access any element
randomly within the queue without any overhead just as a regular
array.
A Queue is analogous to one dimensional unpacked array that grows
and shrinks automatically.
Queues: Methods
Function Description
function int size (); Returns the number of items in the queue, 0 if empty
function void insert (input integer index, input element_t item); Inserts the given item at the specified index position
Deletes the element at the specified index, and if not
function void delete ( [input integer index] );
provided all elements will be deleted
function element_t pop_front (); Removes and returns the first element of the queue
function element_t pop_back (); Removes and returns the last element of the queue
function void push_front (input element_t item); Inserts the given element at the front of the queue
function void push_back (input element_t item); Inserts the given element at the end of the queue

Front

Back
push_front() push_back()
0 1 2 3 4 5 6 7 8 9

pop_front() pop_back()
Indices
int ABC[$]; Elements
0
ABC.push_front[5]; 5

0 1
ABC.push_front[4]; 4 5
0 1 2
ABC.push_back[8]; 4 5 8
0 1 2 3
ABC.push_front[2]; 2 4 5 8

0 1 2
var=ABC.pop_back[]; 2 4 5
0 1
var=ABC.pop_front[]; 4 5
Example of queue
Example of queue
Example of queue

string coworkers[$];
reg [7:0] address[$];
reg [7:0] j;
coworkers = {“Willy”, “Rob”};
address = {8’h3F, 8’hA5};
coworkers.insert(1, “Holger”); //{“Willy”, “Holger”, “Rob”};
address.push_back(8’h00); // {8’h3F, 8’hA5, 8’h00};
j = address.pop_front(); // {8’hA5, 8’h00}, j = 8’h3F
j = address.size(); // j = 2
address.delete();
Example of queue
Selecting subset of queue
Selecting subset of queue
Queue of classes

Create a queue that can hold values of data type "Fruit"

/Create a new class object and call it “Orange“ and push into the queue

Create another class object and call it “Apple" and push into the queue

Iterate through queue and access each class object

Simply print the whole queue, note that class


handles are printed and not class object contents
Queue of dynamic arrays
Queue of dynamic arrays

Determine what will be displayed?


`default_nettype none
module test;
string street[$] = {“Amar", “Akbar", “Anthony"};
initial begin # Street[0] = Amar
$display("Street[0] = %s", street[0]);
street.insert(2, “Ram"); # Street[2] = Ram
$display("Street[2] = %s", street[2]); # Street[2] = Akbar
street.push_front("St. Vrain");
$display("Street[2] = %s", street[2]); # pop_back = Anthony
$display("pop_back = %s", street.pop_back); # street.size = 4
$display("street.size = %d", street.size);
end
endmodule // test
Unbounded Queues Bounded Queues
•unbounded queue – queue with unlimited •bounded queue – queue with the number of
entries or queue size not specified entries limited or queue size specified
bit queue_1[$]; // queue of bits (unbound queue) byte queue_3[$:255]; // queue of byte (bounded queue
int queue_2[$]; // queue of int with 256 entries)
string queue_4[$]; // queue of strings
push_front() push_front()
push_back() push_back()

Front
Front

Back
Back
0 1 2 - - - - - - n 0 1 2 3 4 5 6 7 8 9

Length of queue n Length of queue 10


pop_front() pop_back() pop_front() pop_back()
Bounded queue declaration and accessing

0 1 2

int ABC[$:2];
0 1 2
ABC={5,7,1}; 5 7 1

0 1 2
New element
ABC.push_back(8); 5 7 1 discarded

0 1 2 Last element
ABC.push_front(8); 8 5 7 pushed out
Associative Arrays
• Suppose a processor you are modeling has a 4GB memory space.
• A fixed/packed/dynamic array will take up too much memory
• Use an associative array to model sparse memories
Standard array Associative array

All memory Unused elements


allocated, even don’t use memory
unused elements

byte assoc[byte], idx = 1;


initial begin
do begin
assoc[idx] = idx;
idx = idx << 1;
end while (idx != 0);
foreach (assoc[i])
$display("assoc[%h] = %h", i, assoc[i]);
Associative Arrays
Suppose we want to keep track of the reset values, address, etc of a bank of
configuration registers.
int address[string];

initial begin
address["ADC_REG"] = 0;
address["DAC_REG"] = 1;
address["LCD_REG"] = 2;
address["LED_REG"] = 3;
address["I2C_REG"] = 4;
$display("Address of LCD_REG is %0d“, address["LCD_REG"]);
end

# Address of LCD_REG is 2
Associative Arrays

 An associative array is the one where content is stored with a certain key.
 This is recognized by presence of data types inside square bracket.
 Associative arrays do not have storage allocated until it is used.
 The index expression is not restricted to integral expressions, but can be of any type.

Key is of type int, and data is also of type int


Key is of type string, and data is of type int
Associative Arrays
Associative arrays are generally used for sparse memories.
Associative arrays are :
1.Dynamically allocated, non-contiguous elements
2.Stored in random order.
3.Associative arrays are unpacked arrays
4.Accessed with integer, or string index, single dimension
5.Great for sparse arrays with wide ranging index
6.Array functions: exists, first, last, next, prev
Associative Arrays

Examples of associative array declarations are:


Associative Arrays

// associative array declaration Indices


int ABC[*];
Elements

//array assignment RED

ABC[RED] = 20; 20

RED GR..
ABC[GREEN] = 30;
20 30

RED GR. Bl..


ABC[BLUE] = 40;
20 30 40
Associative Array Methods Example
Associative Array Methods

Method Description
num(), size() returns the number of entries in the associative array
delete(index) removes the entry at the specified index.exa_array.delete(index)
exists(index) returns 1 if an element exists at the specified index else returns 0
first(var) assigns the value of first index to the variable var
last(var) assigns the value of last index to the variable var
next(var) assigns the value of next index to the variable var
prev(var) assigns the value of previous index to the variable var
Associative Array Methods
string s; // The index
$display("The # of array entries is %0d", address.num());
# The # of array entries is 5
if (address.exists("DAC_REG")) $display("address[DAC_REG] exists");
# address[DAC_REG] exists
if (address.first(s)) $display("First address = %0d", address[s]);
# First address = 0

if (address.last(s)) $display("Last address = %0d", address[s]);


# Last address = 4

s="LCD_REG";
if (address.next(s)) $display("next address = %0d", address[s]);
# next address = 3

address.delete("DAC_REG");
$display("The # of array entries is %0d", address.num);
# The # of array entries is 4
Associative Array Method Example
Associative Array Example
Array Methods

• Operate on any unpacked array types


• fixed size
• dynamic
• queue
• associative
• Reduction: sum, product, and, or, xor
• Locator: find, find_index, find_first,
find_first_index, find_last,
find_last_index, min, max, unique,
unique_index
• Ordering: reverse, sort, rsort, shuffle

except associative
Array Reduction Methods
•The result bit width is the same as the element bit widths
•Operate on single bit elements, get a single bit result
• Assigning to a variable of sufficient width doesn’t help.
bit one[10] = ‘{0,1,0,1,0,1,0,1,0,1};
int total;
$display(“one.sum = %0d”, one.sum); // # one.sum=1
total = one.sum;
$display(“total = %0d”, total); // # total = 1

•product() returns the product of all array elements


• and, or, xor returns the bitwise operation of all array elements
byte byte_array[2] = '{8'h35, 8'hFA};
$display("OR = %b", byte_array.or); // # OR = 11111111
$display("AND = %b", byte_array.and); // # AND = 00110000
$display("XOR = %b", byte_array.xor); // # XOR = 11001111
Example: Array Reduction Method
Picking a random element from an associative array

int aa[int] = '{0:1, 5:2, 10:4, 15:8, 20:16, 25:32, 30:64};


int idx, element, count;
element = $urandom_range(aa.size()-1);
foreach(aa[i]) begin
if (count++ == element) begin
idx = i; // Save the associative array index
break; // and quit
end
end
$display("element#%0d aa[%0d] = %0d", element, idx, aa[idx]);

Source: Chris Spear: System Verilog for Verification


Array Locator Methods
•Result returned is always a queue
•min() returns the minimum element
•max() returns the maximum element
•unique() returns all elements with unique values
•unique_index() returns the indexes of all elements with unique values

int f[6] = '{1,6,2,6,8,6};


$display("f.min = %p", f.min);
$display("f.max = %p", f.max);
$display("f.unique = %p", f.unique);
$display("f.unique_index = %p", f.unique_index);

# f.min = '{1}
# f.max = '{8}
# f.unique = '{1, 2, 6, 8}
# f.unique_index = '{0, 2, 1, 4}
Source: Chris Spear: System Verilog for Verification
Example: Array Locator Method
Array Locator Methods
• Array locator methods find* all require a with clause
•The with clause is used to identify what you want to find.
• find() returns all the elements satisfying the expression.
• find_first() returns the first element satisfying the expression.
• find_last() returns the last element satisfying the expression.
• find*_index methods return the index satisfying the expression.
int f[6] = '{1,6,2,6,8,6};
$display("f.find w/ (item >3) = %p", f.find with (item > 3));
$display("f.find_index w/ (item >3) = %p", f.find_index with (item > 3));
$display("f.find_first_index w/ (item >3) =%p", f.find_first_index with
(item >3));
$display("f.find_last_index w/ (item >3) = %p", f.find_last_index with
(item>3));
# f.find w/ (item >3) = '{6, 6, 8, 6}
# f.find_index w/ (item >3) = '{1, 3, 4, 5}
# f.find_first_index w/ (item >3) = '{1}
# f.find_last_index w/ (item >3) = '{5}
Example: Array Locator Methods
Creating the sum of an array of single bits

bit one[10] = ‘{0,1,0,1,0,1,0,1,0,1};


int total;
initial begin
// Compute the single-bit sum
total = one.sum(); // total = 1
// Compute with 32-bit signed arithimetic
total = one.sum() with (int'(item)); // total = 5
end

Source: Chris Spear: System Verilog for Verification


Array Sorting and Ordering
• Modifies the original array
•reverse() reverses the elements of the array
•sort() sorts the array in ascending order
•rsort() sorts the array in descending order
•shuffle() randomizes the order of the elements in the array.
• with clause can be used with sort or rsort
int f[6] = '{1,6,2,6,8,6};
f.reverse;
$display("f = %p", f); # f = '{6, 8, 6, 2, 6, 1}
f.sort;
$display("f = %p", f); # f = '{1, 2, 6, 6, 6, 8}
f.rsort;
$display("f = %p", f); # f = '{8, 6, 6, 6, 2, 1}
f.shuffle;
$display("f = %p", f); # f = '{6, 6, 8, 1, 2, 6}
Example: Array Ordering Method
Example: Array Ordering on Classes
Choosing a Storage Type
• Based on flexibility
• Fixed size is least flexible.
• Dynamic arrays of same type can be processed by 1 subroutine
• Queues of same type can be processed by 1 subroutine

•Based on memory usage


• Use 2-state elements when possible
• Choose multiple of 32-bit data width
• Used packed if data width is not multiple of 32-bits
• Fixed size and dynamic arrays are most memory efficient
• new[] is an expensive operation
•Widely spaced indices: associative array
Choosing a Storage Type

• Based on speed
• Any element in fixed size/dynamic array has = access time
• Inserting/removing elements in queue depends on location
• Accessing associative arrays is slowest

• Choosing the best data structure


• Network packets: Fixed size or dynamic array
• Scoreboard of expected values: Queue or possibly associative
• Modeling > 1M entry memories: 2-state packed associative
• Translating opcode names to opcode values: associative
Choosing a Storage Type
Static Array Dynamic Array
Size should be known at compilation time. No need of size information at compile time.
Time require to access any element is less. To set the size or resize, the size should be provided at runtime.
If not all elements used by the application, then memory Performance to access elements is same as Static arrays.
is wasted. Good for contagious data.
Not good for sparse memory or when the size changes. Memory usage is very good, as the size can be changed dynamically.
Good for contagious data.
Associative Array Queues
No need of size information at compile time. No need of size information at compile time.
Time require to access an element increases with size of Performance to access elements is same as Static arrays.
the array. User doesn't need to provide size information to change the size. It is
Compact memory usage for sparse arrays. automatically resized.
User don't need to keep track of size. It is automatically Rich set of inbuilt methods for Manipulating and analyzing the content.
resized. Useful in self-checking modules. Very easy to work with out of order
Good inbuilt methods for Manipulating and analyzing transactions.
the content. Inbuilt methods for sum of elements, sorting all the elements.
Searching for elements is very easy even with complex expressions.
Useful to model FIFO or LIFO.
Choosing a Storage Type

Manipulating
Array type Memory Performance / Analyzing
Capability
Fixed OK Good Ok
Associative Good OK Ok
Dynamic Good Good Ok
Queue Good Good Very Good
User-Defined Data Types

Class
Enumerations
Struct
Union
Typedef
User-Defined Data Types

Enumeration types – both local and in typedefs


Strict type checking and typecast
Better modeling style
Easier to read and maintain
State encoding – via language (not via embedded pragmas or tool scripts).
Ease of debugging and better waveform display
New types with typedef

In complex testbenches some variable declarations might have a


longer data-type specification or require to be used in multiple
places in the testbench.
In such cases we can use a typedef to give a user-defined name
to an existing data type. The new data-type can then be used
throughout the code and hence avoids the need to edit in
multiple places if required.
Creating new types with typedef
• Useful if you have a common bit width or type
Example: Create a unsigned 2-state byte
typedef bit [7:0] ubyte_t;

• Useful for avoiding bus width errors. For example, if all the busses in
your system are 13-bits wide define it.
typedef logic [12:0] global_bus_t;

•Usage:
ubyte_t my_data
global_bus_t my_bus;
typedef : Example
typedef : Example
Structure
A structure can contain elements of different data types which can be
referenced as a whole or individually by their names.
Array: elements of same data type
Structure: elements of different data type
Normal arrays -> a collection
of variables of same data type

Structures -> a collection of


variables of different data types
Creating User-Defined Structures
• A structure is a collection of variables and/or constants that can be accessed
separately or as a whole
•Why?
• Great for enumerating system resources
• Allows grouping of data
typedef struct {
reg [7:0] data_in;
reg [3:0] address;
} mem_bus;
mem_bus my_mem_bus = ‘{8’hA5, 4’hC};
initial begin
my_mem_bus.data_in = 8'h5A;
my_mem_bus.address = 4'h3;
end
SystemVerilog
Verilog Typedef struct {
module fifo ( bit [7:0] src;
input clk, bit [7:0] dst;
input rstp, bit [31:0] data; C-like struct.
input [7:0] din_src, } packet_t;
input [7:0] din_data, module fifo ( Similar to record in VHDL.
input [31:0] din_data, input clk,
Well proven data structure
input readp, input rstp,
abstraction technique
input writep, input packet_t din,
output reg [7:0] dout_src, input readp, Cuts down number of lines
output reg [7:0] dout_dst, input writep,
output reg [31:0] dout_data, input packet_t dout,
output reg emptyp, output logic emptyp,
output reg fullp output logic fullp
); );
…. ….
Structure: Example
Un-packed Structure
A structure is unpacked by default and can be defined using the struct keyword
and a list of member declarations can be provided within the curly brackets
followed by the name of the structure.

Packed Structure
A packed structure is a mechanism for subdividing a vector into fields that can
be accessed as members and are packed together in memory without gaps. The
first member in the structure is the most significant and subsequent members
follow in decreasing order of significance. A structure is declared packed using
the packed keyword which by default is unsigned.
Un-Packed Structure
Packed Structure
Structure: Example
`default_nettype none
Define a user defined 7-bit type Encapsulate module test;
the fields of the following packet in a structure typedef bit [6:0] bit7_t;
typedef struct {
using your new type bit7_t header;
27 21 20 14 13 7 6 0 bit7_t cmd;
bit7_t data;
header cmd data crc
bit7_t crc;
} packet;

Assign the header to 7’hCA; packet my_packet;

initial begin
my_packet.header = 7'hCA;
end
endmodule
Classes

 Class is a collection of data and subroutines which operate on the data.


 Data in the class is referred as the properties and subroutines as methods.
 Class can be declared using the class and endclass keywords
Union
Unions like structure contain members whose individual data types may differ
from one another. However the members that compose a union all share the
same storage area.
A union allows us to treat the same space in memory as a number of different
variables.
0………....7……15…….23……3
That is a Union offers a
1Bit [0:7] c XXXXXXXXXXXXX
way for a section of
Byte b XXXXXXXXXXXXX memory to be treated as
Int a a variable of one type on
one occasion and as a
0………....7……15…….23……31 different variable of a
Bit [0:7] c / Byte b/ Int a different type on another
occasion.
Packages
•Where to put all this stuff?In a package!
•Packages reduce the need for `include
package ABC;
parameter int abc_data_width = 32;
typedef logic [abc_data_width-1:0] abc_data_t;
parameter time timeout = 100ns;
string message = "ABC done";
endpackage // ABC
Importing Packages
•Recall that package ABC defined abc_data_width, abc_data_t,
timeout, and message
module test;
import ABC::*;
abc_data_t data;
string message = "Test timed out";
initial begin
#(timeout);
$display("Timeout - %s", message);
$finish;
end
endmodule

•Use ABC::message to use the message variable in package ABC.


Packages Example
Packages Example

In order to use value from the package, the package name should be
exclusively mentioned using :: operator.
Packages Example

Refer to types that have been declared in a


package. Package has to be included in
compilation but not necessarily "imported"
Packages Example

Explicit TRUE from my_pkg should


be assigned to val

TRUE from current scope will be


assigned to val
Type Casting

Static Dynamic
Casting Casting

A data type can be changed by SV provides the $cast system task to assign values to variables
using a cast ( ' ) operation. that might not ordinarily be valid because of differing data type.
Example: $cast can be called as either a task or a function.
int’(2.0 * 3.0) Example:
shortint'{{8’hFA,8’hCE}} function int $cast( singular dest_var, singular source_exp );
task $cast( singular dest_var, singular source_exp );
typedef enum { red, green, blue, yellow, white, black } Colors;
Colors col;
$cast( col, 2 + 3 );
Type Conversion
Static cast converts between 2 types No bounds checking
int i;
real r;
byte b;

initial begin
i=int'(10.0-0.1);
$display("i = 0d%0d", i); # i = 0d10
r=real'(42);
$display("r = %f", r); # r = 42.000000
b=byte'(256);
$display("b = 0d%0d", b); # b = 0d0
end

Source: Chris Spear: System Verilog for Verification


Streaming Operators – unpacked to packed
• >> right of the assignment converts unpacked arrays into packed from left to right
• << right of the assignment converts unpacked arrays into packed from right to left
int h;
bit [7:0] j[4] = '{8'hA, 8'hB, 8'hC, 8'hD};
$display("j= %p", j); # j= '{10, 11, 12, 13}
h=j; ...Cannot assign an unpacked type to a packed type
h={ >> {j}};
$display(“h= 0x%0h", h); # h= 0x0a0b0c0d
h={ << {j}};
$display(“h= 0x%0h", h); # i= 0xb030d050
h={ << byte {j}};
$display(“h= 0x%0h", h); # h= 0x0d0c0b0a

Source: Chris Spear: System Verilog for Verification


Streaming Operators – packed to unpacked

• >> left of the assignment converts packed arrays into unpacked from left to right
• << left of the assignment converts packed arrays into unpacked from right to left
int k=32'h89ABCDEF;
byte b1,b2,b3,b4;
b1=k[0];
$display("b1= 0x%0h", b1); # b1= 0x01
{>>{b1,b2,b3,b4}}=k;
$display("b1= 0x%0h", b1); # b1= 0x89
{<<{b1,b2,b3,b4}}=k;
$display("b1= 0x%0h", b1); # b1= 0xF7

Source: Chris Spear: System Verilog for Verification


Why do we need enumeration?
Define new data types as enumerated types. A type name can be given so that the same type can be
used in many places.
Example: typedef enum {NO, YES} boolean;
boolean my_var; // named type

To make code more simple and readable.


Enumerations
•Create list of constant names
enum {CFG, ADC_REG, CTRL} reg_e;
enum {CFG=5, ADC_REG=6, CTRL} reg2_e;

•Easier than:
localparam CFG = 2’b00,
ADC_REG = 2’b01,
CTRL = 2’b10;
•Easier to add/delete registers
•Register name is not visible in waveform
• Usage
bit [1:0] my_reg;
my_reg = CFG;

Source: Chris Spear: System Verilog for Verification


Enumerations
By default, the first name in the enumerated list gets the value 0 and the following
names get incremental values like 1,2 etc.
enum {RED,YELLOW, GREEN} color_1; // int type; RED = 0,YELLOW = 1, GREEN = 2
enum bit[1:0] {RED,YELLOW, GREEN} color_2; // bit type; RED

enum {RED=3,YELLOW, GREEN} color_3; // RED = 3,YELLOW = 4, GREEN = 5


enum {RED = 4,YELLOW = 9, GREEN} color_4; // RED = 4,YELLOW = 9, GREEN = 10 (automatically assigned)
enum {RED = 2,YELLOW, GREEN = 3} color_5; // Error :YELLOW and GREEN are both assigned 3
enum bit[0:0] {RED,YELLOW, GREEN} color_6; // Error: minimum 2 bits are required

Enumeration name can not start with number.


enum {1WAY, 2TIMES, SIXPACK=6} e_formula; // Compilation error on 1WAY, 2TIMES

enum {ONEWAY, TIMES2, SIXPACK=6} e_formula; // Correct way -> change 1 to ONE, 2 to TWO, etc
Enumerations

A range of enumeration elements can be specified automatically, via the syntax.


Below example defines the enumerated type INS.
Example: typedef enum { add=10, sub[5], jmp[6:8] } INS;

assigns the number 10 creates the enumerated named constants


to the enumerated jmp6, jmp7, and jmp8 and assigns them the
named constant add values 16 through 18, respt.
It creates the enumerated named constants
sub0, sub1, sub2, sub3, and sub4 and assigns
them the values 11...15, respt.
Enumerations
How to define a new enumerated data type
Enumerated Types
•Creates user defined type of the enumeration
•Value of register is visible in waveform
typedef enum {CFG, ADC_REG, CTRL} reg_e;
reg_e my_reg;
initial begin
my_reg = CFG;
#30ns;
my_reg = ADC_REG;
#10ns;
my_reg = CTRL;
#10ns;
my_reg = CFG;
end

Source: Chris Spear: System Verilog for Verification


Enumerated-Type Methods

first() function enum first(); Returns the value of the first member of the enumeration
last() function enum last(); Returns the value of the last member of the enumeration
Returns the Nth next enumeration value starting from the
next() function enum next (int unsigned N = 1);
current value of the given variable
Returns the Nth previous enumeration value starting from the
prev() function enum prev (int unsigned N = 1);
current value of the given variable
num() function int num(); Returns the number of elements in the given enumeration
name() function string name(); Returns the string representation of the given enumeration value
Example: Enumerated Types
Example: Enumerated Types
Example: Enumerated Types
Enumerated-Type Methods

typedef enum {ST0, ST1, ST2} state_e;


state_e state;
initial begin # first = 0x0
$display("first = 0x%0h", state.first); # next(1) = 0x1
$display("next(1) = 0x%0h", state.next(1)); # prev(1) = 0x2
$display("prev(1) = 0x%0h", state.prev(1)); # num = 0x3
$display("num = 0x%0h", state.num); # name = ST0
$display("name = %s", state.name); # last (hex) = 0x2
$display("last (hex) = 0x%0h", state.last); # last (string)=ST2
$display("last (string)=%s", state.last);
$finish;
end

Source: Chris Spear: System Verilog for Verification


Stepping through all enumerated members

typedef enum {RED, BLUE, GREEN} color_e;


for (color_e color=color.first; color!=color.last; color= color.next)
$display("Color = %0d/%s", color, color.name);

# Color = 0/RED
# Color = 1/BLUE
typedef enum {RED, BLUE, GREEN} color_e;
color_e color;
color = color.first;
do
begin
$display("Color = %0d/%s", color, color.name());
color = color.next; # Color = 0/RED
end # Color = 1/BLUE
while (color != color.first); # Color = 2/GREEN
Example of usage in testbench
module test ();
reg clk, reset;
typedef enum {CFG, ADC_REG, CTRL} reg_e;
reg_e my_reg;
initial begin
clk = 'b0;
forever #500 clk = ~clk;
end
initial begin
reset = 1'b0; #1000ns;
@(negedge clk); reset = 1'b1; my_reg = CFG;
@(negedge clk); my_reg = my_reg.next;
@(negedge clk); my_reg = my_reg.next;
@(negedge clk); my_reg = my_reg.next;
end
config_reg config_reg(.address(my_reg));
endmodule

Source: Chris Spear: System Verilog for Verification


Example of usage in testbench

Source: Chris Spear: System Verilog for Verification


Enumerated Types in RTL
 Example:
typedef enum {ST0, ST1, ST2} state_e;
state_e current_state, next_state;

 Why? Easier than:


localparam ST0 = 2’b00, ST1 = 2’b01, ST2 = 2’b10;
reg [191:0] ASCII_current_state, ASCII_next_state;
case (current_state)
ST0: ASCII_current_state = “ST0";
ST1: ASCII_current_state = “ST1";
ST2: ASCII_current_state = “ST2";
endcase

Source: Chris Spear: System Verilog for Verification


State Machine using Enumerations
module enum_type (input wire clk, input wire reset);
enum {ST0, ST1, ST2} state_e;
reg [1:0] current_state, next_state;
always @(posedge clk or negedge reset) begin
if (!reset)
current_state <= #1 ST0;
else
current_state <= #1 next_state;
end
always @* begin
next_state = ST0;
case (current_state)
ST0: next_state = ST1;
ST1: next_state = ST2;
ST2: next_state = ST0;
endcase
end
endmodule
Source: Chris Spear: System Verilog for Verification
Simulation of State Machine

Source: Chris Spear: System Verilog for Verification


State Machine using Enumerated Types
module enum_type (input wire clk, input wire reset);
typedef enum {ST0, ST1, ST2} state_e;
state_e current_state, next_state;
always @(posedge clk or negedge reset) begin
if (!reset)
current_state <= #1 ST0;
else
current_state <= #1 next_state;
end
always @* begin
next_state = ST0;
case (current_state)
ST0: next_state = ST1;
ST1: next_state = ST2;
ST2: next_state = ST0;
endcase // case (current_state)
end
endmodule
Source: Chris Spear: System Verilog for Verification
Simulation of State Machine

Source: Chris Spear: System Verilog for Verification


Base Type of Enumerated Types
Replace
typedef enum {ST0, ST1, ST2} state_t;
with
typedef enum reg [1:0] {ST0, ST1, ST2} state_t;

Source: Chris Spear: System Verilog for Verification


Converting to/from enum types
From enum type to non-enum type with simple assignment

typedef enum {Add, Sub, Not_A, ReductionOR} opcode_e;


opcode_e opcode;
int i;
i = Not_A;
$display("i=%0d", i);

# i=2

Source: Chris Spear: System Verilog for Verification


Converting to/from enum types
From non-enum type to enum type requires static cast or $cast

i=3;
if (!$cast(opcode,i))
$display("Cast failed for i=%0d", i);
$display("opcode=%s", opcode); # opcode=ReductionOR
i=4;
if (!$cast(opcode,i))
$display("Cast failed for i=%0d", i); # Cast failed for i=4
$display("opcode=%s", opcode); # opcode=ReductionOR
opcode = opcode_e'(i);
$display("opcode=%s", opcode); # opcode=4

Source: Chris Spear: System Verilog for Verification


Strings
Why?
 Much simpler string manipulation
 No more packing characters into a reg variable

string s;
s=“AMI Semiconductor”;
$display(s.toupper()); # AMI SEMICONDUCTOR
$display(s.substr(3,7)); # Semi

s = {"ON ", s.substr(s.len()-13, s.len()-1)};


$display(s); # ON Semiconductor
s={s, “ 2008”};
$display(s); # ON Semiconductor 2008
Strings
The string data type is an ordered collection of characters.
string variable_name [= initial_value];
Strings
Equality Str1==Str2
Inequality Str1!=Str2
Comparison Str1 < Str2 Returns 1 if the two strings are equal and 0 if they
Str1 <= Str2 are not.
Str1 > Str2 Both operands can be expressions of string type.
Str1 >= Str2 OR one can be an expression of string type and the
other can be a string literal, which shall be implicitly
converted to a string type.
Concatenation {Str1, Str2, ….,Strn} All the strings will be concatenated into one
resultant string
Replication {multiplier {Str} } Replicates the string N number of times, where N is
specified by the multiplier
Indexing Str [index] Returns a byte, the ASCII code at the given index. If
given an index out of range returns 0.
Methods Str.method(….) The dot(.) operator is used to call string functions
Basic String Methods
Usage Definition Comments
str.len() function int len() Returns the number of characters in the string
Replaces the i th character in the string with the
str.putc() function void putc (int i, byte c);
given character
str.getc() function byte getc (int i); Returns the ASCII code of the i th character in str
Returns a string with characters in str converted
str.tolower() function string tolower();
to lowercase
Compares str and s, as in the ANSI C stcmp
str.compare(s) function int compare (string s);
function
Compares str and s, like the ANSI C strcmp
str.icompare(s) function int icompare (string s);
function
Returns a new string that is a substring formed
str.substr (i, j) function string substr (int i, int j);
by characters in position i through j of str
String Conversion Methods
Returns the integer corresponding to the
str.atoi() function integer atoi();
ASCII decimal representation in str
str.atohex() function integer atohex(); Interprets the string as hexadecimal
str.atooct() function integer atooct(); Interprets the string as octal
str.atobin() function integer atobin(); Interprets the string as binary
Returns the real number corresponding to the ASCII
str.atoreal() function real atoreal();
decimal representation in str
str.itoa(i) function void itoa (integer i); Stores the ASCII decimal representation of i into str
str.hextoa(i) function void hextoa (integer i); Stores the ASCII hexadec representation of i into str
str.octtoa(i) function void octtoa (integer i); Stores the ASCII octal representation of i into str
str.bintoa(i) function void bintoa (integer i); Stores the ASCII binary representation of i into str
str.realtoa(r) function void realtoa (real r); Stores the ASCII real representation of r into str
String Operators Example
String Methods Example
Time Units and Precision
•For Verilog 1995/2001 `timescale determines timescale/precision
•Applies for files compiled after `timescale is encountered
•SystemVerilog introduces the timeunit and timeprecision
declarations
module test;
timeunit 1ns;
timeprecision 1ps;
endmodule

•Because these are local to a module must be declared in every module that
has delay statements.
•Overrides `timescale
Time Literals
• For Verilog 1995/2001 `timescale determined the units of #
#5; // ns, ps, fs ???

• SystemVerilog allows specification of units.


Units: fs ps ns us ms s
•Use the Verilog 2001 $timeformat to specify how time is displayed
• Syntax is $timeformat(units_number, precision_number,
suffix_string, minimum_field_width) ;
timeunit 1ns; timeprecision 1ps;
initial begin
$timeformat(-9, 3, “ns”, 8);
#1 $display(“%t”, $realtime); // # 1.000ns
#2ns $display(“%t”, $realtime); // # 3.000ns
#0.1ns $display(“%t”, $realtime); // # 3.100ns
#41ps $display(“%t”, $realtime); // # 3.141ns
end
Time and Variables
•Time values are scaled according to the current timeunit and precision
•time type is a 64-bit integer
timeunit 1ns;
timeprecision 100ps;
initial begin
realtime rtdelay = 849ps;
time tdelay = 800ps;
$timeformat(-12, 0, "ps", 5);
#rtdelay;
$display("@%0t, rtdelay = %t, %f", $realtime, rtdelay, rtdelay);
#tdelay;
$display("@%0t, tdelay = %t, %0d", $realtime, tdelay, tdelay);
end

# @800ps, rtdelay = 800ps, 0.800000


# @1800ps, tdelay = 1000ps, 1
$time vs $realtime
•System task $time returns an integer scaled to the time unit
•$realtime returns a real number scaled to the time precision
timeunit 1ns; timeprecision 1ps;
initial begin
$timeformat(-9, 3, “ns”, 8);
#1 $display(“%t”, $realtime); # 1.000ns
#2ns $display(“%t”, $realtime); # 3.000ns
#0.1ns $display(“%t”, $realtime); # 3.100ns
#41ps $display(“%t”, $realtime); # 3.141ns
end
initial begin
#1 $display(“%t”, $time); # 1.000ns
#2ns $display(“%t”, $time); # 3.000ns
#0.1ns $display(“%t”, $time); # 3.000ns
#41ps $display(“%t”, $time); # 3.000ns
end
Where to write functional code?

Continuous assignments
 assign e.g. assign b=a;
 Only single statement is allowed
Procedural assignment Blocks (within begin…..end)
 always, always_comb, always_latch, always_if
 initial
 final
 task
 function
Write all functional code in SV in any of the above blocks
Where to write functional code?

A procedural statement can be added in system verilog using :


 initial // enable this statement at the beginning of simulation
and execute it only once
 final // do this statement once at the end of simulation
 always, always_comb, always_latch, always_ff // loop forever
 task // do these statements whenever the task is called
 function // do these statements whenever the function is called
and return a value
SystemVerilog Design – Logic Modeling-Key points
Better port mapping: .name, .*
With consistent coding styles significantly simplifies
hierarchical descriptions.
Verilog RTL – only always block
Same construct for combinatorial & sequential
Logic inference by sensitivity list.
One of the top 10 error prone usages.
SV: Enhanced Modeling via dedicated hardware blocks.
always_comb
always_ff
always_latch
What logic is being modeled?

Modeling combinatorial logic? Modeling sequential logic?


Use always_comb Use always_iff
What logic is being modeled?

Modeling Latch?
Use always_latch

Reduces Synthesis-Simulation
discrepancies

Language captures design intent


(not pragmas, tool settings)
let Construct
let construct can be used for text replacement and has a local scope.
Blocking & Non-blocking Assignments
Blocking Assignments: =
 All statements within an always block are executed sequentially every time the block is evaluated.
 The always block is evaluated either in every clock (sequential logic) or when a charge happens in
the sensitivity list (combinational logic)
 RHS of first expression is evaluated, assigned it to the LHS then goto the next expression and do
the same.
 Order of expression matters.
Non-Blocking Assignments: <=
 In simulation, all statements within an always block are executed in parallel every time the block is
evaluated.
 All RHS expressions are evaluated using the values from previous time slot and then LHS assigned
simultaneously exiting the time slot. That means in the non-blocking assignment, all the
assignments will occur at the same time (during the end of simulation timestamp),
 Order of expression does not matter
Blocking Assignments

Values are
immediately
assigned
Non-Blocking Assignments

Values are
assigned in
previous clock
Blocking & Non-blocking Assignments: Other Points
Statement are allowed in both Verilog
and SystemVerilog SystemVerilog also allows a time unit to be
#2 b = a; specified in the assignment statement, as follows:
b = #2 a; #2ns b = a;
b <= #2 a; b = #2ns a;
b <= a; b <= #2ns a;
@c b = a;
b = @c a;
b <= @c a;

Its illegal to make non blocking assignments to automatic variables.


If size of the left hand size is smaller than right hand size information will be lost.
Do not mix blocking and non-blocking assignments in
the same always/initial/final/task/function block
Example: Blocking Assignments
Example: Blocking Assignments
Example: Non-blocking Assignments
Example: Non-blocking Assignments
Flow Control and Looping Constructs

SystemVerilog has the following types of control flow within a process:


 Selection, loops, and jumps
 Task and function calls
 Sequential and parallel blocks
 Timing control
Flow Control and Looping Constructs
•post increment (i++), pre increment (++i)
•post decrement (i--), pre decrement (--i)
•Loop enhancements
•locally defined index (for (int i=0;....) )
•continue
•break
file = $fopen(“commands.txt”, “r”);
while (!$feof(file)) begin
c = $fscanf(file, “%s”, cmd);
case (cmd)
“” : continue;
“done”: break;
........
endcase
end
$fclose(file);
Flow Control and Looping Constructs
•Verilog 1995 supported while loops
•A while loop might never execute
while (count < 128) begin
$display(“Count = %d”, count);
count = count + 1;
end

•SystemVerilog adds a do..while loop (similar to C)


•A do..while loop always executes at least once
•Control of the loop is tested at the end of each pass of the loop
do begin
$display(“Count = %d”, count);
count = count + 1;
end while (count < 128);
Flow Control and Looping Constructs

forever Runs the given set of statements forever


repeat Repeats the given set of statements for a given number of times
while Repeats the given set of statments as long as given condition is true
for Similar to while loop, but more condense and popular form
Repeats the given set of statements atleast once, and then loops as long as
do while
condition is true
foreach Used mainly to iterate through all elements in an array

Use these statements in any procedural blocks i.e. in any of the following
always, initial, final, task, function
if (condition1)
begin
if statement
<statement>
<statement>
end
else if (condition2)
begin
<statement>
<statement>
end
else if (condition3)
begin
<statement>
<statement>
end
else
begin
<statement>
<statement>
end
if statement
SystemVerilog introduced the following if else constructs for violation checks.
unique_if unique0_if priority_if

unique_if evaluates all the conditions parallel and priority_if evaluates all conditions in
does the following: sequential order and a violation is reported
 Report an error when none of the if conditions when none of the conditions are true or if
match unless there is an explicit else. there’s no else clause to the final if construct.
 Report an error when there is more than 1
match in the if else conditions.
unique if
unique if
priority if
repeat
repeat
while
do begin while (condition) begin
<statement> <statement>
<statement> <statement>
end while (condition) end

body
Condition

True True False

Condition
body
False
while
while
do while
do while
for
for (int i=0; i<10; i++) begin
<statement>
<statement>
end
for
for
foreach

foreach (array_name) begin


<statement>
<statement>
end
foreach
forever
Break and Continue

loop construct (<expression>) begin


<statement>
<statement>
break;
<statement>
<statement>
continue;
<statement>
<statement>
end
<statement>
<statement>
Break
The execution of a break statement leads to the end of the loop.
break shall be used in all the loop constructs (while, do-while, foreach, for, repeat and forever).
Continue
Case Statements
case (statement)
val_0: begin
<statement>
A case item can now be a range of values.
<statement>
end
case (address) inside
val_1: begin
[0:16’h1FFF]: $display(“Adddress in ROM”);
<statement>
[16’h2000:16’h7FFF]: $display(“Adddress in SRAM”);
<statement>
[16’h8000:16’hFFFF]: $display(“Adddress in DRAM”);
end
endcase
val_2: begin
<statement>
<statement>
end
default: begin
<statement>
<statement>
end
endcase
Unique Case

 unique and unique0 are used to perform violation checks.


 These statements ensure that there is no overlapping case items and hence can
be evaluated in parallel. If there are overlapping case items, then a violation is
reported.
 If more than one case item is found to match the given expression, then a
violation is reported and the first matching expression is executed.
 If no case item is found to match the given expression, then a violation is
reported only for unique.
 unique0 does not report a violation if no items match the expression.
Unique Case
Unique Case
Priority Case
Example
Final Block
 The final block is like an initial block, defining a procedural block of statements.
 It occurs at the end of simulation time and executes without delays.
 A final block is typically used to display statistical information about the simulation.
 The only statements allowed inside a final block are those permitted inside a function
declaration. This guarantees that they execute within a single simulation cycle.
 Unlike an initial block, the final block does not execute as a separate process; instead, it
executes in zero time, the same as a function call.
 A final block executes when simulation ends due to an explicit or implicit call to $finish.
Disable Statement
The disable can also be used to continue or break out of a loop.
The disable is also allowed to disable a named block, which does not contain the disable statement.
 If the block is currently executing, this causes control to jump to the statement immediately
after the block.
 If the block is a loop body, it acts like a continue. If the block is not currently executing, the
disable has no effect.
SystemVerilog has return from a task, but disable is also supported. If disable is applied to a named
task, all current executions of the task are disabled.
module ...
always always1: begin ... t1: task1( ); ... end
...
endmodule
always begin
...
disable u1.always1.t1;// exit task1, which was called from always1
….
end
Array Operations Example
module test;
bit [11:0] my_array [4];
Write the SystemVerilog code to:
1) Declare a 2-state array, my_array, that holds four 12-bit values initial begin
2) initialize my_array so that: my_array = '{12'h010, 12'h020, 12‘hABC, 12'hDEF};
1) my_array[0] = 12’h010
for (int i=0;i<$size(my_array); i++) begin
2) my_array[1] = 12’h020,
$display("Bits [5:4] of %b is %b", my_array[i], my_array[i][5:4]);
3) my_array[2] = 12’hABC,
end
4) my_array[3] = 12’hDEF;
3) Traverse my_array and print out bits [5:4] of each 12-bit element foreach (my_array[i]) begin
1) Using a for loop $display("Bits [5:4] of %b is %b", my_array[i], my_array[i][5:4]);
2) Using a foreach loop end

end
endmodule
Event Control
Any change in a variable or net can be detected using the @ event control.
A change of any bits of a multi-bit variable shall trigger the event control.
SystemVerilog adds an iff qualifier to the @ event control.
always block will get executed at any change in variables
value within the always block
Named blocks with being-end

module my_test_mod(); always begin: my_main_always_block


initial begin: init_block_1 case(my_var)
if (condition1) begin:cond_1_block 1: <statement>
<statement> 2: <statement>
<statement> 3: begin:
end: cond_1_block <statement>
end: init_block_1 <statement>
end
always begin 4: <statement>
<statement> default: <statement>
<statement> endcase
end end: my_main_always_block
endmodule: my_test_mod
Functions in SystemVerilog

Function is a mechanism of reusing the code.


function return_data_type function_name (argument_list);
Argument list should specify the direction of data flow Input, Output, Inout and Ref.
Return value can be of type void if nothing is returned from the function
Functions –Key Points

Static Function:
Static functions share the same storage space for all function calls.

Automatic Function:
Automatic functions allocate unique, stacked storage for each
function call.
Functions –Key Points
 Allowed to declare an automatic variable in static functions
 Allowed to declare the static variable in automatic functions
 Have more capabilities for declaring function ports
 Passing values by reference, value, names, and position
 Allowed to assign default argument values
 Allowed to have function output and inout ports
 The default direction of argument is input if no direction has been specified.
 Default arguments type is logic if no type has been specified.
Functions –Key Points
 Function can not consume simulation time.
 Have multiple statements within a function without requiring a
begin…end or fork…join block
 Function cannot have controlled statements like @, #, fork join or
wait.
 Function can not start a task since tasks are allowed to consume
simulation time.
 Possible to return from the function before reaching the end of the
function
Functions in SystemVerilog

Function arguments in parentheses Function arguments in declarations and


mentioning directions
ANSI-C Style Declaration

This function returns value of type "byte",


and accepts two arguments “a" and “b”.
Return variable of the same name as
function is implicitly declared and hence
"sum" can be directly assigned without
having to declare a separate return variable

Instead of assigning to "mul", the


computed value can be returned
using "return" keyword
How to pass arguments?

Passing arguments to functions and tasks:


1. argument pass by value
2. argument pass by reference
3. argument pass by position
4. argument pass by name
How to pass arguments by value?

Function is called with "pass by value"


which is the default mode

Even if value of “a” is changed inside the


function, it is not reflected here

This function accepts arguments in "pass


by value" mode and hence copies
whatever arguments it gets into this local
variable called "a".

Any change to this local variable is not


reflected in the main variable declared
above within the initial block
How to pass arguments by value?
How to pass arguments by reference?
How to pass arguments by reference?

Simulation Log Synopsys

Simulation Log Cadence


arguments by reference with ‘const’
How to pass arguments by position?
How to pass arguments by name?
Tasks, Functions, and Void Functions
•In Verilog 2001 functions must specify a return value
function int func_2001(input integer new_int);
func_2001 = new_int;
endfunction

•System Verilog defines the void function


•For functions that have no return value the return is void
function void func_sv(input int new_int);
$display(“new_int = %d”, new_int);
endfunction

•Can ignore a tasks return value


void’(func_2001(1));
‘task’ in SystemVerilog

Can consume simulation time


task task_name(argument_list)
Argument list should specify direction of data flow as input, output, inout or ref.
No return value (use output if you want to return something)
task : Key Points

Static tasks
Static tasks share the same storage space for all task calls.

Automatic tasks
Automatic tasks allocate unique, stacked storage for each task call
task : Key Points
 Allowed to declare an automatic variable in a static task
 Allowed to declare a static variable in an automatic task
 Have more capabilities for declaring task ports
 Have multiple statements within task without requiring a begin…end or
fork…join block
 Possible to return from the task before reaching the end of the task
 Passing values by reference, value, names, and position
 Allowed to assign default argument values
 The default direction of argument is input if no direction has been specified
 Default arguments type is logic if no type has been specified
Comparison between ‘function’ and ‘task’

Function Task
Cannot have time-controlling Can contain time-controlling
statements/delay, and hence executes statements/delay and may only
in the same simulation time unit complete at some other time
Cannot enable a task Can enable other tasks and functions
Should have atleast one input
Can have zero or more arguments of
argument and cannot have output or
any type
inout arguments
Cannot return a value, but can achieve
Can return only a single value
the same effect using output arguments
Routine Arguments
•In Verilog 2001
•begin/end required
•input/output/inoutto tasks/functions copied to a local variable.
•Arrays could not be passed
•SystemVerilog
•begin/end not required
•Argument to tasks/functions can be passed by reference.
• Arrays can be passed.
function automatic void my_func(ref int func_array[1023:0]);
$display("func_array[0] = %h", func_array[0]);
endfunction
or
function automatic void my_func(const ref int func_array[1023:0]);
$display("func_array[0] = %h", func_array[0]);
endfunction
Default value for arguments
•Suppose we have the following task which is called 100’s of times
task compare(input bit [7:0] expected, input logic [7:0] actual)
if (expected !== actual)
$display(“Error: Expect of %h != actual of %h”, expected, actual);
endtask

•Now we want to pass in a string of what is being compared.


•Use default values
task compare(input bit [7:0] expected, input logic [7:0] actual,
input string compared = "NULL");
if (expected !== actual)
$display("Error: For %s expect of %0h != actual of %0h",
compared, expected, actual);
endtask
# Error: For NULL expect of 8 != actual of 5
compare(8'h8, 8'h5); # Error: For my_reg expect of 8 != 5
compare(8'h8, 8'h5, "my_reg");
Passing arguments by name

•Just like modules, specify task/function arguments by name instead of position.


•Only pass those arguments that don’t match default
task many(input int a=1, b=2, c=3, d=4);
$display(“%0d %0d %0d %0d”, a, b, c, d);
endtask

initial begin
many(.d(6),.c(7),.b(8),.a(9)); # 9 8 7 6
many(); # 1 2 3 4
many (.c(5)); # 1 2 5 4
many(, 6, .d(8));
end # 1 6 3 8
Task : Example

Task arguments in parentheses Task arguments in declarations and mentioning directions


Task : Example

The keyword automatic will make the task re-


entrant, otherwise it will be static by default.
If a task is static, then all its member variables
will be shared across different invocations of
the same task that has been launched to run
concurrently.
Returning from a Routine
•With Verilog-2001 no way to end a task/function early
•SystemVerilog adds the return statement
task automatic my_task(ref int my_array[]);
if (my_array.size() == 0)
return;
$display("my_array = %p", my_array);
endtask

•Value returned by a function can be specified by return


function [8:0] increment(input [8:0] address);
return ++address; // Equivalent
// increment = ++address; // Equivalent
endfunction
Returning from a Routine: Example
Task : Example

apply_reset() task can be re-used and it hides


the details of what signals and what time
intervals it is being asserted
Local Data Storage
•With Verilog-1995 space for a task is allocated once.
•All calls to a task use this single memory space.
•Concurrent calls to a task will clobber each other.
int new_address1, new_address2;
initial begin
# new_address1 = 6
my_task(5, new_address1);
$display("new_address1 = %0d", new_address1);
end # new_address2 = 6
initial begin
my_task(6, new_address2);
$display("new_address2 = %0d", new_address2);
end
task my_task(input int address, output int new_address);
#5ns;
new_address = address;
endtask // my_task
Local Data Storage
•With Verilog 2001 memory space can be allocated for each task call
•Deallocated after each task call
•Use the automatic keyword
int new_address1, new_address2;
initial begin
my_task(5, new_address1); # new_address1 = 5
$display("new_address1 = %0d", new_address1);
end
initial begin
my_task(6, new_address2);
# new_address2
$display("new_address2 = %0d", new_address2); = 6
end
task automatic my_task(input int address, output int
new_address);
#5ns;
new_address = address;
endtask // my_task
Variable Initialization

Local variables are initialized before the start of simulation.


program initialization;
task check_bus();
repeat (5) @(posedge clock);
if (bus_cmd === READ) begin
logic [7:0] local_addr = addr<<2;
$display("Local Addr = %h", local_addr);
end
endtask
endprogram

Source: Chris Spear: System Verilog for Verification


Variable Initialization - Solution
Solution 1: Declare program as automatic
program automatic initialization;
...
endprogram

Solution 2: Separate variable declaration from assignment.


program initialization;
task check_bus();
repeat (5) @(posedge clock);
if (bus_cmd === READ) begin
logic [7:0] local_addr;
local_addr = addr<<2;
$display("Local Addr = %h", local_addr);
end
endtask
endprogram
Source: Chris Spear: System Verilog for Verification
Local Data Storage
What is displayed if my_task2 is automatic/not automatic?
int new_address1, new_address2;
bit clk;
initial begin
fork Fork means execute every line in parallel until join is
my_task2(21, new_address1); encountered.
my_task2(20, new_address2); Not automatic: 20 and 20 if the call to
join my_task2(20, new_address2) is scheduled last
$display("new_address1 = %0d", new_address1); Not automatic :21 and 21 if the call to
$display("new_address2 = %0d", new_address2);
my_task2(21, new_address1) is scheduled last
end
Automatic: 21 and 20 if my_task2(21) scheduled
initial begin forever clk=#50 !clk; end first and 20 and 21 if my_task2(20) scheduled first
task my_task2(input int address, output int
new_address);
@(clk);
new_address = address;
endtask
Connecting the Testbench and Design
•Testbench wraps around the Design Under Test (DUT)
•The testbench mimics the environment around the DUT

Testbench

grant[1:0]
request[1:0]
Arbiter
rst clk

•The testbench is separate from the design


Traditional way of port connection

A bus connection between two modules may be composed of many ports. Both
modules must separately declare each port and when the modules are instantiated, a
separately defined signal must be mapped to each port to connect the design blocks.
Separating the Testbench and Design
Connecting all the blocks of a design/testbench is tedious/error prone
module top;
top.sv
stim stim(..I/O..);
Digital DUT(...I/O...);
Digital.v
endmodule
heater.v
module stim(... I/O...);
heater_sm.v endmodule
module Digital(... I/O...);
heater heater(... I/O...);
... endmodule
module heater(... I/O...);
stim.sv
heater_sm heater_sm(... I/O...);
endmodule
module heater_sm(...I/O...)
endmodule
Traditional way: Interface Description in Verilog
 Too Verbose, detailed knowledge of all
the port is required; time consuming.
 Highly error prone
 Difficult to change if the design changes
 Maintenance head-ache
 Tedious to trace and debug
 Not easy to reuse; too easy to make or
break design functionality
 Duplication needed in multiple
modules, communication protocols, and
other places
Traditional way of port connection
SystemVerilogWay of Interfaces

clk clk
Read
Enable
Test Test
DUT Addr DUT Intf
Bench Bench
Data
Verilog Example SystemVerilog Example
As each port must be declared in several places, initial SystemVerilog allows the bus to be declared once as an
construction of the hierarchy is time-consuming and interface. An interface is a design unit in SystemVerilog
maintenance is difficult, as multiple alternations are like a module, i.e. it is declared in a separate file and
required to multiple modules if the bus changes. compiled separately.
SystemVerilog way of Interfaces
Advantages of Using Interfaces

 An interface can be passed as single item.


 Reduces errors which can cause during module connections.
 Easy to add or remove a signal.
 Easy maintainability
 Increases the reusability
Advantages of Using Interfaces

 Port definitions are independent from modules.


 It allows structured information flow between blocks.
 It can contain anything that could be in a module except other module definitions or
instance.
 It Interface can be declared in a separate file and can be compiled separately.
 Interfaces can contain tasks and functions; with this methods shared by all modules
connecting to this information can be in one place.
 Interface can contain protocol checking using assertions and functional coverage
blocks.
The Interface Construct
•An intelligent bundle of signals. Contains:
• connectivity
• synchronization
• functionality
•Can be used for testbench as well as RTL connections
The Interface Construct
•An intelligent bundle of signals. Contains:
• connectivity
• synchronization
• functionality
•Can be used for testbench as well as RTL connections
Testbench

grant[1:0]
request[1:0]
Arbiter
rst clk

interface arb_if(input bit clk);


logic [1:0] grant, request;
Testbench Interface Arbiter bit rst;
endinterface
Using an Interface to Simplify Conn.
module arb( module arb (arb_if arb_bus);
output logic [1:0] grant, always @(posedge arb_bus.clk or
input logic [1:0] request, posedge arb_bus.rst) begin
input logic rst, if (arb_bus.rst)
input logic clk); arb_bus.grant <= 2’b00;
else
always @(posedge clk or ....
posedge rst) begin end
if (rst) endmodule
grant <= 2’b00;
else
....
module top;
end
bit clk;
endmodule
always #5 clk = ~clk;
arb_if arb_bus(clk);
interface arb_if(input bit clk); arb a1(arb_bus);
logic [1:0] grant, request; test t2(arb_bus);
bit rst; endmodule
endinterface
Source: Chris Spear: System Verilog for Verification
Connecting Interfaces and Ports
If the ports of a legacy design cannot be changed to use an interface...
interface arb_if(input bit clk);
logic [1:0] grant, request;
bit rst;
endinterface module top;
bit clk;
always #5 clk = ~clk;
arb_if arb_bus(clk);
arb a1(
.grant(arb_bus.grant),
.request(arb_bus.request),
.rst(arb_bus.rst),
.clk(arb_bus.clk)
);
test t2(arb_bus);
endmodule
Group Signals in I/F using Modport
•Default direction of signals in interface is bi-directional
•Probably not what you want for RTL or testbench.
•Specify direction using modport
interface arb_if(input bit clk);
logic [1:0] grant, request;
bit rst;

modport DUT (input request, rst, clk,


output grant);
endinterface

Usage:
Module definition
module arb(arb_if.DUT arb_bus);
or
Instantiation
arb a1 (arb_bus.DUT);
Mixing interface and ordinary ports
Typically only common busses will be encapsulated in an interface
`default_nettype none
`include "arb_if.v"

module test;
bit clk;
bit [7:0] data_in, data_out;
always #5 clk = ~clk;
arb_if arb_bus(clk);
arb arb (.data_in(data_in), arb_bus.DUT,
.data_out(data_out));
endmodule

module arb(input [7:0] data_in, arb_if arb_bus,


output [7:0] data_out);
Example
Example

Modports allow specification of direction of ports connected to the interface


SV Interface Example

Simulation Log:
Value of a = 6, b = 4
Sum of a and b, c = 10
Example
Example of named port bundle

Example of connecting port bundle


Example
Example
How to parameterize an interface ?
Interface Array
SV Interface- Summary

 Captures communication aspect


 Groups signals
 Controls direction of data flow (modport)
 Describes timing (clocking and specify blocks)
 Checks protocol validity/violation – assertions
 Checks protocol compliance - coverage
Functions in an Interface
Why?
Protocol checkers!

interface mem_bus_if(input bit clk, input bit reset);


reg [7:0] data_in;
reg [3:0] addr;
always @(posedge clk) check_addr(addr);

function check_addr(input reg [3:0] addr);


if (addr == 4'hf) $display("Invalid Address");
endfunction

endinterface
RTL Functions in an Interface
Why?
Provides common functions.
Is only synthesized if called by module

function automatic reg parity(input reg[7:0] data);


return (^data);
endfunction

Need to modify modport


modport DUT (input clk, reset, data_in, addr,
output data_out, import parity);

Call in RTL
assign mem_bus.data_out[8] = mem_bus.parity(.....);

Source: Chris Spear: System Verilog for Verification


Synthesis

Interface synthesizes exactly as DUT without an interface.


No warning on print statement in check_addr of interface.
Need automatic keyword for functions. This makes functions use
automatic storage
An interface function only gets synthesized if called by module.
Interface trade-offs

•Advantages:
•Design reuse – communication with an oft-used protocol
•Adding/changing/deleting a signal is easy
•Enforcing naming conventions, size, direction
•Disadvantages
•Little savings for point to point connections
•Must use interface name in addition to the signal name
•Difficult to connect 2 different interfaces.
Stimulus Timing
•Controlling the timing in a testbench is difficult
•Easy to have race conditions between testbench and DUT.
for (int i=TESTS-1;i>=0;i--) begin
@(negedge clk);
read = 1;
address = address_array[i];
@(posedge clk); // read is complete
#5ns;
Check9Bits(data_read_expect_assoc[address], data_out, address);
data_read_queue.push_back(data_out);
end
Control Timing with a clocking block

•A clocking block:
•Separates the timing and synchronization details from the functionality of your tests.
•Enables modeling at higher level of abstraction

•Use a clocking block:


•To define the clock domain of the testbench
•Specify timing of synchronous signals relative to the clock domain
•Drive inputs just after the active edge
•Sample outputs just before the active edge
•A clocking block can be located in:
•Modules
•Interfaces
•Programs
Sample
interface arb_if(input bit clk);
logic [1:0] grant, request;
name clock domain and active edge
bit rst;

clocking cb @(posedge clk);


output request;
input grant;
endclocking

modport TEST(clocking cb, output rst);

modport DUT(input request, rst, clk, output grant);


endinterface

inputs
TEST DUT
outputs
Source: Chris Spear: System Verilog for Verification
Sample
module test (arb_if.TEST arb_bus);
initial begin
arb_bus.cb.request <= 0;
@arb_bus.cb;
$display(”@%0t: Grant = %b”, $time, arb_bus.cb.grant);
end
endmodule

top

inputs
TEST DUT
outputs
Using a Clocking Block
interface reg_if(input bit clk);
bit reset; bit [3:0] data_in; logic [3:0] data_out;
modport slave (input clk, reset, data_in, output data_out);
modport master(input clk, data_out, output reset, data_in);
endinterface

interface reg_if(input bit clk);


bit reset; bit [3:0] data_in; logic [3:0] data_out;
clocking cb @(posedge clk);
input data_out;
output data_in;
output reset;
endclocking;
modport slave (input clk, reset, data_in, output data_out);
modport master(clocking cb);
endinterface
Example using a Clocking Block
Clocking Block in Module Example
Specifying Delays in Clocking Blocks

•By default inputs are sampled “just before” the clock and outputs driven “just after” the clock.
•“just before” and “just after” can be explicitly set by specifying input and output skew.

clocking cb @(posedge clk);


input
skew
output
skew

inputs
TEST DUT
outputs
Source: Chris Spear: System Verilog for Verification
Input and Output Skew Example

clocking cb @(posedge clk);


input #75ns data_out; // Sample data_out 75ns before the posedge clk
output #25ns data_in; // Drive data 25ns after positive edge
output reset;
endclocking;
input skew

output skew

4
3
Source: Chris Spear: System Verilog for Verification
Sample
Can specify skew for all outputs and inputs using default

clocking cb @(posedge clk);


default input #15ns output #10ns;
output request;
input grant;
endclocking

Clocking blocks allow inputs to be sampled and outputs to be driven at a specific clock event.
Example

There can be multiple clocking blocks in an interface.


Clocking Block Example
Clocking Block Summary
•1st pass at using clocking blocks:
•Define a clock edge clocking cb @(posedge clk);
•Define the outputs to your DUT and inputs from your DUT
input data_out; output data_in; output reset;
Use @<interface_name>.<clock block name> to advance time
@reg_bus.cb;
•2nd pass
• Define input/output skews if necessary input #75ns data_out;
• Define alternate edges for tesbench outputs if necessary
output negedge reset;
•Rules of thumb
• Direction in clocking block is referenced to the block that uses it.
• Put the clocking block in an interface
• Use non-blocking assignments (<=) when assigning to/from signals in a clocking block.
Program Block Considerations
program automatic test (arb_if.TEST arb_bus);
initial $display("Hello World");
.....
endprogram

•Separates the testbench from the DUT.


•A program block cannot contain:
1. always blocks
2. Instantiated modules
3. other programs

•An interface or clocking block is not required to use a program block.


Program Block-Key Points
Region Activity
From previous time slot
Pre-pone Sample
It provides a syntactic context
that specifies scheduling in the Active Design
Reactive region which avoids
races. Observed Assertions

Reactive Program Block

Post-pone $monitor
to next time slot
Program Block-Key Points

 The program block helps ensure that test bench transitions do not have race
conditions with the design
 Just like a module, program block has ports. One or more program blocks can
be instantiated in a top-level netlist, and connected to the DUT.
 It can contain one or more initial blocks
 In the program block, variables can only be assigned using blocking assignments.
Using non-blocking assignments within the program shall be an error
 It creates a scope that encapsulates program-wide data.
 Each program can be explicitly exited by calling the $exit system task. Unlike
$finish, which exits simulation immediately, even if there are pending events.
Example of Program Block

To create a container to hold all other test bench data such as tasks, class objects
and functions

Multiple programs in
the same module can
have shared variables.
Example of Program Block
Example of Program Block
The end of simulation
•Simulation ends when the last initial block finishes in a program
•At the end of which initial do you put the error report?
•A program can have a final block
program automatic test;
int errors, warnings;
initial begin
.... // Main program activity.
end
final
$display(“Test done with %0d errors and %0d warnings”,
errors, warnings);
endprogram
Top-Level Scope
•Compilation unit – the code compiled and treated as 1 logical unit
•Useful for accessing constants in earlier compiled files
•If your simulator supports multi-file compilation
`timescale 1ns/1ns
parameter int TIMEOUT = 1_000_000;
const string time_out_msg = "ERROR: Time out";
module top; // top.sv
test t1();
endmodule

program automatic test; // test.sv


initial begin
#TIMEOUT;
$display(“%s", time_out_msg); # ERROR: Time out
end
endprogram
Top-Level Scope

•By default QuestaSim’s vlog command operates in Single File Compilation


Unit mode.
•Use –mfcu switch to vlog to compile in Multi File Compilation Unit mode
•Need to be conscious of compile order.
vlog -mfcu test.sv top.sv Undefined variable: TIMEOUT.

•Correct compile order


vlog -mfcu top.sv test.sv
Top-Level Scope - $root
•$root allows you to unambiguously refer to names starting with the
top level scope.
•Compiler goes up in scope to find names.

module top;
string my_string = “top”;
middle middle();
string my_string = “middle”;
bottom top();
string my_string = “bottom”;
Top-Level Scope - $root
module top;
string my_string = "top";
middle middle(); module bottom;
initial begin string my_string = "bottom";
#10ns; endmodule
$finish;
end
endmodule
module middle;
string my_string = "middle";
bottom top(); # middle
initial begin # top
$display("%s", my_string); # middle
$display("%s", $root.top.my_string); # bottom
$display("%s", $root.top.middle.my_string); # bottom
$display("%s", $root.top.middle.top.my_string);
$display("%s", top.my_string);
end
endmodule
Mailbox in a Testbench - driver
class Driver;
Transaction tr;
mailbox #(Transaction) mbx;
function new(input mailbox #(Transaction) mbx);
this.mbx = mbx;
endfunction
How is this interface known?
task run(input int count);
repeat (count) begin
mbx.get(tr);
@(posedge bus.cb.ack);
bus.cb.kind <= tr.kind;
...
end
endtask
endclass
Source: Chris Spear: System Verilog for Verification
Mailbox in a Testbench - program
program automatic mailbox_example(bus_if.TB bus, ...);
‘include "transaction.sv“ ‘include "generator.sv“ ‘include
"driver.sv"
mailbox #(Transaction) mbx;
Generator gen;
Driver drv;
int count;
initial begin
count = $urandom_range(50);
mbx = new();
gen = new(mbx);
drv = new(mbx); mbx
fork
gen.run(count);
drv.run(count);
drv.mbx mailbox
join
end gen.mbx
endprogram
Mailbox in a Testbench - driver
class Driver;
Transaction tr;
mailbox #(Transaction) mbx;
virtual bus_if.TB bus;
function new(mailbox #(Transaction) mbx,
input virtual bus_if.TB bus);
this.mbx = mbx;
this.bus = bus;
endfunction
task run(int count);
repeat (count) begin
mbx.get(tr); // Fetch next transaction
@(posedge bus.cb.ack);
bus.cb.kind <= tr.kind;
end
endtask
endclass
Source: Chris Spear: System Verilog for Verification
Mailbox in a Testbench - program
program automatic mailbox_example(bus_if.TB bus);
import my_package::*;
mailbox #(Transaction) mbx;
Generator gen;
Driver drv;
int count;
initial begin
count = $urandom_range(50);
mbx = new();
gen = new(mbx);
drv = new(mbx, bus); mbx
fork
gen.run(count);
drv.run(count); drv.mbx mailbox
join
end gen.mbx
endprogram
Source: Chris Spear: System Verilog for Verification
Addition of interfaces without XMR
module top; program automatic test(bus_ifc bus);
bus_ifc bus(); // Test 1
dut d1(bus); endprogram
test t1(bus); ....
endmodule program automatic test(bus_ifc bus);
// Test N
endprogram

program automatic test(bus_ifc bus,


module top; new_ifc newb);
bus_ifc bus(); // Test 1 needing interface newb
dut d1(bus, newb); endprogram
new_ifc newb(); ....
test t1(bus, newb); program automatic test(bus_ifc bus,
endmodule new_ifc newb);
// Test N not needing interface newb
endprogram
Connecting to an Interface with XMR

module top; program automatic test();


bus_ifc bus(); virtual bus_ifc bus = top.bus;
new_ifc newb(); virtual new_ifc newb = top.newb
dut d1(bus); // Test 1 needing interface newb
test t1(); endprogram
endmodule
....
program automatic test();
virtual bus_ifc bus = top.bus;
// Test N not needing interface newb
endprogram
Example
Modify the following program declaration and instantiation to use cross module references (XMR).
program automatic test(risc_spm_if
risc_bus);
...
endprogram

module top; program automatic test();


.... ....
test t1(risc_bus); virtual risc_spm_if risc_bus = top.risc_bus;
.... endprogram
endmodule `include "risc_spm_if.sv"
module top;
....
test t1();
....
endmodule
Need of Virtual Interface?

SystemVerilog interface is static in nature, whereas classes are


dynamic in nature. Because of this reason, it is not allowed to
declare the interface within classes, but it is allowed to refer to or
point to the interface.

A virtual interface is a variable of an interface type that is


used in classes to provide access to the interface signals.
Virtual Interface
A virtual interface is a variable that represents an interface instance.
Virtual interfaces provide a mechanism for separating abstract models
and test programs from the actual signals that make up the design.
A virtual interface allows the same subprogram to operate on different
portions of a design, and to dynamically control the set of signals
associated with the subprogram.
Instead of referring to the actual set of signals directly, users are able to
manipulate a set of virtual signals.
The virtual interface must be initialized before using it i.e Virtual
interface must be connected/pointed to the actual interface e.g. virtual
mem_intf intf;
Virtual Interface
Accessing the uninitialized virtual interface result in a run-time fatal
error.
Virtual interfaces can be declared as class properties, which can be
initialized procedural or by an argument to new().
Virtual interface variables can be passed as arguments to the tasks,
functions, or methods.
All the interface variables/Methods can be accessed via a virtual
interface handle. i.e virtual_interface.variable
Virtual Interface

Only the following operations are directly allowed on virtual interface variables,
•Assignment ( = ) to and Equality ( == ), inequality ( != ) with,
• another virtual interface of the same type
• an interface instance of the same type
• the special constant null
Advantages of Virtual Interface
1. Virtual interface can be used to make the TestBench independent of the physical
interface. It allows developing the test component independent of the DUT port while
working with multi port protocol.
2. With virtual interface, we can change references to physical interface dynamically.
Without virtual interfaces, all the connectivity is determined during compilation time,
and therefore can't be randomized or reconfigured.
3. In multi port environment,it allows to access the physical interfaces using array index.
4. Physical interfaces are not allowed in object oriented programming, as physical
interface is allocated at compilation time itself. Virtual interface which are set at run
time allows to do object oriented programming with signals rather than just with
variables.
5. Virtual interface variables can be passed as arguments to tasks, functions, or methods.
6. Allows to use Equality ( == ) and inequality ( != ) .
Assignment
Complete the following task:
1. Prepare the specifications for 4-bit ALU
2. Write Verilog code for 4-bit ALU
3. Prepare verification plan for your ALU
4. Write Test-bench as per your verification plan
5. Simulate both design and testbench in EDA Playground
Assignment

1. Declare a 5 by 31 multi-dimensional unpacked array, array1. Each element


of the unpacked array holds a 4-state value.
2. Which of the following assignments are legal and not out-of-bounds?
array1[4][30] = 1'b1;
array1[29][4] = 1'b1;
array1[3] = 31'b1;
3. Declare a 5 by 31 multi-dimensional packed array, array2. Each element of the
packed array holds a 2-state value.
4. Which of the following assignments are legal and not out-of-bounds?
array2[4][30] = 1'b1;
array2[29][4] = 1'b1;
array2[3] = 31'b1;
5. Write code for the following problems.
a) Create memory using an associative array for a processor with a word
width of 24 bits and an address space of 220 words. Assume the PC starts at
address 0 at reset. Program space starts at 0x400. The ISR is at the maximum
address.
b) Fill the associated array with the following instructions:
24'hA50400; // Jump to location 0x400 for the main code
24'h123456; // Instruction 1 located at location 0x400
24'h789ABC; // Instruction 2 located at location 0x401
24'h0F1E2D; // ISR = Return from interrupt
c) Print out the elements and the number of elements in the array.
6. Create the SystemVerilog code for the following requirements
a) Create a 3-byte queue and initialize it with 2, -1, and 127
b) Print out the sum of the queue in decimal
c) Print out the min and max values in the queue
d) Sort all values in the queue and print out the resulting queue
e) Print out the index of any negative values in the queue
f) Print out the positive values in the queue
g) Reverse sort all values in the queue and print out the resulting queue

Verify the above concepts writing the SystemVerilog Code and simulating it in EDA
Playground
Assignment
Complete the following task:
1. Specify that the time should be printed in ps, 2 places to the
right of the decimal point and use as few chars as possible
2. What is displayed by each of these initial blocks?

3. Write any example code in SystemVerilog to verify above


concepts and simulate it in EDA Playground
Assignment
Complete the following task:
o Create a 512 location integer array
o Create a 9-bit address variable to index into the array
o Initialize the last location of the array to 5
o Call a task, my_task(), and pass it the array and the address
o Create my_task() that takes two inputs, a constant 512-element
integer array passed by reference, and a 9-bit address. The task calls
a function, print_int(), and passes the array element, indexed by the
address, to the function, pre-decrementing the address.
o Create print_int() that prints out the simulation time and the value
of the input. The function has no return value.

Write any example code in SystemVerilog to verify above concepts


and simulate it in EDA Playground
Assignment
Complete the following task:
1. Design an interface and testbench for the following ARM High Speed
Bus (AHB). Assume that you are provided an AHB master as verification IP
and you are testing an AHB slave design. Your interface will display an error
if the transaction type is not IDLE or NONSEQ on the negative edge of HCLK.

2. For the following given interface add a clocking block that:


a. Is sensitive to the negative edge of clock
b. All I/O are synchronous to the clock
c. Creates a modport for the testbench called master and for the DUT
called slave
d. Will be used in the master
Popular Questions for Interview on
‘Fundamentals of Verification and SystemVerilog’
1. What is layered architecture?
2. What are the different layers of layered architecture?
3. What is the need of alias in SV?
4. Which is best to use to model transaction? Struct or class?
5. How different is the implementation of a struct and union in SV.
6. What is tagged union ?
7. What is "scope resolution operator"?
8. Write a State machine in SystemVerilog styles.
9. What are the simulation phases in your verification environment?
10. What are void functions ?
11. What is streaming operator and what is its use?
12. How to make sure that a function argument passed has ref is not changed by the function?
13. What data structure is used to store data in your environment and why ?
14. Explain how the timescale unit and precision are taken when a module does not have any
timescale declaration in RTL?
15. What is the difference between bit [7:0] and byte?
16. What is the difference between associative and dynamic array?
17. What is the difference between an initial and final block of the SystemVerilog?
18. Explain the simulation phases of SystemVerilog verification?
19. What is the difference between blocking and non-blocking assignments?
20. How to check if any bit of the expression is X or Z?
21. What is the Difference between param and typedef?
22. What is `timescale?
23. Explain the difference between new( ) and new[ ] ?
24. What is the difference between task and function in class and Module?
25. What is the Difference between SystemVerilog packed and unpacked array?
26. What is alias in SystemVerilog?
27. In SystemVerilog which array type is preferred for memory declaration and why?
28. What are the different types of verification approaches?
29. What are the basic testbench components?
30. What is the difference between logic and bit in SystemVerilog?
31. What is the difference between datatype logic and wire?
32. What is the difference between == and === ?
33. What is $root?
34. Explain the difference between data types logic and reg and wire
35. What is $unit?
36. Explain about pass by ref and pass by value?
37. What is the difference between bit[7:0] sig_1; and byte sig_2;
38. What are the system tasks?
39. What is interface and advantages over the normal way?
40. What is modport and explain the usage of it?
41. What is a clocking block?
42. What is the difference between the clocking block and modport?
43. How to avoid race round condition between DUT and test bench in SystemVerilog verification?
44. What are the ways to avoid race condition between testbench and RTL using SystemVerilog?
45. What are the advantages of the systemverilog program block?
46. Why always blocks are not allowed in the program block?
47. Why forever is used instead of always in program block?
48. What is the input skew and output skew in the clocking block?
49. What is a virtual interface?
50. What is the need of clocking blocks ?
51. What is the need of virtual interfaces ?
52. What is the difference between program block and module ?
53. What is final block ?
54. How to implement always block logic in program block ?
55. What is the use of modports?
56. Why always block is not allowed in program block?
57. Write a clock generator without using always block.
58. What is advantage of program block over clocking block w.r.t race condition?
59. How to avoid the race condition between program block?

You might also like