You are on page 1of 500

Verilog Language and

Application
Version 6.2
Lecture Manual

March 6, 2008

1990-2008 Cadence Design Systems, Inc. All rights reserved.


Printed in the United States of America.
Cadence Design Systems, Inc., 555 River Oaks Parkway, San Jose, CA 95134, USA

Cadence Trademarks
Trademarks and service marks of Cadence Design Systems, Inc. (Cadence) contained in this document are attributed to Cadence with the appropriate symbol.
For queries regarding Cadences trademarks, contact the corporate legal department at the address above or call 800.862.4522.
Allegro
Accelerating Mixed Signal Design
Assura
BuildGates
Cadence (brand and logo)
CeltIC
Conformal
Connections
Diva
Dracula
ElectronStorm
Encounter
EU CAD
Fire & Ice
First Encounter
HDL-ICE

Incisive
InstallScape
IP Gallery
NanoRoute
NC-Verilog
NeoCell
NeoCircuit
OpenBook online documentation library
OrCAD
Palladium
Pearl
PowerSuite
PSpice
SignalStorm
Silicon Design Chain
Silicon Ensemble

Silicon Express
SKILL
SoC Encounter
SourceLink online customer support
Specman
Spectre
Speed Bridge
UltraSim
Verifault-XL
Verification Advisor
Verilog
Virtuoso
VoltageStorm
Xtreme

Other Trademarks
Open SystemC, Open SystemC Initiative, OSCI, SystemC, and SystemC Initiative are trademarks or registered trademarks of Open SystemC Initiative, Inc. in
the United States and other countries and are used with permission.
All other trademarks are the property of their respective holders.

Confidentiality Notice
No part of this publication may be reproduced in whole or in part by any means (including photocopying or storage in an information storage/retrieval system)
or transmitted in any form or by any means without prior written permission from Cadence Design Systems, Inc. (Cadence).
Information in this document is subject to change without notice and does not represent a commitment on the part of Cadence. The information contained herein
is the proprietary and confidential information of Cadence or its licensors, and is supplied subject to, and may be used only by Cadences customer in accordance
with, a written agreement between Cadence and its customer. Except as may be explicitly set forth in such agreement, Cadence does not make, and expressly
disclaims, any representations or warranties as to the completeness, accuracy or usefulness of the information contained in this document. Cadence does not
warrant that use of such information will not infringe any third party rights, nor does Cadence assume any liability for damages or costs of any kind that may
result from use of such information.
RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the
Rights in Technical Data and Computer Software clause at DFARS 252.227-7013.
UNPUBLISHED This document contains unpublished confidential information and is not to be disclosed or used except as authorized by written contract with
Cadence. Rights reserved under the copyright laws of the United States.

Table of Contents

Verilog Language and Application

Table of Contents
Verilog Language and Application
Chapter 1

Verilog Application Workshop


Whats Coming . . . .......................................................................................................... 1-3
Setting Your Expectations . . . ......................................................................................... 1-5
Workshop Philosophy...................................................................................................... 1-7
Esperan HDL Training Agenda ....................................................................................... 1-9
Conventions ................................................................................................................... 1-11
Icons......................................................................................................................... 1-11
Code ......................................................................................................................... 1-11

Chapter 2

Verilog Application
Verilog Application ......................................................................................................... 2-3
What is Verilog? .............................................................................................................. 2-5
Benefits of Using an HDL ............................................................................................... 2-7
Issues in using HDLs ....................................................................................................... 2-9
Applications ................................................................................................................... 2-11
Levels of Abstraction..................................................................................................... 2-13
Abstraction Level Trade-offs......................................................................................... 2-15
Schematic-Based Simulation ......................................................................................... 2-19
Verilog-Based Simulation.............................................................................................. 2-21

Chapter 3

Verilog Language Introduction


The module Keyword .................................................................................................... 3-5
Representing Hierarchy ................................................................................................... 3-7
Connecting Hierarchy - Named Port Connection ............................................................ 3-9
Connecting Hierarchy - Ordered Port Connection ........................................................ 3-11
Procedural Blocks .......................................................................................................... 3-13
Event List ....................................................................................................................... 3-15
The Verilog Connectivity Model ................................................................................... 3-17
Compilation Libraries .................................................................................................... 3-19
Design Configurations ................................................................................................... 3-21
Design Compilation ....................................................................................................... 3-23
Comments and Spacing ................................................................................................. 3-25
Identifier Naming Rules................................................................................................. 3-27

March 6, 2008

Cadence Design Systems, Inc.

iii

Verilog Language and Application

Chapter 4

Table of Contents

Verilog Logic System and Data Types


The Verilog 4-Value Logic System ................................................................................. 4-5
Data Types ....................................................................................................................... 4-7
Concept of a Type............................................................................................................ 4-9
Vectors ........................................................................................................................... 4-11
Vector Assignments and Bit Order ................................................................................ 4-13
Vector Assignments and Bit length ............................................................................... 4-15
Bit and Part Selection .................................................................................................... 4-17
Literal Values................................................................................................................ 4-19
Automatic Extension of Literals .................................................................................... 4-21
Net Types ....................................................................................................................... 4-23
The wire and assign Keywords ............................................................................... 4-25
Logic Conflict Resolution with Nets ............................................................................. 4-27
Register Types ............................................................................................................... 4-29
Register Assignment ...................................................................................................... 4-31
Integer Assignment ........................................................................................................ 4-33
Choosing the Correct Data Type ................................................................................... 4-35
Module Parameters ........................................................................................................ 4-37
Overriding the Values of Parameters............................................................................. 4-39
Local Parameters............................................................................................................ 4-41
Arrays............................................................................................................................. 4-43

Chapter 5

Verilog Operators
Arithmetic Operators ....................................................................................................... 5-5
Bit-Wise Operators .......................................................................................................... 5-7
Logical Operators ............................................................................................................ 5-9
Unary Reduction Operators ........................................................................................... 5-11
Shift Operators ............................................................................................................... 5-13
Relational Operators ...................................................................................................... 5-15
Logical and Case Equality ............................................................................................. 5-17
Equality Operators ......................................................................................................... 5-19
Conditional Operator ..................................................................................................... 5-21
Concatenation ................................................................................................................ 5-23
Replication ..................................................................................................................... 5-25
Operator Precedence ...................................................................................................... 5-27

Chapter 6

Procedural Statements
The initial and always Keywords.......................................................................... 6-5
Procedural Assignments .................................................................................................. 6-7

iv

Cadence Design Systems, Inc.

March 6, 2008

Table of Contents

Verilog Language and Application

Event Control ................................................................................................................... 6-9


Procedural Blocks within Verilog.................................................................................. 6-11
if Statement .................................................................................................................... 6-13
if Statement Syntax ........................................................................................................ 6-15
case Statement................................................................................................................ 6-17
case Statement Syntax ................................................................................................... 6-19
casex............................................................................................................................... 6-21
casez............................................................................................................................... 6-23
Alternate case Statement Form ...................................................................................... 6-25
Loop Statements: for...................................................................................................... 6-27
Loop Statements: repeat and while ........................................................................ 6-29
Loop Statement Syntax .................................................................................................. 6-31
Chapter 7

Continuous and Procedural Statements


Continuous Assignments ................................................................................................. 7-5
Multiple Continuous Assignments................................................................................... 7-7
Review of Procedures ...................................................................................................... 7-9
Multiple Assignments in a Procedure ............................................................................ 7-11
Conditional Operator ..................................................................................................... 7-15
Dont Create Feedback Loops! ...................................................................................... 7-17

Chapter 8

Procedural Statements and the Simulation Cycle


Review of Procedures and Event Control........................................................................ 8-5
Blocking Procedural Assignment .................................................................................... 8-7
Non-Blocking Procedural Assignment ............................................................................ 8-9
Non-Blocking Assignment and the Simulation Cycle ................................................... 8-11
Delta Cycle and Simulation Time.................................................................................. 8-25
Event Based Timing Control ......................................................................................... 8-27
Wait Statement............................................................................................................... 8-29
Simple Delays ................................................................................................................ 8-31
The timescale Compiler Directive ........................................................................ 8-33

Chapter 9

Blocking and Non-Blocking Assignments


Review of Blocking Assignment ..................................................................................... 9-5
Review of Non-Blocking Assignment ............................................................................. 9-7
Blocking Assignment in Sequential Procedures .............................................................. 9-9
Non-Blocking Assignment in Sequential Procedures.................................................... 9-11
Position Dependent Code............................................................................................... 9-13

March 6, 2008

Cadence Design Systems, Inc.

Verilog Language and Application

Table of Contents

Combinational Logic ..................................................................................................... 9-15


Multiple Assignments .................................................................................................... 9-17
Mixed Assignments ....................................................................................................... 9-19
Chapter 10 Verilog Coding Styles
Testbench Organization ................................................................................................. 10-5
Testbenches and Files .................................................................................................... 10-7
Coding RTL Verilog ...................................................................................................... 10-9
Typical Sequential Procedure ...................................................................................... 10-11
Behavioral and RTL Modelling ................................................................................... 10-13
Bus Interface Controller - Behavioral.......................................................................... 10-15
Bus Interface Controller - Implementation Details...................................................... 10-17
Bus Interface Controller - RTL.................................................................................... 10-19
Chapter 11 The Synthesis Process
What Does Synthesis Do?.............................................................................................. 11-5
The Synthesis Flow........................................................................................................ 11-7
How Synthesis Works.................................................................................................... 11-9
Coding Styles Affect Results ....................................................................................... 11-11
Translation Can Be Literal! ......................................................................................... 11-13
What Synthesis Sometimes Cant Do Well . . . ........................................................... 11-15
Programmable Logic Device Specific Issues .............................................................. 11-17
A Synthesis Methodology............................................................................................ 11-19
Language Support ........................................................................................................ 11-21
Chapter 12 Verilog Sample Design
FIFO Specification......................................................................................................... 12-5
FIFO Implementation .................................................................................................... 12-7
FIFO Model Structure.................................................................................................... 12-9
Design Constants ......................................................................................................... 12-11
FIFO I/O ...................................................................................................................... 12-13
Register and Internal Variable Declarations ................................................................ 12-15
FIFO Functional Code ................................................................................................. 12-17
FIFO Outputs ............................................................................................................... 12-19

vi

Cadence Design Systems, Inc.

March 6, 2008

Table of Contents

Verilog Language and Application

The Testbench.............................................................................................................. 12-21


Testbench Declarations.......................................................................................... 12-23
DUT Instantiation .................................................................................................. 12-25
Describing Stimulus............................................................................................... 12-27
Simulation Results ................................................................................................. 12-29
Chapter 13 Definition of RTL Code
Coding RTL Verilog ...................................................................................................... 13-5
Combinational Logic ..................................................................................................... 13-7
Incomplete Event List .................................................................................................... 13-9
Incomplete Assignments in Combinational Logic....................................................... 13-11
Avoiding Latches ......................................................................................................... 13-13
Continuous Assignments ............................................................................................. 13-15
Rules for the Synthesis of Combinational Logic ......................................................... 13-17
Sequential Logic .......................................................................................................... 13-19
Resetting Sequential Logic .......................................................................................... 13-21
Sequential Procedure Templates.................................................................................. 13-23
Synchronous Feedback Inference ................................................................................ 13-25
Sequential Procedure Assignment ............................................................................... 13-27
Blocking and Non-blocking Assignment..................................................................... 13-29
Blocking Assignment in Sequential Procedures .......................................................... 13-31
Chapter 14 Synthesis of Mathematical Operators
High Level Synthesis ..................................................................................................... 14-5
Optimization of Operators ............................................................................................. 14-7
Resource Sharing Concepts ........................................................................................... 14-9
Manual Resource Sharing ............................................................................................ 14-11
Automatic Resource Sharing ....................................................................................... 14-13
Mathematical Optimization ......................................................................................... 14-15
Instantiation of Macro-cells ......................................................................................... 14-17
Chapter 15 Synthesis Coding Styles
Structuring Procedures................................................................................................... 15-5
How Should it be Written? ............................................................................................ 15-7
Review of Finite State Machine (FSM) ......................................................................... 15-9
State Machine: State Diagram ..................................................................................... 15-11
State Machine: Declarations and Sequential Procedure .............................................. 15-13
State Machine: Combinational Procedures.................................................................. 15-15

March 6, 2008

Cadence Design Systems, Inc.

vii

Verilog Language and Application

Table of Contents

Synthesis of if Statements ......................................................................................... 15-17


The Initial Architecture of if and case Statements.................................................. 15-19
Synthesis of case Statements..................................................................................... 15-21
Parallel Case Statements .............................................................................................. 15-23
Synthesis Directives..................................................................................................... 15-25
Synthesis of casex Statements .................................................................................. 15-27
Full Case Statements.................................................................................................... 15-29
The full_case Attribute ......................................................................................... 15-31
You Can Still Get Latches! .................................................................................... 15-33
Synthesis of initial Statements Not! ................................................................ 15-35
Chapter 16 Advanced Synthesis Coding Styles
Unsupported Verilog Constructs ................................................................................... 16-5
Register Inference for Blocking Assignment................................................................. 16-7
Temporary Variable Assignment................................................................................... 16-9
Inferring Latches.......................................................................................................... 16-11
Inference of Tristates ................................................................................................... 16-13
Hierarchy: Register All Outputs .................................................................................. 16-15
Hierarchy Management................................................................................................ 16-17
Chapter 17 Functions and Tasks
Aims and Topics ............................................................................................................ 17-3
The function and task Keywords .......................................................................... 17-5
Function Declaration...................................................................................................... 17-7
Function Call.................................................................................................................. 17-9
Constant Functions ...................................................................................................... 17-11
Task Declaration .......................................................................................................... 17-13
Task Call ...................................................................................................................... 17-15
Tasks without Timing Controls ................................................................................... 17-17
Disabling Tasks............................................................................................................ 17-19
Tasks and Static Arguments ........................................................................................ 17-21
Issues with Functions and Tasks.................................................................................. 17-23
Multiple Function or Task Calls .................................................................................. 17-25
Accessing Module Variables ....................................................................................... 17-27
Out-of-Module Function or Task Calls ....................................................................... 17-29
Review Questions ........................................................................................................ 17-31

viii

Cadence Design Systems, Inc.

March 6, 2008

Table of Contents

Verilog Language and Application

Chapter 18 System Control


Aims and Topics ............................................................................................................ 18-3
Timescale: The `timescale Directive ............................................................................. 18-5
Including Files: The `include Directive ................................................................... 18-7
Text Macro Substitution: The `define Directive ...................................................... 18-9
Conditional Compilation: The `ifdef Directive ...................................................... 18-11
Invocation Options Tests ............................................................................................. 18-13
Output: The $display and $write System Tasks................................................. 18-15
Formatting Text Output ............................................................................................... 18-17
Output: The $strobe System Task........................................................................... 18-19
Simulation Time: $time, $realtime System Functions ....................................... 18-21
Output: The $monitor System Task ........................................................................ 18-23
Formatting Time with the $timeformat System Task ........................................... 18-25
Control: The $finish and $stop System Tasks .................................................... 18-27
Checkpointing: The $save and $restart System Tasks ...................................... 18-29
Waveforms: Value Change Dump (VCD)................................................................... 18-31
Waveforms: Extended Value Change Dump (EVCD) ................................................ 18-33
File Output: Opening Files .......................................................................................... 18-35
File Output: Writing to Files........................................................................................ 18-37
File Input: $readmemb and $readmemh System Tasks.......................................... 18-39
File Formats for Input Data ......................................................................................... 18-41
Enhanced C-Style File I/O ........................................................................................... 18-43
Review ......................................................................................................................... 18-45
Chapter 19 Using a Verilog Test Bench
Design Organization ...................................................................................................... 19-5
Simulation of a Verilog Model ...................................................................................... 19-7
Testbench Organization ................................................................................................. 19-9
In Line Stimulus ....................................................................................................... 19-11
Stimulus From Loops................................................................................................... 19-13
Stimulus From Arrays.................................................................................................. 19-15
Stimulus from Files...................................................................................................... 19-17
Random Stimulus using $random................................................................................ 19-19
The fork and join Keywords.................................................................................. 19-21
Concurrent Stimulus Block.......................................................................................... 19-23
The event keyword ................................................................................................... 19-25
Using Strings to Monitor Progress............................................................................... 19-27
Hierarchical Variables ................................................................................................. 19-29
Vector Capture ............................................................................................................. 19-31

March 6, 2008

Cadence Design Systems, Inc.

ix

Verilog Language and Application

Table of Contents

Vector Playback ........................................................................................................... 19-33


Creating Clocks............................................................................................................ 19-35
Use of Tasks................................................................................................................. 19-37
Chapter 20 Application of Verilog Testbenches
Pseudo-Code Based Testbench ...................................................................................... 20-5
Pseudo-Code Based Telecomms Example .................................................................... 20-7
Use Tasks to Assemble A Data Packet .................................................................... 20-9
Instruction Decode ................................................................................................. 20-11
The Testbench........................................................................................................ 20-13
Running Processor Code.............................................................................................. 20-15
Review of Simulation Outputs..................................................................................... 20-17
Visualized Output ........................................................................................................ 20-19
Results for Comparison ............................................................................................... 20-25
Manufacturing Test Vectors for ASICs ....................................................................... 20-27
Chapter 21 Structural Modeling
Structural Modeling ....................................................................................................... 21-5
Verilog Primitives.......................................................................................................... 21-7
Primitive Pins Are Expandable...................................................................................... 21-9
Conditional Primitives ................................................................................................. 21-11
Primitive Instantiation.................................................................................................. 21-15
Module Instantiation .................................................................................................... 21-17
Array of Instances ........................................................................................................ 21-19
Instance Array Ranges ........................................................................................... 21-21
The generate Construct........................................................................................... 21-23
Logic Strength Modeling ............................................................................................. 21-25
Resolving Strengths ............................................................................................... 21-27
Chapter 22 Modeling Delay
Delay Modeling Types................................................................................................... 22-5
Lumped Delay................................................................................................................ 22-7
Distributed Delays ......................................................................................................... 22-9
Module Path Delays..................................................................................................... 22-11
Accurate Delay Control ............................................................................................... 22-13
The Specify Block ....................................................................................................... 22-15
Parallel and Full Connection Module Paths ................................................................ 22-17
State Dependent Path Delays ....................................................................................... 22-19

Cadence Design Systems, Inc.

March 6, 2008

Table of Contents

Verilog Language and Application

Specify Block Parameters ............................................................................................ 22-21


Inertial and Transport Delay Modes ............................................................................ 22-23
Path Pulse Control ....................................................................................................... 22-25
Negative Pulse Detection............................................................................................. 22-27
Intra-Assignment Delay ............................................................................................... 22-29
Intra-Assignment Delay: Blocking and Non-Blocking ......................................... 22-31
Annotating SDF Timing Data...................................................................................... 22-33
Chapter 23 Timing Checks
Timing Checks ............................................................................................................... 23-3
Overview........................................................................................................................ 23-5
Stability Window Checks .............................................................................................. 23-7
Setup and Hold Checks.................................................................................................. 23-9
Recovery and Removal Checks ................................................................................... 23-13
Event Interval Checks .................................................................................................. 23-17
Nochange Checks ........................................................................................................ 23-19
Width and Period Checks ............................................................................................ 23-21
Skew Checks................................................................................................................ 23-23
Example JKFF ............................................................................................................. 23-27
Chapter 24 Modeling Memories
Modeling a Memory Device .......................................................................................... 24-5
Simple ROM Model....................................................................................................... 24-7
Simple RAM Model....................................................................................................... 24-9
Scalable Memory Device............................................................................................. 24-11
Loading a Memory....................................................................................................... 24-13
Using Bidirectional Ports............................................................................................. 24-15
Bidirectional Ports Using Primitives ..................................................................... 24-17
Bidirectional Ports Using Continuous Assignment ............................................... 24-19
Modeling Memory Ports .............................................................................................. 24-21
Appendix A User Defined Primitives
What is a UDP?............................................................................................................... A-5
UDP Features .................................................................................................................. A-7
Combinational Example: 2-1 Multiplexer ...................................................................... A-9
Combinational Example: Full Adder ............................................................................ A-11
Level-Sensitive Sequential Example: Latch ................................................................. A-13
Edge-Sensitive Sequential Example: D Flip-Flop ........................................................ A-15

March 6, 2008

Cadence Design Systems, Inc.

xi

Verilog Language and Application

Table of Contents

Shorthand To Improve Readability............................................................................... A-17


Example: Flip-Flop With Synchronous Clear .............................................................. A-19
Example: Subtractor Borrow-Out Term ....................................................................... A-21
Example: Latch With Enable and Clear ....................................................................... A-23
Example: Register Using Notifier................................................................................. A-25
Appendix B Review Answers
Verilog Application .........................................................................................................B-3
Data Types and Logic System .........................................................................................B-7
Verilog Operators ............................................................................................................B-9
Procedural Statements....................................................................................................B-11
Continuous and Procedural Statements .........................................................................B-13
Procedural Statements and the Simulation Cycle ..........................................................B-15
Blocking and Non-Blocking Assignment ......................................................................B-17
Verilog Coding Styles....................................................................................................B-19
Verilog Sample Design ..................................................................................................B-21
Definition of RTL Code.................................................................................................B-23
Synthesis of Mathematical Operators ............................................................................B-25
Synthesis Coding Styles.................................................................................................B-27
Advanced Synthesis Coding Styles ...............................................................................B-29
Task and Functions ........................................................................................................B-31
System Control ..............................................................................................................B-33
Structural Modeling .......................................................................................................B-35
Modeling Delay .............................................................................................................B-37
Modeling Memories.......................................................................................................B-39
Appendix C RTL Templates
Multiplexers .....................................................................................................................C-4
Priority Decoders .............................................................................................................C-5
Parallel Priority Decoders ................................................................................................C-6
Bus Logic, Splitting and Reordering ...............................................................................C-7
Comparators.....................................................................................................................C-8
D Type Flip Flop..............................................................................................................C-9
Resettable D Type Flip Flops ........................................................................................C-10
Data Enabled and Clock Gated Flip Flops.....................................................................C-11
Latches ...........................................................................................................................C-12
Tri-state Drivers .............................................................................................................C-13
Counter...........................................................................................................................C-14

xii

Cadence Design Systems, Inc.

March 6, 2008

Table of Contents

Verilog Language and Application

Appendix D Verilog-2001
IEEE Std. 1364-2001 ...................................................................................................... D-3
Enhanced Unsized Constant Extension .......................................................................... D-5
Attributes ........................................................................................................................ D-7
Variable Declaration Assignment ................................................................................... D-9
Enhanced Signed Arithmetic ........................................................................................ D-11
Enhanced Implicit Declarations.................................................................................... D-13
Multi-Dimensional Arrays ............................................................................................ D-15
Local Parameters........................................................................................................... D-17
Enhanced Specify Parameters....................................................................................... D-19
Power Operator ............................................................................................................. D-21
Indexed Vector Part Selects .......................................................................................... D-23
Array Bit and Part Selects............................................................................................. D-25
Alternative Event OR Operator .................................................................................... D-27
Implicit Event Expression List ..................................................................................... D-29
Re-Enterable Tasks and Recursive Functions .............................................................. D-31
Combined Port/Data Type Declarations ....................................................................... D-33
ANSI-style Port Lists.................................................................................................... D-35
Constant Functions ....................................................................................................... D-37
Verilog Generate........................................................................................................... D-39
Parameter Value Assignment by Name ........................................................................ D-41
Verilog Configurations ................................................................................................. D-43
On-Detect Pulse Error Propagation .............................................................................. D-45
Negative Pulse Detection.............................................................................................. D-47
Enhanced Timing Constraint Checks ........................................................................... D-49
New Timing Constraint Checks.................................................................................... D-51
C-Style File I/O............................................................................................................. D-55
SDF Annotation ............................................................................................................ D-57
Enhanced PLA Modeling.............................................................................................. D-59
Standard Random Number Generator........................................................................... D-61
Invocation Option Tests................................................................................................ D-63
Extended VCD Files ..................................................................................................... D-65
Disable Implicit Net Declarations................................................................................. D-67
Enhanced Conditional Compilation.............................................................................. D-69
New `line Directive .................................................................................................. D-71
Appendix E SystemVerilog-2005
IEEE Std. 1800-2005 .......................................................................................................E-3

March 6, 2008

Cadence Design Systems, Inc.

xiii

Verilog Language and Application

Table of Contents

SystemVerilog Design Features.......................................................................................E-5


Literal Values.............................................................................................................E-7
Data Types ...............................................................................................................E-11
Arrays.......................................................................................................................E-13
Declarations .............................................................................................................E-15
Operators..................................................................................................................E-17
Procedural Statements..............................................................................................E-19
Processes ..................................................................................................................E-21
Tasks and Functions.................................................................................................E-23
Hierarchy and Connectivity .....................................................................................E-25
Interfaces..................................................................................................................E-27
SystemVerilog Verification Features.............................................................................E-29
Classes .....................................................................................................................E-31
Enhanced Scheduling Semantics .............................................................................E-33
Constrained Randomization.....................................................................................E-35
Interprocess Synchronization...................................................................................E-37
Clocking Blocks.......................................................................................................E-39
Program Blocks........................................................................................................E-41
SystemVerilog Assertions (SVA) ............................................................................E-43
Data-Oriented Functional Coverage ........................................................................E-45
Direct Programming Interface (DPI) .......................................................................E-47

xiv

Cadence Design Systems, Inc.

March 6, 2008

Verilog Application Workshop


IVA3

1-1

Notes

Verilog Application Workshop

1-2

Whats Coming . . .

Objectives
Introduce Verilog language
Understand its uses, strengths and weaknesses

Format
Morning Lectures
Afternoon Lab Exercises

Timing
Coffee . . .
Lunch . . .

Verilog Application Workshop (IVA3)

1-3

Whats Coming . . .

Verilog Application Workshop

1-4

Setting Your Expectations . . .

What you will learn:


Introduction to Verilog language
Advanced Verilog language details
Application issues, including:
The synthesis process
Synthesis coding styles
Building sophisticated testbenches
Practical use with both simulation and synthesis tools

Following the course . . .


Several months hands-on work to become experienced

Verilog Application Workshop (IVA3)

1-5

Setting Your Expectations . . .

Verilog Application Workshop

1-6

Workshop Philosophy

Use real world, hardware-oriented examples

Many new concepts to learn


Discuss several times
Review questions at end of most chapters

Interactive classroom style


Ask questions
May take off line if too detailed!

Verilog Application Workshop (IVA3)

1-7

Workshop Philosophy

Verilog introduces many new concepts and terminology.

We will introduce the main concepts several times throughout the course.

Don't worry if you don't understand the first time: the main ones will be covered again later!

Hardware orientated examples: no obscure square root algorithms, etc.!

Stay awake: exercises!

Verilog Application Workshop

1-8

Esperan HDL Training Agenda


Day 1

RTL
Language
Basics

Day 2

Further RTL
Language
Language
Application

Day 3

HDL for
Synthesis
in-depth

Day 4

Day 5

Advanced
Language

Advanced
Language

Testbench
Design

Design
Management

HDL Application Workshop


Introduction module
MasterClass HDL
Tutorial

Advanced module
Advanced Plus (customized)

Both Verilog and VHDL Courses follow the same agenda

Verilog Application Workshop (IVA3)

1-9

Esperan HDL Training Agenda


Esperan offers 5-day workshops in both Verilog and VHDL, and both workshops follow the same basic
agenda.

Verilog Application Workshop

1-10

Conventions
Code
signifies code
omitted for
reasons of space

module halfadd(a, b, sum, carry);


output sum, carry;
input a, b;
assign sum
= a ^ b;
assign carry = a & b;
...
endmodule

lower case: key


words and user
defined names
bold: item of
note

Caution
These may differ to those used inside your own company

Icons

Error

Incorrect use of Verilog which will cause


Important
compilation errors
A rule or guideline in the use of Verilog which
must be followed
Synthesis
Particular issue for use of Verilog with
Caution
synthesis tools
A particular issue to watch out for that
frequently causes problems
Tip
A tip or hint in using the language effectively
Verilog Application Workshop (IVA3)

1-11

Conventions

Verilog Application Workshop

1-12

Verilog Application
VAP3

2-1

Notes

Verilog Application Workshop

2-2

Verilog Application
Objectives

Identify the advantages of designing with an HDL

Discover the main applications of Verilog

Define what is meant by levels of abstraction with respect to:


Circuit design
Verilog modeling

Verilog Application (VAP3)

2-3

Terms and Definitions


Hardware Description
Language (HDL)

A programming language that describes the functionality and timing of


hardware circuits

Simulator

Software that reads the HDL and emulates the hardware described by the
HDL

Level of Abstraction

The detail level defined by the modeling style used, such as behavioral and
gate-level

ASIC

Application Specific Integrated Circuit

ASIC Vendor

The company manufacturing the chips. This company is responsible for


developing and providing the library cells.

Bottom-Up Design Flow

A design methodology in which you build the low-level components first and
then connect them to make large systems

Top-Down Design Flow

A design methodology in which you define the system at a very high level of
abstraction and build down.

Register Transfer Logic (RTL) A level of abstraction applicable to designs that will be synthesized
Tool Command Language (Tcl) A scripting language used for issuing commands to interactive programs

Verilog Application Workshop

2-4

What is Verilog?

Verilog is not a software language

Verilog is a Hardware Description


Language (HDL)
Programming language with special
constructs for modeling hardware

Physical (netlist & hierarchy)

Verilog supports: Structural modeling


Software (subprograms)

structure

b
c

Behavioral modeling
Serial (sequential)

Tpd

Concurrent (parallel)

Timing

Abstraction levels

behavior
Tsetup
Thold

Tclk-q

Tnet
clk

timing
Verilog Application (VAP3)

2-5

What is Verilog?
Verilog is an HDL, not a conventional software language like C, Pascal, Fortran or Basic.
An HDL contains some high-level programming language constructs, along with constructs to describe
the digital electronic systems.
The Verilog language contains features and constructs to support description of:

Structure both physical, such as hierarchical block diagrams and component netlists, and
software, such as subprograms. This allows you to describe large, complex systems and manage
the complexity.

Behavior both serial and parallel. In serial behavior, you pass the output of one functional block
to the input of another, which is similar to the behavior of a conventional software language.
However in parallel behavior, you can pass a block output to the inputs of a number of blocks
acting in parallel, and the outputs of these blocks may eventually converge back together. Verilog
has to support concurrent behavior, where many, separate events will be happening at the same
moment in time

Time. Typically, programming languages have no concept of time. In hardware, there are
propagation delays, clock periods and timing checks to be modeled.

Different abstraction levels. You can describe a hardware function at several levels of abstraction,
from a high-level algorithmic model to a low level netlist.

Verilog Application Workshop

2-6

Benefits of Using an HDL


The benefits of using an HDL include:
You write HDL in plain old ASCII text
Capture the design quickly and easily manage modifications

You can design at a higher abstraction level


Easily explore design alternatives
Find problems earlier in the design cycle

The description is implementation independent


You can delay the choice of implementation technology
You can more easily make architectural and functional changes
You can more easily adapt the design to future projects

Verilog Application (VAP3)

2-7

Benefits of Using an HDL


Higher level Verilog design entry allows simulation to be carried out sooner and quicker than schematic
design entry. Earlier simulation allows earlier debugging easier and quicker with Verilog. Quicker
simulation allows possibility for different architectures of an algorithm to be investigated. This allows a
better chance of selecting an optimal architecture and partitioning.
RTL code is mostly independent of the implementation technology you can defer the selection of target
ASIC or FPGA technology until the majority of design is entered. You can also switch technology or
vendor with the minimum of redesign.
Use of a standard HDL facilitates reuse of designs from previous projects or from commercial
Intellectual Property (IP) providers. You can move or switch between different tools/vendors without
re-entry, reformat or translation of the design description.

Verilog Application Workshop

2-8

Issues in using HDLs

Steep learning curve


A new programming language to understand
Simulation and synthesis EDA tools to learn

Major change in design methodology


No standard off-the-shelf methodology
Needs to be planned and implemented

Aimed at digital design only


Although analog extensions do exist (Verilog-A)

Correct coding styles influence project success

Much design planning and partitioning required before coding

Other specific issues as we will see during the course

Verilog Application (VAP3)

2-9

Issues in using HDLs


Adopting Verilog requires learning a new language, learning at least two new EDA tools (simulator and
synthesis tool) and a change to a more software-like design methodology.
The way in which you write your code can affect the speed and efficiency of simulation and synthesis
tools, and the performance and area of the final design.

Verilog Application Workshop

2-10

Applications
The Verilog HDL is used by:
Model developers describing ASIC or FPGA macrocells and higher-level IP

System architects doing high level system simulations

ASIC and FPGA designers writing RTL code for synthesis

Verification engineers writing advanced tests for designs at all levels

Verilog Application (VAP3)

2-11

Applications

Verilog Application Workshop

2-12

Levels of Abstraction
Behavioral
- algorithmic

Register
Transfer
Level
Verilog

Logic synthesis

Gate level
- structural
- netlist
Layout/
Place & Route

Physical
- silicon
- polygons

Verilog Application (VAP3)

2-13

Levels of Abstraction
At each level of abstraction, you can describe a system as a group of hierarchical models in varying
amount of detail.
Within the Verilog language, you can write models with different levels of detail. The three main levels
of abstraction in Verilog are:

Behavioral
Describe the system using mathematical equations
You can omit timing the system may simulate in zero-time like a software program

Register Transfer Level (RTL)


Partition the system into combinational and sequential logic, using constructs and coding
styles supported by synthesis
Define timing in terms of cycles, based on defined clock(s)

Structural (Gate-Level)
Instantiate and interconnect already-defined modules
Instantiate and interconnect built-in logic primitives (gates) for greater accuracy, especially in
timing
Output a netlist from a logic synthesis tool

EDA tools facilitate the translation between abstraction levels.

Verilog Application Workshop

2-14

Abstraction Level Trade-offs


Faster simulation/
entry

Behavioral
- algorithmic

Less detailed

Register
Transfer
Level

Gate level
- structural
- netlist
Slower simulation/
entry

Physical
- silicon
- polygons

More detailed

Verilog Application (VAP3)

2-15

Levels of Abstraction (continued)


Designers model at all three of the common levels of abstraction, for different reasons:

Designers first model functional blocks at the behavioral level, for ease and maximum simulation
speed

They later refine the functional blocks to the RTL level for a logic synthesis tool

Library developers model most cell components at the structural level. These libraries are used in
synthesis. The Structural Modeling unit of this course provides more information on structural
(gate-level) modeling.

Verilog Application Workshop

2-16

Abstraction Level Example: Divide by 2


// BEHAVIORAL
op

data

always @(data)
op <= data/2;

/2

4
op

data

// RTL

SR1

4
always @(posedge clk)
op <= data >> 1;

clk

// STRUCTURAL
FD1 op[2:0] (.D(data),.CP(clk),.Q(op));

Verilog Application (VAP3)

2-17

Abstraction Level Example: Divide by 2

Verilog Application Workshop

2-18

Schematic-Based Simulation

Apply low-level, proprietary,


non-portable stimulus

Observe results in waveform


display

Manually verify function and


timing

Lets compare to using


Verilog...

10011100
00110011
01101001

Verilog Application (VAP3)

2-19

Schematic-Based Simulation

Verilog Application Workshop

2-20

Verilog-Based Simulation

High level Verilog testbench


Testbench written in
behavioral style

Interacts with design


Design written in RTL
style

May automatically verify


design function

Portable between tools

Testbench
behavioral

Design
RTL

Compare

Actual
results

Expected
results

Verilog Application (VAP3)

2-21

Verilog-Based Simulation
You can use Verilog at all levels of abstraction. It is very common to have a behavioral testbench exercise
a design having behavioral, RTL, and structural components. Verilog also has rudimentary switch
primitives for modeling at the transistor level.

Verilog Application Workshop

2-22

Review
1. What is Verilog?
2. How is Verilog implementation independent and why is this an advantage?
3. What level of abstraction is used in:
a. Testbenches
b. Synthesisable designs
c. Net lists

Verilog Application (VAP3)

2-23

Review

Verilog Application Workshop

2-24

Verilog Language Introduction


VLE7

3-1

Notes

Verilog Application Workshop

3-2

Aims and Topics

Aim
Examine fundamental language objects
Introduce the main language concepts

Topics
Verilog objects
Verilog connection model
Hierarchy
Rules and regulations

Verilog Language Introduction (VLE7)

3-3

Terms and Definitions

Verilog Application Workshop

3-4

The module Keyword

Describes interface and behavior

Modules communicate through


ports
List port names in parentheses
after the module name

Define each port as input,


output, or inout

module halfadd (a, b, sum, carry);


output sum, carry;
input a, b;
assign sum
= a ^ b;
assign carry = a & b;
endmodule

In list after module declaration


input a, b;
Verilog-2001: in port list
(input a, b, ...);

^ is the exclusive or operator

& is an logical and operator

Important
Verilog is case sensitive for identifiers

halfadd
a

sum

+
b

carry

Keywords are always lowercase


Verilog Language Introduction (VLE7)

3-5

The module Keyword

Modules are the basic building blocks in the design hierarchy.

Modules define a new scope (level of hierarchy).

Modules can represent:


A physical block such as an IC or ASIC cell
A logical block such as the ALU portion of a CPU design
The complete system

Every module description starts with the keyword module, has a name (halfadd, dff, alu,
etc.), and ends with the keyword endmodule.
The module name must be unique.

Here is the module for a half adder block. Notice that the module defines a name for the block (halfadd
in this case); the input ports a and b and output ports sum and carry.
The outputs sum and carry are defined in terms of the inputs a and b so we have described the behavior
of our half-adder. The ^ (xor) and & (and) functions used here are not gates but Verilog operators. This
way of describing the behavior uses concurrent Verilog assign constructs (we can reverse the order of
the statements and still get the same behavior!). We will discuss the differences between concurrent and
sequential (procedural) statements in later sections.

Verilog Application Workshop

3-6

Representing Hierarchy
Create hierarchy by
Instantiating module(s)

Connecting module ports


to local ports or nets
Local nets need to be
declared (usually)

fulladd

b
cin

sum

n_sum

a
U1

U2

halfadd

halfadd

n_carry2

U3
n_carry1

carry

or

module fulladd (input a, b, cin, output sum, carry);


wire n_sum, n_carry1, n_carry2;

Local nets of type wire

halfadd U1(.a(a), .b(b), .sum(n_sum), .carry(n_carry1));


halfadd U2(.a(n_sum), .b(cin), .sum(sum), .carry(n_carry2));
or
U3(carry, n_carry2, n_carry1);
endmodule
Built-in gate primitive

Verilog Language Introduction (VLE7)

3-7

Representing Hierarchy
You can create a larger system or hierarchy by listing instances of other modules and connecting those
instances by their ports.
Now we have fully-described our half-adder, we can use it to build a full-adder. We need to create two
instances of the half-adder block for the full-adder.
First we need a module for the full-adder, defining the name, inputs and outputs. Then we need to
instantiate two half-adder blocks and an OR gate and connect them up to make the full-adder.
Instantiating a module is not the same as calling a routine. Each instance is a complete, independent, and
concurrently active copy of the module.
We also need some internal nets to connect up the half-adders; we create these using the wire
declaration.
Note that each module has its own instance name (U1, U2, and U3). The instance name gives a unique
identity to every object, and is used in navigating the design hierarchy.
The module instantiation syntax is:module_identifier [ parameter_value_assignment ] module_instance
{ , module_instance } ;
The module instance syntax is:
name_of_instance ( [ list_of_port_connections ] )
Verilog supplies some pre-defined modules for basic logical functions, called primitives. Here we use an
or gate primitive in the structural model of the full adder. Alternatively we could use an assign
statement to describe the OR gate behavior
assign out = nsela | selb;
Verilog Application Workshop

3-8

Connecting Hierarchy - Named Port Connection

Explicitly specify which


instance port is mapped to
which local port/wire

instantiation
a

n_sum

n_carry1

module

U2

sum

carry

halfadd

module fulladd (input a, b, cin, output sum, carry);


wire n_sum, n_carry1, n_carry2;
...
halfadd U1(.a(a), .b(b), .sum(n_sum),.carry(n_carry1));
...

module halfadd (a, b, sum, carry);


output sum, carry;
input a, b;
...
endmodule

wire n_carry1 of
module fulladd
mapped to output
carry of module
halfadd
Tip
Use named port connection
for linking hierarchy
Verilog Language Introduction (VLE7)

3-9

Connecting Hierarchy - Named Port Connection


The list of named port connections syntax is:named_port_connection { , named_port_connection }
The named port connection syntax is:{ attribute_instance } .port_identifier ( [ expression ] )
where:attribute_instance is a Verilog-2001 implementation-defined attribute
port_identifier is the port name declared in the instantiated module
expression is typically a net or register of the instantiating module
Since named port connection explicitly specifies how each port on the component is mapped to each
port/net in the module which instantiates the component, it is much more readable and less prone to error
than alternatives.
Named port connection allows ports to be connected in any order, e.g.
halfadd U1(.sum(n_sum), .carry(n_carry1), .a(a), .b(b));
A port can be left unconnected by omitting that port name from the connection list, e.g.
halfadd U1(.a(a), .b(b), .sum(n_sum));
Unconnected input ports initialize to z and feed that value into the component, which can cause
problems. More common are redundant or unwanted outputs which are left unconnected to be optimized
away in synthesis

Verilog Application Workshop

3-10

Connecting Hierarchy - Ordered Port Connection

Map local port/wire to


instance ports by position
in the order the ports are
declared

instantiation

module

n_sum

n_carry1

U2

sum

carry

halfadd

module fulladd (input a, b, cin, output sum, carry);


wire n_sum, n_carry1, n_carry2;
...
halfadd U1(a, b, n_sum, n_carry1);
...

input a of fulladd mapped to


input a of halfadd
input b of fulladd mapped to
input b of halfadd

module halfadd (a, b, sum, carry);


output sum, carry;
input a, b;
...
endmodule

Caution
Less readable and more error-prone
than named port connection
Verilog Language Introduction (VLE7)

3-11

Connecting Hierarchy - Ordered Port Connection


The list of ordered port connections syntax is:ordered_port_connection { , ordered_port_connection }
The ordered port connection syntax is:{ attribute_instance } [ expression ]
Notice that the order of the ports in the instance follows the order in the module definition.
Notice that the expression itself is optional Use a comma as a place holder in the connection list.
This notation is more prone to error and less readable than named port connection since if the order of
instantiation port list and module port list are not exactly the same, wrong connections will be made.
Hierarchical designs which contain wrong connections can be difficult to debug.
A port can be left unconnected by omitting that port name from the connection list, e.g.
halfadd U1(a, b, ,n_carry);
This leaves the output port sum unconnected.
Unconnected input ports initialize to z and feed that value into the component, which can cause
problems. More common are redundant or unwanted outputs which are left unconnected to be optimized
away in synthesis.

Verilog Application Workshop

3-12

Procedural Blocks

Section containing procedural


statements
Multiple procedures interact
concurrently
always procedure
Loops throughout simulation
Continues when any variable
in event list changes value
Hardware construct
initial procedure
Executes once at start of
simulation
Testbench construct

always @(a or b or sel)


if (sel == 1)
op = a;
event list
else
op = b;

1
op

sel

Synthesis
initial blocks are not synthesizable

initial
begin
a = 1;
b = 0;
end

Verilog Language Introduction (VLE7)

3-13

Procedural Blocks
When we defined the behavior of our half-adder we used concurrent Verilog assign statements.
We could have described the behavior using a Verilog procedure such as the example on the slide. Inside
a procedure we can use Verilog procedural statements which work like conventional software. Inside a
procedure the statements are executed line-by-line so the order of statements is important. Verilog has a
variety of procedural statements many of which are very similar to statements in conventional software
languages such as the if statement in the example. Procedural statements give Verilog a lot of power
when describing complex behavior as we will see later.
A Verilog procedure can only be used inside an module. A single module can have many procedure
which execute concurrently and communicate simultaneously with each other using variables.
initial and always procedures are used in different ways:

The initial block is an unsynthesizable proactive testbench construct that executes exactly
once

The always block is a synthesizable reactive hardware construct that loops forever

Verilog Application Workshop

3-14

Event List
event list constructed using or operator

Procedure resumes when an event in the


event list occurs

An event is any transition of the


specified signals

Verilog-2001 added the comma and


wildcard operators.
The wildcard operator adds all
signals that go into the block and into
any functions called from the block

Note: Parentheses are optional for event


expressions consisting of a single token

always @(a or b or sel)


if (sel == 1)
op = a;
else
op = b;
event list constructed using , operator
always @(a, b, sel)
if (sel == 1)
op = a;
else
op = b;
event list constructed using * wildcard
always @(*)
if (sel == 1)
op = a;
else
op = b;
Verilog Language Introduction (VLE7)

3-15

Event List
Note: The or event list operator has nothing to do with the bitwise OR operator | or the logical OR
operator ||.
The language allows any events or variables to be placed in the @(events list) control of a procedural
block.
The gives rise to the concept of the complete event list, where all of the variables whose values are
read in the procedure are included in it.
A change in value of any input to a block of combinational logic can change the outputs. Therefore we
need to force the execution of a procedure modeling combination logic when any of the inputs change,
to re-evaluate the output. Note that a change in strength of the variable can also trigger a procedure.
Hence to model and simulate combinational logic we need a complete event list.

Verilog Application Workshop

3-16

The Verilog Connectivity Model

Multiple procedures interact


concurrently
Execute statements in
sequence, like
conventional software

Procedure

Communicate
concurrently through
events and variables

Typically, several modules


each contain one or may
procedural blocks

Procedure
Procedure

Procedure

Verilog Language Introduction (VLE7)

3-17

The Verilog Connectivity Model


This capability to have many procedures communicating concurrently with each other via variables is
the basic model which Verilog uses to describe hardware. The procedures many be in a single module or
partitioned into a number of modules in a hierarchical structure, but the basic model remains the same.

Verilog Application Workshop

3-18

Compilation Libraries
Some Verilog tools use compilation
libraries: A collection of compiled modules or
primitives
my_design.v
WORK

Referred to by library name

Physically exists as a directory

Simulator startup file specifies


mapping
Library name -> directory name

PRIMS

primitives

MYWORK
module

module

Tools compile into a WORK


library
WORK is mapped to a specific
library name during compilation

module
module

primitives

primitives

PROJ

module
module

Important
Not all Verilog simulators use compilation
libraries

Verilog Language Introduction (VLE7)

3-19

Compilation Libraries
To simulate a Verilog model, we must first convert our source files into a binary form that can be
recognized by the simulator. The process of checking the syntax and producing the binary file is known
as compilation.
Some Verilog tools use libraries in the compilation and simulation of models. This is a feature
particularly of tools which allow the compilation and simulation of VHDL and Verilog models together
co-execution tools. The following is only applicable to tools which use libraries:When you compile a design in Verilog, you can compile it into a data structure known as a library.
A library is normally a directory on the computer's disc where the compiled, binary design units are
placed.
There is also a mechanism to allow different libraries to be selected as the current working library.
When Verilog source files are compiled, the resulting binary files are stored in the current working
library.

Verilog Application Workshop

3-20

Design Configurations
Verilog-2001 provides a standard means to specify a design configuration
You can specify a compiler mapping of source files into libraries
library rtlLib rtlSrc/*.v;

You can declare named configuration blocks, each of which can specify:
The module to which it applies
An ordered list of libraries from which to bind instance descriptions by default
Specific library lists or named configurations for specific types or instances
config bot;
design rtlLib.bot;
default liblist rtlLib gateLib;
cell ALU liblist gateLib;
endconfig
config top;
design behLib.top;
default liblist behLib rtlLib;
instance top.bot1 use rtlLib.bot:config;
endconfig
Verilog Language Introduction (VLE7)

3-21

Design Configurations
Configuration names may be the same as cell names and do not need to be related, though you are
strongly advised to make them related if you use the same name. If a cell and configuration have the same
name, then to differentiate between the two, you add the :config qualifier when referring to the
configuration name.
Here is the formal syntax of a configuration block:
config_declaration ::=
config config_identifier ;
design_statement
{config_rule_statement}
endconfig
design_statement ::=
design { [library_identifier.]cell_identifier } ;
config_rule_statement ::=
default liblist [{library_identifier}]
| instance inst_name liblist [{library_identifier}]
| instance inst_name use [library_identifier.]cell_identifier[:config]
| cell [ library_identifier.]cell_identifier liblist [{library_identifier}]
| cell [ library_identifier.]cell_identifier use
[library_identifier.]cell_identifier[:config]

Verilog Application Workshop

3-22

Design Compilation

tb_one

Design compiled from a


list of Verilog files

Compile testbench first if:

testbench

Contains compiler
directives

design

Provides additional
information for the
compiler/simulator

structural

cpu

pnet_read

behavioral

RTL/structural

read_frame
netlist

pnet_write

Order of other files


generally not important

Hierarchical connections
are automatically made

Verilog allows different


levels of abstraction
anywhere in the hierarchy

behavioral

write_frame
primitives

Verilog Language Introduction (VLE7)

3-23

Design Compilation
Now let's look at an example which puts together all of the building blocks we have discussed so far.
The diagram on the slide shows a complete hierarchical design structure. The top-level of the hierarchy
is the module tb_one, a behavioral level testbench. This instantiates a structural module design,
which contains the top level partitioning of the design. Three modules are instantiated within module
design; cpu and pnet_write, which are behavioral models, and pnet_read which is a structural
module instantiating the modules read_frame and write_data. write_data is hand-crafted
gate level model of Verilog primitives, and read_frame contains a synthesized netlist.
There are a number of dependencies in the hierarchical design structure we discussed on the previous
slide.
Verilog does not require the modules of a hierarchical design to be compiled in any particular order.
However, the order of the Verilog code compiled may be important if compiler directives are being used.
You will see compiler directives later in the course.
Compile the testbench module first if it contains compiler or simulator directives which may affect the
compilation of all the modules in the design. The compiler must be aware of these directives before
compiling any other information, hence the testbench is generally compiled first.
The compiler will automatically link together the design hierarchy as the individual modules are
compiled.

Verilog Application Workshop

3-24

Comments and Spacing


// This is a 'line' comment. Each line must begin with //
// Comments end with a new line
module muxadd (a, b, sel, sum, carry, op);
output sum, carry, op;
input a, b, sel;
// End of line comment
...
/* This is a block comment. Text in a block comment
can span many lines. */
// Verilog is
// Additional
assign sum
assign carry

a free-format language
spaces can be used to enhance readability
= a ^ b;
= a & b;

// use indentation to aid readability and debugging


always @(a or b or sel)
if (sel == 1)
op = a;
else
op = b;
...

Verilog Language Introduction (VLE7)

3-25

Comments
Verilog is a free-format language.
You can use white space to enhance the readability and the organization of code. The Verilog language
ignores these characters, except when they serve to separate other language tokens.
Verilog comments are created using //. Anything on a line to the right of the double-slash is taken as
a comment. If the line begins with // then the whole line is a comment. Verilog also provides multi-line
comments. If you want to use comment headers at the beginning of Verilog files to define version control
information, change histories and descriptions of the block then the comment header must start with /*
and end with */. Note that block comments cannot be nested.
Indentation and line breaks can help make your code more readable, particularly for large nested if
structures, and aid debugging - by having one executable statement per line, source code debug is easier.
Use comments only where necessary to communicate your intentions to later readers.
This comment for example is totally unnecessary:
// multiply a and b and set the answer to c
always @ (a or b)
c = a * b;
Why? Because it is already obvious from the code that a and b are being multiplied!

Verilog Application Workshop

3-26

Identifier Naming Rules

Names may consist of any


alphanumeric character, including
dollar sign ($) and underscore (_)

Names must start with a letter or


an underscore

Verilog identifiers are case


sensitive
Keywords must be lowercase

These names do not refer to the


same object
ABC, Abc, abc

Names can be of any length

unit_32
structural
bus_16_bits
a$b
unit@32
unit-32
16_bit_bus

Tool or methodology may


restrict name lengths

Verilog Language Introduction (VLE7)

3-27

Identifier Naming Rules


Identifiers are user-provided names for Verilog objects within a description.
Identifiers must begin with an alphabetical character (a-z, A-Z) or an underscore (_) and can contain
any alphanumeric character, including the dollar sign ($), and the underscore.
Note: Objects with names beginning with $ are treated as system tasks or functions by the compiler (see
chapter 18: System Control)
Identifiers are case sensitive. Keywords are only recognized if they are in lower case. An upper case
keyword may be recognized as an identifier, depending on the context, i.e. it is possible (although
definitely NOT good design practice) to have:module MODULE (a, b, c...);
Verilog supports the use of escaped identifiers, which allow any printable ASCII character to be used in
an identifier. Escaped identifiers must begin with a backslash (\) and end with a whitespace.
e.g. \unit@32

\unit-32

\16-bit-bus are all legal escaped identifiers.

Escaped identifiers are primarily designed for Verilog compatibility with tools and technology libraries.
For example, many technology libraries have historical names for cells where the first character specifies
the number of inputs, e.g. 2nand 4or 2and2or. Using escaped identifiers would allow Verilog to use
instantiate modules with such names.
Escaped identifiers should not be used unless there are no other options.

Verilog Application Workshop

3-28

Review
1. What is the basic building block of a Verilog design?
2. How do Verilog procedures communicate?
3. What Verilog file do you compile first?
4. Write the code to instantiate the following module:ALU1
data
ac_out
opcode
clock
reset

ALU
a_in
y_out
b_in
op_in
z_out
clk
rst

alu__out
zero

Verilog Language Introduction (VLE7)

3-29

Review

Verilog Application Workshop

3-30

This page left intentionally blank

Verilog Logic System and Data


Types
VDL5

4-1

Notes

Verilog Application Workshop

4-2

Aims and Topics

Aims
To introduce the Verilog logic value system and to understand the different data
types and the rules covering their use.

Topics
Logic value system
Data type classes
Vectors and literal values
Net data types and their use
Register data types and their use
Choosing the correct data type
Parameters
Memory arrays

Verilog Logic System and Data Types (VDL5)

4-3

Aims and Topics

Verilog Application Workshop

4-4

The Verilog 4-Value Logic System


buf

Zero, Low, False, Logic Low, Ground,


VSS, Negative Assertion

buf

One, High, True, Logic High, Power,


VDD, VCC, Positive Assertion

x, Unknown (bus contention), Uninitialized

HiZ, High Impedance, Tri-State, Undriven,


Unconnected, Disabled Driver (Unknown)

buf

bufif1

Important
The unknown logic value x is not the same as dont care.
Verilog Logic System and Data Types (VDL5)

4-5

The Verilog 4-Value Logic System


The unknown logic value in Verilog represents a situation where the value of a node cannot be
predicted. In real hardware, this node will usually be at either 1 or 0.
Bus contention can occur on tristate buses when two drivers are simultaneously enabled and are driving
conflicting values, e.g. 0 and 1. In this situation, the final value of the tristate bus cannot be determined,
and so is given the simulation value x to reflect this. In real hardware, the net may be a logic 1; logic 0
or something in between, and the final value may be determined by gate output driver sizes; capacitive
or resistive load on the net; noise in the circuit etc.
In Verilog, data objects (including ports) usually initialize to x, i.e. is the beginning of simulation, all
data types have the value x. The initial x value remains until the data object is assigned another value
during the course of simulation. If a data object remains at x for the duration of simulation, then this is
usually an indication of a logic initialization problem, e.g. registers not reset.
An exception to the above rule is for unconnected data objects (e.g. unconnected ports in a component
instantiation). Unconnected data objects initialize to z. If a data object remains at z for the duration of
simulation, then this is usually an indication of a component ports being accidently or deliberately
unconnected.
Tristate buses usually initialize to z also. At initialization, all bus drivers are usually disabled, resulting
in an undriven tristate bus. This is reflected in simulation by initializing the bus to z.

Verilog Application Workshop

4-6

Data Types

Verilog objects communicate using variables

All variables have a type

Verilog provides numerous built in types


Verilog is a very loosely typed language

There are three different classes of data type


Nets
Represent physical connection between structures and objects e.g. wire
Registers
Represent abstract storage elements e.g. reg
Parameters
Run-time constants

Verilog Logic System and Data Types (VDL5)

4-7

Data Types

Verilog Application Workshop

4-8

Concept of a Type

You specify the variable type upon


declaration. If more than one bit wide,
you also specify width.

For example: module ports by default


are single-bit wire
Specify type and width as needed

Rules govern use of data types

For example: procedural assignments


are only to register types
integer real reg time realtime

1
op

b
sel

reg op;

type reg

module mux
(
input
input
output reg
);

variable name(s)

a, b,
sel,
op

always @(a or b or sel)


if (sel == 1)
op = a;
else
op = b;

endmodule

Verilog Logic System and Data Types (VDL5)

4-9

Concept of a Type
If you use the list of ports syntax, you separately declare the port direction and again (if needed)
separately declare the port type.
module mux (a, b, sel, op);
input a, b;
input sel;
output op;
reg
op;
If you use the list of port declarations syntax, you declare the port direction and type together.
module mux (
input
a, b,
input
sel,
output reg op
);

Verilog Application Workshop

4-10

Vectors

A vector is a net or reg with a width of two or more bits

You specify the width when declaring the variable


[ left position : right position ]

Tip

Convention is to use [msb:lsb] e.g. [3:0]


module mux4 (
input wire [3:0] a, b,
input wire
sel,
output reg [3:0] op
);

4-bit vector wire


4-bit vector reg

always @(a or b or sel)


if (sel == 1)
op = a;
else
op = b;

a
4
b
sel

endmodule

1
op
0

Verilog Logic System and Data Types (VDL5)

4-11

Vectors
Format is [msb:lsb] <name>
Variable vector type declaration:

type is the type of the variable.

range is the vector range, in the [MSB:LSB] format.

net_name is the name of the net.

You can declare more than one net in the same declaration by using a list of names separated by commas.

Verilog Application Workshop

4-12

Vector Assignments and Bit Order

You can access vector elements by position


Select one or more contiguous bits

input [3:0] inp;


output [3:0] outp;

reg [3:0] ibus;


reg [0:3] obus;

assign outp = inp;

obus = ibus;

outp[3]

inp[3]

obus[3]

ibus[0]

outp[2]

inp[2]

obus[2]

ibus[1]

outp[1]

inp[1]

obus[1]

ibus[2]

outp[0]

inp[0]

obus[0]

ibus[3]

assign outp[3] = inp[0];


outp[3]

inp[3]

outp[2]

inp[2]

outp[1]

inp[1]

outp[0]

inp[0]

Verilog Logic System and Data Types (VDL5)

4-13

Vector Assignments and Bit Order


You access elements by position, not element number use the vector whichever way you declared it.

Verilog Application Workshop

4-14

Vector Assignments and Bit length

Vector widths do not need to match in an assignment!


If source is bigger than target, source is truncated (from msb)
If source is smaller than target, target is padded with 0 (from msb)

You can use slices and concatenation operator {} to match vector widths
reg [3:0] zbus;
// 4 bit vector
reg [5:0] widebus; // 6 bit vector
zbus = widebus;

zbus[3]
zbus[2]
zbus[1]
zbus[0]

widebus = zbus;

widebus[5]
widebus[4]
widebus[3]
widebus[2]
widebus[1]
widebus[0]

slice
zbus = widebus[3:0];

widebus[5]
widebus[4]
widebus[3]
widebus[2]
widebus[1]
widebus[0]

0
0
zbus[3]
zbus[2]
zbus[1]
zbus[0]

concatenation
widebus = {2'b00, zbus};

Verilog Logic System and Data Types (VDL5)

4-15

Vector Assignments and Bit Length


Verilog does not require vectors to be the same size on the left hand (source) and right hand (target) sides
of an assignment.
If the target vector is bigger then the source vector, then the source vector is fitted to the lowest
(right-most) bits of the target, and the excess target bits assigned to 0;
If the source vector is bigger then the target vector, then the target is assigned from the lowest
(right-most) bits of the source (i.e. source data is truncated to match the target width).
Obviously this can give undesirable result, and so it is good coding style to match the widths of target
and source vectors.
Where the target is bigger then the source, specify the excess bits explicitly by, for example, using the
concatenation operator:widebus = {2'b00, zbus};
widebus = [zbus, 2'b00};

// pad from the MSB


// pad from the LSB

Where the source is bigger then the target, take a slice of the source to specify which bits of the source
to use:zbus = widebus[3:0];
zbus = widebus[5:2];

Verilog Application Workshop

4-16

Bit and Part Selection


For Verilog-1995 the bit-select index may be variable but the range-select indices must
be constant:
primary ::= ...
| identifier [ expression ]
| identifier [ msb_constant_expression :
lsb_constant_expression ]
| ...
Verilog-2001 adds syntax permitting range-select using a constant width and a variable
index:
range_expression ::=
expression
| msb_constant_expression : lsb_constant_expression
| base_expression +: width_constant_expression
| base_expression -: width_constant_expression
Where base_expression is the variable starting bit position
and width_constant_expression is the constant plus or minus offset.
Verilog Logic System and Data Types (VDL5)

4-17

Bit and Part Selection

Verilog Application Workshop

4-18

Literal Values

Literal values are represented as:<size><base><value>


size is number of bits
unsized literals default to 32 bits
base can be b(binary), o(octal),
d(decimal), or h(hexadecimal)
4b1001 = 4d9 = 4O11
unbased literals default to decimal
value is any legal number in the
selected base (plus Z, X if bin/oct/hex)

...
reg [3:0] zbus;
...
zbus = 4b1001;
zbus = 4o05;
zbus = 4d14;
zbus = 4h2f;
...

//
//
//
//

1001
0101
1110
1111

Important
To avoid truncation or padding, size
literal to match target

8b1100_0001

8-bit binary

64hff01

64-bit hexadecimal

9o17

9-bit octal

12

unsized, unbased value (defaults to decimal 32 bits)

h83a

unsized hexadecimal (defaults to 32 bits)

32bz

32-bit z (leftmost x and z automatically extended)


Verilog Logic System and Data Types (VDL5)

4-19

Literal Values

The parser ignores underscores _ in values use underscores to improve readability.

Good coding style uses lower case for base to distinguish octal o from logic 0

Integers can be sized or unsized, based or unbased:


Literal Type

Details

Unsized

The size defaults to 32 bits.


If the base is not selected, it defaults to decimal.

Sized

The width is specified in number of bits.


It is represented as:

<size><base><value>
where base and value are case insensitive.

It is good practice to size a literal to match the value of the literal, and the variable to which it is
assigned.

Remember over-long values are truncated, and over-short values padded with 0 in the msb
e.g the following are legal Verilog, but not good design practice
A Verilog compiler may report warnings for some or all of the below...

...
reg [2:0] zbus;
...
zbus = 4'b1001;
zbus = 3'ha;
zbus = 3'b10;
zbus = 2'b1;

//
//
//
//

001
010
010
001

literal
literal
literal
literal

size/value too long, msb truncated


value too long, msb truncated
value too short, 0 padding at msb
size/value too short, 0 padding at msb

Verilog Application Workshop

4-20

Automatic Extension of Literals

Depending on the base of the


literal, the digits represent
different values
one bit (binary)
three bits (octal)
four bits (hexdecimal)

Question
What is the value in a after these
assignments?

reg [7:0] a;
reg [11:0] b;
initial
begin
// 0 padding
a = 8h11;
a = 8b11;
a = 8d11;
a = 8h01;
a = 8h10;
a = 0;

// z padding
b = 12hzzz;
b = 12hz;
b = 12h0z;
b = 12hz0;
end

If the most significant bit is


an X or Z that value left
extends up to at least 32 bits
Verilog-2001: extends up
to the expression width

//
//
//
//
//
//

contents of a
00010001

00000001
00010000
00000000

z padding
contents of b
// zzzzzzzzzzzz
// zzzzzzzzzzzz
// 00000000zzzz
// zzzzzzzz0000
0 padding

Verilog Logic System and Data Types (VDL5)

4-21

Automatic Extension of Literals


There are three things to know when using literals.
1. The size is always the width of the bus in bits.
2. The base is important because it identifies how many bits are assigned by each digit in the value and
because only binary, octal, and hexadecimal numbers may contain z or x digits.
3. If the most significant digit of the literal is 0 or 1, then the literal left-fills with 0 to the length of
the literal, which by default is 32 bits. If the most significant digit of the literal is z or x, then the literal
left-fills with that digit to the length of the literal.
Verilog-2001 changed this slightly. An unsized literal in an assignment takes the size of the
containing expression, so the 0, z or x extends leftward as far as needed.

Verilog Application Workshop

4-22

Net Types

A net type behaves like a real wire

Various net types are available (wire is the most commonly used)

Undeclared identifiers you use in instance port connections default to wire type
Verilog-2001 adds undeclared identifiers when target of continuous assignment
Change default with `default_nettype <nettype> compiler directive

Continuous assignments (assign) and instance output/inout ports drive nets


wire
wire
wand
tri

sel;
[31:0] w1, w2;
c;
[15:0] busa;

Net types:wire, tri


supply1, supply0
wor, trior
wand, triand
trireg, tri0, tri1

//
//
//
//

Scalar wire
Two 32-bit wires with msb = bit 31
Scalar wired-AND net
A 16-bit tri-state bus, msb = bit 15

module halfadd (
input a, b,
// default to wire
output sum, carry // default to wire
);
// change with assign
assign sum = a ^ b;
assign carry = a & b;
endmodule
Verilog Logic System and Data Types (VDL5)

4-23

Net Types

Nets are continuously driven by the devices that drive them Verilog automatically propagates a
new value onto a net when the drivers on the net change value.
input and inout ports can only use net types
output ports can use net or integral register types

Net types are changed with assign statements in what are called continuous statements. They
can also be changed by a module, primitive or gate which is driving them.

Various net types are available for modeling design-specific and technology-specific
functionality. The most common net type is wire.

Net Types

Functionality

wire, tri
supply1, supply0
wor, trior
wand, triand
trireg
tri1, tri0

For standard interconnection wires (default)


For power or ground rails in netlists only
For multiple drivers that are Wire-ORed
For multiple drivers that are Wire-ANDed
For nets with capacitive storage
For nets that pull up or down when not driven

Synthesis
The IEEE Std. 1364.1 supports synthesis of all net types except tri0, tri1, and trireg.

In some contexts, undeclared nets default to the wire type. You can override this using the
`default_nettype <nettype> compiler directive. With this directive, undeclared nets
default to the nettype in the compiler directive. For this directive, Verilog-2001 adds the none net
type, i.e. do not allow implicit net declarations.
Verilog Application Workshop

4-24

The wire and assign Keywords


a

You can merge the wire


declaration and
assignment

Remember - ports default


to a net type

Note: ~ is an inversion
operator

nsela

sel

out

nsel

selb

Nets
module mux (
input sel, b, a,
output out
);
wire nsela, selb, nsel;
assign nsel = ~sel;
assign selb = sel & b;
assign nsela = nsel & a;
assign out
= nsela | selb;
endmodule

module mux (
input sel, b, a,
output out
);
wire nsel = ~sel;
wire selb = sel & b;
wire nsela = nsel & a;
assign out
= nsela | selb;
endmodule

Verilog Logic System and Data Types (VDL5)

4-25

The wire and assign Keywords


This example is to illustrate use of wire data types & assign statements to build simple circuits. As
we have seen previously, it is easier to describe a multiplexor using procedures. However, assign
statements are not limited to simple structural designs - we will see more complex assign statements
later.
The assign statements could also be mixed with primitive instantiations and simple procedural
statements to describe low level functionality.
e.g. the or gate description
wire out;
assign out = nsela | selb;
can also be described using:a primitive
wire out;
or U1 (out, nsela, selb);
a procedural statement
reg out;
always @(nsela or selb)
out = nsela | selb;

Verilog Application Workshop

4-26

Logic Conflict Resolution with Nets

If the same net is driven


from multiple sources a
conflict occurs

Net types have a resolution


function to determine final
value of target

b
y declared as

y declared as

y declared as

ab

0
1
x
z

0
x
x
0

x
1
x
1

x
x
x
x

0
1
x
z

0
1
x
z

0
0
0
0

0
1
x
1

0
x
x
x

0
1
x
z

wor y;
trior y;

wand y;
triand y;

wire y;
tri y;

assign y = a;
assign y = b;

0
1
x
z

0
1
x
0

1
1
1
1

x
x
1
x
x

z
0
1
x
z

Verilog Logic System and Data Types (VDL5)

4-27

Logic Conflict Resolution with Nets

Net types have a truth table (net resolution function) to determine final value of target

Multiple drivers use the net resolution function recursively


e.g. when driving 0, 1 and z onto a net, resolution of the 1 and 0 returns x; resolution
of this value (x) with the final driving value z returns x for the resulting value of the net.

Use wired AND (wand) or wired OR (wor) nets to resolve to a 0 or 1

Technology-dependent logic conflict resolution is supported.


wired-AND for open collector
wired-OR for ECL

Net types tri and wire are identical in functionality. You can use the different names to
enhance readability. For example, you can use tri for the nets that have multiple drivers.
Another reason to declare a net as a tri is to indicate that this net can be driven to a
high-impedance (z) state.

Synthesis tools that support wor and wand, will create extra logic to implement the wired-AND
or wired-OR connections.

Verilog Application Workshop

4-28

Register Types
Register types store value until you
procedurally assign a new value.
Verilog has these register types:
reg unsigned user-defined width 4-state
Verilog-2001 adds reg signed

integer signed 32-bit 4-state

time unsigned 64-bit 4-state

real double-precision float

realtime same as real

parameter constant of any type

module mux (
input
a, b, sel,
output reg op
);
always @(a or b or sel)
if (sel == 1)
op = a;
else
op = b;
endmodule

Synthesis
Synthesis tools accept integer and reg but do not
necessarily infer a storage device
reg [3:0] vect;
reg [2:0] p, q;
integer aint;
reg s;
time delay;

//
//
//
//
//

4-bit unsigned vector


two 3-bit unsigned vector
32-bit signed integer
unsized reg defaults to 1-bit
time value

Verilog Logic System and Data Types (VDL5)

4-29

Register Types
A register variable holds its value until a new value is assigned to it.

Register Types Functionality


reg
reg signed
integer
real
time

Unsigned integer variable of varying bit width


Signed integer variable of varying bit width Verilog-2001
Signed integer variable, 32-bits wide. Arithmetic operations
produce 2s-complement results.
Signed floating-point variable, double precision.
Unsigned integer variable, 64-bits wide.

reg is the most common register type. You can declare it to be scalar or vector.
integer is used for signed (2s complement) arithmetic. It is always 32 bits.
real has the same usage as integer, except that you use it for real numbers.
time stores and manipulates simulation time, delays etc.
Reals

Real numbers can be represented in scientific notation or decimal notation.

Scientific notation:- <mantissa><e or E><exp> , interpreted as <mantissa> * 10<exp


32e-4
4.1E3

scientific notation for 0.0032


scientific notation for 4100
Verilog Application Workshop

4-30

Register Assignment

You assign to register types using


procedural assignments only

You make procedural assignments


to register types only

You can assign from nets and


registers from inside or outside
procedures

Error

Net type assigned


in procedure

Error

Register type
assigned outside
procedure

module mux (
input a, b, sel,
output mux
);
wire aandb, nmux;
reg mux, nota;
always @(a or b or sel)
if (sel == 1)
begin
mux = a;
nmux = b;
end
else
begin
mux = a;
nmux = b;
end
assign nota = ~a;
assign aandb = a & b;
...

Verilog Logic System and Data Types (VDL5)

4-31

Register Assignment
If we assign a value to a variable from within a procedure, then the variable must be a register type.
Likewise a register variable type can only be updated from within a procedure.
Net types can be assigned to register types in procedural assignment
Register types can be assigned to net types in assign statements

Verilog Application Workshop

4-32

Integer Assignment

Unsized literals default to


32 bits

integer variables are


signed 32 bits

reg variables are sized


unsigned vectors
Verilog-2001 adds reg
signed type

Can assign integer to


reg and reg to integer
Over-sized data is
truncated

...
// Verilog-2001 declaration assignment
integer int = 129; // 11..1000001
reg [3:0] data;
initial
begin
data =
int =
int =
data =
int =
end
...

32 bits assigned to 4 bits


data truncated

int;
data;
-3;
int;
data;

Under-sized data is
padded with 0

//
//
//
//
//

data = 0001
int = 1
11..1111101
data = 1101
int = 13

signed integer
assigned to
unsigned reg...
...value assigned
back to integer
as positive number

Caution
When assigning integer to reg
(by default unsigned) sign is lost

Verilog Logic System and Data Types (VDL5)

4-33

Integer Assignment
Remember:

Literals can be decimal, hexadecimal, octal or binary. Decimal is the default

Unsized literals default to 32 bits in length

integer types are 32 bits in length

reg and integer types can be freely assigned to each other using procedural assignment
statements

When a negative integer value is assigned to a reg variable, the reg variable will contain the
2s complement value of the negative value: but because reg types are unsigned, this value will
be treated as positive. So if the value is then assigned back to the integer variable, the
integer variable will contain a positive value.
Verilog-2001 adds the reg signed declaration to preserved sign information
Verilog-2001 adds the $signed and $unsigned system tasks to convert between signed
and unsigned types

Verilog Application Workshop

4-34

Choosing the Correct Data Type


Module Boundary of DUT

Input Port
net/register
atop

net
a
b

Output Port
net/register
net

btop

module top;
wire ytop;
reg atop, btop;

net

ytop

Inout Port
net

initial
begin
atop = 1b0;
btop = 1b0;
end

module dut (
input a, b,
output y
);

dut U1 (.a(atop), .y(ytop), .b(btop));


endmodule

assign y = a & b;
endmodule

Verilog Logic System and Data Types (VDL5)

4-35

Choosing the Correct Data Type


Data type rules:

An input port can be driven by a net or a register, but it can only drive a net.

An output port can be driven by a net or a register, but it can only drive a net.

An inout port can only be driven by a net, and it can only drive a net.

If a signal is assigned a value from a procedural block, it must be declared as a register.

Here are some common user errors, along with their typical error messages:

You make a procedural assignment to a signal that you either declared as a net or you forgot to
declare.
illegal assignment

You connect an output from an instance to a signal declared as a register. This is illegal as a
module output can only drive a net.
illegal output port specification

You declare a signal as a module input and as a register. This is illegal as inputs can only be nets
incompatible declarations

Verilog Application Workshop

4-36

Module Parameters

Module parameters are


instance-specific constants

Use them to parameterize


your module definition
Width of ports, variables etc.

Can override for each


individual instance

// example parameter list


parameter INTEGER_P = 8,
REAL_P
= 2.039,
VECTOR_P = 16bx;
Note: Verilog-2001 allows you to
specify a parameter type and to
sign and size vector parameters

// Verilog-1995 syntax
module mux (a, b, sel, out);
parameter WIDTH = 2;
input [WIDTH-1:0] a, b;
input
sel;
output [WIDTH-1:0] out;
reg
[WIDTH-1:0] out;
...
endmodule
// Verilog-2001 alternative
module mux
#(
parameter integer WIDTH = 2
)
(
input wire [WIDTH-1:0] a, b
input wire
sel,
output reg [WIDTH-1:0] out
);
...
endmodule

Verilog Logic System and Data Types (VDL5)

4-37

Module Parameters

Use module parameters to parameterize your module definition

You can use a module parameter anywhere that you can use a literal

Typically, you use module parameters to define delays and widths of variables

You can override module parameter values on a per-instance basis

You cannot modify module parameters during runtime they are not variables

Verilog-1995 syntax for module parameters is:


parameter_declaration ::=
parameter list_of_param_assignments ;
list_of_param_assignments ::=
param_assignment { , param_assignment }
param_assignment ::=
parameter_identifier = constant_expression

Verilog-2001 allows you to specify a type and to sign and size vector parameters:
parameter_declaration ::=
parameter [ signed ] [ range ] list_of_param_assignments ;
| parameter integer list_of_param_assignments ;
| parameter real list_of_param_assignments ;
| parameter realtime list_of_param_assignments ;
| parameter time list_of_param_assignments ;

Verilog-2001 allows to declare a module parameter port list:


module_declaration ::=
{ attribute_instance } module_keyword module_identifier
[ module_parameter_port_list ] [ list_of_port...
module_parameter_port_list ::=
# ( parameter_declaration { , parameter_declaration } )
Verilog Application Workshop

4-38

Overriding the Values of Parameters


You can change the parameter values for individual instances of the module
module muxs (abus, bbus, anib, bnib, sel, opbus, opnib, opnib1);
parameter NIB = 4;
input [NIB-1:0] anib, bnib;
input [7:0] abus, bbus;
input sel;
output [7:0] opbus;
output [NIB-1:0] opnib, opnib1;

module mux (a, b, sel, out)


parameter WIDTH = 2;
...

// module instantiations for different sized muxes


mux #(8)
mux8 (.a(abus), .b(bbus), .sel(sel), .out(opbus));
mux #(NIB) muxN (.a(anib), .b(bnib), .sel(sel), .out(opnib));
mux mux4 (.a(anib), .b(bnib), .sel(sel), .out(opnib1));
defparam mux4.WIDTH = 4;
endmodule

Synthesis
The synthesis standard disallows the defparam construct.

Verilog Logic System and Data Types (VDL5)

4-39

Overriding the Values of Parameters

Use the #() construct to override the values of parameters for a particular instance of a module
in the module instantiation statement
Update module parameter values in the order you declared the parameters in the module

For Verilog-1995 to update a parameter value, you must also update positionally earlier values
For example, if module mod declared three parameters, a, b, and c:
mod U1 #(a,b) (...);
// valid - parameter c unchanged
mod U2 #(a) (...);
// valid - parameters b & c unchanged
mod U3 #(a, ,c) (...); // invalid - cannot omit b
mod U4 #(, b,c) (...); // invalid - cannot omit a

For Verilog-2001 you can update parameter values by name:


mod U3 #(.a(a), ,.c(c)) (...); // valid in Verilog-2001
mod U4 #(, .b(b),.c(c)) (...); // valid in Verilog-2001

Note: You also use the # character to specify primitive delays. As modules cannot have associated
primitive delays, for modules, this character always means a module parameter override.
Caution
The defparam construct also overrides parameter values. The statement must include the relative
hierarchical name of the parameter from the defparam statement location. Use of defparam is
superfluous when done locally and can potentially cause much confusion when not done locally.

Verilog Application Workshop

4-40

Local Parameters
Verilog-2001 adds the localparam construct.
A constant you cannot override not a module parameter

Otherwise identical to module parameters in all respects


Module or block declaration item
Replace parameter with localparam

Use for constants that should never be overridden upon instantiation


For a module that is not instantiated (testbench?)
For enumerations (FSM states?)
localparam integer WAITING
STATE1
STATE2
STATE3

=
=
=
=

0,
1,
2,
3;

Verilog Logic System and Data Types (VDL5)

4-41

Local Parameters

Verilog Application Workshop

4-42

Arrays
Verilog-1995 supports one-dimensional arrays of integer, reg, and time
integer int_a [0:99]; // array of 100 integer
reg [7:0] reg_a [0:99]; // array of 100 8-bit vectors

You access one element (word) at a time by indexing to that word

You cannot directly take bit or part selects of a word (use an intermediate variable)
reg [7:0] word, array [0:255]; // memory word and array
reg bit;
...
word = array[5]; // access address 5
word = array[10]; // access address 10
bit = word[7];
// access bit 7 of extracted word

Verilog-2001 supports multi-dimensional arrays of integer, real, realtime, reg, time,


and nets
reg reg_b [0:99] [7:0]; // 100x8 array of 1-bit elements

You can directly take bit and part selects of an indexed element
reg [7:0] array [0:255]; // memory array
bit = array[10][7];
Verilog Logic System and Data Types (VDL5)

4-43

Arrays

The syntax for a memory array is:


reg [msb:lsb] <memory_name> [first_addr:last_addr];
where:
msb and lsb (in either order) determine the word size of the array.
memory_name is the name of the array.
first_addr and last_addr (in either order) determine the depth of the array.
Some more examples
reg [7:0] prep [hFFFE:hFFFF]; // 2 x 8-bit 2-d array
time hold[2:0];
// Array of time values 3 deep

You can declare word size and array depth with any legal expression.
You can use module parameters to specify the memory size:
parameter WORDSIZE = 16;
parameter MEMSIZE = 1024
reg [WORDSIZE-1:0] mem3 [MEMSIZE-1:0];

An array element is accessed using any valid expression as an index to the array.
array_name [addr_expr]

Verilog Application Workshop

4-44

Summary

A net type behaves like a real wire driven by a logic gate


Nets not explicitly declared default to type wire
Net values changed with assign statement or when driven by a
module/primitive

Register types stores value until a new value is assigned


Register types do not have to synthesize to a register hardware element
Register types can only be updated with a procedural assignment
Procedural assignment can only update register types
When assigning integer to reg, sign information is disregarded

Registers and nets can be mixed on the right-hand-side of an assignment

Module ports are defined as wire by default


Inputs must be net types, but can be driven by nets or registers
Inouts must be net types and can only be driven by a net
Outputs can be net or a register types, but can only drive a net

Verilog Logic System and Data Types (VDL5)

4-45

Summary

Verilog Application Workshop

4-46

Review
1. What is the primary difference between a net and a register?
2. The bitwise AND operator is &. Code the following hardware using (i) a reg type
(ii) a wire type

a
c

3. How may bits wide is the integer type?


4. What are the 4 logic values in the Verilog Value System
5. Rewrite the following statement using a hexadecimal literal:aval = 8b11010011

Verilog Logic System and Data Types (VDL5)

4-47

Review

Verilog Application Workshop

4-48

Verilog Operators
VVO4

5-1

Notes

Verilog Application Workshop

5-2

Aims and Topics

Aims
Introduce the operators available in the Verilog language

Topics
Operator Type

Symbol

arithmetic

+ - * / %
~ & | ^ ~^
! && ||
& | ^ ~& ~| ~^
<< >>
< > <= >=
== != === !==
?:
{}
{{}}

bit-wise
logical
reduction
shift
relational
equality
conditional
concatenation
replication

Verilog Operators (VVO4)

5-3

Operator Types
Verilog has arithmetic, bit-wise, logical, reduction, shift, relational, equality, conditional,
equality, concatenation and replication operators. An explanation of each with an example is
shown in this chapter.

Verilog Application Workshop

5-4

Arithmetic Operators
+

add

subtract

multiply

divide

% modulus

integer is signed

reg is unsigned
Verilog-2001 you can
also declare a reg signed
Verilog-2001 you can
convert between signed and
unsigned using $signed
and $unsigned

module arithops;
//Verilog-2001 local constants
localparam integer CONST_INT = -3,
CONST_5
= 5;
localparam [3:0] rega = 3,
regb = 4b1010,
regc = 14;
integer val;
reg [3:0] num;
initial
begin
val
val
val
num
num
num
num
end

=
=
=
=
=
=
=

CONST_5 * CONST_INT;
(CONST_INT + 5)/2;
CONST_5/CONST_INT;
rega + regb;
rega + 1;
CONST_INT;
regc % rega;

//
//
//
//
//
//
//

-15
1
-1
1101
0100
1101
2

endmodule

Verilog Operators (VVO4)

5-5

Arithmetic Operators
An arithmetic operation on an integer type behaves differently than an operation on a reg type. In
Verilog, a reg data type can only contain an unsigned value while an integer type contains a signed
value.
Integers are always truncated to a whole number. Hence in the example ans = FIVE/int; 5 divided
by -3 yields -1.
The example num = int; shows the integer -3 assigned to a 4 bit reg. -3 in 2's compliment is
32b1111111....11101. This is truncated to our 4 bit reg yielding 4b1101 . Since reg variables
are unsigned, this is interpreted as +13!
Caution
Binary arithmetic on unsigned quantities, such as reg variables, is unsigned (negative results are
converted to the twos complement).

Verilog Application Workshop

5-6

Bit-Wise Operators
~ not
& and
| or
^ xor
~^ xnor

module bitwise ();


reg [3:0] rega, regb, regc;
reg [3:0] num;
initial
begin
rega = 4b1001;
regb = 4b1010;
regc = 4b11x0;

^~ xnor

Bit-wise operators
operate on vectors.

Operations are
performed bit by bit
on individual bits.

num = ~rega;
num = rega &
num = rega &
num = rega |
num = regb &
num = regb |
end
endmodule

0;
regb;
regb;
regc;
regc;

//
//
//
//
//
//

num
num
num
num
num
num

=
=
=
=
=
=

0110
0000
1000
1011
10x0
1110

Note: Unknown bits in an operand do not necessarily lead to unknown bits in the result.

Verilog Operators (VVO4)

5-7

Bit-Wise Operators
Bit-wise binary operators perform bit-wise manipulations on two operands. They compare each bit in
one operand with its corresponding bit in the other operand to calculate each bit for the result. Normally
used for vectors but works equally on scalar (single bit) values.
regb = 4b1010
regc = 4b1x10
num = regb & regc = 1010;
The operators can be used with operands of different sizes - the smaller operand is zero-extended to the
size of the larger operand and the result is the width of the larger operand (result could be truncated if
assigned to a variable of smaller width)
For example:
reg
reg
reg
...
a =
b =
c =

[3:0] a;
[7:0] b;
[5:0] c;
4b1011;
8b01010011;
a | b;

a is zero-extended to 8b00001011, a | b evaluates to 8b01011011, and is truncated to


6b011011 when assigned to c.
Unknown bits in an operand do not necessarily lead to unknown bits in the result. For the regb | regc
example, the unknown bit in regc is ORed with a 1 in regb, resulting in a 1.
Verilog Application Workshop

5-8

Logical Operators
!

not

module logical;
// Verilog-2001 local constants
localparam integer FIVE = 5;
localparam [3:0] CONST_A = 4b0011,
CONST_B = 4b10xz,
CONST_C = 4b0z0x;
reg ans;

&& and
|| or
Logical operators interpret their
operands as either true (1b1) or false
(1b0) or unknown (1bx)
1 if any bit 1
0 if all bits 0
x if any bit z or x and no bit 1

initial
begin
ans
ans
ans
ans
ans
ans
end

=
=
=
=
=
=

!CONST_A;
CONST_A &&
CONST_A ||
CONST_A &&
CONST_A &&
CONST_C ||

0;
0;
FIVE;
CONST_B;
0;

//
//
//
//
//
//

0
0
1
1
1
X

endmodule

Verilog Operators (VVO4)

5-9

Logical Operators
Logical operators reduce both operands to a single bit, and then performs a single bit operation.
Rules for reduction are:

If the operand contains all zeroes, it reduces to logic 0.

If the operand contains any ones, it reduces to logic 1.

If the operand contains no ones, but does contain one or more x or z values, its logical value is
ambiguous, and it reduces to x

The logical negation operator reduces an operand to its logical inverse. For example, if an operand
contains all zeroes, it is false (logic 0), so its inverse is true (logic 1).

Verilog Application Workshop

5-10

Unary Reduction Operators


&

and

or

xor

module reduction;
// Verilog-2001 local constants
localparam [3:0] CONST_A = 4b0100,
CONST_B = 4b1111;
reg val;

~& nand
~| nor
~^ xnor
^~ xnor

Reduction operators
perform a bit-wise
operation on all the bits of
a single operand.

initial
begin
val
val
val
val
val
val
val
val
val
end

=
=
=
=
=
=
=
=
=

&CONST_A ;
|CONST_A ;
&CONST_B ;
|CONST_B ;
^CONST_A ;
^CONST_B ;
~|CONST_A;
~&CONST_A;
^CONST_A && &CONST_B;

//
//
//
//
//
//
//
//
//

0
1
1
1
1
0
0
1
1

endmodule

The result is always


1b1, 1b0 or 1bx.
Verilog Operators (VVO4)

5-11

Unary Reduction Operators


Unary reduction operators operate on all bits of a single operand to produce a single-bit result.
In the first example, &CONST_A is evaluated as ((CONST_A[3] & CONST_A[2]) &
CONST_A[1]) & CONST_A[0]
x or z values in the operand can be hidden by ORing with 1 or ANDing with 0. Any x or z value in a
XOR or XNOR operand will always produce x.
The compiler distinguishes between unary reduction operators and bit-wise operators by examining the
context of use.

Verilog Application Workshop

5-12

Shift Operators
<< logical shift left
>> logical shift right

module shift ();


reg [7:0] rega = 8b10011001;
reg [7:0] regb;

Logical shift operators


perform left or right bit
shifts on the left operand

initial
begin
regb = rega << 1; // 00110010
regb = rega >> 1; // 01001100
regb = rega << -1; // 00000000
end

Ignores operand signs


Fills extra bits with 0

Use to implement division


or multiplication by
powers of two

Verilog-2001 adds arithmetic


shift left <<< and shift right
>>>. The arithmetic shift
left operates like the logical
shift left. The arithmetic shift
right preserves the sign of the
left operand.

endmodule

-1 is 2**32-1

Verilog Operators (VVO4)

5-13

Shift Operators
<< shifts the left operand left by the number of positions specified by the right operand.
>> shifts the left operand right by the number of positions specified by the right operand.
In an assignment, if the result of the RHS is of:

Greater bit-width than the LHS, its most significant bits are truncated

Smaller bit-width than the LHS, it is zero-extended

Verilog Application Workshop

5-14

Relational Operators
>

greater than

<

less than

module relationals;
reg [3:0] rega, regb, regc;
reg val;

>= greater than or equal


<= less than or equal

The result is:-

initial
begin
rega = 4b0011;
regb = 4b1010;
regc = 4b0x10;

1b1 if the condition is true


1b0 if the condition is false
1bx if the condition cannot be
resolved

val
val
val
val
end

=
=
=
=

regc
regb
regb
regb

> rega ;
< rega ;
>= rega;
> regc ;

//
//
//
//

val
val
val
val

=
=
=
=

x
0
1
x

endmodule

Verilog Operators (VVO4)

5-15

Relational Operators
If differently sized vectors are compared, the shorter is padded out with leading 0s to match the length
of the larger operand.

Verilog Application Workshop

5-16

Logical and Case Equality


== is the logical equality operator.
==

...
a = 2b1x;
b = 2b1x;
if (a == b)
// values match & do not contain z or x
else
// values do not match or contain z or x
// above values execute this else branch

=== is the case equality (identity) operator.


===

...
a = 2b1x;
b = 2b1x;
if (a === b)
// values match exactly
// above values execute this if branch
else
// values do not match

Verilog Operators (VVO4)

5-17

Logical and Case Equality


The difference between the logical and case equalities is the handling of the x and z values.
With the logical equality operator, an x or z in either of the operands is logically unknown.
2'b0x == 2'b1x evaluates to 1'bx
With the case equality (identity) operator, the result can still evaluate to true (1) or false (0) when x or z
values are present in the operands.
2'b0x === 2'b1x evaluates to 0, because they are not identical
2'b1x === 2'b1x evaluates to 1, because they are identical
Case equalities can be useful for creating 3-state detectors (for example) to monitor the value on a tristate
bus for a testbench.
Case equality is essential in a testbench to detect erroneous values:
if (actual_response !== expected_response) ...
Caution
Remember: = is the assignment operator.

Verilog Application Workshop

5-18

Equality Operators
== logical equality
!= logical inequality
=== case equality
!== case inequality

For logical equalities, the


result is always 1b1,
1b0 or 1bx
For case equalities, the
result is always 1b1 or
1b0
Synthesis
The synthesis standard does not
support case equality operators

module equalities();
reg [3:0] rega, regb, regc;
reg val;
initial
begin
rega = 4b0011;
regb = 4b1010;
regc = 4b1x10;
val = rega
val = rega
val = regb
val = regc
val = rega
val = rega
val = regb
val = regc
end
endmodule

== regb;
!= regb;
!= regc;
== regc;
=== regb;
!== regc;
=== regc;
=== regc;

//
//
//
//
//
//
//
//

val
val
val
val
val
val
val
val

=
=
=
=
=
=
=
=

0
1
x
x
0
1
0
1

Verilog Operators (VVO4)

5-19

Equality Operators
An expression with the equality operator evaluates to:

1 (true) if the LHS and RHS have equal, known values. Known values do not contain x or z

0 (false) if the LHS and RHS have known values and are not equal.

x (unknown) if either the LHS or RHS have unknown values. Unknown values contain x or z.

!= is the inequality operator. It is the inverse of the == operator and works the same way.
The case equality operators are also called the identity operators because they test to see if the operands
are identical.
An expression with the identity operator evaluates to:

1 (true) if the LHS and RHS have identical values, including x and z

0 (false) if the LHS and RHS do not have identical values

!== is the inverse of the === operator and works the same way.

Verilog Application Workshop

5-20

Conditional Operator
module tribuf (
input
in, enable,
output reg out
);

?: conditional

in

always @(enable, in)


out = enable ? in : 1bz;

out

endmodule

enable

...
wire out3;
reg out1, out2;

always @ (a or b or sel)
out1 = sel ? a : b;

out
b

sel
Note: Sometimes the if else
construct may be more
readable

always @ (a or b or sel)
if (sel)
out2 = a;
else
out2 = b;
assign out3 = sel ? a : b;
...
Verilog Operators (VVO4)

5-21

Conditional Operator
The syntax for the conditional operator is:
<LHS> = <condition> ? <true_expression> : <false_expression>

This can be read as:


if condition is TRUE, then LHS = true_expression, else LHS = false_expression
Each conditional operator must have all three RHS arguments. If one is missing, an error message will
be displayed. The final operand serves as a default.
For example. If sel is 0 then out is set equal to a, if sel is 1 out is set equal to b.
assign out = (sel == 0) ? a : b;
a and b may be constants or complex scalar or vector expressions
Think of the conditional operators as a simple 2_to_1 multiplexer, selecting one of two inputs depending
on the outcome of the logical select evaluation.
You can nest conditional expressions:
cond1 ? (cond2 ? a : b) : (cond2 ? c : d)

Verilog Application Workshop

5-22

Concatenation
{} concatenation

Allows you to select


bits from different
vectors and join them
into a new vector.
Used for bit
reorganization and
vector construction
e.g. rotates

Can used on either


side of assignment

Important
Literals used in concatenation
must be sized

module concatenation;
reg [7:0] rega, regb, regc, regd, new;
reg [3:0] nib1, nib2;
initial
begin
rega =
regb =
regc =
regd =

8b00000011;
8b00000100;
8b00011000;
8b11100000;

new = {regd[6:5], regc[4:3], regb[3:0]};


// new = 8b11_11_0100
new = {2b11, regb[7:5], rega[4:3], 1b1};
// new = 8b11_000_00_1
new = {regd[4:0], regd[7:5]};
// rotate regd right 3 places
// new = 8b00000_111
{nib1, nib2} = rega;
// nib1 = 40000, nib2 = 40011
end
endmodule
Verilog Operators (VVO4)

5-23

Concatenation
You can use concatenation on an unlimited number of operands. The operator symbol is {} with
operands separated by commas. For example: {A, B, C, D, E}
You must use sized quantities in concatenation. If you do not, an error message will be displayed.
Here are some examples that fail to size their operators:
a[7:0] = {5b01010, 2}; //decimal value 2 unsized
c[3:0] = {3b011, b0}; //binary value b0 unsized

Verilog Application Workshop

5-24

Replication
{{}} replication

Replication allows you to


reproduce a sized variable a set
number of times
Can be nested and used with
concatenation

Syntax is:-

{<repetitions> {<variable>}}
Important
Literals used in replication must be sized
4x rega concatenated
with 2x regc[1:0]
regc concatenated
with 2x regb
regc concatenated with 2x
1b1 and replicated 2 times

module replicate ();


reg rega;
reg [1:0] regb;
reg [3:0] regc;
reg [7:0] bus;
initial
begin
rega = 1b1;
regb = 2b11;
regc = 4b1001;

single bit rega


replicated 8 times

bus = {8{rega}};
// bus = 11111111
bus = { {4{rega}}, {2{regc[1:0]}} };
// bus = 1111_01_01
bus = { regc, {2{regb}} };
// bus = 1001_11_11
bus = { 2{regc[2:1], {2{1b1}}} };
// bus = 00_1_1_00_1_1
end
endmodule

Verilog Operators (VVO4)

5-25

Replication
The operator symbol is {{}}
Syntax is:- {<no repetitions> {<variable>}}
In the second and third examples above, replication is used with concatenation to make a new 8 bit
register.
You can also use replication on an unlimited number of operands.
For example: {{4{A}}, {6{B}}, C}
You must use sized quantities in concatenation and replication. If you do not, an error message will be
displayed.
Here are some examples that fail to size their operators:
a[7:0] = {4{b10}};
//binary value b10 unsized
b[7:0] = {2{5}};
//decimal value 5 unsized

Verilog Application Workshop

5-26

Operator Precedence
Reliance on operator precedence may make your code unreadable use parentheses!
Type of Operators

Symbols

Concatenation / Replication
Inversion (Logical / Bitwise / Arithmetic)
Exponential
Arithmetic
Shift
Relational
Equality
Bit-wise / Reduction

Logical
Conditional

{ }
!
**
*
+
<<
<
==
&
^
|
&&
||
? :

{{ }}
~
/
>>
<=
!=
~&
^~
~|

Highest

%
(binary)
<<< >>>
>
>=
=== !==

Precedence

~^

Lowest
Verilog Operators (VVO4)

5-27

Operator Precedence
Without looking at the above table, what is the precedence of the subexpressions?
a ? ~ b * c << d : e < f ^ g || h
Wouldnt it really help if the author used parentheses?
a ? ((~b * c) << d) : (((e < f) ^ g) || h)

Verilog Application Workshop

5-28

Review
1. How many bits is the result of a logical && operation?
2. What is the difference between && and &, if any?
3. What must you do to values you replicate with the replication operator?
4. Given
regx = 4b0101;
what is the value of:bus = { 2{regx[3:1], {3{1b0, regx[0]}}} };
5. If regb is defined as a four bit signed number as shown below, give the code for
an arithmetic binary division by two. Hint: the sign bit (or most significant bit) must
remain intact.
reg [3:0] regb;

Verilog Operators (VVO4)

5-29

Review

Verilog Application Workshop

5-30

This page left intentionally blank

Procedural Statements
V1E3

6-1

Notes

Verilog Application Workshop

6-2

Aims and Topics

Aim
To introduce some of the most commonly used procedural statements

Topics
Procedures
Procedural statements
if then else
case
loops

Procedural Statements (V1E3)

6-3

Terms and Definitions

Verilog Application Workshop

6-4

The initial and always Keywords


There are 2 types of procedural blocks

always procedure executes


repeatedly throughout the simulation
triggered by a change of value for
any variable in the event list

initial procedure executes once at


start of simulation

You must group multiple statements


within a block using begin...end
or fork...join (more later)

Synthesis
The synthesis standard does not support the initial
construct

...
reg a, b, zor, zand;
initial
begin
a
= 1b1;
b
= 1b0;
end
Verilog-2001
wildcarded
always @*
event list
begin
if (a | b)
zor = 1b1;
else
zor = 1b0;
if (a & b)
zand = 1b1;
else
zand = 1b0;
end
...
Procedural Statements (V1E3)

6-5

The initial and always Keywords

Procedural blocks are of two types:


initial procedural blocks, which execute only once
always procedural blocks, which execute in a loop

always blocks act like a continuous loop, but initial blocks operate once and stop.

always

initial
s
s
s
s
s
s
s

s
s
s
s
s
s
s

Verilog Application Workshop

6-6

Procedural Assignments

Assignments made inside


procedural blocks are called
procedural assignments

All variables on the


left-hand side must be
register data-types, e.g reg

module fulladder (
input
a, b, cin,
output reg [1:0] out
);
reg sum, carry;
always @(a,
begin
sum
=
carry =
out
=
end

b, cin)
a ^ b ^ cin;
(a & b) | cin & (a ^ b);
{carry, sum};

endmodule

Procedural Statements (V1E3)

6-7

Procedural Assignments
Assignments made inside procedural blocks are called procedural assignments.

Right-hand side of a procedural assignment can be any valid expression - there is no restriction on
the data types used in the expression.

Left-hand side of procedural assignment must be a suitable register type, e.g. reg

Verilog Application Workshop

6-8

Event Control

always procedure resumes when


one or more variables in the event
list change value

Synthesis
For the generation of combinational logic, ensure
that all signals read by the block are in the event list.

Can also use negedge or


posedge qualifiers

always @(a or b or sel)


begin
if (sel == 1)
event list
y = a;
else
y = b;
end

always @(posedge clk)


// procedural statements

Procedure resumes on a specific edge


of a variable
Use to model sequential logic
Synthesis
The synthesis standard supports event lists that are
either fully edge-qualified (sequential) or fully not
edge-qualified (combinational)

always @(negedge clk)


// procedural statements

always @(negedge clk or rst)


// not synthesisable
...

Procedural Statements (V1E3)

6-9

Event Control
Note: The or event control modifier has nothing to do with the bitwise OR operator | or the logical OR
operator ||.
The language allows any variables to be placed in the @(events list) control of a procedural block.
This gives rise to the concept of the complete event list, where all of the variables whose values are
read in the procedure are included in it.
A change in value of any input signal to a block of combinational logic can result in a change at the
outputs. Therefore, whenever any of the inputs to a procedural block which models combinational logic
change, we need to force the re-execution of the block to re-evaluate the output.
Hence to model and synthesize combinational logic we need a complete event list.
Synchronous or registered logic outputs will only be updated on the rising or falling edge of a clock
(assuming the logic is not asynchronously reset). Therefore we only need to force the execution of a
sequential logic procedure on the edge of a clock.
So to model and synthesize sequential logic, we use either (posedge clk) or (negedge clk).
More on this later.
Synthesis requires the triggers in an event list to be either all edge-qualified or none edge-qualified.

Verilog Application Workshop

6-10

Procedural Blocks within Verilog


module design;
wire nsela;
wire nsel
wire selb

= !sel;
= sel & b;
Procedure

always @(nsel or selb)


out = nsel | selb;
Procedure
assign nsela

= nsel & a;

always @(a or b or sel)


begin
// procedural statements
end

Procedure

// continuous statements
Procedure
...
endmodule

Procedural Statements (V1E3)

6-11

Procedural Blocks within Verilog


So if we now relate our concept to how it is represented in Verilog code, we see that we can have any
number of procedures defined within an module.
Outside of the procedures we are allowed to have other statements which are continually driven, called
continuous assignments.
In fact, these single continuous assignment statements are considered to be like miniature procedures, so
that they fit into the model that we have seen
The statements inside procedures are executed in the order in which they are written - like real software

Verilog Application Workshop

6-12

if Statement

if is a conditional
statement

Condition is boolean
expression

Each if condition is
tested in sequence

The first valid test


executes that branch

Conditions can overlap

module if_example (
input
[3:0] a, b, c, d,
output reg [3:0] y
);
always @(a or b or c or d)
if (d == 4b0000)
y = a;
else if (d <= 4'b0101)
y = b;
else
y = c;
endmodule

?Question
What would be the effect of
swapping the if and else if
conditions?

Inferred hardware
structure

c
Synthesis
if synthesizes to mux structures

0101

b
a

0000

<=
=
0
1

mux

mux
Procedural Statements (V1E3)

6-13

if Statement
So having looked at the theory behind continuous and procedural statements, we will spend the rest of
this section looking at three different examples of procedural statements: if, case and for loops
if statements are conditional and allow procedural statements to be executed dependant on the result
of testing a conditional statement.
In the example above, when a, b, c or d change value, the always procedure is executed.
If d is equal to zero (logical equality) then the procedural statements associated with the condition are
executed, and y is assigned the value of a.
If d is not equal to 0, then the else branch is taken. This branch contains another if statement testing
whether d is less than or equal to 0101. If this condition is true, then b is assigned to y. If this condition
is false, then the else branch is executed - this does not contain any further conditions, so c is assigned
to d.
Notice that the conditions d == 0 and d <= 4'b0101 overlap, but because d == 0 is tested
first, then y is assigned a when d = 0000. It is only if d does not equal 0 that the second condition is
tested.
Therefore the conditions of an if-else-if statement are tested in order - the first condition having
the highest priority, the second condition having the next highest priority, etc.

Verilog Application Workshop

6-14

if Statement Syntax
if (CONDITION) begin
// procedural statements
end

Single if statements execute


procedural statements only if
the condition is true...

if (CONDITION) begin
// procedural statements
end
else begin
// procedural statements
end

...add an unconditional else


to execute procedural
statements when the if
condition is false...

...add else if to test


further conditions if the first
is false

if (CONDITION) begin
// procedural statements
end
else if (CONDITION) begin
// procedural statements
end
else begin
// procedural statements
end

Final else is optional and


can be used to indicate
default operation

Use begin and end to


bound multiple procedural
statements

Procedural Statements (V1E3)

6-15

if Statement Syntax
The order of evaluation (priority) is sequential, testing the if condition first...
If the conditional evaluates to true, the simulator executes the procedural statements for the if branch.
If false the optional else branch is executed
On completion of the active branch the if-else statement will terminate.
Notice that omitting the optional else may result in no branches being executed.
In nested if sequences, else is associated with the closest previous if.
Use indentation to aid readability.
To ensure proper association, use begin...end block statements.

Verilog Application Workshop

6-16

case Statement

case is a multiway
conditional statement

case expression is
evaluated and compared
against each item in turn
Branch items can overlap
The first item match
executes that branch

The optional default


captures unspecified values
In this example, values
containing x or z

module case_example (
input
[3:0] a, b, c, d,
output reg [3:0] y
);
always @*
case (d)
0
1,2,3,4,5
6
7
default
endcase

:
:
:
:
:

y
y
y
y
y

=
=
=
=
=

a;
b;
c;
c;
4'b0000;

endmodule

Procedural Statements (V1E3)

6-17

case Statement
The case statement evaluates an expression and selects one of a number of sequences of statements
depending on the value of the expression.
In the example above, when a, b, c or d change value, the always procedure is executed. The case
statement examines the value of d. If d is 0000, output y is assigned a; if d is 0001, 0010, 0011,
0100 or 0101, output y is assigned b; if d is 0110 or 0111, y is assigned c. For all other values of d,
the default statement ensures that y is assigned 0000
We can decode multiple case values to a single statement by simply listing the values, separated by
commas. So in the example above, a value of 1, 2, 3, 4 or 5 will cause variable b to be assigned to y
The default catches all undeclared values including undefined x
Note that expression is checked against the case items in the order in which they appear.

It is not illegal to have the same value appear more than once in the list. As the list is checked in
order, the first match will mask any subsequent matches.

e.g. value 5 below is in the branch for y = b and y = c, but because the values are checked in
the order they are listed, y = b when d = 5.

Check case item lists carefully to avoid problems!


case(d)
0
1,2,3,4,5
5,6
7
default
endcase

:
:
:
:
:

y
y
y
y
y

=
=
=
=
=

a;
b;
// 1st 5: this branch taken when d = 5
c;
// 2nd 5: this branch masked when d = 5
c;
4'b0000;

Verilog Application Workshop

6-18

case Statement Syntax


case (expression)
item1 : statement
item2 : statement
item3,
item4 : begin
statements
end
....
itemn : statement
default : statement
endcase

Use begin and end to bound


multiple procedural statements

casex and casez allow x


and/or z to be treated as dont
care conditions
casex : x, z, and ? are
considered as dont care

casex (expression)
item1
: statements
....
itemn
: statements
default : statements
endcase
casez (expression)
item1
: statements
....
itemn
: statements
default : statements
endcase

casez : only z and ?


considered as dont care

Procedural Statements (V1E3)

6-19

case Statement Syntax


The case statement is a multi-way conditional statement that tests whether the expression matches one
of a number of other expressions and branches accordingly.

The case statement does a bit-by-bit comparison for an exact match (including x and z).

The default statement is optional. It is executed when none of the statements match the case
expression. If it is not specified, Verilog takes no action.

Important
It is a good programming practice to always use the default statement, especially to check for x and z.

Use of multiple default statements is illegal.

Verilog Application Workshop

6-20

casex
module casex_example (
input
[3:0] a, b, c, d,
output reg [3:0] y
);
always @(a or
casex (d)
4'b0000 :
4'b0xx1 :
4'b111x :
4'bxxx1 :
default :
endcase
endmodule

case expression (d)


case item expression
4'b111x

b or c or d)
y
y
y
y
y

=
=
=
=
=

a;
b;
c;
c;
4'b0000;

casex treats x, ? and z as


dont cares in

Allows more concise


description of behavior

Very useful for describing


priority encoders, address
decoders etc.

casex does not match bit


positions having unknown
(x) values, so can hide
initialization problems

Important
In your testbench use casez in preference to casex to expose initialization problems
Synthesis

casex is supported by most synthesis tools and provides a means to better optimization
Procedural Statements (V1E3)

6-21

casex
The casex statement is a variation of the case statement that allows you to specify bit positions it
should not compare.
The casex statement treats x, z, and ? as dont-care values.
The casex statement does not compare bit positions of either the case expression or the case items that
have any of these dont-care values.

4b111z, 4b111x, 4b111? will match 4b1110; 4b1111, 4b111z, 4b111x

Avoid using z as the dont care value to avoid confusion with the high-impedance logic state.
You must use binary or hexadecimal radix for literals containing dont-care values.
4b? = ????
4h? = ????
As the casex statement treats an undefined or uninitialized value in the case expression as dont-care,
this form of the case statement can hide initialization problems. For this reason, casez is a better
construct to use than casex in your testbench.

Verilog Application Workshop

6-22

casez
module casez_example (
input
[3:0] a, b, c, d,
output reg [3:0] y
);
always @(a or
casez (d)
4'b0000 :
4'b0??1 :
4'b111? :
4'b???1 :
default :
endcase

case expression (d)


case item expression
4'b111?

b or c or d)
y
y
y
y
y

=
=
=
=
=

a;
b;
c;
c;
4'b0000;

casez interprets z and ?


as dont cares in

casez does match bit


positions having unknown
(x) values, so can detect
initialization problems

endmodule

Tip
Do not use z as dont care within casez as you may later confuse it with the high impedance
state

Procedural Statements (V1E3)

6-23

casez
The casez is a variation on a case statements and allows dont-care conditions in the comparisons.
Dont-care values, in any bit of either the case expression or the case items, are treated as dont-care
conditions during the comparison. In other words, that bit position is not considered in the comparison.
In casez statements, ? and z are treated as dont-care values.

4b111z, 4b111? will match 4b1110; 4b1111, 4b111z

Avoid using z as the dont care value to avoid confusion with the high-impedance logic state
You must use binary or hexadecimal radix for literals containing dont-care values.
4b? = ????
4h? = ????

Verilog Application Workshop

6-24

Alternate case Statement Form

module finscase (
input
[3:0] a, b, c, d,
input
x, y,
output reg [3:0] op
);
always @*
case (1'b1)
x
:
y
:
(c==d) :
default :
endcase

op
op
op
op

=
=
=
=

case item can be an


expression as well

Can use case to check


several variable values at
once

Items are prioritized


according to order

a;
b;
c;
d;

endmodule

Procedural Statements (V1E3)

6-25

Alternate case Statement Form


The case statement can be viewed in another way as shown in the example above. It is still
synthesizable but rather than matching a signal to values, we are matching a value to a number of signals.

Verilog Application Workshop

6-26

Loop Statements: for

Iterates around loop for a


specified number of times

Loop variable must be declared


When loop executed:

Loop variable initialized


Loop statement(s) executed
Loop operation performed
When condition false, loop exits
// for loop expansion
tmp = 0 ^ a[0];
// =a[0]
tmp = tmp ^ a[1];
tmp = tmp ^ a[2];
tmp = tmp ^ a[3];

Synthesis
The synthesis standard support for loops
that have constant bounds.

module parity (
input wire [3:0] a,
output reg
odd
);
integer i;
reg tmp;
always @ a
begin
tmp = 0;
for (i = 0; i <= 3; i = i + 1)
tmp = tmp ^ a[i];
odd = tmp;
end
endmodule

a[0]
a[1]
a[2]
a[3]

tmp

Procedural Statements (V1E3)

6-27

Loop Statements: for


Syntax:
for (<initialization>; <condition>; <operation>)
First, the initialization is performed on the loop index. Then the condition is checked. If the condition is
true, the loop statements are executed (if the condition is initially false, the loop statements will never be
executed). After each time the loop executes, the operation is performed. The condition is then
rechecked. The loop executes as long as the condition evaluates to TRUE
In this example, we declare a local reg variable called tmp and initialize it to 0, this ensures our
algorithm is independent of the value that tmp had when the procedure was last called. The procedure
then executes a for loop with the loop variable I initialized to 0, and incrementing while I is less than
or equal to 3.
The final value of I would be 4 which makes the final condition in the for loop false and hence we exit
from the loop.
Finally, having performed the algorithm, the value of tmp is assigned to the output odd.
What architecture would be synthesized from this code? A chain of xor gates, the first xoring 0 and
a[0], the second xoring the output of the first xor gate with a[1], and so on.

Verilog Application Workshop

6-28

Loop Statements: repeat and while


module multiplier (
input
[3:0] op_a, op_b,
output reg [7:0] result
);

repeat loops iterate


by the number
specified
Number can be
literal, variable or
expression

reg [7:0] shift_opa;


reg [3:0] shift_opb;
always @(op_a, op_b)
begin
result = 0;
shift_opa = op_a; // Zero extend left
shift_opb = op_b;
repeat (4)
begin
if (shift_opb[0])
result = result + shift_opa;
shift_opa = shift_opa << 1; // left
shift_opb = shift_opb >> 1; // right
end
end
endmodule

while loop iterates


while the expression
is true, or non-zero

...
while (count < 10)
begin
// statements
count = count + 1;
end
...

Procedural Statements (V1E3)

6-29

Loop Statements: repeat and while


repeat loop executes a block of procedural statements a given number of times as specified by the
value or expression enclosed in brackets.
Note that in the example above, shift_opa is shifted a number of times to the left. Hence although
op_a is only 4 bits, shift_opa is 8 bits in length to handle the 4 left shift operations without losing
MSB information.
while loop executes a block of procedural statements while its expression is true (or nonzero).
If the expression is initially false, the statements are not executed.
If a standalone variable is used in a repeat loop expression, the variable value dictates how many times
the loop is executed.
repeat (count) // executes number of times = count value
If a standalone variable is used in a while loop expression, the size of the variable dictates how many
times the loop is executed, e.g.
...
reg [7:0] tempreg;
reg [3:0] count;
...
// Count the ones in tempreg
count = 0;
while (tempreg) // loops by number of bits in tempreg = 8
begin
if (tempreg[0])
count = count + 1;
tempreg = tempreg >> 1; // Shift right
end
...

Verilog Application Workshop

6-30

Loop Statement Syntax

for loop requires a loop


variable declaration

while loop continues


while the condition is true

repeat iterates the


number of times defined
by the expression

forever loops forever

// loop variable must be declared


for (initial; condition; inc_dec)
begin
// statements
end
while(condition)
begin
// statements
end

Synthesis
The synthesis standard does not support the
forever, repeat, and while constructs. Use these
constructs only in testbenches and simulation
models.

repeat(expression)
begin
// statements
end
forever
begin
// statements
end

Procedural Statements (V1E3)

6-31

Loop Statement Syntax


Caution
You must check for loop initialization, condition and operation for compatibility - the compiler will
not!
Incompatibility can lead to infinite or unexecuted loops, e.g. for loops:
for (i = 0; i < 0; i = i + 1)
//Loop never executed : condition initially false
for (i = 0; i >= 0; i = i + 1)
//Infinite loop : condition never false for increment

for loop variable can be written as well as read, although this can be dangerous!
for (i = 0; i <= 3; i = i + 1)
begin
// statements
i =0;
// resetting variable means condition never false end

Verilog Application Workshop

infinite loop

6-32

Review
1. If more than one condition of an if..else statement is true, which condition
takes priority?
2. Are if, case and for statements continuous or procedural statements?
3. Code the following conditional logic:-

a
b

mux
mux
1b0

1
0

<

ctrl
f

4b0110

Procedural Statements (V1E3)

6-33

Review

Verilog Application Workshop

6-34

Review Homework (for day 2)


module twelve_wrong (w, v, y, t, b, c, s)

Find at least
twelve things
wrong!

input [3:0] a, b, c, s;
output [3,0] w, v, y, t;
reg
[3:0] w, v, y, t,
assign W = s;
always @(a or b or c and s)
if (s == 0)
v = a;
y = b;
t = c;
else if (s <= 4b0101)
begin
v = c;
y = b;
t = a;
a = s;
end
else if (s == 6 or s == 7)
v = c;
else v == 4bxxxx;
endmodule
Procedural Statements (V1E3)

Verilog Application Workshop

6-35

6-36

Continuous and Procedural


Statements
VSE8

7-1

Notes

Verilog Application Workshop

7-2

Aims and Topics

Aims
To explain the difference between continuous and procedural statements.

Topics
Continuous assignments
Multiple continuous assignments to single source
Procedural assignments
Multiple procedural assignments to single source
Conditional assignment
Feedback loops

Continuous and Procedural Statements (VSE8)

7-3

Terms and Definitions

Verilog Application Workshop

7-4

Continuous Assignments
Continuous assignments:
Reside outside procedures

wire [3:0] tp;


wire [4:0] op;

Continuously drive net data types

Have no concept of order

assign tp = a + b;
assign op = c + tp;

assign op = c + tp;
assign tp = a + b;

tp

op

c
Continuous and Procedural Statements (VSE8)

7-5

Continuous Assignments
So first lets look at the issues with continuous assignments
The example on the slide shows two continuous assignments to op and tp
We can see that continuous assignments are order independent, so we can write these statements in either
way and we are describing the same topology.
Best way to visualize what is going on is to draw each operation like a schematic: such a drawing is
always concurrent!

Verilog Application Workshop

7-6

Multiple Continuous Assignments


a

Multiple continuous assignments to a


single net are wired together
In this illustration, if op is a wire
type and both drivers are opposite
values, the value of op is x

+
b

The wire, wand and wor net types


all resolve value conflicts
differently

op

+
d

Question
How is the value of op resolved?

wire/tri

wire [3:0] op;


...
assign op = a + b;
assign op = c + d;

0
1
x
z

0 1 x z
0
x
x
0

x
1
x
1

x
x
x
x

0
1
x
z

Continuous and Procedural Statements (VSE8)

7-7

Multiple Continuous Assignments


So now lets look at how procedural and continuous assignments differ....
A procedural assignment is a statement inside a procedural block.
A continuous assignment is an assign statement outside a procedural block.
Remember that if we have two assignments to the same net, we need to resolve what happens when the
drivers are different values
A wire or tri net will resolve to an undefined x.Whilst a wired and wand resolves to zero, a wired
or wor resolves to one
Net types tri and wire are identical in functionality. You can use the different names to enhance
readability. For example, you can use tri for the nets that have multiple drivers. Another reason to
declare a net as a tri is to indicate that this net can be driven to a high-impedance (z) state.
wand or wor types are useful for testbench or simulation modelling. Synthesis tools that support these
types will create extra logic to implement the required functionality.

a
wand op;
...
assign op = a + b;
assign op = c + d;

+
b

&

op

+
d
Verilog Application Workshop

7-8

Review of Procedures
module and_or (a, b, z_or, z_and);
Remember...
Procedures execute concurrently

Procedures resume upon any event


in the event list

Procedural statements execute in


sequence

Blocking assignments block until


the assignment is made
By default immediately

Nonblocking assignments are


always scheduled (more later)

input a, b;
output z_or, z_and;
reg z_or, z_and;
always @*
begin
if (a | b)
z_or = 1;
else
z_or = 0;
if (a & b)
z_and = 1;
else
z_and = 0;
end

Procedural
Statements

endmodule

Continuous and Procedural Statements (VSE8)

7-9

Review of Procedures
Now lets take a look at how we use procedural statements
Remember that procedural statements can only be used within a procedural block, either always or
initial.
Procedures start with the key word always or initial, followed by a list of variables that will cause
the procedure to execute when they change value.
Multiple procedural statements must be contained within begin and end statements. begin and end
are not required for a single statement.
Variables update immediately in procedures using blocking assignments (=). We have only seen
blocking assignments (=) so far, but there is another assignment called the non-blocking assignment (<=)
where the variables are not updated immediately, but are sampled in value, and then scheduled to be
updated later.

Verilog Application Workshop

7-10

Multiple Assignments in a Procedure


a
wire op;
...
assign op = a + b;
assign op = c + d;

+
b

op

+
d

reg op;
...
always @(a, b, c, d)
begin
op = a + b;
op = c + d;
end
...

op

Continuous and Procedural Statements (VSE8)

7-11

Multiple Assignments in a Procedure


If we consider the same assignments as in our continuous assignment example, we see that the outcome
here is very different. In this case, only the last procedural assignment to any given variable takes effect.
In the example above, the statement op = a + b is executed first and assigns a value to op, but this
is followed by another assignment to op, op = c + d, overriding the previous assignment. So the
procedure is now complete with op assigned to c + d.
The value assigned to op will remain until a change in a, b, c or d triggers the procedure again.
Remember that there has been no time advance inside the procedure so the effect of the first assignment
is invisible and no glitches occur at the output op.
For continuous assignments variable op must be a net type, but in procedural assignments it must be a
register type.

Verilog Application Workshop

7-12

Multiple Procedural Assignments: Example


These implementations are equivalent.
Later assignments override previous

For the second example:


Specifying a default output prevents
inadvertent latch inference by
synthesis tools (more later)
Making the most common assignment
the default can increase simulation
performance

always @(a or b or sel)


begin
if (sel)
op = a;
else
op = b;

end
always @(a or b or sel)
begin
op = b; // default
if (sel)
op = a;
end

Continuous and Procedural Statements (VSE8)

7-13

Multiple Procedural Assignments: Example


So lets take a look at an example of how you may want to use this capability...
In the first, if sel is true a is assigned to op
But in the second, op is always assigned to b initially, but if sel is 'true' a is now assigned, over-riding
the previous assignment.
So both examples are equivalent.

Verilog Application Workshop

7-14

Conditional Operator

Can be used in either procedural


or continuous assignments

Procedure containing single if


statement with single target can
be replaced by continuous
assignment
More compact than
procedural equivalent
Target must be a net type!

module
input
output
reg

proc_if (a, b, c, sel, opr);


[3:0] a, b, c, sel;
[3:0] opr;
[3:0] opr;

always @(a or b or c or sel)


if (sel == 0)
opr = a;
else if (sel <= 4'b0101)
opr = b;
else
opr = c;
endmodule

// alternative procedure using conditional operator


always @(a or b or c or sel)
opr = (sel == 0) ? a:((sel <= 4'b0101) ? b : c);
module continuous_if (a, b, c, sel, opw);
input [3:0] a, b, c, sel;
output [3:0] opw;
// continuous assignment equivalent
assign opw = (sel == 0) ? a: ((sel <= 4'b0101) ? b : c);
endmodule
Continuous and Procedural Statements (VSE8)

7-15

Conditional Operator
Conditional operator can be used instead of an if statement with a single target.
In the proc_if module above, the if statement only assigns to opr, and so can be replaced by a
conditional operator statement.
The conditional operator assignment can be used in both procedural and continuous assignments.
Therefore a procedure which only contains an if statement with a single target can be replaced by a
continuous assignment using the conditional operator.
Note In the procedural form the target variable must be a register type, but in the continuous assignment
form the target must be a net type.

Verilog Application Workshop

7-16

Dont Create Feedback Loops!


Zero-delay feedback loops may cause your simulator to appear to lock.
Most synthesis tools recognize and reject feedback loops and issue an error.
Synthesis tools ignore delays all feedback loops are zero-delay for synthesis.
// As a continuous assignment
assign op = op + y;
// As a procedure
always @(y or op)
op = op + y;

op

Continuous and Procedural Statements (VSE8)

7-17

Dont Create Feedback Loops!


Concurrent assignments have subtly different semantics than a conventional programming language and
one has to be careful to not create combinational feedback loops.
In the example above, when y changes, the continuous assignment and procedure are executed. op is
assigned a new value. However a change in value for op will trigger the continuous assignment
statement and the procedure...which will generate a new value for op...which will re-trigger the
assignments...which will generate a new value for op..etc. A zero-delay combinational feedback path
like this will create an infinite program loop in simulation
In a conventional programming language this statement means you take the contents of register op, add
them to the contents of register y and put the result back into register op. In Verilog, this statement infers
a combinational feedback loop, with no registers and with a delay-less feedback path. This may be
syntactically correct Verilog, but you cannot implement it in hardware.

Verilog Application Workshop

7-18

Review
1. What happens if multiple procedural assignments are made to the same variable?
2. Is a conditional assignment statement continuous, procedural or both?
3. Why should you not create combinational feedback loops?
4. Code the following hardware using (i) a continuous assignment and (ii) using a
procedure.

a[3:0]

d[4:0]

b[3:0]
0
c[4:0]
add

Continuous and Procedural Statements (VSE8)

7-19

Review

Verilog Application Workshop

7-20

Procedural Statements and the


Simulation Cycle
V2E3

8-1

Notes

Verilog Application Workshop

8-2

Aims and Topics

Aim
Fully explain capabilities that a procedure can offer

Topics
Procedures and event control(review)
Blocking procedural assignment
Non-blocking procedural assignment
The simulation cycle
Timing control
Event based
Level based
Simple delays

Procedural Statements and the Simulation Cycle (V2E3) 8-3

Terms and Definitions

Verilog Application Workshop

8-4

Review of Procedures and Event Control


module adder (
input
[3:0] a, b, c,
output reg [3:0] o, p
);
always @(a or b or c)
begin : ADDING
o = a + b;
p = a + c;
named
end

Multiple procedures execute


concurrently

endmodule

Procedures can be named

@ is an edge triggered event control

always procedures execute when any


variable in event list changes value
Run throughout simulation

procedure

module flop (
input wire clr, d, clk,
output reg q
);

Can specify a particular edge


flop module updates on positive clock
edges

always @(posedge clk)


if (clr)
// CLOCKD
q <= 0;
else
q <= d;

Can also use negedge

endmodule

Sequential logic uses non-blocking


assignment: <=

Procedural Statements and the Simulation Cycle (V2E3) 8-5

Review of Procedures and Event Control


The @ timing control is used for combinational and sequential procedures at the RTL and behavioral
levels. You can qualify variable sensitivity with the negedge and posedge keywords, and you can
wait for changes on multiple variables by using the or keyword.
Note: The or event control modifier has nothing to do with the bitwise OR operator | or the logical
OR operator ||.
In the module adder, if a changes value, then both always procedures are executed to update o and p.
The procedures are said to execute concurrently - i.e. both procedures are executed in parallel at the same
point in simulation time without any delay between the outputs.
Procedures can be named by specifying a name after the begin statement. If a procedure contains a
single statement which does not require a begin...end block, then the begin...end statements
must be added in order to name the procedure. Naming is useful for documentation. Naming procedures
can slow down certain simulators - an alternative is to use comments.
Generally any begin...end block can be named...
always @(posedge clk)
if (clr)
begin : REGD_CLR
q
<= 0;
qbar <= 1;
end
else
begin : REGD_CLK
q <= d;
qbar <= ~d;
end
Verilog Application Workshop

8-6

Blocking Procedural Assignment

Blocking assignment: =

Further execution blocks until assignment completes


By default immediately

Almost all examples do far have used blocking assignments

This causes problems with some code structures...

Error

byte[7:4] =
byte[3:0] =
4b0000

initial
begin
byte = 8b00001111;
#10;
// try to swap nibbles
byte[3:0] = byte[7:4];
byte[7:4] = byte[3:0];
#10;
...

Caution
byte[3:0]
immediately updated
with 4b0000

Procedural Statements and the Simulation Cycle (V2E3) 8-7

Blocking Procedural Assignment


Almost everything we have seen so far has used only blocking assignments.
A blocking procedural assignment is executed, and the assignment target takes its new value, before the
next statement in the procedure is executed.
If we try to use blocking assignment to swap the upper and lower nibbles of a byte, then as soon as we
assign the upper nibble (byte[7:4] - 4b0000) to the lower nibble (byte[3:0] - 4b1111), the
lower nibble is immediately over-written (byte[3:0] = 4b0000). So when we try to assign the
lower nibble to the upper nibble, the original lower nibble data has been lost and we are duplicating the
upper nibble data (byte = 8b00000000)

Synthesis
blocking assignment is used in combinational logic descriptions

Verilog Application Workshop

8-8

Non-Blocking Procedural Assignment

Non-blocking assignment: <=

Assignment completion is scheduled


Value is calculated and stored
Further execution does not block
Variable is updated later
By default at the end the current time slice

byte[7:4]
scheduled to
receive 4b1111

initial
begin
byte <= 8b00001111;
#10;
// try to swap nibbles
byte[3:0] <= byte[7:4];
byte[7:4] <= byte[3:0];
#10;
...

byte[3:0]
scheduled to
receive 4b0000

procedure suspends, scheduled


assignments updated and nibbles
successfully swapped
Procedural Statements and the Simulation Cycle (V2E3) 8-9

Non-Blocking Procedural Assignments


When a non-blocking procedural assignment is executed, the new value for the variable is calculated and
stored. The assignment of the value to the variable is then scheduled, i.e. its does not take place
immediately. The variable is updated with its new value after the procedure suspends.
If we use non-blocking assignment to swap the upper and lower nibbles of a byte, then when we assign
the upper nibble (byte[7:4] - 4b0000) to the lower nibble (byte[3:0] - 4b1111), the upper
nibble value is saved and the lower nibble is scheduled to be updated after the procedure has been
executed. So when we assign the lower nibble to the upper nibble, we read 4b1111 from the lower
nibble and schedule the assignment to the upper nibble. When the procedure finishes, the scheduled
assignments take place; the variables are updated and the nibbles are successfully swapped (byte =
8b11110000)
Tip: helpful to remember that Non-Blocking (2 words) assignment requires 2 symbols (<=) whereas
Blocking (1 word) assignment requires 1 symbol (=)

Synthesis
Use non-blocking assignments in sequential procedures.

Verilog Application Workshop

8-10

Non-Blocking Assignment and the Simulation Cycle

At one point of simulation time


Variables assigned with non-blocking
assignment are updated
Procedure event lists checked for
variables which have changed value

Variable
Event List

Procedures to be executed are placed


in scheduler

When all non-blocking assigned


variables have been updated...

Procedure
Scheduler

Procedures in scheduler are executed


until they suspend
Variables to be updated are placed in
event list
When all procedures in scheduler are
executed...

One loop known as a Delta Cycle

Procedural Statements and the Simulation Cycle (V2E3)

8-11

Non-Blocking Assignment and the Simulation Cycle


Non-blocking assignments happen in two steps:
1. The procedure is executed and the non-blocking assignment values calculated; stored and
scheduled (procedure execution phase).
2. After the procedure has been executed, the scheduled assignments take place and the variables
are updated (variable update phase)

Important
The above refers only to variables which are assigned values within a procedure using Non-Blocking
assignment. Variables assigned via blocking assignment update immediately

Caution
The simulation cycle explained here is a simplification of the actual simulation cycle

Verilog Application Workshop

8-12

Simulation Cycle (Slide 1/5)


module sim_ex (
input
a,
output reg m, y, w
);

Variable
Event List

Procedure
Scheduler

always @(a or m)
begin:P1
m <= a;
y <= m;
end

a <= 1
always @(m)
begin:P2
w <= m;
end

Assume a, m, y, w all
1b0
a changes value from
1b0 to 1b1

endmodule

Variable values
at start

a
m
y
w

:
:
:
:

0
0
0
0

Procedural Statements and the Simulation Cycle (V2E3)

8-13

Simulation Cycle (Slide 1/5)


To demonstrate the behavior of non-blocking assignment statements and the simulation cycle, we will
consider an architecture with two procedures, P1 and P2. Both procedures have the variable m in their
event list, and P1 assigns to m as well as being triggered by it.
As the simulation proceeds, the simulator will maintain two lists, the contents of which will change with
simulator time. At a particular time in the simulation, the Variable Event List will contain all variables
which have just changed value and the Procedure Scheduler List will contain all procedures sensitive to
those variables.
Let us say that there has been an event upon variable a, in other words it has changed value. a is added
to the Variable Event List...

Verilog Application Workshop

8-14

Simulation Cycle (Slide 2/5)


module sim_ex (
input
a,
output reg m, y, w
);

Variable
Event List

Procedure
Scheduler

m <= 1

P1

always @(a or m)
begin:P1
m <= a;
y <= m;
end

a updated from 1b0 to 1b1

Procedure P1 executes

Update to m scheduled

No change in value for y

always @(m)
begin:P2
w <= m;
end
endmodule

Variable values
at start

a
m
y
w

:
:
:
:

1
0
0
0

Procedural Statements and the Simulation Cycle (V2E3)

8-15

Simulation Cycle (Slide 2/5)


... when the variables are updated, a takes the new value '1'.
a is in the event list of procedure P1, so P1 is put on the Procedure Scheduler List.
P1 is then executed with m and y being assigned values. m is assigned the new value of a, '1', but y is
assigned get the old value of m, '0'. m will change value but not y. There is therefore an event upon m
but not on y.
The use of non-blocking assignment means these assignments do not take effect immediately but after
all procedures on the procedure scheduler list have suspended. Since only m has an event scheduled, only
m goes on the Variable Event List...

Verilog Application Workshop

8-16

Simulation Cycle (Slide 3/5)


module sim_ex (
input
a,
output reg m, y, w
);

Variable
Event List

Procedure
Scheduler

m <= 1

P1
P2

always @(a or m)
begin:P1
m <= a;
y <= m;
end
always @(m)
begin:P2
w <= m;
end

m changes value to 1b1

Procedure P1 placed on
scheduler list

Procedure P2 placed on
scheduler list

endmodule

Variable values
after 1 delta

a
m
y
w

:
:
:
:

1
1
0
0

Procedural Statements and the Simulation Cycle (V2E3)

8-17

Simulation Cycle (Slide 3/5)


....and when the variables are updated, m changes value from '0' to '1'.
m is in the event list of procedures P1 and P2, causing P1 and P2 to be scheduled for execution.

Verilog Application Workshop

8-18

Simulation Cycle (Slide 4/5)


module sim_ex (
input
a,
output reg m, y, w
);

Variable
Event List

always @(a or m)
begin:P1
m <= a;
y <= m;
end

Procedure
Scheduler

y <= 1
w <= 1

Procedures P1 and P2 execute


(random order)

Updates to y and w scheduled

No change in value for m

always @(m)
begin:P2
w <= m;
end
endmodule

Variable values
after 1 delta

a
m
y
w

:
:
:
:

1
1
0
0

Procedural Statements and the Simulation Cycle (V2E3)

8-19

Simulation Cycle (Slide 4/5)


When procedures P1 and P2 are executed, both y and w are assigned the current value of m ('1').
m is reassigned a ('1'), but since this is not a change of value, m is not placed on the Variable Event list.

Verilog Application Workshop

8-20

Simulation Cycle (Slide 5/5)

Variable
Event List

Procedure
Scheduler

y and w updated to
1b1

No more procedures to
be executed

module sim_ex (
input
a,
output reg m, y, w
);
always @(a or m)
begin:P1
m <= a;
y <= m;
end
always @(m)
begin:P2
w <= m;
end
endmodule

Variable values
after 2 deltas

a
m
y
w

:
:
:
:

1
1
1
1

Procedural Statements and the Simulation Cycle (V2E3)

8-21

Simulation Cycle (Slide 5/5)


Finally y and w are updated with their new values ('1'). These variables are not in the event lists of the
procedures here (although they may be in the event list of other procedures), so P1 and P2 do not have
to be executed.
The model has reached a steady state in two delta cycles, after a change in the input a.

Verilog Application Workshop

8-22

Simulation Cycle: Summary


Variable values
at start

a
m
y
w

:
:
:
:

0
0
0
0

Variable
Event list

Procedure
scheduler

a <= 1

P1

a
m
y
w

:
:
:
:

1
0
0
0

m <= 1

P1
P2

a
m
y
w

:
:
:
:

1
1
0
0

a
m
y
w

:
:
:
:

1
1
1
1

y <= 1
w <= 1

Variable
values

module sim_ex (
input
a,
output reg m, y, w
);
always @(a or m)
begin:P1
m <= a;
y <= m;
end
always @(m)
begin:P2
w <= m;
end
endmodule

Procedural Statements and the Simulation Cycle (V2E3)

8-23

Simulation Cycle: Summary


Initially the module sim_ex is in a steady state with all variable values = 0.
Input a is then assigned the value 1 (from a testbench or connecting module). a is added to the Variable
Event List and when the variables are updated, a takes the new value '1'.
a is in the event list of procedure P1, so P1 is put on the Procedure Scheduler List.
P1 is then executed with m and y being assigned values. m is assigned the new value of a, '1', but y is
assigned get the old value of m, '0'. m will change value but not y. There is therefore an event upon m but
not on y.
The use of non-blocking assignment means these assignments do not take effect immediately but after
all procedures on the procedure scheduler list have suspended. Since only m has an event scheduled, only
m goes on the Variable Event List...
....and when the variables are updated, m changes value from '0' to '1'.
m is in the event list of procedures P1 and P2, causing P1 and P2 to be scheduled for execution.
When procedures P1 and P2 are executed, both y and w are assigned the current value of m ('1').
m is reassigned a ('1'), but since this is not a change of value, m is not placed on the Variable Event list.
Finally y and w are updated with their new values ('1'). These variables are not in the event lists of the
procedures here (although they may be in the event list of other procedures), so P1 and P2 do not have
to be executed.
The model has reached a steady state in two delta cycles, after a change in the input a.

Verilog Application Workshop

8-24

Delta Cycle and Simulation Time


Multiple delta cycles at each point of simulation
time

You can specify procedural timing inside of procedural blocks,


using three types of timing controls:
Edge-sensitive timing control: @

Simple delays: #

Level-sensitive timing control: wait

Simulation Time

Procedural Statements and the Simulation Cycle (V2E3)

8-25

Delta Cycle and Simulation Time


Procedural block timing is specified using three types of timing controls:

@(<event_expression>)edge-triggered timing control


Delays execution until an edge occurs on variable. You can specify the active edge of
variable using posedge or negedge. You can specify several variable arguments using
the or keyword.

#<delay>

simple delay

Delays execution for a specific number of time steps.

wait(<expr>) level-sensitive timing control

Delays execution until expr evaluates true (non-zero). If expr is already true, the statement executes
immediately.

Verilog Application Workshop

8-26

Event Based Timing Control


module reg_adder (
input
clk,
input
[2:0] a, b,
output reg [3:0] out
);
reg [3:0] sum;
always @(a or b)
sum = a + b;
always @(negedge clk)
out <= sum;
endmodule

Timing controls can also be


embedded in procedures
Synthesis
The synthesis standard does not
support embedded timing

when any change


occurs on a or b
at every negative
edge of clk
initial
begin
repeat(12)
begin
@(posedge clk)
waveform_b <= ~waveform_b;
end
end

Procedural Statements and the Simulation Cycle (V2E3)

8-27

Event Based Timing Control


You can qualify variable sensitivity with the negedge and posedge keywords, and you can
wait for changes on multiple variables by using the or keyword.
Important
The or event control modifier has nothing to do with the bitwise OR operator | or the logical OR
operator ||.

Verilog Application Workshop

8-28

Wait Statement
module latch_adder
input
input
[2:0]
output reg [3:0]
);

(
en,
a, b,
out

Use wait for level-sensitive


timing control in behavioral
code.

When the wait statement is


executed: If en is high, the procedure
suspends until en is low
before performing the
addition

always @(a or b)
begin
// continue if/when en is low
wait (!en)
out = a + b;
end

If en is low, the addition is


performed immediately

endmodule

Synthesis
The synthesis standard does not support
wait statements

Procedural Statements and the Simulation Cycle (V2E3)

8-29

Wait Statement
In the example above, the addition is executed only when en is low. If en is already low when a or b
changes, the wait statement triggers immediately.

Verilog Application Workshop

8-30

Simple Delays
...
reg [3:0] current_time;
reg
in_a, out_b;
initial
begin
current_time
#10; // wait
current_time
#5; // wait
end

#<value> provides a simple time


delay

Provides timing for


Stimulus in testbenches

= 4'b0000;
10 time units
= 4'b1001;
5 time units

Propagation delays in gate level


simulation models

It will lock the simulator

always @(in_a)
// in_a assigned to out_b
// after 10 time-units
#10 out_b = in_a;
...

initial clk = 0;
always clk = ~clk;

Synthesis
Synthesis tools ignore delays

always #50 clk = ~clk;

Avoid zero delay feedback

Procedural Statements and the Simulation Cycle (V2E3)

8-31

Simple Delays
You can use module parameters to parameterize simple delays that you can set for each instance.
module clock_gen
#(
parameter integer CYCLE=20
)
(
output reg clk
);
initial clk = 0;
always
#(CYCLE/2) clk = ~clk;
endmodule

Verilog Application Workshop

8-32

The timescale Compiler Directive

timescale controls time unit


and precision

Format
timescale <unit>/<precision>
Delays are scaled to <unit>,
rounded up to <precision>

Important

You must place timescale outside of


any module definition.

timescale 1 ns/100 ps
module tb_ddrv ;
reg [3:0] current_time;
initial
begin
current_time
#10; // wait
current_time
#5; // wait
end

= 4'b0000;
10 ns
= 4'b1001;
5 ns

// 100 ns period clock


always #50 clk = ~clk;
...

Compiler directives:
Start with the grave accent

Are not statements do not end with ;

Procedural Statements and the Simulation Cycle (V2E3)

8-33

The timescale Compiler Directive

The `timescale compiler directive declares the time unit and its precision.
`timescale <time_unit> / <time_precision>
<time_unit> specifies the units of measurement for delays and time.
<time_precision> tells the simulator how to round delay values before using them in
simulation.

The time_precision must be less than or equal to the time_unit.

The time_precision and time_unit both consist of an integer representing the magnitude and a
character string representing the unit.
The valid integers are 1, 10, and 100.
The valid unit strings are s(second), ms(millisecond), ns(nanosecond), us(microsecond),
ps(picosecond), and fs(femtosecond).
Any combination of these is allowed.

The simulation speed may be greatly reduced if there is a large difference between the time units
and the precision, as some simulators advance by increments equal to the precision, e.g.
For `timescale 1s/1ps, to advance 1 second, the simulator increments 1012 times versus
`timescale 1s/1ms, where it only increments 103 times.

If a timescale is not specified, some simulators have a default timescale unit which will be used for all
blocks.

Verilog Application Workshop

8-34

Timing Control Example


always begin
wait (set);
@(posedge clk);
#3 q = 1;
#10 q = 0;
wait (!set);
end

10

always #10 clk = ~clk;


initial begin
{clk,set}
#15 set =
#33 set =
#22 set =
end

30

50

70

90

= 2b00;
1b1;
1b0;
1b1;

110

clk
set
q

15

48
33

70

43

93

103

clock edge may or may not be missed


Procedural Statements and the Simulation Cycle (V2E3)

8-35

Timing Control Example


The above timing control example illustrates a race condition.
This is a user-created condition in which stimulus is generated from two or more procedures. The result
is dependent on which procedure is executed first. This is an extremely poor modeling style.
Race conditions can be very difficult to debug.
The following sequence of events occur in the above example:
1. Wait for set = 1, ignoring the posedge of clk at time 10.
2. Wait for the next posedge of clk, which occurs at time 30.
3. Wait 3 time units before setting q = 1 at time 33 (30 + 3).
4. Wait 10 time units before setting q = 0 at time 43 (33 + 10).
5. Wait for set = 0, which happens at time 48.
6. Wait for set = 1, which happens at time 70, and coincides with the posedge of clk.
7. Wait for the next posedge. The edge at 70 is ignored because by the time this statement is
reached, clk = 1, as shown in this example.

Verilog Application Workshop

8-36

Review
1. Within the simulation cycle, what is one loop known as?
2. How is time advanced in a simulation?
3. Name three methods of timing control?
4. What is the difference in updating a variable when using:
i) A non-blocking assignment?
ii) A blocking assignment?
5. Where is the timescale compiler directive placed?

Procedural Statements and the Simulation Cycle (V2E3)

8-37

Review

Verilog Application Workshop

8-38

This page left intentionally blank

Blocking and Non-Blocking


Assignments
BNB2

9-1

Notes

Verilog Application Workshop

9-2

Aims and Topics

Aim
To explain the differences between blocking and non-blocking assignments
To give guidelines on the usage of blocking and non-blocking assignments

Topics
Blocking assignment review
Non-blocking assignment review
Blocking and non-blocking procedural assignment in sequential procedures
Blocking and non-blocking assignment in combinational procedures
Mixing blocking and non-blocking assignment

Blocking and Non-Blocking Assignments (BNB2)

9-3

Terms and Definitions

Verilog Application Workshop

9-4

Review of Blocking Assignment

Blocking assignment: =

Blocks further execution until complete


By default completes immediately

always @ (a or b or sel)
if (sel)
d = a;
else
d = b;

module seqblocking (
output reg [2:0] seq
);
integer i;
initial
begin
seq = 3'b000;
for (i = 0; i <= 4; i = i + 1)
begin
if incremented
seq
#10;
incremented
seq = 3b100,
seq = seq + 1;
every 10 ns
reset
if (seq == 3'b100)
seq = 3'b000;
end
seq sequence
end
endmodule

omits 3b100
value

ns
0
10
20
30
40
50

seq
000
001
010
011
000
001

Blocking and Non-Blocking Assignments (BNB2)

9-5

Review of Blocking Assignment


When a blocking procedural assignment executes, the assignment target takes its new value before the
next statement in the procedure executes.
The procedure in the seqblocking behavioral module increments seq every 10 time units. If the
incremented value is 3b100, the very next statement immediately resets to 3b000. The value
3b100 does not appear in the sequence of values.

Verilog Application Workshop

9-6

Review of Non-Blocking Assignment

Non-blocking assignment: <=

Variable update is scheduled

...
reg q;
Update scheduled for after procedures suspend always @(posedge clk)
q <= d;
module seqnonblocking (
output reg [2:0] seq
);
integer i;

initial
begin
seq = 3'b000;
for (i = 0; i <= 4; i = i + 1)
seq
begin
scheduled for
if current seq =
#10;
increment
3b100, reset
seq <= seq + 1;
after
procedure
if (seq == 3'b100)
completes
seq <= 3'b000;
end
seq
end
sequence

includes
3b100

endmodule

ns
0
10
20
30
40
50

seq
000
001
010
011
100
000

Blocking and Non-Blocking Assignments (BNB2)

9-7

Review of Non-Blocking Assignment


Non-blocking assignments happen in two steps:
1. During procedure execution, expression values are calculated, and non-blocking assignments are
scheduled for completion
2. After all procedures have suspended, the scheduled assignments complete (the variables are
updated)
The procedure in the seqnonblocking behavioral module increments seq every 10 time units.
These assignments are scheduled, so the statement testing for the value of 3b100 sees the old value
instead of the scheduled update value. The value 3b100 does appear in the sequence of values because
the testing statement sees it in the iteration after that in which it occurs.

Verilog Application Workshop

9-8

Blocking Assignment in Sequential Procedures

Blocking assignments can lead to race


conditions
Specifically when:
Multiple procedures trigger from the
same event, such that...
A procedure can read a variable that
another procedure simultaneously
writes

initial
begin
avar = 1b1;
bvar = 1b1;
end
always @(posedge clock)
bvar = avar + 1b1;

Example: Both procedures execute on positive


edge of clock
Blocking assignments to bvar and
cvar complete immediately upon
statement execution
But which statement executes first?

always @(posedge clock)


cvar = bvar;

Important
Procedures can execute in any order. Do
not rely upon execution order.

Value of cvar depends upon


which procedure executes first
Blocking and Non-Blocking Assignments (BNB2)

9-9

Blocking Assignment in Sequential Procedures


In the sequential procedure example above, both procedures are executed on a positive clock edge. Since
a blocking assignment is used, the final value of cvar depends on the execution order of the procedures.
On the first edge of the clock, if the upper procedure is executed first, then bvar is immediately updated
to 2. When the lower procedure executes, cvar is then assigned to the incremented value of bvar = 2.
If, however, on the first edge of clock, the lower procedure is executed first, then cvar is immediately
updated with the un-incremented value of bvar = 1. When the upper procedure executes, bvar is
immediately updated to 2.
So the value of cvar is dependent on the order of execution of the procedures. The Verilog Language
Reference Manual (LRM) specifically states that procedures can be executed in any order. Therefore the
value of cvar may be different for different simulators and, in theory, different simulation runs on the
same simulator. The value of cvar cannot be determined in advance of the simulation run, therefore the
behavior of the circuit is non-deterministic.

Verilog Application Workshop

9-10

Non-Blocking Assignment in Sequential Procedures

Non-blocking assignments avoid race


conditions
Example: Both procedures execute on positive
edge of clock
Assignments to bvar and cvar are
scheduled
Assignment to cvar assigns value of
bvar from before rising edge of clock

initial
begin
avar = 1b1;
bvar = 1b1;
end
always @(posedge clock)
bvar <= avar + 1b1;
always @(posedge clock)
cvar <= bvar;

Tip
Use non-blocking assignment for sequential logic

Blocking and Non-Blocking Assignments (BNB2)

9-11

Non-Blocking Assignment in Sequential Procedures


In the sequential procedure example above, both procedures are executed on a positive clock edge. Since
a non-blocking assignment is used, race conditions are avoided.
On the first edge of the clock, bvar is scheduled the value 2 (the incremented value of avar) and cvar
is scheduled the value 1 (the current value of bvar). After both procedures have executed, the variables
are updated.
The value of cvar is not dependent on the order of execution of the procedures. The value of cvar can
be determined in advance of the simulation run, therefore the behavior of the circuit is deterministic.

Verilog Application Workshop

9-12

Position Dependent Code


Blocking assignments in sequential procedures can result in position dependent code
always @(posedge clk)
begin
d = c;
c = b;
b = a;
end

always @(posedge clk)


begin
b = a;
d = c = b = a,
c = b;
b and c optimized
out
d = c;
end
a

?Question
What would the diagrams look like if non-blocking assignments were used?
Blocking and Non-Blocking Assignments (BNB2)

9-13

Position Dependent Code


There is another issue with using blocking assignment in sequential procedures.
In the example on the left, the variables b and c are assigned and then used immediately hence, they are
optimized away. One register would be inferred by synthesis.
In the example on the right, the variables b and c are read before they are assigned. Hence, the variable
values need to be remembered. Three flip flops would be inferred by synthesis.
This is an example of position dependent code - the logic inferred is determined by the order of the
statements in the procedure. Generally this is a bad design practice.
By using non-blocking assignment, the procedure is no longer position dependent. Whatever the order
of code, three flip flops would always be inferred by synthesis.

Verilog Application Workshop

9-14

Combinational Logic
always @(a or b)
begin
m = a;
n = b;
p = m + n;
end

always @(a or b or m or n)
begin : P1
m <= a;
n <= b;
p <= m + n;
end

Non-blocking assignment can be


inefficient for combinational logic
Specifically when logic contains serial
behavior or intermediate variables
Intermediate variables must be added to
event list
Procedure will take several delta cycles
to reach steady state

Variable
Event list

Procedure
scheduler

a <= 1
b <= 2

P1

m <= 1
n <= 2

P1

p <= 3

Tip
Use blocking assignment for combinational procedures
Blocking and Non-Blocking Assignments (BNB2)

9-15

Combinational Logic
Simulators and synthesis tools can support use of either blocking or non-blocking assignments to
describe combinational logic.
However use of non-blocking assignments can be inefficient. If the combinational logic description uses
intermediate variables (used to temporarily store a value) then these intermediate variables need to be
added to the procedure event list. In the example above, when variable a changes to 1, m will be
scheduled with an update to 1, but when p is assigned, the current value of m is used to calculate a value.
m needs to be added to the event list to force a re-execution of the procedure when m changes value in
order to calculate a value for p using this new value of m. Hence the procedure will take 2 delta cycles
to reach a steady state.
With blocking assignment, the procedure is evaluated in a single delta cycle

Verilog Application Workshop

9-16

Multiple Assignments
always
begin
m <=
n <=
p <=
m <=
q <=
end

always @(a, b, c)
begin
m = a;
n = b;
p = m + n;
m = c;
q = m + n;
end

+
?

@(a, b, c, m, n)
a;
b;
m + n;
c;
m + n;

?Question
What are the inputs to these
adders (in terms of a, b, and c)
for each procedure?

Multiple assignments can be made to a variable within one procedure


Subsequent assignments override previous assignments

Multiple assignments should be either blocking or non-blocking


Blocking and Non-Blocking Assignments (BNB2)

9-17

Multiple Assignments
Blocking and non-blocking assignments can create completely different results. For these examples:
For blocking assignments, variable update is completed before execution continues. Intermediate values
are available until overwritten. In the blocking example above, the value of a assigned to m is used to
calculate p (a+b), and the value of c assigned to m is used to calculate q (b+c).
For non-blocking assignments, variable update is scheduled. Values are available only after the update
occurs. In the non-blocking example above, the assignment of a to m is scheduled and immediately
overwritten by the scheduled assignment of c to m. In the variable update phase, only the value of c is
assigned to m.

Verilog Application Workshop

9-18

Mixed Assignments

You can use blocking assignments to


temporary variables within sequential
procedures

Usage model
Assign inputs to temporary
variables with blocking assignment

always @(posedge clk)


begin : blk
integer temp;
temp = a + b;
q <= temp + c;
end

Perform algorithm with temporary


variables and blocking assignment
Assign temporary variables to
outputs with non-blocking
assignment
Caution
Declare temporary variables locally to
discourage their use outside the block
Synthesis
Do not mix assignments to the same variable

always @(posedge clk)


begin : blk
integer tempa,tempb;
tempa = ip1;
...
tempb = f(tempa);
...
op1 <= tempb;
...
end

Blocking and Non-Blocking Assignments (BNB2)

9-19

Mixing Assignments
You can use blocking assignments to temporary variables within sequential procedures.
An efficient usage model is: capture the needed procedure inputs into local temporary variables using
blocking assignment; do required calculations using local temporary variables and blocking
assignments; and assign to procedure output variables using non-blocking assignments to avoid race
conditions.
This usage model requires that you declare separate variables for temporary use within a procedure, and
that no other procedure access those variables. It is best to declare these temporary variables as locally
as possible to where they are used. This discourages their use elsewhere.

Verilog Application Workshop

9-20

Example
Write the Verilog code for the following block diagram. You can write it in one
procedure.

a
b
c

0
1

0
1

sl
clk

Blocking and Non-Blocking Assignments (BNB2)

9-21

Example
Write your outline code here. Dont worry about declarations, were only interested in the structure of
the code.

Verilog Application Workshop

9-22

Review
1. What is the primary difference between blocking and non-blocking assignments?
2. Where should you use non-blocking assignments?
3. Where should you use blocking assignments?
4. When might you use blocking assignments in a sequential procedure?

Blocking and Non-Blocking Assignments (BNB2)

9-23

Review

Verilog Application Workshop

9-24

Verilog Coding Styles


VDE8

10-1

Notes

Verilog Application Workshop

10-2

Aims and Topics

Aim
To look at some of the different applications of Verilog and the methods and
coding styles involved

Topics
Testbench style
RTL style
Behavioral versus RTL

Verilog Coding Styles (VDE8)

10-3

Terms and Definitions

Verilog Application Workshop

10-4

Testbench Organization

Simple testbench

Testbench

Just send data to design


No interaction
Small number of procedures
to create stimulus

Stimulus

Design to
Verify

Testbench

Design to
Verify

As in lab exercises

Sophisticated testbench
Models environment around
design
Talks to design, e.g bus
cycles
Evolves towards board model
Possibilities of self checking

Verilog Coding Styles (VDE8)

10-5

Testbench Organization
Testbenches tend to start off simple but quickly become sophisticated. Typically, at least 50% of the time
you will spend writing Verilog on a project will be taken up with coding your test bench. In our simple
testbench, a circle represents a process and a square represents a component instantiation. The outer
rectangle represents the testbench entity which doesn't have any ports. Such a testbench simplifies the
business of getting into the simulator and is useful for checking out an idea, or a bit of Verilog you are
not sure of.
In a sophisticated testbench you may well want to model the environment with which your design has to
interact, you might want to model the bus cycles of a microcontroller which talks to your design, you
may want to evolve your testbench towards a model of your design sub-system.

Verilog Application Workshop

10-6

Testbenches and Files

Verilog allows information to be written to and read from external files


Input could be created by another program/tool
e.g. image data

Design to

Testbench

Verify
Test Data

Errors

Visualization

Results

Verilog Coding Styles (VDE8)

10-7

Testbenches and Files


You might want to read in the contents of a file containing, for example, some image data. Perhaps the
file has been created by another program or tool such as a system modelling tool. We will be looking at
how to do this later in the course.
There are many reasons you might want to generate an output file. You might want a record of any errors
or warnings, although most simulators give you another way of doing this by allowing you to keep a copy
of the messages that appear in the simulator transcript window. You might want to generate a
visualization of your output data as we will do during the lab exercises. You may want to generate results
for automatic comparison with the results of subsequent simulation runs.

Verilog Application Workshop

10-8

Coding RTL Verilog


Combinational Procedure
always @(a or b or c)
begin
...
...
...
end

Sequential Procedure
always @(posedge clock)
begin
...
...
...
end

Synthesis
Procedures must conform to specific templates to be synthesizable!

Verilog Coding Styles (VDE8)

10-9

Coding RTL Verilog


First, let's look at the RTL style of Verilog. In an RTL model there are only two types of procedures used:
a combinational procedure and a sequential procedure. We can also use continuos assignment statements
to model combinational behavior.
We already know about combinational procedures; the event list must contain all variables which are
read. You must also make sure that all assignments are complete, that is to say, that assignments to an
output signal take place under all conditions - if you don't, the synthesis tool will have to create a latch
to provide a value when the missing condition occurs. The easiest way to do this is to provide default
assignments, as you will see later.
The other type of process is a sequential procedure. Normally synthesis tools only give you a limited
number of ways to write a sequential procedure, although there are a very large number of ways to
express the same functionality for simulation purposes.

Verilog Application Workshop

10-10

Typical Sequential Procedure


module counter (
input wire
clk,
output reg [3:0] count
);

always @(posedge clk)


if (count >= 9)
count <= 0;
else
count <= count + 1;

Registers are inferred on all


non-blocking assignments in
sequential procedures

?Question
What is the problem with this counter
description?

endmodule

4d0

1
0
4

count
sel

>=

clk

4d9
Verilog Coding Styles (VDE8)

10-11

Typical Sequential Procedure


This sequential procedure only has the clock variable clk in its event list. The posedge event control
will only trigger the procedure on the rising edge of the clock. The if statement in the procedure describes
the combinational logic required to calculate a new value for count on the next rising edge of clk.
Since this is a sequential procedure, any variables assigned to with non-blocking assignment in the
procedure will be registered.
Although some synthesis tools do support other coding styles for sequential procedures, if you stick to
the one shown here you won't go wrong and you will be writing code which is most portable between
synthesis tools.
Note: This example lacks a reset to initialize the count value! We will discuss the impact of this and
examine a solution in the chapter on synthesis coding styles

Verilog Application Workshop

10-12

Behavioral and RTL Modelling


Behavioral Modelling

RTL Modelling

Addresses function not


implementation

RTL defines architecture for


implementation

May not include clocks

Generally required to be
synchronous

Can trigger activities on edge of


any signal

Trigger activities on the clock


edge

Explicit delays synchronize data

Do not need to imply storage information retained in variables

Timing is clock cycle accurate

Registers and memory need to be


inferred or instantiated

Code constructs and style restricted


by synthesis tool support

Used for all code to be synthesized

Can use full scope of language


Used for testbench design and
simulation models
Occasionally for initial
block/system modelling?

Verilog Coding Styles (VDE8)

10-13

Behavioral and RTL Modelling


Behavioral modeling techniques are important for use in testbench design; simulation models; etc.
For behavioral models we are only interested in behavior. We do not have to make the model
synchronous so we can dispense with clocks, registers and resets using the variables themselves to store
values. All assignments can happen immediately, cleanly and with zero delay. We also use assignments
to trigger other activities.
It is possible to create an initial behavioral model of a system or block. This may be useful to:

Create a functional model of the specification, which can help highlight ambiguities and errors in
the specification.

Experiment with different architectures and partitioning for implementation, with the possibility
of obtaining some performance analysis of alternatives through simulation.

Create libraries of test data - both stimuli and expected responses - which can be used in the
verification of RTL models.

Although behavioral synthesis tools are available, behavioral to RTL translation is usually manual.
Therefore full behavioral modeling may only be used for the design of a completely new, major system.
An RTL model has to consider implementation effects such as propagation delays and signal glitches.
To solve these problems, we make our circuits synchronous. A synthesis methodology is, essentially, a
synchronous methodology. We do not model the delays through the combinational logic which, for
simulation efficiency we assume to be zero.
We do have to worry about registers, which we use to store values, about what clocking scheme to use,
about the reset and the amount of logic in between them.

Verilog Application Workshop

10-14

Bus Interface Controller - Behavioral


min 10

Specification

max 20

data
data_read
data read
data_valid

CPU_RD
data_valid
DATA
WRITER

data

DATA
READER

local_buffer

data_read

always
begin: CPU_RD
wait(data_valid == 1);
data_read = 1;
#20;
local_buffer = data;
#10;
data_read = 0;
wait(data_valid == 0);
end

Verilog Coding Styles (VDE8)

10-15

Bus Interface Controller - Behavioral


The specification for a Bus Interface Controller is shown in the waveform diagram.
data_valid is an external variable which is asserted true just before some data is put onto the bus.
The controller will assert the data_read line and, after at least 20 ns, read the data into a local buffer.
The behavioral procedure starts executing on the rising edge of data_valid
data_read will be set to '1' and the procedure will then suspend at the statement: #20; In a waveform
viewer you would see both data_valid and data_read become '1' at the same time - which is
a slight, but unimportant, difference to the specification.
After 20 ns the procedure will resume its execution; write to local_buffer and suspend again with
the statement: #10;
After 10 ns execution progresses until the wait statement: wait(data_valid == 0); when
data_read is de-asserted. Procedure execution will wrap back to the start and re-suspend at
wait(data_valid == 1); until the next rising edge of data_valid.

Verilog Application Workshop

10-16

Bus Interface Controller - Implementation Details


data

clk
data_valid
data_read
data read

data read
read_state

WAITING STATE1

STATE2

STATE3

STATE1

STATE2

STATE3

Clock period not less than 20 ns


WAITING

!data_valid

data_read = 0

WAITING

data_valid

STATE1

STATE3

data_read = 1

STATE2
local_buffer = data

Verilog Coding Styles (VDE8)

10-17

Bus Interface Controller - Implementation Details


To write an RTL model of the same controller we need to design a state machine.
In this slide we have added a clock variable and a new variable called read_state which has as many
values as the number of states we need, in this case: WAITING, STATE1, STATE2, STATE3. This
variable will be used to tell us what state we are in. We have allocated the states across the waveform
diagram.
WAITING

waiting for data_valid to be '1'

STATE1

set data_read and wait 20 ns

STATE2

read data and wait 20 ns

STATE3

clear data_read

Note, we can only change state on a clock edge.

Verilog Application Workshop

10-18

Bus Interface Controller - RTL


// Constants and variables
localparam integer WAITING
STATE1
STATE2
STATE3
reg [7:0] local_buffer;
reg [1:0] read_state;
reg
data_read;

=
=
=
=

0,
1,
2,
3;

// state variables - sequential


always @(posedge clk or posedge reset)
if (reset == 1)
begin // async reset logic
read_state
<= WAITING;
local_buffer <= 8'h0;
end
else
case (read_state)
WAITING: if (data_valid)
read_state <= STATE1;
STATE1 : begin
read_state <= STATE2;
local_buffer <= data;
end
STATE2 : read_state <= STATE3;
STATE3 : if (!data_valid)
read_state <= WAITING;
endcase

// output decode - combinational


always @(read_state)
case (read_state)
STATE1 : data_read = 1'b1;
STATE2 : data_read = 1'b1;
default : data_read = 1'b0;
endcase

Verilog Coding Styles (VDE8)

10-19

Bus Interface Controller - RTL


The simple procedure we used in the behavioral model must be transformed into a RTL model of a state
machine using a style recognized by synthesis tools. In this example we are using a sequential procedure
for the state variable and local_buffer assignment. The use of non-blocking assignment in this
procedure will infer registers for both state variable and local_buffer in synthesis. We have a
separate combinational process for the output decode logic to derive the data_read variable from the
current state.
Here, the sequential procedure has posedge reset as well as posedge clk in the event list. The
if condition tests the reset value, giving it priority over clk. If reset == 1 the state machine is
put into its default state: WAITING, and local_buffer is cleared. If reset is 0, the case statement
will be executed.
The case statement has a branch for every value of read_state, in other words for every state.
The logic in every branch of the case statement simply defines the conditions under which the machine
will change state and, if that happens, assigns the new state to read_state. If the conditions do not
exist for a change of state then, because read_state is registered, the machine will remain in the same
state.
The separate combinational process will be executed every time the read_state state variable
changes. If the current state is STATE1 or STATE2, then data_read is set high, otherwise set low.

Verilog Application Workshop

10-20

Review
1. What are the two types of procedure used for RTL code?
2. How do we infer registers for synthesis?
3. What is behavioral modeling used for?
4. How do you define the states for an FSM?

Verilog Coding Styles (VDE8)

10-21

Review

Verilog Application Workshop

10-22

This page left intentionally blank

The Synthesis Process


VSP8

11-1

Notes

Verilog Application Workshop

11-2

Aims and Topics

Aims
To introduce the synthesis process and look at its strengths and weaknesses

Topics
How a synthesis tool works
Synthesis based methodology
Synthesis strengths and weaknesses
Programmable Logic Device synthesis issues
Language subsets

The Synthesis Process (VSP8)

11-3

Aims and Topics


To explore the strengths and weaknesses of synthesis tools we first need to understand how a synthesis
tool works. We will then assess the impact this knowledge has on a synthesis methodology. Finally we
will be comparing synthesizing to cell based ASICs with synthesizing to FPGAs.

Verilog Application Workshop

11-4

What Does Synthesis Do?

Infers registers from sequential procedures

Builds optimized combinational logic

A new engineer asks:


How much of it?
How well?
Do you trust it?

clk

The Synthesis Process (VSP8)

11-5

What Does Synthesis Do?


Synthesis automatically transforms your design, expressed in RTL Verilog into an implementation
consisting of a structure of cells. The obvious questions are:

How much of your design can be built?

How well does the tool build it?

Can you trust it?

Verilog Application Workshop

11-6

The Synthesis Flow

Verilog Code is the most


important input - the
quality of results depends
mainly on the code.

Technology Library is
used to build the circuit
from the verilog
description.

Constraints File drives the


synthesis engine.

Verilog
Code

Technology
Library

Synthesis
Engine

Speed

Area/Speed Curve

Constraints
File

Gate Level Netlist

Area

Schematic
The Synthesis Process (VSP8)

11-7

The Synthesis Flow


A synthesis tool can read your RTL Verilog code and convert it into a gate level netlist, using gates and
cells from a specified target technology library.
The synthesis tool will try to meet your design constraints for the area and performance of the netlist, and
will produce reports to tell you how successful it has been.
Design constraints may be as simple as a required clock speed specification, or include more complex
constraints, covering input and output timing requirements, area goals, environmental conditions etc.
The Area/Speed Curve:
The Area/Speed Curve Envelope is the best that the synthesis engine can accomplish given the circuit
architecture and the area and speed constraints. For example, synthesis can produce a small slow circuit
or a large fast circuit or something in between.
The synthesis constraints located in the constraints file direct or drive the synthesis engine to produce the
type of circuit required.
A typical synthesis constraint may be to set the required maximum clock frequency for a design.

Verilog Application Workshop

11-8

How Synthesis Works


Verilog
Code

Constraints
File

Boolean

Parsing

Mapping

Technology
Library

Gates

Optimization

Gate Level Netlist

Schematic
The Synthesis Process (VSP8)

11-9

How Synthesis Works

Synthesis tools represent a design internally both as logic (in the form of boolean equations and
registers), and as an interconnection of gates from a specific technology.

A synthesis tool translates the Verilog constructs into boolean equations which are represented in
the logic level.

When optimization, or mapping is carried out, then the synthesis tool optimizes these equations
using boolean algebra, and then implements then in a specific silicon technology at the gate level.

The gate level design is also optimized. More sophisticated synthesis tools are able to re-optimize
the logic based upon information learned from the initial mapping to gates.

Inputs to the gate level optimization part are:


Library of gate level primitives available
Constraints which guide the mapping to optimize for speed or silicon area

When the optimization is complete, then a gate level description can be written out from the
synthesis tool for gate level simulation and layout.

The diagram shown on the slide is a rather simplified view of reality. During the synthesis process, the
first thing that happens is that your Verilog gets mapped to two-level sum of products logic expressions;
i.e. the output of each blob of combinational logic is expressed in terms of the inputs to the logic. These
expressions are then minimized. Common factors are then extracted to create multi-level expressions
which are also minimized. All synthesis tools use the same algorithms for these minimization steps. The
optimized multi-level expressions are then mapped to the target technology and the algorithm used for
mapping will vary from tool to tool. Next, a timing analysis is performed on the result to see if any of
your constraints have been violated. If they have, remapping, perhaps to higher drive cells, could solve
the problem; if not, the synthesis tool will re-factorize and try again, perhaps with fewer levels of logic.

Verilog Application Workshop

11-10

Coding Styles Affect Results

Number of registers
Combinational logic optimized only, not register numbers or placement

Amount of combinational logic between registers


Pipelining and logic timing must be considered when code written

Structure of logic

clk

The Synthesis Process (VSP8)

11-11

Coding Styles Affect Results


Remember, a synthesis tool does not optimize the registers or latches in your design. You need to be
careful how you structure your registered processes so you only infer the registers you need. Check
synthesis reports carefully to make sure!
You also need to be careful how much combinational logic is placed between adjacent register banks. If
you place a 32 bit multiplier between adjacent register banks with a 10 ns clock period, don't be surprised
if the synthesis tool struggles to produce a result.
Generally you need to be careful how you partition and structure your design into combinational and
registered logic.

Verilog Application Workshop

11-12

Translation Can Be Literal!


Synthesis tools initially generate logic directly from the structure of your code.
They then optimize the logic as needed to meet area/power/speed constraints

Here the == operator is redundant but may still appear in the synthesized netlist

always @(posedge clk)


if (d < 3)
y <= a;
else if (d > 3)
y <= b;
else if (d == 3)
y <= c;

Question
What would be the input at ?

Inferred hardware
structure

011

011

011

>

c
b
a

<
mux

0
1

mux

0
1

y
mux

clk

The Synthesis Process (VSP8)

11-13

Translation Can Be Literal!


Synthesis tools cannot interpret or analyze your code to understand your requirements. Translation of
your code to Boolean logic is a very literal process. Although synthesis optimization may remove
redundant logic from your design, it is better if the redundant logic is removed by the designer before
synthesis.

Verilog Application Workshop

11-14

What Synthesis Sometimes Cant Do Well . . .

Clock trees
Usually require detailed, accurate net delay information

Complex clocking schemes


Synthesis tools prefer simple, single clock synchronous designs

Memory, IO pads, technology-specific cells


You will probably need to instantiate these by hand

Specific macro-cells

Almost always as well as you can


Synthesis tools can analyze hundreds of potential implementations in
much less time than you need to analyze one

The Synthesis Process (VSP8)

11-15

What Synthesis Sometimes Cant Do Well...


From the foregoing discussion, it should be obvious that synthesis tools are targeted at optimizing
combinational logic. Of course, large parts of your design will not be combinational logic.
For example, clock trees. Clock tree design is a global, chip-wide problem which, particularly in deep
submicron designs, requires detailed and realistic net delay information. There are also no algorithms
around which perform a good job in all circumstances. Clock tree design will probably need to be done
as part of silicon layout
Synthesis tools do not cope well with complex clocking schemes. Typically, each block to be synthesized
will be allowed to have one clock although two-phase clocks or multiple, harmonically related clocks
may be supported.
You probably would not want to synthesis large blocks of memory since a synthesis tool will build it out
of flip-flops.
Since synthesis tools are not very good at selecting large cells, or macros, from a technology library, you
may have to instantiate them by hand. Some macro-cells, such as large datapath elements with regular
structures, are may be best produced using the silicon compilers supported by your silicon vendors
Lastly, synthesis tools are not guaranteed to produce the smallest possible result. They do not always do
as good a job as you could, if only you had the time! If you are having problems with a critical path you
could always look at it on a schematic - you may be able to spot an optimization the tool has missed.

Verilog Application Workshop

11-16

Programmable Logic Device Specific Issues

Different architectures for different


technologies

Fixed architecture within a specific


technology

Architecture-specific tricks for good


utilization and speed

Code becomes technology specific

Refer to vendor literature

The Synthesis Process (VSP8)

11-17

Programmable Logic Device Specific Issues


Many of the comments so far have assumed synthesis to an ASIC. With an FPGA there are some
different problems. ASIC synthesis tools all work in the same way, using the same optimization
algorithms, and the target technology libraries all have similar cells. As you know, with FPGAs there are
different technologies, EEPROM, SRAM and anti-fuse, and each vendor has different building blocks,
which tend to be much larger than the gate-level primitives used in an ASIC.
For a particular FPGA, the architecture is fixed, limiting the usefulness of static timing analysis since
routing delays can vary widely - with an ASIC they are much more predictable. What's more, to get a
good fit the FPGA designer traditionally employs architecture specific tricks which are difficult to
implement in a synthesis tool.
What all of this means is that your Verilog code needs to make technology and architecture specific
directives which are ignored by the simulator but are recognized by the device fitting algorithms used in
your FPGA vendor's software. These directives are often expressed with user-defined attributes,
comments or direct instantiation of specific cells. This, of course, restricts the technology independence
and portability of your Verilog.
A key issue is how well your synthesis tool handles your chosen technology. To achieve a good result,
it will need architecture specific algorithms.

Verilog Application Workshop

11-18

A Synthesis Methodology
change code
change constraints file

netlist

tech library
constraints
n
synthesis
Verilog

rtl
simulation
testbench

y
meets area/speed?
functional?
y

gate
simulation

compare

change code

golden results

results
The Synthesis Process (VSP8)

11-19

A Synthesis Methodology
With all synthesis tools you will be following a very similar methodology to the one shown here. First
you select a block of an appropriate size for the capacity of your tool. The size of the block is often a
trade-off between how much of your design you want to synthesize at once and the ability of your
computer resources to produce you a result in a reasonable time! After simulation you synthesize the
block after setting up some timing constraints such as the maximum allowable propagation delay. At the
same time, you could make your design more testable by automatically inserting scan chains, or at least
scan path flip flops which you join up into scan chains later.
After synthesis you would do a static timing analysis using the synthesis tool's built-in analyzer to check
how well the tool has met your constraints. If satisfied, you would carry out a gate-level simulation to
check that you still have the same functionality you started with.
The problems arise if the results from synthesis are not good; perhaps because you are exceeding some
critical timing delay. There are a number of things you can do then which we have listed in order of effort
from top to bottom. The easiest thing to do is to change some of the switches available in the synthesis
tool which affect how the optimization algorithms work. This is not predictable but they are worth
playing about with. Secondly, you could modify some of your constraints; if you have over constrained
the tool you will have unnecessarily limited the degrees of freedom it has to meet your constraints
automatically.
Finally you could change the Verilog; the easiest thing to do here is alter the hierarchy by partially
flattening it - this again gives the tool more degrees of freedom to meet your constraints. Finally, if
nothing else works, you may have to bite the bullet and change the architecture of your design.
We will come back to this important subject. Hopefully we have said enough now to make it obvious to
you that a synthesis methodology is an iterative one and one in which you are learning more and more
about how your synthesis tool works best.

Verilog Application Workshop

11-20

Language Support

IEEE Std. 1364.1 defines the synthesizable Verilog constructs


Most synthesis tools still accept their own previously accepted constructs

Full Verilog Language


Synthesis Subsets
Tool 1
Tool 2
Tool 3
Tool 4
Tool 5

The Synthesis Process (VSP8)

11-21

Language Support
If you write your RTL code using the coding guidelines and templates described in this course, then your
code will be portable between the maximum number of synthesis tools

Verilog Application Workshop

11-22

Summary

RTL for synthesis


Logic and gate optimization

Coding style affects results

Synthesis tools support subsets of language style

The Synthesis Process (VSP8)

11-23

Summary
In this section we have explored the subject of synthesis by looking at what a synthesis tool does with
your RTL Verilog code. The motto of this course, which we will take up in future lectures is Think
Hardware!

Verilog Application Workshop

11-24

Verilog Sample Design


VSD3

12-1

Notes

Verilog Application Workshop

12-2

Aims and Topics

Aims
To review basic Verilog concepts and code structures
To explore a real life example

Topics
FIFO (First-In First-Out) design specification
Implementation
Module declarations
Functional code
Testbench design and implementation

Verilog Sample Design (VSD3)

12-3

Sample Design

Verilog Application Workshop

12-4

FIFO Specification

FIFO is parameterized for width and length

FIFO is asynchronously reset

FIFO is synchronous written and read


Data is written on rising edge of clock when write enable is high
Data is read on rising edge of clock when read enable is high
Data is read in same order as written

When the FIFO is full, set f_full high and ignore write operations

When the FIFO is empty, set f_empty high and ignore read operations

Verilog Sample Design (VSD3)

12-5

FIFO Specification

Verilog Application Workshop

12-6

FIFO Implementation

Use a register array for the


FIFO contents

Access the array using


write and read pointers

Derive the FIFO status


from the pointer addresses

FIFO length

0 1 2 3 . . . . . . . n

FIFO
width

FIFO full
FIFO empty

rd_ptr

wr_ptr

Read pointer
follows write
and accesses
data in same
order as
written

<free>

wr_ptr
write here

four

three

two

one

rd_ptr

FIFO write:
assign data to
current write
pointer &
increment

wr_ptr
Verilog Sample Design (VSD3)

12-7

FIFO Implementation
The FIFO is implemented using an array of registers. The array is indexed by separate FIFO write and
FIFO read pointers. When we write to the FIFO, data is written to the current write pointer location and
the pointer is incremented. As more data is written, the write pointer moves forward through the array.
When we read data, we read from the current read pointer location, and increment the read pointer. So
the read pointer chases the write pointer through the array, reading the data in the order in which it was
written to the array. When the pointers reach the end of the array, they independently wrap back to the
start. This allows the write pointer to overwrite data which has been read from the FIFO.
The write pointer operates on a write, then increment approach. Input data is written directly to the
current write pointer location, and then the pointer is incremented to point to the next free location.
By monitoring the relative values of the pointers, we can determine whether the FIFO is full or empty.

Verilog Application Workshop

12-8

FIFO Model Structure


module fifo
#(
Verilog-2001 list_of_parameter_declarations
)
(
Verilog-2001 list_of_port_declarations
);
// signal declarations
// functional code
endmodule

Verilog Sample Design (VSD3)

12-9

FIFO Model Structure


Modules are the basic building blocks in the design hierarchy. Every module description starts with the
keyword module, has a name (fifo), and ends with the keyword endmodule. The module name
must be unique within a design hierarchy.
Following the module name is a list of the inputs and outputs of the module.
As you will parameterized the input and output port width, you must declare the parameters before you
declare the input and output ports of the module.
You must declare all constants and variables before you use them.

Verilog Application Workshop

12-10

Design Constants
You can use module
parameters to define the
data and address width

You can change the


values for each
individual instance

Declare the parameters


before you declare the
ports

0 1 2 3 . . . . . . LENGTH-1
0
1
2

. . .

WIDTH-1
rd_ptr[ADDRESS_WIDTH-1:0]

module fifo
// Verilog-2001 list_of_parameter_declarations
#(
parameter integer DWIDTH = 8,
parameter integer AWIDTH = 5
)

// 16 wide by 16 deep FIFO


fifo #(16,4) fifo16x16 (...

Verilog Sample Design (VSD3)

12-11

Design Constants

Use module parameters to parameterize your module definition

You can use a module parameter anywhere that you can use a literal

Typically, you use module parameters to define delays and widths of variables

You can override module parameter values on a per-instance basis

You cannot modify module parameters during runtime they are not variables

The IEEE Std. 1364-1995 syntax for module parameters is:


parameter_declaration ::=
parameter list_of_param_assignments ;
list_of_param_assignments ::=
param_assignment { , param_assignment }
param_assignment ::=
parameter_identifier = constant_expression

The IEEE Std. 1364-2001 allows you to specify a type and to sign and size vector parameters:
parameter_declaration ::=
parameter [ signed ] [ range ] list_of_param_assignments ;
| parameter integer list_of_param_assignments ;
| parameter real list_of_param_assignments ;
| parameter realtime list_of_param_assignments ;
| parameter time list_of_param_assignments ;

The IEEE Std. 1364-2001 allows to declare a module parameter port list:
module_declaration ::=
{ attribute_instance } module_keyword module_identifier
[ module_parameter_port_list ] [ list_of_port...
module_parameter_port_list ::=
# ( parameter_declaration { , parameter_declaration } )
Verilog Application Workshop

12-12

FIFO I/O
module fifo
// Verilog-2001 list_of_parameter_declarations
#(
parameter integer DWIDTH = 8,
parameter integer AWIDTH = 5
)
// Verilog-2001 list_of_port_declarations
(
input clock, reset, wr_en, rd_en,
input [DWIDTH-1:0] data_in,
data_in
output f_full, f_empty,
output [DWIDTH-1:0] data_out
);
fifo
DWIDTH
// local variables
// functional code

data_out
DWIDTH

wr_en

f_full

rd_en

f_empty

endmodule
reset
clock

Verilog Sample Design (VSD3)

12-13

FIFO I/O
Use the parameters in the definition of the input and output ports of the FIFO module.

Verilog Application Workshop

12-14

Register and Internal Variable Declarations


module fifo
// parameter declarations
// port declarations

rd_ptr

// track last operation


reg last_was_write;
//functional code
endmodule

1
2
3

. . . . . . .

// pointer declarations
reg [AWIDTH-1:0] wr_ptr;
reg [AWIDTH-1:0] rd_ptr;

. . . . . . . . . .

// FIFO array declaration


// Verilog-2001 power operator
reg [DWIDTH-1:0] mem [0:2**AWIDTH-1];

mem

LENGTH-1
wr_ptr

[DWIDTH-1:0]

Verilog Sample Design (VSD3)

12-15

Register and Internal Variable Declarations


FIFO contents will be held in a 1-dimensional array of vector reg memD where each location in the array
is a vector of size [DWIDTH-1:0] and the array depth is [0:2**AWIDTH-1].
To access the array requires read and write pointers of size [AWIDTH-1:0].
By defining the FIFO array and pointers in terms of the design parameters, you can easily set the data
and address lengths differently for each FIFO instance.

Verilog Application Workshop

12-16

FIFO Functional Code


always @ (posedge clock or posedge reset)
if (reset)
// asynchronous reset
begin
rd_ptr <= 0;
wr_ptr <= 0;
last_was_write <= 0;
// nonblocking
end
else
begin
if (wr_en && !f_full)
// write operation
begin
mem[wr_ptr] <= data_in; // write to array
wr_ptr <= wr_ptr + 1;
// increment pointer
end
if (rd_en && !f_empty)
// read operation
begin
rd_ptr <= rd_ptr + 1;
// increment pointer
end
last_was_write <= wr_en; // track last operation
end

Verilog Sample Design (VSD3)

12-17

FIFO Functional Code


This sequential procedure describes the main functionality of the FIFO. The FIFO uses an asynchronous
reset, so the procedure event list must contain the reset as well as the clock input. Remember synthesis
tools require that all variables in an event list for a sequential procedure must be edge-qualified. So the
procedure will be triggered by the positive edge of reset and the positive edge of clock.
When reset is active the read and write pointers are initialized to location 0.
When reset is not active, we check for a successful read or write operation.
If the read enable is active and the FIFO is not empty, we have a successful read operation and increment
the read pointer.
If the write enable is active and the FIFO is not full, we have a successful write operation and write
data_in to the current write pointer location, and then increment the pointer.

Verilog Application Workshop

12-18

// full and empty pointers


assign f_full = (rd_ptr == wr_ptr
&& last_was_write);
assign f_empty = (rd_ptr == wr_ptr
&& !last_was_write);

wr_ptr

// output
assign data_out = mem[rd_ptr];
endmodule

if read pointer catches write


pointer, FIFO empty!

rd_ptr

<free>

// sequential procedure

read data

if write pointer
catches read
pointer, FIFO full!

write here

module fifo ...


// declarations

write here

FIFO Outputs

Continuous assignments combinationally drive outputs.


rd_ptr

wr_ptr

Verilog Sample Design (VSD3)

12-19

FIFO Outputs
Ports of a type not explicitly declared default to the wire type, so the output ports are nets. You set net
values using continuous assign statements.
We generate the data_out output by indexing the FIFO array with the read pointer rd_ptr.
We generate the FIFO status flags by comparing the read and write pointer values. If rd_ptr is equal
to wr_ptr, then the FIFO is either empty or full. If the last operation was a write, then it must be full,
and otherwise empty.

Verilog Application Workshop

12-20

The Testbench
Testbench
Design Under Test
Stimulus
and
Control

data_out
data_in
f_full

clock
reset
wr_en
rd_en

f_empty

Response
Generation
and
Verification

The testbench:
Instantiates and connects to the Design Under Test (DUT)

Applies stimuli to the DUT input data and control ports

Monitors the DUT output ports to verify correct behavior


Verilog Sample Design (VSD3)

12-21

The Testbench
To verify that our FIFO model works correctly we need to simulate the model with some meaningful
stimuli. We will need to write a testbench to apply this stimuli to the FIFO and check for the correct
response. A testbench will typically perform 3 functions:1. Instantiate the Device Under Test (DUT) and connect the input and output ports to local variables
2. Apply stimuli to the input data and control (clock, reset) ports
3. Monitor the output ports to capture the response of the design to the applied stimuli, and verify
that these results are as expected
This final function may actually be performed by examining the input and output variables in a waveform
viewer and taking the manual decision whether the design behavior is correct or not.
Testbenches tend to start off simple but quickly become sophisticated. Typically, at least 50% of the time
you will spend writing Verilog on a project will be taken up with coding your test bench.

Verilog Application Workshop

12-22

Testbench Declarations
module fifo_tb;
// Verilog-2001 local constants
localparam integer DWIDTH = 8;
localparam integer AWIDTH = 5;
localparam integer PERIOD = 10;
// Signal declarations
// for FIFO inputs
reg [WIDTH-1:0] data_in;
reg clock, wr_en, rd_en, reset;
// for FIFO ouputs
wire f_full;
wire f_empty;
wire [WIDTH-1:0] data_out;
// FIFO instantiation
// Apply stimulus
endmodule

Question
Why does the testbench have no ports?

Verilog Sample Design (VSD3)

12-23

Testbench Declarations
The testbench has no ports because we expect it to not be instantiated in another module.

Verilog Application Workshop

12-24

DUT Instantiation
module fifo_tb;
// Declarations
// FIFO instantiation
fifo
// Verilog-2001 parameter value by name
#(
.AWIDTH(AWIDTH)
.DWIDTH(DWIDTH),
)
dut
(
.data_in
.data_out
.clock
.reset
.wr_en
.rd_en
.f_full
.f_empty
);

(data_in),
(data_out),
(clock),
(reset),
(wr_en),
(rd_en),
(f_full),
(f_empty)

The module definition name is


fifo

Override the module parameters

The module instance name is dut

Use named port connections to


bind FIFO ports to local variables
Syntax .port(variable)

// Apply stimulus
endmodule

Verilog Sample Design (VSD3)

12-25

DUT Instantiation

Verilog Application Workshop

12-26

Describing Stimulus
//Apply stimulus

initial clock = 1b0;


always #(PERIOD/2) clock = ~clock;

initial begin
$monitorb("%d",$time,,clock,,reset,,wr_en,,rd_en,,
data_in,,f_full,,f_empty,,data_out);
@(negedge clock) // assert reset
reset = 1b1;
@(negedge clock) // deassert reset
reset = 1b0;
{wr_en, rd_en} = 2b00;
@(negedge clock) // load 1 word
wr_en = 1b1;
data_in = {WIDTH {1b1}};
repeat(2**AWIDTH-2)
@(negedge clock) // load n-2 words
data_in = data_in - 1;
@(negedge clock) // load 1 word
data_in = data_in - 1;
@(negedge clock) // attempt load
data_in = data_in - 1;
@(negedge clock) // unload 1 word
{wr_en, rd_en} = 2b01;
data_in = {WIDTH {1bX}};
repeat(2**AWIDTH-2)
@(negedge clock); // unload n-2 words
@(negedge clock); // unload 1 word
@(negedge clock); // attempt unload
@(negedge clock)
$finish;
end

establish clock
monitor value changes
synchronize to clock
initialize flags
load 1 word - not empty

almost fill - not yet full


load 1 word - full
load 1 word - ignored
unload 1 word - not full

almost empty - not empty


unload 1 word - empty
unload 1 word - ignored
terminate simulation

Verilog Sample Design (VSD3)

12-27

Describing Stimulus
$finish is a system task that ends simulation.
$monitor is a system task that outputs the value of the variables if they change.

Verilog Application Workshop

12-28

Simulation Results
0
clock
reset
f_full
f_empty
wr_en
data_in
rd_en
data_out

100

200

300

400

500

600

FF FE FD FC FB FA F9 F8 F7 F6 F5 F4 F3 F2 F1 F0 EF EE EDEC EB EA E9 E8 E7 E6 E5 E4 E3 E2 E1 E0

FF

700
800
1000
900
1100
1200
1300
clock
reset
f_full
f_empty
wr_en
data_in DF
rd_en
data_out FF FE FD FC FB FA F9 F8 F7 F6 F5 F4 F3 F2 F1 F0 EF EE ED EC EB EA E9 E8 E7 E6 E5 E4 E3 E2 E1 E0 FF

Verilog Sample Design (VSD3)

12-29

Simulation Results

Verilog Application Workshop

12-30

Review
1. How can you change the value of a parameter?
2. What are the basic functional blocks of a test fixture?
3. Using a parameter, write code that creates a clock stimulus.

Verilog Sample Design (VSD3)

12-31

Review

Verilog Application Workshop

12-32

Definition of RTL Code


VRE7

13-1

Notes

Verilog Application Workshop

13-2

Aims and Topics

Aim
To define the rules and coding guidelines for RTL code, and to give an overview
of portability issues

Topics
Combinational Procedures
Sequential Procedures

Definition of RTL Code (VRE7)

13-3

Terms and Definitions


Logic is considered combinational if its outputs, at any time, are determined directly from the present
combination of the inputs any input change can immediately effect the outputs.
Logic is considered sequential if it implies storage. If the output cannot be determined at any given
moment by the state of the inputs, storage is implied.
It is important that you understand what type of output to expect from your source code and be able to
look back to determine why the synthesis tool you used produced a particular output.

Verilog Application Workshop

13-4

Coding RTL Verilog


// Combinational Block

// Sequential Block

always @( all input signals )


begin
blocking assignments
...
end

always @( clock edges )


begin
nonblocking assignments
...
end

Synthesis
Procedures to be synthesized must conform to specific templates!

Definition of RTL Code (VRE7)

13-5

Coding RTL Verilog


The definition of the RTL style is that you are required to write your code in:

Continuous assignments (that always represent combinational logic)

Combinational procedures that represent combinational logic


The simulator re-evaluates a combinational block when an input to the logic changes value

Sequential procedures that represent sequential logic


The simulator re-evaluates a sequential block only on specific edges of specific signals

Verilog Application Workshop

13-6

Combinational Logic
The event list for a combinational block
must contain all inputs to the logic.

always @(a or b or sel)


begin
if (sel == 1)
y = a;
else
y = b;
end

Question
What would the behavior be if sel
was missing from the event list?

Do not include temporary variables


those written and then read in the same
procedure and nowhere else.

always @(a or b or c)
begin : comb_blk
reg temp;
temp = a + b;
q = temp + c;
end

Definition of RTL Code (VRE7)

13-7

Combinational Logic
The Verilog language allows you to place any variables in the sensitivity list and use blocking and
nonblocking assignments anywhere in the procedure. The synthesis tool requires code that
unambiguously states your design intentions. Code meant for the synthesis tool may use only a subset of
the Verilog constructs and coding styles.
For combinational logic:

All edges of all signals input to the logic must be present in the sensitivity list. This is due to the
rule that any changes on any inputs to the logic must be given the opportunity to immediately
affect the output
Do not place temporary variables in the sensitivity list. A temporary variable is one that the
block reads (and is read nowhere else) only after the block writes it. It is not input to the logic.

You should use only blocking assignments within purely combinational procedures. This is a
recommendation to obtain higher simulation performance nonblocking assignments are not
necessary and simulate more slowly.
It is an absolute requirement that you never mix blocking and nonblocking assignments to the
same variable!

The synthesis standard states that the sensitivity list shall not affect the generation of combinational
logic. That means that if the synthesis tool recognizes the block as combinational logic, it will proceed
as if you had included all inputs to the logic in the sensitivity list. The synthesis tool may or may not warn
you about missing inputs. The generated gates will simulate correctly, but very likely differently than the
incorrect RTL block.

Verilog Application Workshop

13-8

Incomplete Event List


always @(a or b or sel)
begin
if (sel == 1)
y = a;
else
y = b;
end

Synthesis
For combinational logic, include all
in the event list all variables that are
input to the logic. When in doubt use
the * wildcard.
// incomplete
always @(a or b)

// complete
always @(a or b or sel)
always @(*)

sel

sel

Definition of RTL Code (VRE7)

13-9

Incomplete Event List


This example illustrates the effect of an incomplete sensitivity list.

If sel is missing from the event list, the assignment to y is made on changes of a or b
Changes in sel have no affect

Debug of problems caused by incomplete sensitivity lists is difficult you might want to develop
the habit of simply always using * for combinational blocks

Verilog Application Workshop

13-10

Incomplete Assignments in Combinational Logic

?Question
What is the value of b if ctrl = 0 ?

What hardware would the synthesis tool


infer to implement this functionality?
How would you rewrite this block to
avoid this hardware?

module incomplete (
input wire a, ctrl,
output reg y
);
always @(ctrl or a)
if (ctrl)
y = a;
endmodule

Definition of RTL Code (VRE7)

13-11

Incomplete Assignments in Combinational Logic


If there is an execution path through a combinational procedure where an output variable from that
procedure is not updated (in this example when ctrl does not equal 1), then that variable must retain
its previous value.
To implement this in hardware, a synthesis tool will infer a transparent latch.
How can we modify the code to give combinational logic (such that b = 0 when ctrl = 0)?

Verilog Application Workshop

13-12

Avoiding Latches
Two very common ways exist to
avoid latch inference...

// Default Assignment
always @(ctrl or a)
begin
b = 0; // default
if (ctrl)
b = a;
end

?Question
Which would you use for a procedure
with complex nested if statements?

// Default if/case branch


always @(ctrl or a)
begin
if (ctrl)
b = a;
else
b = 0; // default
end

Definition of RTL Code (VRE7)

13-13

Avoiding Latches
There are two ways to prevent a synthesis tool creating transparent latches:1. Initialize b at the top of the procedure with a default assignment
2. Use an else clause for the if statement
Which is the best technique in a real design?
If you have a procedure with a complex set of conditional assignments, you are likely to not assign a
value to the output for one or more of these branches. A single default assignment to the output at the top
of the procedure prevents this problem.

Verilog Application Workshop

13-14

Continuous Assignments
Continuous assignments drive values onto nets.
Continuous assignments always represent combinational logic.
The output is a function of the current inputs
module orand (
input a, b, c, d, e,
output y
);
assign y = e & (a|b) & (c|d);
endmodule

a
b
e
c
d

Definition of RTL Code (VRE7)

13-15

Continuous Assignments

Verilog Application Workshop

13-16

Rules for the Synthesis of Combinational Logic


Here once more are the rules for a purely combinational block:
Ensure the event list is complete

Use blocking assignments

Provide default assignments to prevent latches

Avoid combinational feedback loops

Continuous assignment always synthesizes to combinational logic

Functions always synthesize to combinational logic


Functions will be described later

Definition of RTL Code (VRE7)

13-17

Rules for the Synthesis of Combinational Logic


These materials have not yet discussed functions.
Most synthesis tools synthesize Verilog functions to purely combinational logic even if they have
incomplete assignments.

Verilog Application Workshop

13-18

Sequential Logic
The event list for a sequential block contains only
single edges of clock signals.
Use only posedge/negedge in event list

The synthesis tool infers registers for all


non-blocking assignments in sequential
procedures

module counter (
input wire clk,
output reg [3:0] count
);
always @(posedge clk)
if (count >= 9)
count <= 0;
else
count <= count + 1;
endmodule

count

1
4

Question
Is there a problem with
this counter description?

sel

<
9

clk

Definition of RTL Code (VRE7)

13-19

Sequential Logic
This sequential procedure only has the clock variable clk in its event list. The posedge event control
will only trigger the procedure on the rising edge of the clock. The if statement in the procedure
describes the combinational logic required to calculate a new value for count on the next rising edge
of clk. Since this is a sequential procedure, any variables assigned to with non-blocking assignment in
the procedure will be registered.
Synthesis tools recognize sequential procedures by looking for a particular code template in this case,
a procedure with an event list containing only edge-qualified signals. Although some synthesis tools do
support other coding styles for sequential procedures, if you stick to the one shown here you won't go
wrong and you will be writing code which is most portable between synthesis tools.
Note: This example lacks a reset to initialize the count value!

Verilog Application Workshop

13-20

Resetting Sequential Logic


Use an if...else statement to add reset
to a procedure.
Put the reset behavior in the first
branch of the if statement

Put the normal sequential behavior in


the else branch of the statement

For asynchronous resets, add the active


reset edge to the event list

module synch_rst (
input wire clk, rst,
output reg [3:0] count
);
always @(posedge clk)
if (rst) // active high reset
count <= 4b0;
else if (count >= 9)
count <= 4b0;
else
count <= count + 4b1;
endmodule
module async_rst (
input
clk, rst,
output reg [3:0] count
);
always @(posedge clk or posedge rst)
if (rst) // active high reset
count <= 4b0;
else if (count >= 9)
count <= 4b0;
else
count <= count + 4b1;
endmodule
Definition of RTL Code (VRE7)

13-21

Resetting Sequential Logic


To infer reset registers, use an if...else statement. Place the reset behavior in the if branch and
the normal sequential behavior in the else branch, and make no assignments to the register outside
of this if/else structure.
The test for the reset comes first in the if-else structure, so the reset takes priority over the normal
sequential behavior.
For asynchronous resets, trigger the procedure on the active edge of the reset add posedge reset
for active high and negedge reset for active low. The active edge of the reset must also trigger the
procedure, to execute the reset behavior.
For synchronous resets, trigger the procedure on only the clock edge.
Code synchronously reset, asynchronously reset and not reset registers in separate procedures.

Verilog Application Workshop

13-22

Sequential Procedure Templates


Code must follow these templates:
An always procedure

always @(posedge clk)


begin
// normal sequential behavior
end

Event list contains only:


posedge/negedge clock
posedge/negedge reset for
asynchronous reset

Tip
Keep procedures with asynchronous resets
separate from procedures with synchronous
resets and separate from procedures with no
reset.

always @(posedge clk)


if (!rst)
begin
// synchronous reset behavior
end
else
begin
// normal sequential behavior
end
always @(posedge clk or negedge rst)
if (!rst)
begin
// asynchronous reset behavior
end
else
begin
// normal sequential behavior
end

Definition of RTL Code (VRE7)

13-23

Sequential Procedure Templates


Sequential procedures have the clock edge in the event list, and also the reset edge if there is an
asynchronous reset.
The event list must not contain any other signals used within the procedure. A sequential procedure must
activate only on the active edge of the clock (and asynchronous reset if required).

Verilog Application Workshop

13-24

Synchronous Feedback Inference


Incomplete assignment in a sequential
procedure implies sequential feedback
not a latch.

module dffn (
input wire d, clk, en,
output reg q
);
always @(posedge clk)
if (en)
q <= d;
endmodule

q
mux

en
clk

Question
Write this using one combinational
block and one sequential block.
Definition of RTL Code (VRE7)

13-25

Synchronous Feedback Inference


If a variable is not updated during procedure execution, then the variable value is unchanged. In
combinational procedures, this infers a latch to store the previous variable value. For synchronous
procedures, the variable value is stored in the register which is inferred by the nonblocking assignment.
Therefore in synchronous procedures we do not need to use default assignment or else clauses to
prevent latch inference.

Verilog Application Workshop

13-26

Sequential Procedure Assignment

clk

?Question
Code this design in Verilog.

Definition of RTL Code (VRE7)

13-27

Sequential Procedure Assignment


What is the Verilog description of this design?

Verilog Application Workshop

13-28

Blocking and Non-blocking Assignment


1: GOOD

3: WORKS

always @(posedge clk)


begin
c <= b;
b <= a;
end

always @(posedge clk)


begin
c = b;
b = a;
end

2: GOOD

4: BROKEN

always @(posedge clk)


begin
b <= a;
c <= b;
end

always @(posedge clk)


begin
b = a;
c = b;
end

Use non-blocking assignments to infer registers in sequential procedures.

Definition of RTL Code (VRE7)

13-29

Blocking and Non-blocking Assignment


Use non-blocking assignments infer registers in sequential logic. Every assignment will infer registers.
With non-blocking assignment, the order in which the statements appear determines whether each
assignment will infer registers.
Example 3 reads variable b before writing it, therefore 2 registers are inferred by this procedure.
Example 4 writes variable b and then reads it. Variable b is a temporary variable. The synthesis tool
infers only one register.

Verilog Application Workshop

13-30

Blocking Assignment in Sequential Procedures


A variable written with a blocking assignment
and then read in the same procedure is a
temporary variable no register is inferred.
A variable written with a blocking assignment
after it is read in the same procedure is a
persistent variable a register is inferred.

?Question

module flops1 (
input wire in1, clk,
output reg out1
);
always @(posedge clk)
begin: fblk
reg tmp;
tmp
= !in1;
out1 <= tmp;
end

How many registers in each procedure

Synthesis
Use blocking assignment in sequential procedures
only for temporary variables.

module flops2 (
input wire in1, clk,
output reg out1
);
always @(posedge clk)
begin: fblk
reg tmp;
out1 <= tmp;
tmp
= !in1;
end
Definition of RTL Code (VRE7)

13-31

Blocking Assignment in Sequential Procedures


Blocking assignment can be useful for temporary variables in sequential procedures
Use a temporary variable is used to hold the result of an expression before you use it elsewhere in the
procedure. In the list of sequential statements in the procedure, you must assign a value to the temporary
variable before you read from it. You can use temporary variables to break up complex expressions and
combinational logic into a series of smaller steps making complex logic easier to describe, understand
and maintain.
A typical usage model would be to use temporary blocking variables in the calculation of an expression,
and then assign the result to other variables using non-blocking assignment. Registers are then inferred
for the non-blocking assignment. Use separate variables for temporary use!
You may prefer to simply adopt the convention of never using blocking assignments or temporary
variables in a sequential procedure.

Verilog Application Workshop

13-32

Review Questions
Find and fix the coding mistakes in the following procedures intended for synthesis:

always @(posedge clk or negedge rst) // one


if (rst)
q <= 1b0;
else
always @(posedge clk or d) // two
q <= d;
if (rst)
q <= 1b0;
else
q <= d;

always @ (posedge reset) // three


if (reset)
q <= 1b0;
always @ (posedge clk)
q <= d;

always @(posedge clk) // four


if (clk)
q = d;
else
q = 1b1;

always @(posedge clk or posedge rst) // five


begin
if (rst)
q <= 1b1;
else
q <= d;
always @(ctrl | s) // six
if (rst)
if (ctrl)
p <= 1b0;
op = s;
else
else
p <= c;
op = 1b0
end
end

Definition of RTL Code (VRE7)

13-33

Review

Verilog Application Workshop

13-34

This page left intentionally blank

Synthesis of Mathematical
Operators
VME7

14-1

Notes

Verilog Application Workshop

14-2

Aims and Topics

Aims
To explain the issues associated with both simulation and synthesis of
mathematical operators

Topics
High level synthesis
Resource sharing
Intermediate variables
Operator architectures
Macro generation

Synthesis of Mathematical Operators (VME7)

14-3

Aims and Topics

Verilog Application Workshop

14-4

High Level Synthesis


Synthesis tools can recognize and separately
optimize complex operations that use
operators.
Often by selecting template circuitry
from a library

Operator
a = b + c;

A high-level synthesis phase detects


and isolates complex operators

Synthesis tools very rarely recognize


operations that you code yourself without
utilizing operators.

Logic
b
c

Your use of operators can thus have a large


effect on resulting hardware.

Gates
not u1 (nsel,sel);
and u2 (selb,sel,b);
and u3 (nsa,ns,a,);

Synthesis of Mathematical Operators (VME7)

14-5

High Level Synthesis


A single line of Verilog code containing an arithmetic operator may synthesize to many more gates than
several dozen lines of simple or conditional assignments containing only logical or relational operators.
Since such operators can have a large effect on the area and performance of the final design, most
synthesis tools treat arithmetical, and sometime relational, operators with special care. When Verilog
code is compiled into a synthesis tool and translated into a boolean representation, a special high level
synthesis phase identifies and isolates such operators from the reset of the logic. These operators may
be partitioned into a separate level of hierarchy so that they can be optimized separate from the other
logic.

Verilog Application Workshop

14-6

Optimization of Operators
The synthesis tools treatment of operators focuses on four issues:
Does it infer the operator hardware from a library or does it implement the operator
as discrete gates?

What is the operator architecture (e.g. ripple-carry, carry-look-ahead etc.)


Automatically chosen based on cost factors?
User-specified as a directive to the tool?

Sharing of operators . . .

Synthesis of Mathematical Operators (VME7)

14-7

Optimization of Operators
The first issue is how the synthesis tool implements the operator.
The synthesis tool can choose to map to a single adder cell from the vendors library or to an
implementation in discrete gates.
The second issue is what architecture to select or build.
The synthesis tool can (for example) choose between ripple carry and carry look-ahead architecture.
Modern synthesis tools can automatically choose the architecture based upon design cost factors such
as area and speed.
Modern synthesis tools also permit you to specify the architecture using a synthesis directive.
The third issue to be aware of that synthesis tools may implement complex operators in a new level of
hierarchy.
The fourth issue is that of resource sharing.

Verilog Application Workshop

14-8

Resource Sharing Concepts


always @(sel or a or b or c)
if (sel)
op = a + b;
else
op = a + c;

Question
Draw the hardware architecture
that you think this code will infer.

Synthesis of Mathematical Operators (VME7)

14-9

Resource Sharing Concepts


This example has two add operations that are mutually exclusive only one of the operations occurs at
at time.

Verilog Application Workshop

14-10

Manual Resource Sharing


always @(sel or a or b or c)
if (sel)
op = a + b;
else
op = a + c;

?Question
Rewrite this code to use
only a single add operator.

Synthesis of Mathematical Operators (VME7)

14-11

Manual Resource Sharing


Some synthesis tools can automatically share resources.
The decision whether to share the resource considers cost factors such as area and delay.

Verilog Application Workshop

14-12

Automatic Resource Sharing


o = a + b + c;
n = a + b + d;
m = c + d;

o = a + b + c;
n = b + a + d;
m = c + d;

o = a + b + c;
n = a + d + b;
m = c + d;

Caution
Operand order and position may affect automatic resource sharing.

Tip
Use intermediate terms to force resource sharing
t
o
n
m

=
=
=
=

a
t
t
c

+
+
+
+

b;
c;
d;
d;

Synthesis of Mathematical Operators (VME7)

14-13

Automatic Resource Sharing


Some synthesis tools implement hardware for each operator in the source code.
Other synthesis tools can automatically share resources.
The synthesis tools may only identify common sub-terms where the operands are in the same order
and position in the expression.
You can help these tools by identifying the common sub-terms yourself and generating intermediate
variables.

Verilog Application Workshop

14-14

Mathematical Optimization
Chain (serial) structure

Tree (parallel) structure

op = a + b + c + d;

op = (a + b) + (c + d);

a
c

op
op
Synthesis of Mathematical Operators (VME7)

14-15

Mathematical Optimization
Most compilers parse an expression from left to right. Thus a synthesis tool might initially construct
hardware for a + b + c + d by adding a and b and then adding that result to c and then that
result to d. This would likely not be the most optimal implementation, so the synthesis tool might need
to slightly transform the design.
You can help the tool arrive at an initially more optimal structure by judicious use of parentheses.

Verilog Application Workshop

14-16

Instantiation of Macro-Cells
Explicit macro instantiation creates issues:
Makes the code less readable

Code is dependent upon a specific


technology

module my_adder ( ... );


always @* y = a + b;
// OR
vendor_adder a1 (a, b, y);
...
endmodule

For what situations might you need to


explicitly instantiate a macro?
When the tool cannot automatically
infer a macro-cell from a library:
Memory block
Embedded micro-processor
Third party IP
For these situations, create your own
wrapper module around the macro so that
swapping in some other IP is a
configuration change rather than a module
rewrite.
Synthesis of Mathematical Operators (VME7)

14-17

Instantiation of Macro-Cells
In the case where a synthesis tool is not able to infer a technology-specific macro from a statement it may
be necessary to explicitly instantiate the macro as a component in order to obtain the required optimal
results.
Instantiating a specific macro will make the code technology-dependent (i.e. the code will need to be
edited if another technology is targeted), but explicit instantiation does give more control over the
resulting synthesized design.
Modern synthesis tools generate good results for arithmetic operators. You may still need to explicitly
instantiate memory blocks, embedded processors and third-party Intellectual Property (IP).
To make the design more technology independent, it is possible to instantiate the vendors macro within
a user defined module, and then to instantiate this module in the actual design. In this case, it is easier to
change to a new technology at a later date, as you are only required to modify the definition of the user
defined cells, rather than having to change each case where one of these parts has been instantiated.

Verilog Application Workshop

14-18

Summary
Read the synthesis vendors documentation!
Understand what the synthesis tool does about operators
Apply this knowledge to your structure of Verilog expressions

Synthesis of Mathematical Operators (VME7)

14-19

Summary

Verilog Application Workshop

14-20

Review Questions
1. In what two ways may the synthesis tool implement mathematical operators?
2. What are two disadvantages to directly instantiating macrocells instead of using
mathematical operators?
3. How would you implement the following expression in hardware using just one two
input adder? Give the hardware and also the code.
y = a + b + c;

Synthesis of Mathematical Operators (VME7)

14-21

Review

Verilog Application Workshop

14-22

This page left intentionally blank

Synthesis Coding Styles


VYE9

15-1

Notes

Verilog Application Workshop

15-2

Aims and Topics

Aims
To take a detailed look at how Verilog constructs relate to hardware and
therefore understand how coding style will affect synthesis results.

Topics
Structuring Procedures
State machines
if and case statement synthesis
Synthesis directives
Initialization

Synthesis Coding Styles (VYE9)

15-3

Aims and Topics

Verilog Application Workshop

15-4

Structuring Procedures

clk

?Question

always @(posedge clk)


begin
// logic in blocks A and B

Can this code describe this logic i.e.


is it possible to describe the above
structure using one sequential
procedure?

end

Synthesis Coding Styles (VYE9)

15-5

Structuring Procedures
It is important when writing your RTL code to correctly partition design behavior between procedures
to control the location of registers in the design.
Lets look at an example. Does this code describe this logic?

Verilog Application Workshop

15-6

How Should it be Written?

clk

?Question
How should the code be structured?
(There are at least three options)

Synthesis Coding Styles (VYE9)

15-7

How Should it be Written?


Spend a few minutes working out how the code should be written - there are at least three different
ways...

Verilog Application Workshop

15-8

Review of Finite State Machine (FSM)


All FSM have:
Current state storage

Next state encoding logic (A)

Output decoding logic (B)

clk

Moore FSM

FSM outputs can be a function of:

Only the current state only


(Moore machine)

The current state and the current


inputs (Mealy machine)

clk

Mealy FSM

Synthesis Coding Styles (VYE9)

15-9

Review of Finite State Machines (FSM)


An FSM is a control path logic structure. It is sequential, and has a number of defined states which it
can be in. Transition between states is determined by a combination of the current state and the current
inputs to the FSM (examined at a clock edge).
For a Moore FSM, the output logic depends only on the state
For a Mealy FSM, the output logic depends on inputs as well as state

Verilog Application Workshop

15-10

State Machine: State Diagram

A
a = 1b1

o1 = 1b0
o2 = 1b0

c
3b011
B

b = 1b0

o1 = 1b1
o2 = 1b1

a = 1b0

{a,b} = 2b01

Transition
Conditions:
{a,b}=2b01

{a,b} = 2b11

3b001

State Encoding:
A=3b000,
B=3b001...

3b000
b = 1b1

State Names
(A,B,C,D,E)

o1 = 1b0
o2 = 1b0

Output values:
o1=1b0

D
3b010

a = 1b1

o1 = 1b0
o2 = 1b0

E
3b110
o1 = 1b0
o2 = 1b1

Synthesis Coding Styles (VYE9)

15-11

State Machine: State Diagram


You can use local constants to define the states. This gives the states names, which improves readability.
You can use a case statement to describe the next state function. Each branch is a current FSM state
and determines the next FSM state.
The example is a Moore machine, as the outputs are a function of only the current state. If the outputs
were a function of the current state and the inputs, the FSM would be a Mealy machine.

Verilog Application Workshop

15-12

State Machine: Declarations and Sequential Procedure


Declare constants to represent the states.
Select an FSM reset strategy.
Optionally partition the FSM into a
sequential procedure and a combinational
procedure.

State Register

o1
o2

Next State Logic


state

next_state

// state encoding
localparam [2:0] A
B
C
D
E

=
=
=
=
=

3b000,
3b001,
3b011,
3b010,
3b110;

// state vectors
reg [2:0] state, next_state;

Output Logic

a
b

module fsm (
input wire a, b, clock, reset,
output reg o1, o2
);

// sequential procedure for state


always @ (posedge clock
or posedge reset)
if (reset)
state <= A;
else
state <= next_state;
...

Synthesis Coding Styles (VYE9)

15-13

State Machine: Declarations and Sequential Procedure


This is a synthesizable description of the state register logic using a synchronous procedure with an
asynchronous reset.
On the rising edge of the clock, the procedure assigns the current value of the next_state to the
state variable.

Verilog Application Workshop

15-14

State Machine: Combinational Procedures


// combinational procedure for next state
always @ (a or b or state)
begin
next_state = state;
case (state)
A: if (a)
next_state = C;
else if (b)
next_state = B;
B: if (~b)
next_state = A;
else if ({a,b} == 2b01)
next_state = D;
C: if (a)
next_state = E;
else if ({a,b} == 2b11)
next_state = D;
D: next_state = A;
E: if (~a)
next_state = C;
endcase
end

// output decode
always @ (state)
begin
// default assignments
o1 = 1b0;
o2 = 1b0;
case (state)
B: begin
o1 = 1b1;
o2 = 1b1;
end
E: o2 = 1b1;
endcase
end

Next state and output decode


combinational procedures
could be merged

Next state and state register


procedures could be merged

Synthesis Coding Styles (VYE9)

15-15

State Machine: Combinational Procedures


The example ensures that the combinational procedures are complete. It does this by assigning an initial
value upon entry to the block and then conditionally assigning another value.
This example describes the FSM using 3 separate procedures:

A synchronous procedure with asynchronous reset for state register

A combinational procedure to derive the next state

A combinational procedure to derive the outputs,

Separating the next-state logic and the state register requires a variable (next_state) to carry
information from the combinational next state procedure to the synchronous state register procedure.
This is only one valid partitioning of the state machine.
The combinational next state and output decode procedures can be merged.
The sequential block can absorb the combinational next state function.

Verilog Application Workshop

15-16

Synthesis of if Statements
module if_example (
input
a, b, c,
input [3:0] ctrl,
output reg op
);
always @(a or b or c or ctrl)
if (ctrl == 4'h0)
op = a;
else if (ctrl <= 4'h4)
op = b;
else
op = c;
endmodule

Question
Draw the hardware architecture this represents.

Synthesis Coding Styles (VYE9)

15-17

Synthesis of if Statements
Spend a few minutes working this out architecture in terms of multiplexers and comparators.
It is important to understand what hardware architecture the synthesis tool would produce.
Your Verilog coding style influences the initial architecture the synthesis tool produces.
Thus making it more or less difficult for the synthesis tool to meet timing requirements.

Verilog Application Workshop

15-18

The Initial Architecture of if and case Statements


if (ctrl == 4h0)
op = a;
else if (ctrl <= 4h4)
op = b;
else
op = c;

ctrl
0

<=
4

case (ctrl)
0:
op = a;
0,1,2,3,4: op = b;
default:
op = c;
endcase

ctrl

=
0

op

Synthesis
How would this change if we directed the
synthesis tool to build the case branches in
parallel?

Synthesis Coding Styles (VYE9)

15-19

The Initial Architecture of if and case Statements


All synthesis tools start with a structure that essentially mirrors the RTL statements. They then optimize
that structure as required to meet timing and other requirements.

Verilog Application Workshop

15-20

Synthesis of case Statements


The conditions of the if and case branches can overlap. The synthesis tool by default
interprets their meaning the same way the simulation tool does it prioritizes them.
The synthesis tool by default interprets these two case statements identically:
case (ctrl)
0:
op = a;
0,1,2,3,4: op = b;
default:
op = c;
endcase

ctrl
0

<=
case (ctrl)
0:
op = a;
1,2,3,4: op = b;
default:
op = c;
endcase

ctrl

=
0

op

Synthesis Coding Styles (VYE9)

15-21

Synthesis of case Statements


Verilog case statements may have overlapping branches the top code example has two branches for
when ctrl is 0. Simulation (and by default synthesis) tools take the first branch that matches.
The synthesis tool by default starts with a priority structure, and then if the branches are mutual
exclusive, may optimize away the redundant circuitry (if needed) to meet the timing requirements.
If you know that your case branches are mutually exclusive, you can direct the synthesis tool to build the
branches in parallel without a priority structure.

Verilog Application Workshop

15-22

Parallel Case Statements


Synthesis tools can build mutually-exclusive case
branches without a priority structure.
Synthesis tools can recognize an obviously
parallel case. For others, use either:
A metacomment (still accepted)

(* synthesis, parallel_case *)
case (1)
this:
op = a;
that:
op = b;
default: op = c;
endcase

// ambit synthesis case = full

A Verilog-2001 attribute (now standard)


(* synthesis, parallel_case *)

Important
Never apply to a non-parallel case.

this
a

Note: Verilog-2001 provides the attribute


construct but does not define any attributes.
The synthesis standard defines several
attributes.

that
b
this
that
c

op
no priority
structure

Synthesis Coding Styles (VYE9)

15-23

Parallel Case Statements


A case with mutually exclusive choices is known as a parallel case the synthesis tool can implement it
with non-prioritized, parallel logic. Most synthesis tools can recognize a simple parallel case statement
and implement parallel logic. If the tool cannot recognize a parallel case, or the case statement is more
complex, you can direct the synthesis tool to build parallel circuitry.
You can use synthesis attributes to control or influence the synthesis of the code to which it is attached.
WARNING: If you apply a parallel-case synthesis attribute to a non-parallel case (where the choices are
not mutually exclusive) then the gate level functionality will not match the RTL functionality.

Verilog Application Workshop

15-24

Synthesis Directives
Most synthesis tools also
accept synthesis
directives as
metacomments.
Metacomments are
Verilog comments,
ignored by simulation but
meaningful to other tools.

case (test) // ambit synthesis parallel_case


2'b00:
op = a;
2'b01,
2'b10:
op = b;
2'b11:
op = c;
default: $display ("unknown test!");
endcase

Their effect is identical to


that of the standard
synthesis attribute.
Caution
Can lead to different
RTL/Gate level
functionality from same
design use with caution!

Synthesis Coding Styles (VYE9)

15-25

Synthesis Directives
The directives usually have the tool or company name in the comment. Some tool vendors also support
the directives of other companies.
Refer to your tool documentation to understand which specific directives your tools support.
The examples below show directives from Synopsys Design Compiler, Ambit BuildGates, and
Exemplar, and a generic directive (synthesis ...) initially recommended by Accellera.

Synthesis Compilation Directives

Case Directives

//synopsys translate_on

//synthesis parallel_case

//synopsys translate_off

//ambit synthesis case = mux

//ambit synthesis on

//exemplar parallel_case

//ambit synthesis off

//synopsys full_case

Other directives can be used to control, for example, the implementation of arithmetic operators or
FSMs.
NOTE: Since directives are ignored by simulation but affect synthesis they can lead to mismatches
between RTL and gate level behavior - use them with extreme caution!

Verilog Application Workshop

15-26

Synthesis of casex Statements


The casex and casez statements allow
you to specify dont-care bit positions.
The synthesis tool otherwise interprets
these exactly as it interprets the case
statement.
It is sometimes difficult to determine
whether a casex or casez statement is
truly parallel.

Question
Are these casex statements parallel?

always @(pri_in)
casex (pri_in)
4'b1???: op = 3;
4'b01??: op = 2;
4'b001?: op = 1;
4'b0001: op = 0;
default: op = 0;
endcase
end
always @(ctrl) begin
int = 3'b000;
casex (ctrl)
3'b??1: int[0] = 1'b1;
3'b?1?: int[1] = 1'b1;
3'b1??: int[2] = 1'b1;
endcase
end

Synthesis Coding Styles (VYE9)

15-27

Synthesis of casex Statements


Given the nature of casex and casez statements, it can be difficult to determine whether they are truly
parallel. You need to be more careful about using the parallel_case attribute with these constructs.

Verilog Application Workshop

15-28

Full Case Statements


Combinational logic: The output is at all times
determined by the current state of the inputs.
If an input combination exists for which the
output is not determined, the synthesis tool
latches the output for that combination.

// no latch
always @(ctrl or a or b)
case (ctrl)
0,1: op = a;
2:
op = b;
3:
op = 1bx;
endcase
// no latch

reg [1:0] ctrl;


reg a, b, op;

always @(ctrl or a or b)
case (ctrl)
0,1:
op = a;
2:
op = b;
default op = 1bx;
endcase

// latch op when ctrl==3


always @(ctrl or a or b)
case (ctrl)
0,1: op = a;
2:
op = b;
endcase

// no latch

Synthesis
Assigning the unknown state x is telling the synthesis tool that
you dont care what the output is for that input combination.

always @(ctrl or a or b)
begin
op = 1bx;
case (ctrl)
0,1: op = a;
2:
op = b;
endcase
end
Synthesis Coding Styles (VYE9)

15-29

Full Case Statements


In the non-full case example, the case statement has no branch for ctrl having the value 3 (11). The
synthesis tool infers a latch to hold the value of op when ctrl has the value 3.
To avoid latch inference, fully assign the outputs for all combinations of inputs.
Assuring that you have a case branch for every possible binary value of the case expression is a good
start, but not truly sufficient, as you will see later.
The best solution is a statement that makes a default assignment to all outputs.

Verilog Application Workshop

15-30

The full_case Attribute


The synthesis standard supports a
full_case attribute to force the
synthesis tool to assume that all case
branches are represented.

// no latch

It is the equivalent of a default case


match item that assigns dont-care to
all the outputs.
Caution

// no latch

It does not do anything more than you can


do yourself with a default case match item.
It does not prevent latch inference.

always @(ctrl or a or b)
(* synthesis, full_case *)
case (ctrl)
0,1:
op = a;
2:
op = b;
endcase

always @(ctrl or a or b)
case (ctrl)
0,1:
op = a;
2:
op = b;
default op = 1bx;
endcase

Synthesis Coding Styles (VYE9)

15-31

The full_case Attribute


Most synthesis tools also support nonstandard full_case synthesis pragmas:
//synthesis full_case
//synopsys full_case
//ambit synthesis case = full

Verilog Application Workshop

15-32

You Can Still Get Latches!


The synthesis tool can still infer latches for a case statement tagged with full_case
The full_case attribute applies only to the case match expressions

Any variable not fully assigned in the combinational block is still latched

Default assignments prevent latch inference use them!

module select (
input wire [1:0] sel
output reg
a, b
);
always @(sel) begin
a = 0; b = 0; // prevents latch for a
(* synthesis, full_case *)
case (sel)
2'b00: begin a = 0; b = 0; end
2'b01: begin a = 1; b = 1; end
2'b10: begin a = 0; b = 1; end
2'b11:
b = 1;
default: begin a = 'bx; b = 'bx; end
endcase
end
endmodule

Synthesis Coding Styles (VYE9)

15-33

You Can Still Get Latches!


You should not rely upon the full_case attribute to let you ignore the basic rules for describing
combinational logic.
In this example, although the case statement is naturally full, has a default branch, and has a full_case
attribute, you would still get a latch if you did not use the default assignment. That is because there is no
assignment to a when sl is 11, so the synthesis tool must latch it.

Verilog Application Workshop

15-34

Synthesis of initial Statements Not!


module counter (
input wire clk,
output reg [3:0] q
);

module counter (
input wire clk, rst,
output reg [3:0] q
);

initial q = 0;

always @(posedge clk)


if (rst)
q <= 4h0;
else if (q = 9)
q <= 4h0;
else
q <= q + 1;

always
if (q
q <=
else
q <=

@(posedge clk)
= 9)
4h0;
q + 1;

endmodule

endmodule

Synthesis
The synthesis standard supports the initial
construct only for initialization of ROM data
and requires it be accompanied by the
logic_block or rom_block attributes.

Synthesis Coding Styles (VYE9)

15-35

Synthesis of initial Statements Not!


In a Verilog initial block you can assign an initial value to a variable.
Synthesis tools do not accept this method to initialize a variable very rarely do manufacturers guarantee
that their storage cells power up in any known state.
The IEEE Std. 1364.1 supports the initial statement only for ROM modeling.

Verilog Application Workshop

15-36

Review Questions
1. What sort of hardware structure are inferred by both case and if statements, by
default, in Verilog?
2. How could you change a case statement in order that its implementation does not
result in a priority structure?
3. If you are not using a synthesis attribute, how can you assure coverage of all
conditions for a case statement?
4. Give the code for an asynchronously and synchronously resettable flip-flop as
shown in the diagram below?
async_reset
1b0

sync_reset
clock

Synthesis Coding Styles (VYE9)

15-37

Review

Verilog Application Workshop

15-38

This page left intentionally blank

Advanced Synthesis Coding Styles


VMS2

16-1

Notes

Verilog Application Workshop

16-2

Aims and Topics

Aims
To examine some more advanced synthesis coding styles and issues

Topics
Unsupported Verilog constructs
Register inference in synchronous logic
Latches and Tristates
Hierarchy management

Advanced Synthesis Coding Styles (VMS2)

16-3

Aims and Topics

Verilog Application Workshop

16-4

Unsupported Verilog Constructs


Synthesis tools compliant with IEEE Std. 1364.1 do not support:
assign/deassign (as a procedural statement)
defparam
disable
event
force/release
forever
fork/join
macromodule
primitive
pulldown/pullup
real
realtime

repeat
time
tri0/tri1/trireg
cmos/nmos/pmos/rcmos/rnmos/rpmos
tran/tranif0/tranif1/rtran/rtranif0/rtranif1
wait
while
-> (event emission)
===/!=== (identity operator)
expression in event list
hierarchical identifiers
system functions (except $signed/$unsigned)

Synthesis tools compliant with IEEE Std. 1364.1 ignore:


# (delay, if occurs after event control)
initial (except supported for ROM modeling)
specify (entire block)
strength specifications

system tasks
variable declaration assignment
`celldefine, `endcelldefine, `line, `timescale
`unconnected_drive, `nounconnected_drive
Advanced Synthesis Coding Styles (VMS2)

16-5

Unsupported Verilog Constructs


The @ event control must immediately follow the always keyword.

Verilog Application Workshop

16-6

Register Inference for Blocking Assignment


module blockshift (
input wire clk, ip,
output reg op
);
reg [7:0] shift_reg;
integer i;

always @(posedge clk)


begin
// for loop expansion

always @(posedge clk)


begin
op = shift_reg[7];
for (i = 7; i >= 1; i = i - 1)
shift_reg[i] = shift_reg[i-1];
shift_reg[0] = ip;
end
endmodule

op
shift_reg[7]
shift_reg[6]
shift_reg[5]
shift_reg[4]
shift_reg[3]
shift_reg[2]
shift_reg[1]
shift_reg[0]

=
=
=
=
=
=
=
=
=

shift_reg[7];
shift_reg[6];
shift_reg[5];
shift_reg[4];
shift_reg[3];
shift_reg[2];
shift_reg[1];
shift_reg[0];
ip;

end

For a blocking assignment, a register


is inferred if the variable is read
before it is written.

?Question
How many registers are inferred?

Advanced Synthesis Coding Styles (VMS2)

16-7

Register Inference for Blocking Assignment


The statements in a procedure are executed sequentially in the order in which they appear. For blocking
assignments, if a variable is read before it is assigned, then the value read must be the value which was
assigned to the variable in the previous execution of the procedure. For a synchronous procedure, this is
the value assigned to the variable on the previous clock edge. Hence the synthesis tool creates a register
to store the value of the variable between clock cycles.
Note: Reading a variable before assigning a value in a combinational procedure, will either result in
a latch being inferred (for the same reason as in a registered process) or will be reported by the
synthesis tool as a syntax error.

Verilog Application Workshop

16-8

Temporary Variable Assignment


Variables written with blocking assignments
and then later read in the same procedure are
temporary the synthesis tool does not infer
storage for them.

The synthesis tool always infers storage


for variables written with nonblocking
assignments.

module tworeg (
input wire d, clk,
output reg q
);
reg rega;
always @(posedge clk)
begin
rega = d;
q
<= rega;
end
endmodule

mux
1
0

rega

d
clk

module tworeg (
input wire d, clk,
output reg q
);
reg rega;
always @(posedge clk)
begin
rega <= d;
q
<= rega;
end
endmodule

mux

q
1
0

rega

d
clk
Advanced Synthesis Coding Styles (VMS2)

16-9

Temporary Variable Assignment

Verilog Application Workshop

16-10

Inferring Latches
An incomplete assignment in a
combinational procedure infers
latch storage.
This is how you code a latch-based
design if you want one.
You most likely do not really want
latches so correctly code the
combinational block.
Latches can have asynchronous
set/reset.

module latch (
input data, enable,
output reg q
);
always @(enable, data)
if (enable)
q = data;
endmodule
module latch (
input enable, data, set, clr,
output reg q
);
always @(enable, data, set, clr)
if (set)
q = 1;
else if (clr)
q = 0;
else if (enable)
q = data;
endmodule
Advanced Synthesis Coding Styles (VMS2)

16-11

Inferring Latches

Verilog Application Workshop

16-12

Inference of Tristates
module tri_state_drivers (
input
en_1, en_2,
input [7:0] data_1, data_2,
output [7:0] data_bus
);

en_1

data_1
data_bus

assign data_bus = en_1 ? data_1 : 8'bz;


assign data_bus = en_2 ? data_2 : 8'bz;
endmodule
data_2
en_2

Caution
Use of net type wire assumes enable lines are mutually exclusive,
otherwise use triand or trior net type (check synthesis support)

Advanced Synthesis Coding Styles (VMS2)

16-13

Inference of Tristates
This example shows the type of code that represents the behavior of tri-state drivers, and the code that
synthesis tools require to infer tri-state drivers in the design.
A tri-state driver is inferred from a specific form of conditional assignment.
The assignment condition examines the enable variable of the conditional assignment.

If the enable is active, the input value is driven onto the tri-state bus

If the enable is inactive, the z value is driven onto the tri-state bus

For simulation, you can also use procedures containing if statements. The synthesis standard does not
explicitly specify whether synthesis tools shall accept or reject this method.
output reg [7:0] data_bus;
always @(data_1 or en_1)
if (en_1)
data_bus = data_1;
else
data_bus = 8'bz;
always@(data_2 or en_2)
if (en_2)
data_bus = data_2;
else
data_bus = 8'bz;

Verilog Application Workshop

16-14

Hierarchy: Register All Outputs

Advanced Synthesis Coding Styles (VMS2)

16-15

Hierarchy: Register All Outputs


You will find the synthesis process is easier to manage if you have registers on the outputs of each of the
hierarchical blocks in your design. This is because it is easier to set the constraints on each block, as the
arrival time of signals at each input and output are well defined.

With registered outputs, the synthesis tool has almost a complete clock period to implement the
combinational logic at the input of the second block.

With unregistered outputs, the designer must specify what proportion of the clock period is
available to implement each combinational block. This is done by specifying input and output
delays for each block. These delays must be realistic and reflect the comparative performance of
the logic blocks

Verilog Application Workshop

16-16

Hierarchy Management
Some things to consider:
Merging combinational logic

Optimization strategies

Synthesizeable sizes

Control of critical paths

Decoder

FSM

Multiplexer
ALU

Advanced Synthesis Coding Styles (VMS2)

16-17

Hierarchy Management

Verilog Application Workshop

16-18

Review
1. Under what conditions does the synthesis tool infer a register for a blocking
assignment to a reg variable? If the synthesis tool does not infer a register, what
does it do with the reg variable?
2. How do you infer tristate gates for synthesis?
3. Under what conditions is a for loop synthesizable?

Advanced Synthesis Coding Styles (VMS2)

16-19

Review

Verilog Application Workshop

16-20

Functions and Tasks


VFE9

17-1

Notes

Verilog Application Workshop

17-2

Aims and Topics

Aims
Explain these two types of subprogram

Topics
Subprogram concepts
Functions
Tasks
Issues

Functions and Tasks (VFE9)

17-3

Aims and Topics


This chapter describes Verilog subprograms, called functions and tasks. It explains where and how to
define them, how to invoke them, and some issues involved with using them.

Verilog Application Workshop

17-4

The function and task Keywords


Subprograms:
Encapsulate portions of
repeated code

Contain statements that


execute in sequence

inputs
function...

<function call>

Function subprograms:
Have one or more inputs and
return a single value

single return value


inputs
task...

Are invoked as an expression


term
<task call>

Task subprograms:
Have zero or more
input/outputs

outputs

Are invoked as a procedural


statement

Functions and Tasks (VFE9)

17-5

The function and task Keywords


Lets first examine the purpose of subprograms:
You can think of a subprogram as a level of hierarchy, or structure, in sequential code.
You use subprograms to encapsulate some frequently used code in one place where you can more easily
manage it. You can provide this code with inputs, to which you assign values as you invoke the
subprogram. These input values can flexibly direct the subprogram to perform slightly differently for
each invocation.
Encapsulating sequential code in subprograms is similar to encapsulating design units in modules.

Verilog Application Workshop

17-6

Function Declaration
return type

width defaults to single bit

function name

function integer zero_count;


input [7:0] in_bus;
input type
integer i;
begin
declaration
zero_count = 0;
for (i = 0; i < 8; i = i + 1)
if (!in_bus[i])
zero_count = zero_count + 1;
end
endfunction return value through function

function [3:0] zero_cnt_vec;


input
[7:0] in_bus;
integer i;
begin
zero_cnt_vec = 0;
for (i = 0; i < 8; i = i + 1)
if (!in_bus[i])
zero_cnt_vec = zero_cnt_vec + 1;
end
endfunction

name as procedural assignment

For Verilog-2001 you can also declare:


function signed <range_or_type>

input reg signed [...]

input <port_type>
time

real

realtime

Synthesis
Always synthesizes to
combinational logic

integer

<function_identifier> ( <function_port_list> ) ;

Functions and Tasks (VFE9)

17-7

Function Declaration
Here are some key features of functions:

The function declaration must appear only within a module definition.

You can specify a type for the function. Functions by default represent single-bit integral values.
The function declaration implicitly declares a variable of that type local to the function, of the
same name as the function, to which your function can make blocking procedural assignments.

You must declare at least one input port and must not declare any output or inout ports.

You may declare variables in a function declaration, to which your function can make blocking
procedural assignments.

Functions define a new scope in Verilog. Variables declared in that scope are local to the function.

You must not declare design structure, such as modules or nets, in a function declaration.

Your functions procedural statements may not utilize the scheduler:


A function must execute as a whole in zero simulation time and without suspension
It must not contain non-blocking assignment, event control (@ or wait) or delay (#)
It must not enable a task, as tasks can contain timing controls
It must not make procedural continuous assignments or trigger events

To effectively return multiple values, assign the return value to a concatenation:


{o1,o2,o3} = zero_cnt_vec (a,b,c,d,e,f,g,h);

Verilog Application Workshop

17-8

Function Call
function integer zero_count;
input [7:0] in_bus;
integer i;
begin
zero_count = 0;
for (i = 0; i < 8; i = i + 1)
if (!in_bus[i])
zero_count = zero_count+1;
end
endfunction

in_bus

32
zero_count

module zfunct (
input clk,
input [7:0] a_bus, b_bus,
output [31:0] bcount,
output reg azero
);
// function declaration
assign bcount = zero_count(b_bus);
always @ (posedge clk)
if (zero_count(a_bus) == 0)
azero = 1b1;
else
azero = 1b0;
endmodule

Important
Call a function as an expression term

Functions and Tasks (VFE9)

17-9

Function Call
You call a function as an expression operand. The simulator assigns the values of the argument
expressions to the input ports in the order in which they appear in the call.
When the function completes, the simulator uses the value of the function name variable where the call
appears in the calling expression. Functions return a single value that you use as an operand in rvalue
expression. An rvalue expression is one that may appear only on the right side of an assignment, you
cannot assign a value to an rvalue expression. If the function never completes, for example, in a loop that
loops forever, it never returns and the simulation hangs.
In this example, the zero_count function returns an integer value representing the number of bits of
the in_bus port that are zero. It returns a value between 0 and 8. The continuous assignment call assigns
the returned value to the bcount module output port. The conditional expression call uses the function
return value as an operand of a relational expression.

Verilog Application Workshop

17-10

Constant Functions
Verilog-2001 introduces the constant function.
You can use a constant function anywhere Verilog requires a constant expression.
Replication, part-select, initialization, etc.
A constant function is a function for which the elaborator can determine its value:
Cannot define within a generate scope

Input arguments must be constant expressions

Cannot contain hierarchical references

Cannot reference module variables other than module parameters


Must define module parameter before constant function call (call is inlined)
Result of defparam to module parameter is not defined

Cannot invoke system functions (system tasks other than $display are ignored)
Can call other constant function defined in the same module if the other function
does not use a constant expression

parameter integer my_param = 5; // different each inst


localparam integer my_int = my_const_func(my_param);
Functions and Tasks (VFE9)

17-11

Constant Functions
Verilog-2001 introduces the constant function.
You can use a constant function anywhere Verilog requires a constant expression.
The standard severely restricts the definition of a constant function. Several of the features of a
non-constant function cannot be present in a constant function.

Verilog Application Workshop

17-12

Task Declaration
task name

input argument output


argument

task zero_count;
input [7:0] in_bus;
width defaults
output [3:0] count;
to single bit
integer i;
begin
local variable
count = 0;
#5;
for (i = 0; i < 8; i = i + 1)
if (!in_bus[i])
count = count + 1;
end
assign to outputs
endtask

Synthesis
Can synthesize only if
no timing controls

For Verilog-2001 you can also declare:


{input | output | inout} reg signed [...]

{input | output | inout} <port_type>


time

real

realtime

integer

<task_identifier> ( <task_port_list> ) ;
Functions and Tasks (VFE9)

17-13

Task Declaration
Here are some key features of tasks:

The task declaration must appear only within a module definition.

You can declare any number (including zero) of ports of any mode (input, output, inout).

You may declare variables in a task declaration, to which your task can make blocking or
non-blocking procedural assignments.

Tasks define a new scope in Verilog. Variables declared in that scope are local to the task.

You must not declare design structure (such as modules or nets) in a task declaration.

Your tasks procedural statements may utilize the scheduler:


It may contain non-blocking assignment, event control (@ or wait) and delay (#)
It may call functions and enable tasks
It may make procedural continuous assignments and trigger events
You can rewrite as a function, a task that does not utilize the scheduler

Verilog Application Workshop

17-14

Task Call
task zero_count;
input [7:0] in_bus;
output [3:0] count;
integer i;
begin
count = 0;
#5;
for (i = 0; i < 8; i = i + 1)
if (!in_bus[i])
count = count + 1;
end
endtask

module zerotask (
input clk,
input [7:0] a_bus,
output reg azero
reg [3:0] a_count;
// task declaration
always @(posedge clk)
begin
zero_count(a_bus, a_count);
if (a_count == 4b0)
azero = 1b1;
else
azero = 1b0;
end
endmodule

Important
Call a task as a procedural statement

Functions and Tasks (VFE9)

17-15

Task Call
You call a task as a procedural statement. The simulator assigns the values of the input and inout
argument expressions to their ports.
When the task completes, the simulator assigns the values of the output and inout ports to their lvalue
expression arguments (an lvalue expression may appear on the left side of an assignment, you can assign
a value to an lvalue expression) If the task never completes for example, in a loop that loops forever, it
never returns and its calling procedure cannot continue. However, if the task consumes time,
procedures other than the calling procedure may execute.

Verilog Application Workshop

17-16

Tasks without Timing Controls


Tasks can utilize the scheduler (e.g. with delays and timing controls).
You can rewrite as a function a task that does not utilize the scheduler.
Here is such a situation:
task zero_count;
output [3:0] count;
input [7:0] in_bus;
integer
i;
begin
count = 0;
for (i = 0; i <= 7; i = i + 1)
if (!in_bus[i])
count = count + 1;
end
endtask

function [3:0] zero_count;


input [7:0] in_bus;
integer i;
begin
zero_count = 0;
for (i = 0; i <= 7; i = i + 1)
if (!in_bus[i])
zero_count = zero_count + 1;
end
endfunction

Synthesis
The synthesis standard supports tasks that have
no timing controls.

Functions and Tasks (VFE9)

17-17

Tasks Without Timing Controls


The task in this example has no internal timing control.
You can rewrite as a function, a task without timing controls.
The synthesis tool infers combinational logic for functions and tasks without timing controls. This is true
even if the subprogram has incomplete case or if statements that in a procedural block would infer a
latch.

Verilog Application Workshop

17-18

Disabling Tasks
You can disable a task (force it to exit):
In this example, detection of an
interrupt disables any currently
running cpu_driver task

Future statements can again call the


cpu_driver task

Tip
You can also disable named blocks in the
same manner.

module test_busif;
...
always #50 clk = !clk;
initial
begin: stimulus
neg_clocks(5);
cpu_driver(8'h00);
cpu_driver(8'haa);
...
end
...
always @(posedge interrupt)
begin
disable cpu_driver;
service_interrupt;
end
endmodule

Functions and Tasks (VFE9)

17-19

Disabling Tasks
A Verilog task can consume simulation time, by using event controls and wait statements.
Code that calls the task cannot continue execution until the task completes.
Some other executing process can disable the task, thus allowing the calling process to continue.

Verilog Application Workshop

17-20

Tasks and Static Arguments


cpu_data

data_valid
data_read
data read

data read

task cpu_driver_bad;
input read;
input [7:0] write_data;

Arguments are static

Arguments are passed by value


Variable values assigned to input

begin
arguments upon invocation
#30 date_valid = 1'b1;
wait(read == 1'b1);
Output argument values assigned to
#20 cpu_data =
variables upon return
write_data;
wait(read == 1'b0);
#20 cpu_data = 8'hzz;
Error
data_valid = 1'b0;
Task never completes changes in read not detected
end
endtask
cpu_driver_bad(data_read, 8'hff);

Functions and Tasks (VFE9)

17-21

Tasks and Static Arguments


The problem with the cpu_driver_bad task is that read is a task input port. The simulator assigns
the argument value to the input port upon enabling the task. The wait statement within the task waits
for the value of the read port to be equal to 1, but the value of the read port does not follow changes
of the value of the argument.

Verilog Application Workshop

17-22

Issues with Functions and Tasks


The following pages address issues presented by functions and tasks:
Function and task definitions and declarations are by default static
Multiple execution threads within a function or task by default all use the same
set of ports and variables.
As tasks can consume time, you can easily have multiple task calls
simultaneously executing
Functions and tasks can recursively call themselves

A function or task can have side effects


Can directly access variables in the scope of the module that defines it
Can access (using out-of-module references) any static variable

Functions and Tasks (VFE9)

17-23

Issues with Functions and Tasks


The following pages explore two characteristics of functions and tasks.
The first issue is that by default there is only one copy of a subprograms ports and variables, so that
multiple outstanding calls to the same subprogram clobber each other.
The second issue is that subprograms can have side-effects, they can directly access the defining
modules nets and variables, and can through out-of-module references access any nets and variables in
the simulation. This can greatly ease your testbench development effort.

Verilog Application Workshop

17-24

Multiple Function or Task Calls


You can invoke a task or function recursively and from multiple locations.
Verilog-1995: One copy of ports and local variables serves all execution threads

Avoid simultaneous concurrent calls

Verilog-2001: Use automatic qualifier when declaring task or function


New copy of ports and local variables allocated for each invocation
Cannot write these temporary variables with nonblocking assignments
Cannot access these temporary variables from outside task or function
No $monitor or $dumpvars etc.

// Returns 1
function integer f;
input integer in;
if (in <= 1)
f = in;
else
f = f(in-1) * in;
endfunction

// Returns factorial
function automatic integer f;
input integer in;
if (in <= 1)
f = in;
else
f = f(in-1) * in;
endfunction

Functions and Tasks (VFE9)

17-25

Multiple Function or Task Calls


Be careful about calling a task from more than one section of code. Because a task by default maintains
only one copy of its local variables, concurrent invocations will likely produce incorrect results. This
happens most often when you use timing controls in a task.
You can alternatively declare your subprograms to be automatic. Automatic subprograms create a new
copy of their ports and variables for each invocation. You cannot access these automatic variable from
outside the subprogram.

Verilog Application Workshop

17-26

Accessing Module Variables


cpu_data

module test_local_vars;
reg data_read, data_valid;
reg [7:0] cpu_data;

data_valid

task cpu_driver;
input [7:0] write_data;
begin
#5 data_valid = 1;
wait(data_read == 1);
#20 cpu_data = write_data;
wait(data_read == 0);
#20 cpu_data = 8'hzz;
data_valid = 0;
end
endtask
initial
begin
cpu_driver(8'hff);
cpu_driver(8'h00);
...

write_data

data_read
data read

module variable
read inside task

Functions and tasks can directly


access nets and variables of the
enclosing module scope

Advantage allows encapsulation


and repetition of frequently used code

Disadvantage more difficult to


re-use the task for other purposes

Functions and Tasks (VFE9)

17-27

Accessing Module Variables


Functions and tasks can bypass their ports to directly read and write variables of the defining module.
This feature greatly simplifies your testbench.
In this example, by directly referencing the data_read module variable instead of having the
data_read value passed as an argument, the wait statements inside the task can detect transitions of
the data_read variable and the task will complete correctly.
Caution
Direct references to module variables from within a function or task are resolved to variables within the
defining moduless scope and not the calling modules scope.

Verilog Application Workshop

17-28

Out-of-Module Function or Task Calls


module mytasks;

cpu_data

task neg_clocks;
input integer number;
repeat(number)
@(negedge clk);
endtask

data_valid

write_data

data_read
data read

// test harness
module test_busif;

task cpu_driver;
input [7:0] write_data;
begin
#5 data_valid = 1b1;
wait(data_read == 1b1);
#20 cpu_data = write_data;
wait(data_read == 1b0);
#20 cpu_data = 8'hzz;
data_valid = 1b0;
end
endtask

reg clk = 0;
always #50 clk = ~clk;
// instantiate mytasks
mytasks m1 ();
// creating stimulus
initial begin
m1.neg_clocks(6);
m1.cpu_driver(8h00);
...
$finish;
end

endmodule

hierarchical paths
endmodule
Functions and Tasks (VFE9)

17-29

Out-of-Module Function or Task Calls


You can call functions and tasks from a different module by using hierarchical names. The hierarchical
name is an absolute or relative path to the task or function.
This example instantiates the mytasks module (even though it has no ports) in the test harness. It
invokes the tasks defined in mytasks to generate stimulus using the hierarchical name of the task:
m1.neg_clocks(6)

Verilog Application Workshop

17-30

Review Questions
1. Write a function that adds two four-bit unsigned numbers and returns an unsigned
five-bit result, and write a call to the function.
2. Which type of subprogram can contain event control?
3. Can logic synthesis infer sequential logic from statements in a function?
4. Write the count_from task to produce the following stimulus. The function
of the task is to load a_bus with a value (passed as a parameter) and to increment
a_bus for 3 clock cycles. The task also controls the select signal.
start

finish

clock

module testbench;
reg clk;
reg [3:0] a_bus;
reg select;
initial clk = 1b0;
always #50 clk = !clk;

select
a_bus[3:0]

initial
begin
count_from(4d4);
count_from(4d2);
end
endmodule

Functions and Tasks (VFE9)

17-31

Review

Verilog Application Workshop

17-32

System Control
VSV2

18-1

Notes

Verilog Application Workshop

18-2

Aims and Topics

Aims
Describe some of the compiler directives, system tasks and system functions
available in Verilog

Topics
Compiler directives (indicated with accent grave )
System tasks and functions (indicated with $)
Text output in Verilog
Accessing simulation time
Simulation system tasks
File I/O capabilities

System Control (VSV2)

18-3

Aims and Topics

Verilog Application Workshop

18-4

Timescale: The `timescale Directive


The timescale directive defines the time
unit and time precision
timescale numbers must be 1, 10 or 100

The simulator rounds time


specifications to the precision of the
module and scales them to the time unit
of the module

The overall simulation precision is the


smallest of the defined precisions

No standard default timescale exists


Always specify a timescale!

Important
timescale must appear outside of the module

timescale 10ns/1ns
module test;
localparam real tdelay = 2.55;
inital
begin
#tdelay; // 26 ns delay
...
endmodule
timescale 1ns/100ps
module first (...);
...
#10; // 10 ns delay
...
endmodule
timescale 1ps/100fs
module second (...);
...
#100; // 100 ps delay
...
endmodule

System Control (VSV2)

18-5

Timescale: The `timescale Directive


Timescale defines the time units of delays and the precision to which these delays are calculated.
In module test, time units are scaled to 10 ns with a precision of 1 ns. So the 2.55 tdelay is rounded
to 2.6 and scaled 26 ns. These calculations are carried out before assignments are made, so waiting for
2*tdelay will wait for 52 ns, not 51. The value of the constant tdelay is still 2.55 throughout the
simulation.
Usually timescale is specified once in a design, normally at the testbench module, but in gate level, or
large designs with IP or reuse blocks, there may be several timescale directives.
The smallest precision of all the timescale directives determines the simulator time increment, because
the simulator needs to preserve the smallest precision specified in the design.
1. For module test, time units are multiples of 10 ns, rounded to 1 ns.
2. For module first, time units are multiples of 1 ns, rounded to 100 ps.
3. For module second, time units are multiples of 1ps, rounded to 100 fs.
The smallest precision of all timescales is 100 fs, so the simulator precision will be 100 fs. In order to
advance one time unit in module 1, the simulator take 107 increments!
Note: To modify a timescale, you need to edit the file and recompile that file and all other files that
utilized that directive. No method exists to modify a timescale during simulation.

Verilog Application Workshop

18-6

Including Files: The `include Directive


// Clock and simulator constants
// could also include tasks etc

// Include global variables

localparam INITIAL_CLOCK = 1;
localparam integer MAX_CYCLES = 100;
localparam time PERIOD = 10;

`include "globals.txt"

The include directive inserts the


contents of an entire file at that point.
You can use this method to ensure
that all module descriptions use the
same:
constants
tasks and functions

You can nest included files


The included file can contain
another include directive

initial
begin : CLK
time END_TIME;
END_TIME = PERIOD * MAX_CYCLES;
while ($time < END_TIME)
begin
CLK = INITIAL_CLOCK;
#(PERIOD/2);
CLK = !INITIAL_CLOCK;
#(PERIOD/2);
end
$display($time,"Test Finished");
$stop;
end

System Control (VSV2)

18-7

Including Files: The `include Directive


You can use the`include compiler directive to insert the contents of an entire file.
`include "pathname"
Where filename is the file system pathname to the file to include (Note that absolute pathnames can
cause portability issues).
You can nest the `include compiler directive to at least 16 levels.
You can use the `include directive to:

Include global or commonly used definitions (e.g. define directives) stored in a separate file.

Include tasks without repeating the code within multiple module definitions, to simplify
maintenance of the code.

Verilog Application Workshop

18-8

Text Macro Substitution: The `define Directive


The compiler preprocesses compiler
directives such as text replacement
macros.
Text replacement macros can use
other text replacement macros

Text replacement macros provide a


simple way to modify dispersed
code from one source file

Many tools provide a


vendor-dependent command-line
way to set text replacement macros

define stimulus test1.vec


localparam integer SIZE = 256;
...
reg [7:0] mem [1:SIZE];
initial $readmemb("stimulus", mem);

% ncverilog +define+stimulus="test2.vec" ...

System Control (VSV2)

18-9

Text Macro Substitution: The `define Directive


You can use `define to:

Make the description more readable

Define global design constants, like delays and widths of vectors, in a single place. The advantage
is that to change the configuration, you only need to make changes in one place.

Define shorthand strings for Verilog commands.


`define vectors_file "/design1/library/vectors"
`define results_file "/design1/library/results"

You can place a list of `define directives in a single file that is compiled with the other design files
and included as required with the include directive
To remove the definition of a macro use:
undef macro_name
Important
A mistake in the text macro gives you an error at the point where the text macro is used.

Verilog Application Workshop

18-10

Conditional Compilation: The `ifdef Directive


You can hide sections of code from the
compiler
Use the ifdef, else, endif
compiler directives to control
compilation of certain sections of
code

Verilog-2001 adds ifndef and


elsif

You can define the macros without


supplying a value

Many tools provide a


vendor-dependent command-line
way to set text replacement macros

localparam integer SIZE = 256;


...
reg [31:0] memory [1:SIZE];
integer i;
initial
ifdef init2zero
for (i = 1; i <= SIZE; i = i + 1)
memory[i] = 0;
else
$readmemb("romdata.dat",memory);
endif

% ncverilog +define+init2zero ...

System Control (VSV2)

18-11

Conditional Compilation: The `ifdef Directive


The example provides the option to initialize the ROM to (i) all zeros or (ii) values read from a file. The
ifdef compiler directive provides this control over how the ROM is initialized.

Verilog Application Workshop

18-12

Invocation Options Tests


Verilog-2001 adds two system functions for retrieving command-line options.
$test$plusargs("prefix")
Returns 0 if no command-line plusarg starts with the provided prefix
Returns 1 if a command-line plusarg starts with the provided prefix
% ncverilog +Hello_There ...
if ($test$plusargs("Hello")) ... // true

$value$plusargs("prefix%format",variable)
Formatters are: %b %o %d %h %e %f %g %s
Returns 0 if no command-line plusarg starts with the provided prefix
Returns 1 if a command-line plusarg starts with the provided prefix
Places scanned command-line plusarg suffix in variable
ncverilog +"stimulus=test2" ...
if ($value$plusargs("stimulus=test%d",testnum)) ...

Note: Unlike define does not require recompilation!

System Control (VSV2)

18-13

Invocation Options Tests

Verilog Application Workshop

18-14

Output: The $display and $write System Tasks


These system tasks print values to the
standard output.
$display appends a newline

module disp_wr;
reg [7:0] var1, var2, var3, var4;
initial
begin
var1 = 8'h0F;
// 15
var2 = 8'b01010101;
// 85
var3 = 8'b11001100;
// 204
$display (var1,var2,var3);
$displayb (var1,, var2,, var3);
$displayh (var1);
$write (var1);
$writeh (" var2(hex) is ", var2);
$writeo ("\n var3(oct) is ", var3);
end
endmodule

$write does not

The default base is decimal. Verilog


supports other bases:
$displayb

$displayo

$displayh

Arguments can include formatting


strings, which can include escaped
characters: \n \t \ddd \\ \"

15 85204

output sized to variable - 8 bits always


written in decimal as 3 characters

00001111 01010101 11001100

consecutive commas replaced by single space

0f
15 var2(hex) is 55
var3(oct) is 314
System Control (VSV2)

18-15

Output: The $display and $write System Tasks


$display and $write are identical, except that $display adds a newline character to the end of
every output, whereas $write does not.
$display and $write support multiple bases. The default base is decimal. The other supported bases
are binary, hexadecimal and octal. Default base can be changed to binary by using $displayb octal
using $displayo and hexadecimal using $displayh.
The length of the value output depends on the maximum size of the variable and the base. For example,
the maximum size of an 8 bit vector written as decimal would be 3 characters (maximum value 256) and
so every 8 bit value will be written in decimal as 3 characters. The 8 bit vector would be displayed using
2 hex, 3 octal and 8 binary characters. For decimal display, leading zeros are replaced by spaces. For all
other formats, leading zeros are always displayed. You can override this automatic sizing by inserting a
zero between the % character and the letter that indicates the radix.
You can incorporate strings in the output to differentiate between values and make the output more
meaningful. You can embed formatting characters like tab and newline into the string using escaped
literals. You must escape special characters to use them in an output string.
Escaped Literals:

\t

\n

\\

\"

%%

tab

new line

backslash

double quote

percentage

The percentage character is escaped with another percentage, not a backslash.

Verilog Application Workshop

18-16

Formatting Text Output


Each format specifier formats one argument value.
These are most usually grouped in one format string the first argument

You can distribute them among the task arguments (subject to rules)
They are matched to argument values in order one to one match
It is an error to have more format specifiers than values to format
Extra unformatted values simply use the default format

module disp_wr_fmt;
reg [7:0] var1, var2,
00001111
var3, var4;
var2 binary: 01010101
hex:
initial
begin
0f
55
cc
var1 = 8'h0F;
var2 = 8'b01010101;
var3 is hex cc octal 314
var3 = 8'b11001100;
$display ("%b", var1);
$display ("var2 binary: %b \t", var2, "\t hex: %h", var2);
$display ("%h \t %h \t %h", var1, var2, var3);
$write ("var3 is hex %h \t octal %o", var3, var3);
end
endmodule

55

System Control (VSV2)

18-17

Formatting Text Output


Format specifiers and escaped characters, enclosed in double quotes, provide more control over output.
Formatting can be grouped at the being of the output argument, in which case the format specifiers are
matched to the objects in order, or the specifiers can directly precede the object to which they apply.
Format Specifiers:
%h
%H
hex

%o
%O
octal

%d
%d
decimal

%b
%B
binary

%c
%C
ASCII

%s
%S
string

%v
%V
strength

%m
%M
module

%t
%T
time

Specifiers are not case-sensitive.


The %m formatter is replaced by the module name and is not matched to a variable:
$display ("var3 in %m is hex %h", var3);
produces
var3 in disp_wr_fmt is hex cc
You can also specify a formatter of %0d to indicate you want a decimal value with no leading zeroes.
Note that format specifiers can be incompatible with the double comma technique to add a space
between adjacent values, e.g. some simulators report $display has invalid arguments for:
$display ("%d %h", var1,, var2); // ERROR

Verilog Application Workshop

18-18

Output: The $strobe System Task


The $strobe task is similar to the $display task.
Execution of $strobe is scheduled for the end of the current time slice.
module strobe_blk;
reg [31:0] data;
initial
begin
data = 10;
$strobe ("strobe ", data);
$display("display", data);
data = 20;
#10;
data = 30;
end
endmodule

display
strobe

scheduled
executed
$strobe
executed

module strobe_non;
reg [31:0] data;
initial
begin
data <= 10;
$strobe ("strobe ", data);
$display("display", data);
data <= 20;
#10;
data <= 30;
end
endmodule

10
20

display
strobe

x
20

System Control (VSV2)

18-19

Output: The $strobe System Task


Execution of the $strobe system task is scheduled for the end of the time slice. When you use the
$strobe system task, you see the argument values at the end of the time slice, when they have
presumably settled. This is different from the $display and $write system tasks, which
immediately print the value of the signal, whatever it is.
The default base of the $strobe system task is decimal, although $strobe supports all bases through
task variants ($strobeb, $strobeo, $strobeh) as well as all the formatting specifiers and
characters you can use with $display.
Note that use of blocking and non-blocking assignment affects which values are output.

Verilog Application Workshop

18-20

Simulation Time: $time, $realtime System Functions


Retrieve the simulation time using:
$time
returns time as a 64-bit integer

$stime
returns time as a 32-bit integer

$realtime
returns time as a real number

The simulator scales returned time


values to the timescale of the calling
module.

The %0d formatter removes leading


spaces from decimal time value

module timeop;
reg [5:0] data;
initial
begin
#10;
data = 6d20;
$display ($time,, data);
#10.4;
data = 6d30;
$write ("time: %0d", $time);
$write (" real time: ", $realtime);
$write (" data: ", data);
end
endmodule

10 20
time: 20 real time: 20.4 data: 30

System Control (VSV2)

18-21

Simulation Time: $time and $realtime System Functions


The output system tasks only allow automatic sizing (by default) or leading zero suppression with the
%0b, %0o, %0d and %0h formatters. Verilog does not support any further C-style field size control (i.e.
%1d is not legal).
The time unit is defined by the `timescale compiler directive.
The $stime system function returns time as a 32-bit integer. For time values greater than 232, the
function returns the least significant 32 bits. You can use $stime rather than $time if you want to use
less space to display the unformatted decimal time.

Verilog Application Workshop

18-22

Output: The $monitor System Task


The $monitor system task
continuously monitors variables.
It acts like $strobe when any
argument (other than $time)
changes value

Only one $monitor task can be


active at a time
A new $monitor replaces any
current $monitor

You can disable monitoring with


$monitoroff and re-enabled it
with $monitoron

The $monitor system task


supports the same bases and
formatters as the $display
system task

module monitor_time;
reg [7:0] var1, var2, var3, var4;
initial
begin
$monitor("%0d \t %h %h %h",
$time, var1, var2, var3);
var1 = 8'h0F;
var2 = 8'b0101_0101;
var3 = 8'b1100_1100;
#5;
var1 = 8'h80;
#8;
var2 = 8'h66;
var3 = 8'h77;
#4;
var1 = 8'h55;
end
endmodule

0
5
13
17

0f
80
80
55

55
55
66
66

cc
cc
77
77

System Control (VSV2)

18-23

Output: The $monitor System Task


Output: The $monitor System Task
The $monitor system task, once invoked, continually monitors its arguments and display their values
at the end of the time slice in which any of them changed.
Thus the $monitor system task, like the $strobe system task, involves the scheduler.
Only one $monitor system task can be active at a time. A new call to $monitor call replaces the list
of monitored signals. The signals in the argument list of the new $monitor are monitored, while those
in the previous $monitor are not.
You can control monitoring with $monitoroff and $monitoron system tasks. This is useful when
you are interested in the signal values only between certain time intervals of the simulation.
The $monitor system task accepts the same formatting characters as $display.
The $monitor system task supports multiple bases. The default base is decimal.
$monitorb
$monitoro
$monitorh

Verilog Application Workshop

18-24

Formatting Time with the $timeformat System Task


The $timeformat system task
sets the display format for the %t
formatter.
Controls units, precision,
suffix and field width

Ensures %t display is same


for all timescales
timescale is required

Formats values returned


from $time, $stime and
$realtime

Usable with all variants of


display, monitor, strobe and
write tasks

`timescale 1 ns / 10 ps
module time_fmt;
wire o1;
reg in1;
assign #9.53 o1 = ~in1;
initial
begin
$display("time \t realtime \t in1 \t o1");
$timeformat(-9, 2, " ns", 10);
$monitor("%0d \t %t \t %b \t %b",
$time, $realtime, in1, o1);
in1 = 0;
#10;
in1 = 1;
#10;
end
endmodule

time
0
10
10
20

realtime
0.00 ns
9.53 ns
10.00 ns
19.53 ns

in1
0
0
1
1

o1
x
1
1
0

System Control (VSV2)

18-25

Formatting Time
You can use the $timeformat system task to specify how the %t formatter displays time values.
The syntax of the $timeformat system task is:
$timeformat(<unit>, <precision>, <suffix>, <min_width>);
Parameter

Definition

unit

Integer between 0 (s) and -15 (fs), indicating the time scale

precision

Number of decimal digits to display

suffix

String to display after time value

min_width

Minimum field width used for display

Important
The Verilog standard states that the $timeformat applies to all %t formats specified in all
modules that follow in the source description until another $timeformat system task is invoked.
The $realtime function returns the time as a real number scaled to the timescale of the calling
module.
The $stime system function returns the time as a 32-bit integer scaled to the timescale of the calling
module and then rounded to an integer value.
The $time system function returns the time as a 64-bit integer scaled to the timescale of the calling
module and then rounded to an integer value.
Verilog Application Workshop

18-26

Control: The $finish and $stop System Tasks

The $stop system task


interrupts simulation and
enters the interactive mode.
You can continue the
simulation from the
stop point

task expect (input [7:0] resp, exp);


if (resp !== exp)
begin
$display("want %b - got %b",
exp, resp);
$display("TEST FAILED");
$stop;
end
endtask

The $finish system task


terminates the simulation and
exits the simulator.

initial
begin
wait (empty);
$display("Data buffer empty");
$display("TEST COMPLETE");
$finish;
end

System Control (VSV2)

18-27

Control: The $finish and $stop System Tasks


The $stop system task interrupts the simulator and allows the user to enter commands interactively.
You can continue the simulation from the stop point.
The $finish system task ends the simulation and exits the simulation environment.

Verilog Application Workshop

18-28

Checkpointing: The $save and $restart System Tasks


Debugging long simulations can be
tedious, especially if a problem occurs
only after several minutes of simulation.
To quickly iterate through the
debug/simulate cycle:
Use $save to save the simulation
database at the point just before the
problem occurs

Use $restart to reload the


simulation database from the last
saved file

To periodically checkpoint a very long


simulation, initially use $save to save the
full database and then periodically use
$incsave to save an incremental
database.
Restart using the incremental
database

ifdef SAVE
initial $save("tb_sim.db");
always #5000 $incsave("tb_inc.db");
endif
ifdef RESTART
initial $restart("tb_inc.db");
endif

verilog +define+SAVE
verilog +define+RESTART
Note: The Cadence NC-Verilog simulator
does not support these system tasks.
Instead use the save and restart
interactive commands.

System Control (VSV2)

18-29

Checkpointing: The $save and $restart System Tasks


These constructs are very useful for long simulations.
While debugging the problem, you need to simulate again up to the point of the problem every time you
monitor a different set of signals.
If you save the state of the simulation just prior to the point of the problem, then you can quickly restart
simulation at the point of the problem.
The $save system task saves everything needed to restart the simulation.
The $incsave system task saves only the current states of the nets, variables, and event queues.
The incremental database is associated with the full database, which must still exist to restart the
simulation.
Note: Most simulator vendors also provide a proprietary method for checkpointing the simulation that
may have additional features. Check the vendors documentation of their simulator.

Verilog Application Workshop

18-30

Waveforms: Value Change Dump (VCD)


You can accumulate variable transition data in a value change dump (VCD) file.
You can provide this VCD file to a waveform display tool.
Open the file with $dumpfile("filename");
The filename, if omitted, defaults to verilog.dump
$dumpfile("waves.dump");

Specify the variables with


$dumpvars(levels,list_of_modules_or_variables);
The levels, if omitted, defaults to the all hierarchy levels
The list, if omitted, defaults to the current scope
$dumpvars;

Limit the data file size with $dumplimit(max_bytes)


Stops dumping after file size reaches max_bytes

Suspend and resume data accumulation with $dumpoff and $dumpon

Dump all watched signals values at any point with $dumpall

Flush the dump file buffer to disk with $dumpflush

System Control (VSV2)

18-31

Waveforms: Value Change Dump (VCD)


The syntax for the $dumpvars system task is as follows:
$dumpvars(<levels><,<module | variables>>*);
There are also a number of other related system tasks: $dumpon, $dumpoff, $dumpflush,
$dumpall.
Simulator commands can also be used to create VCD files, e.g. in a simulation script file rather than from
within the Verilog code.
As well as simulation and verification, VCD files are also used in Power Estimation and Fault
Simulators.

Verilog Application Workshop

18-32

Waveforms: Extended Value Change Dump (EVCD)


Verilog-2001 adds a new extended VCD format that accumulates direction and strength
data, but only for ports. Tools can play this data back against a gate-level version of
your ASIC model (for example).
Open the file and specify the ports with
$dumpports(scope_list,"filename");
You cannot dump individual variables!
The scope_list, if omitted, defaults to the current scope
The filename, if omitted, defaults to dumpports.vcd
For the following tasks, the filename, if omitted, defaults to all open EVCD files:
Limit the data file size with
$dumpportslimit(max_bytes,"filename")

Suspend and resume with $dumpportsoff and $dumpportson

Dump all watched ports values at any point with


$dumpportsall("filename");

Flush the dump file buffer to disk with $dumpportsflush("filename");

System Control (VSV2)

18-33

Waveforms: Extended Value Change Dump (EVCD)

Verilog Application Workshop

18-34

File Output: Opening Files


You can write to text files.
Open the file with $fopen

...
integer data_chan, warn_chan;
reg [7:0] var1, var2;

Returns a 32-bit unsigned integer


multi-channel descriptor (MCD)
with one bit set
Returns 0 if unsuccessful
Each successful $fopen returns
a different MCD bit set
Channel 0 is the standard output
You can have up to 31 other
channels simultaneously open

initial
begin
data_chan = $fopen("data.txt");
if (!data_chan) $finish;
warn_chan = $fopen("warn.txt");
if (!warn_chan) $finish;
$fmonitor (data_chan, var1, var2);
...
$fclose(data_chan);
end

Close the file with $fclose


Allows channel reuse
MCD Values:
<stdout> 00000000000000000000000000000001
data_chan 00000000000000000000000000000010
warn_chan 00000000000000000000000000000100
System Control (VSV2)

18-35

File Output: Opening Files


Use $fopen to open a file and return a 32-bit unsigned multichannel descriptor (MCD) that is uniquely
associated with the file. It returns 0 if the file could not be opened for writing.
You must save the returned MCD as an integer or 32-bit reg.
Use $fclose to close the channels specified in the MCD.
Think of the MCD as a set of 32 flags, where each flag represents a single output channel.
The least significant bit of an MCD is reserved for the standard output which is written to a simulator
transcript or operating system window as well as, usually, a simulator specific log file.
All other bits of the MCD are available for files to be opened by the $fopen system function. Thus, you
can open a maximum of 31 files for your own use. Your simulator may reserve one or more of the other
channel descriptors for tool-specific use, therefore all 31 files may not be available to you.
Note: Verilog-2001 compliant simulators reserve bit 31.
The operating system may impose further restrictions on the number of files being used.
The $fclose task closes the specified channels and prevents further access to the associated files.
Subsequent $fopen calls can reuse the released MCD bits for other files.

Verilog Application Workshop

18-36

File Output: Writing to Files


Each $display, $monitor, $strobe and $write system task has an equivalent
version that starts with $f and takes an MCD as the first argument.
You can write multiple files simultaneously using a Multi-Channel Descriptor.
...
data.txt
reg [7:0] x, y;
X-axis 77
integer datafile, timefile, bothfile;
Y-axis
2
initial
Output to both files
begin
datafile = $fopen("data.txt");
timefile = $fopen("timing.txt");
timing.txt
bothfile = datafile | timefile;
50 X = 77 Y = 2
X = 77;
Output to both files
Y = 2;
#50;
$fdisplay(datafile, "X-axis %d\n Y-axis %d", x, y );
$fdisplay(timefile, "$0d X = %0d Y = %0d", $time, x, y );
$fdisplay(bothfile, "Output to both files");
end

System Control (VSV2)

18-37

File Output: Writing to Files


The file output system tasks start with $f and take the MCD as an additional argument.
All four formatted display tasks ($display, $write, $monitor, and $strobe) have counterparts
that write to specific files as opposed to the standard output (simulator transcript window).
These counterpart tasks ($fdisplay, $fwrite, $fmonitor, and $fstrobe) accept the same
parameters as the tasks they are based upon, with one exception: the first parameter must be an MCD
that indicates where to direct the file output. The MCD can be an expression, but must evaluate to a 32-bit
unsigned integer. This value determines which open files the task writes to.
You can simultaneously write multiple files by writing to integer variables that are a logical OR of
existing MCDs. In the example above, the MCDs might have the following values:
datafile 00000000000000000000000000000010
timefile 00000000000000000000000000000100
bothfile 00000000000000000000000000000110
Writing to the bothfile MCD writes output to both datafile and timefile.
Setting MCD bit 0 sends output to the standard output.
integer datafile, timefile, bothfile, all_chan;
...
all_chan = bothfile | 1;
$fdisplay(all_chan, "broadcast");
...

Verilog Application Workshop

18-38

File Input: $readmemb and $readmemh System Tasks


Verilog system tasks read from a
file into 1-D vector array
$readmemb (binary)

$readmemh (hex)

You can optionally specify start


and end addresses (data at these
addresses must exist in the file)

vect.txt
00000000
00000001
00000010
00000011

module readfile;
reg [7:0] array4 [0:3];
reg [7:0] array7 [6:0];
start end
initial
begin
$readmemb("vect.txt", array4);
$readmemb("vect.txt", array7, 2, 5);
end
...
endmodule

array4
3: 00000011
2: 00000010
1: 00000001
0: 00000000

array7
6: xxxxxxxx
5: 00000011
4: 00000010
3: 00000001
2: 00000000
1: xxxxxxxx
0: xxxxxxxx
System Control (VSV2)

18-39

File Input: $readmemb and $readmemh System Tasks


The $readmemb and $readmemh system tasks load data from a text file into an array.
$readmemb ("filename", <array>, <start_addr>, <end_addr>);
$readmemh ("filename", <array>, <start_addr>, <end_addr>);

filename is the file from which the memory array is to be loaded

array is the name of the array into which the data is to be loaded

Optional start and finish addresses determine the addresses of the array to be loaded. The start
value becomes the starting address and the finish value becomes the end address. If you do not
specify start and end addresses as either system task arguments or in the data file, $readmemb/h
reads from the left index of the memory array (as declared) toward the right index.
Note: Cadence simulators in this situation read from the lowest address toward the highest
address.

The simulator loads data numbers from the file into words in memory. You should ensure that the
numbers are the width of the memory word.

The simulator will report a warning if there are too many or too few data items in the file.

Verilog Application Workshop

18-40

File Formats for Input Data


You can embed address information
in the text file.
You can use comments, underscores
and spacing as needed to aid
readability.

0000_0000
0110_0001 0011_0010
// comments are ignored
// addresses 3-255 not defined
@100 // hex
1111_1100
/* addresses 257-1022 not defined */
@3FF
1110_0010
7 .... 0
3FF: 11100010

...
reg [7:0] mem1Kx8 [0:1023];
...
$readmemb("format.txt", mem1Kx8);
...

100: 11111100

00110010
01100001
000: 00000000

System Control (VSV2)

18-41

File formats for Input Data


File data can only contain:

Comments (single-line and multi-line)

Case-insensitive address values


Using the syntax: @hex_digits

Case-insensitive data values using binary ($readmemb) or hexadecimal ($readmemh) digits


Values may embed underscores (_) to aid readability
Values must not contain base or length information

White space (space, newline, form-feed or tab characters) between values

If the file contains address values, then any address values provided with the $readmemb/h call must
lie within the range of provided addresses.

Verilog Application Workshop

18-42

Enhanced C-Style File I/O


Verilog-2001 adds C-like filesystem operations to the Verilog language.
With added type option, $fopen returns a 32-bit file descriptor (FD)
Type option is access, e.g. "r", "w", "a"
FD has bit 31 set to differentiate it from an MCD
Can represent 2**31 channels but never multiple channels
Channels 0, 1, 2 already opened to stdout, stdin, stderr

Counterparts exist to almost all C filesystem functions


Reading characters, lines, binary, or formatted
$fgetc $ungetc $fgets $fread $fscanf
Writing characters, lines, binary, or formatted
$fdisplay $fmonitor $fstrobe $fwrite $fflush
Manipulating the file pointer
$fseek $ftell $rewind

Note: The standard does not address MCD support of the new routines.

System Control (VSV2)

18-43

Enhanced C-Style File I/O


$fclose ( fd ) ;

// close a file

errcode

= $ferror ( fd, str ) ;

// get error code and description

char

= $fgetc ( fd ) ;

// get a character

errcode

= $fgets ( str, fd ) ;

// get a string

$fflush ( [ fd ] ) ;

// flush output buffer(s)

fd

= $fopen ( "filename", type ) ;

// open a file

errcode

= $fread ( reg, fd ) ;

// read binary data to a reg

errcode

= $fread ( mem, fd [ , [start] [ , [count] ] ] );

// read binary data to an array of reg

errcode

= $fscanf ( fd, format, args ) ;

// read formatted data from a file

errcode

= $fseek ( fd, offset, operation ) ;

// reposition the file pointer

position

= $ftell ( fd ) ;

// get the file pointer position

errcode

= $sscanf ( str, format, args ) ;

// read formatted data from a string

errcode

= $rewind ( fd ) ;

// rewind the file pointer

length

= $sformat ( reg, format, args ) ;

// format data to a string

$swrite ( reg, args ) ;


errcode

= $ungetc ( c, fd ) ;

// format data to a string


// unget (put back) a character

Verilog Application Workshop

18-44

Review
1. Which two system tasks display the steady state values of the argument list?
2. Which is better to use when creating test vectors? $display or $strobe?
3. How would you cater with opening 35 files?
4. What is the output of the following piece of code?
module test;
reg [3:0] a;
initial
begin
a <= 11;
a = 4b0011;
$display("display", a);
$strobeb("strobe", a);
end
endmodule

System Control (VSV2)

18-45

Review

Verilog Application Workshop

18-46

Verilog Application Workshop

18-47

Verilog Application Workshop

18-48

Using a Verilog Test Bench


VTB4

19-1

Notes

Verilog Application Workshop

19-2

Aims and Topics

Aims
Learn coding styles and methods that are commonly used to create a test bench

Topics
Simulation behavior
Testbench organization
Stimulus
Concurrent blocks
event
fork - join
Vector capture and playback
Clock generation

Using a Verilog Test Bench (VTB4)

19-3

Aims and Topics

Verilog Application Workshop

19-4

Design Organization
vendor
libraries

include
files

simulator
design
files

compilation

data
clk
read
write

file input:
stimulus,

simulation

expect patterns

file output:
stimulus, results
patterns

Using a Verilog Test Bench (VTB4)

19-5

Design Organization
Dashed lines indicate that compilation can check for the existence and readability of input files, as well
as the permission to create output files.

Verilog Application Workshop

19-6

Simulation of a Verilog Model


initial
avec = 8h00;
always @(posedge clk)
q <= d;
always @(a or b or sel)
if sel
y = a;
...

compilation

Procedure
Procedure

initialization
Procedure

Procedure
Procedure

Procedure

simulation
Procedure

z
Procedure

Using a Verilog Test Bench (VTB4)

19-7

Simulation of a Verilog Model


Verilog simulation takes the following steps:
1. Compilation:
The compiler parses the design description(s), and compiler directives, and partially builds a
data structure representing the design hierarchy. As Verilog has module parameters and
out-of-module references, the elaborator completes this data structure later, when the complete
design is available.
2. Initialization:
The initialization phase initializes nets to the high impedance state z and initializes variables
to the unknown state x. The initialization phase then propagates these value changes through
the design hierarchy.
3. Simulation:
When simulation commences at time zero the simulator executes the statements in each
initial and always block up to the point at which a timing control or delay suspends
execution of the block. These assignments can trigger events at time zero and at later times.
When time advances, scheduled events are executed, causing more events to be scheduled. This process
continues throughout simulation.
Verilog variables initialize to the unknown state x. The variable remains at the x state until assigned
some other state. If a variable remains at x for the duration of simulation, then this is an indication of
a logic initialization problem, e.g. unreset registers.
Undriven nets initialize to the high impedance state z. If a net remains at z for the duration of
simulation, then this is an indication of a net that has been left unconnected.

Verilog Application Workshop

19-8

Testbench Organization
Simple testbench
Just sends data to design

Few processes

No interaction

Simple Testbench

Design
to verify

stimulus

Sophisticated testbench
Models environment
around design

Talks to design

Evolves towards system


model

Self-checking

Sophisticated Testbench
stimulus
Design
to verify

verify
results

Using a Verilog Test Bench (VTB4)

19-9

Testbench Organization
A simple testbench applies vectors to the design under test and the user manually verifies the results.
A sophisticated testbench is self-checking, it automatically verifies the results.
Placing stimulus in a separate level of hierarchy is useful if you want to have multiple versions of the
stimulus for different situations.
You could also have a separate hierarchical block monitoring the results.
Real projects tend to use some form of intelligent or smart testbench that reacts to the response from
the DUT (e.g. bus cycles, handshake mechanisms, etc.)
Sophistication of your testbench is only limited by your time and imagination...

Verilog Application Workshop

19-10

In Line Stimulus
You need only specify the variable value
transitions.
You can easily specify complex timing
relationships.
This type of testbench can become very
large for complex tests.

module inline_tb;
reg [7:0] data_bus, addr;
reg reset;
// instance of DUT
initial
begin
reset = 1b0;
data_bus = 8h00;
#5 reset = 1b1;
#15 reset = 1b0;
#10 data_bus = 8h45;
#15 addr = 8hf0;
#40 data_bus = 8h0f;
end
endmodule

Using a Verilog Test Bench (VTB4)

19-11

In-Line Stimulus
When first developing a test, you might simply write a sequence of stimulus over time in a single process.
You describe the stimulus using a series of signal assignments separated by wait statements.
Although having separate delays between each signal assignment allows you to describe complex timing
relationships, this is an inefficient way to write large amount of stimulus.

Verilog Application Workshop

19-12

Stimulus From Loops


You can in a loop repeatedly
modify the same stimulus variable.
Advantages include:
Ease of entry

Compact description

This method may be best for


stimulus having:
A set time period

Regular values

Important
Do not forget to insert a timing control
in the loop!

module loop_tb;
reg clk;
reg [7:0] stimulus;
integer i;
// instance of DUT
// clock generation
initial
begin
for (i=0; i<=255; i=i+1)
@(negedge clk)
stimulus = i;
end
endmodule

Using a Verilog Test Bench (VTB4)

19-13

Stimulus From Loops


This example uses a for loop to create an incrementing set of values on a bus.
The loop determines the number of stimuli to be applied (256) and also uses the loop variable as the
stimulus vector.
The event control statement inside the loop provides new stimulus on each falling clock edge.

Verilog Application Workshop

19-14

Stimulus From Arrays


You can preload stimulus values into
an array and then in a loop apply the
array values. Advantages include:
Compact description
This method may be best for stimulus
having:
A set time period

Irregular values

You can alternatively load the


stimulus array from a file...

module array_tb;
// stimulus word and array
reg [7:0] data_bus, stim_array[0:15];
integer i;
// instance of dut
// define clock
initial begin
// load array with values
stim_array[0] = 8h2f;
stim_array[1] = 8h7a;
...
stim_array[15] = 8h0b;
// apply stimulus from array
for (i = 0; i <= 15; i = i + 1)
@(negedge clk)
data_bus = stim_array[i];
end
endmodule

Using a Verilog Test Bench (VTB4)

19-15

Stimulus from Arrays


If you wish to apply irregular data values at set time intervals, you can use an array.
Define an array and load it, using either in-line code, or directly from an external data file.
Then use a for loop to apply the data at regular intervals. The loop variable indexes each array element
in turn.

Verilog Application Workshop

19-16

Stimulus from Files


This example is equivalent to
the previous, but preloads the
memory array from a file.

module file_array_tb;
// stimulus word and array
reg [7:0] data_bus, stim_array[0:15];
integer i;
// instance of dut
// define clock
initial begin
// load array with values
$readmemb("stimulus.txt",stim_array);
// apply stimulus from array
for (i = 0; i <= 15; i = i + 1)
@(negedge clk)
data_bus <= stim_array[i];
end
endmodule

Using a Verilog Test Bench (VTB4)

19-17

Stimulus from Files

Verilog Application Workshop

19-18

Random Stimulus using $random


You can create random numbers using the
$random system function.
Returns a random 32-bit signed integer
Verilog-1995: Algorithm is not standard
and not portable
Verilog-2001: Algorithm is standard
and portable
You can seed the generator to produce repeatable
sequences.
Verilog provides system functions with which
you can alter the distribution of random numbers.

module random_tb;
reg [3:0] avec;
reg [7:0] bvec;
...
initial
begin
avec = $random;
bvec = $random;
...
end
endmodule

$dist_chi_square
$dist_erlang
$dist_exponential
$dist_normal
$dist_poisson
$dist_t
$dist_uniform
Using a Verilog Test Bench (VTB4)

19-19

Random Stimulus
You can use the $random system function to easily create random data patterns.
Random data may find errors in a design that more predictable data does not.
The function returns a 32-bit random value that you can assigned to any size vector (extra bits are
truncated). For random numbers wider than 32 bits, you can concatenate multiple calls to $random.
You can provide a seed value to produce a repeatable sequence of pseudo-random numbers.
Note: Simulators compliant with the 1995 Verilog standard may produce different random number
sequences. Simulators compliant with the 2001 Verilog standard must produce identical
random number sequences. You must refer to the vendors documentation to determine whether
these algorithms are different and how to select the standard algorithm.

Verilog Application Workshop

19-20

The fork and join Keywords


Statements enclosed by fork...join execute
concurrently.

module forkfoin_tb;
reg [7:0] data, addr;

Each statement is subject to whatever event


control or delays it includes.

// instance of DUT

The fork...join block completes when all


forked statements have completed.

initial
fork
data = 8h00;
#10 data = 8h45;
#15 addr = 8hf0;
#30 data = 8h0f;
join

Synthesis
The synthesis standard does not support the
fork...join construct.

endmodule

fork
#10
#15
data= data= addr=
8'h00; 8'h45; 8'hf0;

#30
data=
8'h0f;

join
Using a Verilog Test Bench (VTB4)

19-21

The fork and join Keywords


You use the fork..join construct in a testbench. Statements within the fork...join block execute
concurrently rather than sequentially. They all start execution immediately and are then subject to their
own event controls and delays. The event controls and delays of each statement are relative to the time
execution entered the block. The block does not complete until all statements within the block complete.

Verilog Application Workshop

19-22

Concurrent Stimulus Block


A concurrent block can contain any
procedural statement (tasks calls, loops, etc).
Some issues to be aware of are:
You cannot predict the execution order
of statements scheduled to execute at
the same simulation time. This can
cause race conditions.

If any statement (e.g. forever loop)


does not complete, the block never
joins.

module concurrent_tb;
reg [7:0] data;
// instance of DUT
initial
fork
#10 data =
#20 repeat
#10 data
#25 repeat
#20 data
#99 data =
join

8h45;
(7)
= data + 1;
(5)
= data << 1;
8h0f;

endmodule

Using a Verilog Test Bench (VTB4)

19-23

Concurrent Stimulus Block


The two repeat loops above start at different times, and execute concurrently. Applying this stimulus
would be very difficult to do in a single begin..end block.

Verilog Application Workshop

19-24

The event keyword


Declare a Verilog named event
using the event keyword.
Notify the event using the -> event
trigger operator.
Use the event in an @ event control.

Synthesis
The synthesis standard does not support
the event construct

module event_example (
input [3:0] in1, in2,
output [4:0] o1
);
event e1; // declare event
always @ (in1 or in2)
begin
o1 = in1 + in2;
-> e1; // notify event
end
always @(e1) // use event
$displayb(o1);
endmodule

Using a Verilog Test Bench (VTB4)

19-25

The event Keyword


Where you simply need to trigger a testbench process and do not need the connectivity or value of a net
or register, to increase simulator performance, use a Verilog named event.

Verilog Application Workshop

19-26

Using Strings to Monitor Progress


Displaying informative strings can
assist you with your debug efforts
by monitoring simulation progress.

module testbench;
reg [40*8:1] message;
task reset;
begin
message = "reset";
@(negedge clock);
reset <= 1b1;
@(negedge clock);
reset <= 1b0;
end
endtask

Define a vector with 8 bits for each


ASCII character.
Assign a string literal to the vector
(padded/truncated like any other
number).
Define a process triggered by
change of the message that displays
the new message.

task test1;
input [3:0] a_vec,b_vec;
output [7:0] d_vec;
begin
message = "test one";
...
end
endtask

View the messages with the


waveform display tool (set display
radix to ASCII).

always @ (message)
$display("%s",message);
initial begin
reset;
test1(a,b,out);
end
endmodule
Using a Verilog Test Bench (VTB4)

19-27

Using Strings to Monitor Progress


Verilog does not have a string type, but you can use a vector to hold the equivalent ASCII encoding for
a character string. You can create such character strings to display meaningful progress messages and to
view in a waveform window. You can also load messages from an external file. With the Verilog-1995
file input ($readmemb/h) you must represent the message ASCII value in binary or hexadecimal. With
the Verilog-2001 file input ($fgets, $fscanf) you can directly read ASCII characters.

Verilog Application Workshop

19-28

Hierarchical Variables
You can access out-of-module
variables using a hierarchical
pathname.
This is useful in testbenches.
Pathnames can be relative or absolute.
This example has a relative pathname.
The equivalent absolute pathname
might be:

module mux (
input a, b, sel, clk,
output reg f );
wire g = sel ? a : b;
always @ (posedge clk)
f <= g;
endmodule
module tb;
...
mux uut (.a (1b0), .b (bnet), .sel
(select), .clk (clk),.f (f));

wait (tb.uut.g);
initial
begin
wait (uut.g);
$display("mux has a logic one");
end
...
endmodule

Using a Verilog Test Bench (VTB4)

19-29

Hierarchical Variables
This example uses a relative pathname from the accessing module to the hierarchical variable. Relative
pathnames can only go down the hierarchy and not up the hierarchy. You can alternatively use an
absolute pathname starting from the hierarchy root. Absolute pathnames can access any net and
persistent variable. You cannot access nonpersistent variables such as those declared in Verilog-2001
automatic tasks and functions.

Verilog Application Workshop

19-30

Vector Capture
You can capture the
stimulus and response at
the pins of your DUT.
You can play these vectors
back against the DUT
using only a
stripped-down test
environment.
You can provide these test
vectors to the device
manufacturer.

module capture_tb;
reg [7:0] stimulus, response;
integer stimfile, respfile;
// instance of dut
initial
begin
stimfile = $fopen("stimulus.txt");
respfile = $fopen("results.txt");
fork
if (stimfile != 0 )
forever #(period)
$fstrobeb (stimfile, "%b", stimulus);
if (respfile != 0 )
#(period/2) forever #(period)
$fstrobeb (respfile, "%b", response);
join
end
endmodule

Using a Verilog Test Bench (VTB4)

19-31

Vector Capture

Verilog Application Workshop

19-32

Vector Playback
You can play back vectors
read from a file

module playback_tb;
localparam integer num_vecs = 256;
reg [7:0] data_bus;
reg [7:0] stim [0:num_vecs-1];
integer i;
//instance of dut

00111000
00111001
00111010
00111100
00110000
00101000
00011000
01111000
10111000
...

initial
begin
// load stimuli
$readmemb("vec.txt", stim);
// replay vectors
for (i=0; i<num_vecs; i=i+1)
#50 data_bus = stim[i];
end

vec.txt

endmodule

Using a Verilog Test Bench (VTB4)

19-33

Vector Playback
Using vector files for input and output of your simulation means:

You can more quickly modify your stimulus

You can use an offline utility to quickly compare response files

Verilog Application Workshop

19-34

Creating Clocks
Clock generator examples
always begin // simple
#(period/2) clk = 0;
#(period/2) clk = 1;
end
initial begin // delayed
clk = 0;
#(period)
forever
#(period/2) clk = ~clk;
end
initial begin // irregular
#(period + 1) clk = 1;
#(period/2 - 1)
forever begin
#(period/4) clk = 0;
#(3 * period/4) clk = 1;
end
end

nand #(period/2) u1 (ck, ck, go);


initial begin
go = 0;
#(period/2) go = 1;
end
nand #(period/2) u1 (ck, ck, go);
initial begin
go = 0;
#(period) go = 1;
end
nand #(period/4, 3*period/4)
u1 (ck, ck, go);
initial begin
go = 0;
#(period) go = 1;
end

Using a Verilog Test Bench (VTB4)

19-35

Creating Clocks
There are many ways to model a clock oscillator. Here are a few examples.

Verilog Application Workshop

19-36

Use of Tasks
Using tasks in a testbench
encapsulates repeated operations,
making your code more efficient.

data

clk

data_valid

module bus_ctrl_tb
reg [7:0] data;
reg data_valid;
wire data_read;
task cpu_driver;
input [7:0] data_in;
begin
#30 data_valid = 1;
wait (data_read == 1);
#20 data = data_in;
wait (data_read == 0);
#20 data = 8hzz;
#30 data_valid == 0;
end
endtask

data_read

// cpu instantiation
initial
begin
cpu_driver (8b0000_0000);
cpu_driver (8b1010_1010);
cpu_driver (8b0101_0101);
end
endmodule

Using a Verilog Test Bench (VTB4)

19-37

Use of Tasks

Verilog Application Workshop

19-38

Summary
Several Verilog constructs are useful in testbench construction:
Concurrent blocks and fork..join statements

Include files

Here you have examined several methods of applying stimulus:


In-line stimulus from an initial block

Stimulus from a loop

Stimulus indexed from an array

Vector capture and playback

Using a Verilog Test Bench (VTB4)

19-39

Summary

Verilog Application Workshop

19-40

Application of Verilog Testbenches


VEE7

20-1

Notes

Verilog Application Workshop

20-2

Aims and Topics

Aims
To look at testbenches for verifying complex designs

Topics
Pseudo-code based testbenches
Simulation output

Application of Verilog Testbenches (VEE7)

20-3

Aims and Topics

Verilog Application Workshop

20-4

Pseudo-Code Based Testbench


User-defined instructions specify:
Sequence of test operations

Data associated with operations

Testbench interprets each instruction and performs pre-defined operation

Testbench

Design to
Verify

user defined
instructions

Application of Verilog Testbenches (VEE7)

20-5

Pseudo-Code Based Testbench


You can define a set of instructions (pseudo-code) to control the test sequence. The testbench can read
these instructions from a text file. This is also know as a script-driven testbench.
Following slides illustrate the testbench interpreting the textual instruction and performing the operation.
As the instruction set is manually generated, the testbench must assume the potential for error and
carefully check the instruction syntax.

Verilog Application Workshop

20-6

Pseudo-Code Based Telecomms Example


GOAL: Test the RX UUT
Write pseudo code
to generate the data
packets

Assemble and
transmit the
packets

Data
generator
Header
generator

Data packet
transmission

8-bit
header

16-bit data
packet

CRC
generator

Data
RAM
Header
RAM

Clock
generator

Check

Instruction
decode

Instructions

8-bit
CRC

RX
Protocol
Engine

CRC
generator
UUT

Testbench broken
into 5 tasks

(external file)

Application of Verilog Testbenches (VEE7)

20-7

Pseudo-Code Based Telecomms Example


The TX Data Protocol Engine reads pseudo code instructions from a file and builds a data packet for
transmission to the RX UUT.
The testbench decodes each coded instruction and calls an appropriate task to execute the operation.
Each task performs a particular operation.
To assemble a data packet, the testbench reads the header address byte from the Systems Header RAM
and the data part from the Systems Data RAM and generates a CRC code word for the data packet, then
transmits the packet to the Receive Protocol Engine
Following slides illustrate how to use tasks to perform these operations.

Verilog Application Workshop

20-8

Use Tasks to Assemble A Data Packet


Define a task for each
packet assembly
operation:
Get the header
from the header
RAM

Get the data from


the data RAM

Generate a CRC
for the packet

task clock (input integer cnt);


repeat(cnt)
@(posedge clk);
endtask
task get_hdr (input [7:0] addr, output [7:0] hdr);
begin
hdr_ram_addr = addr;
ce_2 = 1;
// select header ram
wrb = 1;
// read mode
clock(1);
// allow 1 cycle access time
hdr = ram_hdr; // capture data
clock(1);
ce_2 = 0;
// deselect data ram
end
endtask
task get_data(input [7:0] addr, output [15:0] data);
begin
data_ram_addr = addr;
ce_1 = 1; // select data ram
wrb = 1;
clock(1); // allow 1 cycle access time
data = ram_data;
clock(1);
ce_1 = 0
end
task gen_crc(input [23:8] hdr_data, output [7:0]
endtask
crc);
begin
...
end
endtask
Application of Verilog Testbenches (VEE7)

20-9

Use Tasks to Assemble A Data Packet


Break data packet assembly down into simple tasks. Each task performs a specific operation.

Verilog Application Workshop

20-10

Instruction Decode
Testbench passes instruction
to decode task.
Decode task assembles and
returns packet.
Utilizes other tasks

`define crc pkt[31:8]


`define addr instruction[15:8]
`define oper instruction[7:0]
task instr_decode (
input [15:0] instruction,
output [31:0] pkt
);
localparam NOP
= 0,
FETCH_DATA = 1,
FETCH_HDR = 2,
CRC_GEN
= 3,
XMIT_PKT
= 4;
begin
case(`oper)
NOP
: clock(1);
FETCH_HDR : get_hdr (`addr, pkt[31:24]);
FETCH_DATA : get_data(`addr, pkt[23:8]);
CRC_GEN
: gen_crc (`crc, pkt[7:0]);
XMIT_PKT
: begin
xmit = 1;
clock(10);
xmit = 0;
end
default
: $display("illegal instruction");
endcase
end
endtask

Application of Verilog Testbenches (VEE7)

20-11

Instruction Decode
Text macro substitution can sometimes make your code more readable.

Verilog Application Workshop

20-12

The Testbench
module datacomms_tb;
reg xmit, clk, ce_1, ce_2, wrb;
wire [31:0] xmit_packet;
reg [15:0] instr_mem [255:0];
integer i;
`include "tasks.v"

// read the tasks file

initial $readmemh("instructions.txt", instr_mem);

ff_02
6e_01
00_03
00_04
00_00
...
...
55_02
c2_01
00_03
00_04
00_00

//
//
//
//
//

get_hdr
get_data
crc_gen
xmit_pkt
nop

//
//
//
//
//

get_hdr
get_data
crc_gen
xmit_pkt
nop

// instance of system under test ...


always begin
clk = 0; #30;
clk = 1; #30;
end
always
for (i=0; i <= 255; i = i + 1)
instr_decode(instr_mem(i), xmit_packet);
endmodule

Application of Verilog Testbenches (VEE7)

20-13

The Testbench
The testbench is reduced to a few simple instructions.
The operations performed are complex but offloaded to individual tasks.
You can use such subprograms to make your testbench more readable.

Verilog Application Workshop

20-14

Running Processor Code


You would ideally have a fully functional processor model:
Verilog?

C-based instruction-set simulator?

Emulator?

The processor model could run a low level set of instructions, such as a
firmware-based power-up self-test.
Hardware/software co-verification tools are available, allowing
interactive debug of Verilog and software.

Testbench

Design to
Verify

user defined
instructions

Application of Verilog Testbenches (VEE7)

20-15

Running Processor Code


It is possible to actually run low level code from a simple processor if your Verilog system includes a
fully functional model of the processor. This model is not usually written in Verilog, but is more often
written in C or derived from a hardware modeling environment.
A hardware modeler can integrate a processor device into a Verilog simulation environment. The
processor is instantiated and connected as a component. Data sent to the processor component is then
applied to the actual device by the modeler, and the response applied to the output ports of the component
This method allows low level code to be debugged before any hardware has been built
For more complex processors, hardware/software co-simulation environments allow the designer to
integrate a software simulator (running processor code) with a Verilog simulator (simulating the
hardware system) through a specially written processor model.

Verilog Application Workshop

20-16

Review of Simulation Outputs


Previous slides illustrated Verilog reading stimulus data from a file.
Following slides illustrate Verilog writing simulation data to files.

Testbench

Design to
Verify

Test Data

Errors &
Warnings

Visualization

Results for
comparison
and analysis

Manufacturing
test vectors

Application of Verilog Testbenches (VEE7)

20-17

Review of Simulation Outputs


File I/O is as important for capturing data from the simulation as it is for applying stimulus.
You can use the $display, $write, $strobe and $monitor tasks to report simulation
information.
Following slides illustrate the types of output you testbench can generate.

Verilog Application Workshop

20-18

Visualized Output
Analyzing binary data for errors can be difficult.
Graphical display of data may aid the debug efforts.

Design to

Testbench

Verify
Test Data
####
#
#
#
#

#
#
#
#
####

Visualization

#
#
#
#

#
#
#
#
####

Application of Verilog Testbenches (VEE7)

20-19

Visualized Output
You can sometimes better analyze binary output if you can somehow visualize it.
In the Alarm Clock labs, it is difficult to verify by looking at the binary output data that the correct
segments of the seven-segment display are active. You can alternatively visualize the output by
generating output text files from your simulation. You can represent the seven-segment display as a
two-dimensional array of space and '#' characters set in a seven-segment pattern. You can output this
two-dimensional character array each time the display signals change value, and monitor the file content
in a shell window.

Verilog Application Workshop

20-20

Visualized Output Example (1)


parameter
parameter
parameter
parameter
parameter
parameter
parameter

CHARACTER_WIDTH
CHARS_PER_DIGIT
DIGIT_WIDTH
NUMBER_OF_DIGITS
LINE_WIDTH
NUMBER_OF_LINES
MESSAGE_WIDTH

=
=
=
=
=
=
=

8 ;
10 ;
CHARS_PER_DIGIT * CHARACTER_WIDTH ;
4 ;
DIGIT_WIDTH*NUMBER_OF_DIGITS + CHARACTER_WIDTH*1 ;
11 ;
LINE_WIDTH * NUMBER_OF_LINES ;

####
always @ ( DISP_7SEG )
#
#
begin : DISPLAY
#
#
integer mcd ;
#
#
integer line ;
#
#
integer digit ;
reg [2:0] code ; // five things a digit line can look like
####
reg [1:DIGIT_WIDTH] digit_string ;
#
#
reg [1:LINE_WIDTH] line_string ;
#
#
reg [1:MESSAGE_WIDTH] message_string ;
#
#
for ( line=1; line<=NUMBER_OF_LINES; line=line+1 )
#
#
begin
####
// digit 0 is RIGHTMOST digit
for ( digit=0; digit<=(NUMBER_OF_DIGITS-1); digit=digit+1 )
begin
case ( line )
1:
code = { DISP_7SEG[digit*7+0],
1'b0,
1'b0 } ;
2,3,4,5:
code = {
1'b0, DISP_7SEG[digit*7+5], DISP_7SEG[digit*7+1] } ;
6:
code = { DISP_7SEG[digit*7+6],
1'b0,
1'b0 } ;
7,8,9,10:
code = {
1'b0, DISP_7SEG[digit*7+4], DISP_7SEG[digit*7+2] } ;
11:
code = { DISP_7SEG[digit*7+3],
1'b0,
1'b0 } ;
endcase
...

Application of Verilog Testbenches (VEE7)

20-21

Visualized Output Example


This is the first half of the DISPLAY procedure used in the Alarm Clock lab to output the seven-segment
display to a text file.
The outer loop loops through the lines of the display. For each line, an inner loop loops through the digits.
For each digit line, the procedure selects from five possible patterns of space and # characters.

Verilog Application Workshop

20-22

Visualized Output Example (2)


case ( code ) // select digit line
3'd0: digit_string = "
" ;
3'd1: digit_string = "
#
" ;
3'd2: digit_string = "#
" ;
3'd3: digit_string = "#
#
" ;
3'd4: digit_string = " ####
" ;
default: digit_string = "
" ;
endcase
case ( digit ) // place digit line within display line
3: line_string[DIGIT_WIDTH*0+1:DIGIT_WIDTH*1] = digit_string ;
2: line_string[DIGIT_WIDTH*1+1:DIGIT_WIDTH*2] = digit_string ;
1: line_string[DIGIT_WIDTH*2+1:DIGIT_WIDTH*3] = digit_string ;
0: line_string[DIGIT_WIDTH*3+1:DIGIT_WIDTH*4] = digit_string ;
endcase
end
line_string[LINE_WIDTH-7:LINE_WIDTH] = "\n" ; // terminate line
case ( line ) // place display line within message
1: message_string[LINE_WIDTH*00+1:LINE_WIDTH*01] = line_string ;
2: message_string[LINE_WIDTH*01+1:LINE_WIDTH*02] = line_string ;
3: message_string[LINE_WIDTH*02+1:LINE_WIDTH*03] = line_string ;
4: message_string[LINE_WIDTH*03+1:LINE_WIDTH*04] = line_string ;
5: message_string[LINE_WIDTH*04+1:LINE_WIDTH*05] = line_string ;
6: message_string[LINE_WIDTH*05+1:LINE_WIDTH*06] = line_string ;
7: message_string[LINE_WIDTH*06+1:LINE_WIDTH*07] = line_string ;
8: message_string[LINE_WIDTH*07+1:LINE_WIDTH*08] = line_string ;
9: message_string[LINE_WIDTH*08+1:LINE_WIDTH*09] = line_string ;
10: message_string[LINE_WIDTH*09+1:LINE_WIDTH*10] = line_string ;
11: message_string[LINE_WIDTH*10+1:LINE_WIDTH*11] = line_string ;
endcase
end
mcd = $fopen ( "clock.txt" ) ;
if ( mcd == 0 )
begin
$display ( "Cannot open clock.txt" ) ;
$finish ;
end
$fwrite ( mcd, "%s", message_string ) ; // output message
$fclose ( mcd ) ;
end

####
#
#
#
#

#
#
#
#
####

#
#
#
#

#
#
#
#
####

Application of Verilog Testbenches (VEE7)

20-23

Visualized Output Example (continued)


This is the second half of the DISPLAY procedure used in the Alarm Clock lab to output the
seven-segment display to a text file.
Having selected the pattern to represent a digit line, the inner loop then inserts that pattern in the
appropriate place of the display line. The outer loop inserts the display line in the appropriate place in
the overall display. The procedure opens the file, writes the display, and closes the file.
Reopening the file for each display ensures that the previous display is overwritten rather than appended
to. Writing the entire display in one system task makes it much more likely that any time you look at the
file it will contain exactly one whole display.

Verilog Application Workshop

20-24

Results for Comparison


Automated response checking is essential for large amounts of output.
If comparing between abstraction levels (Behavioral/RTL, RTL/gates):
Account for differences of propagation delay

Account for lower levels of abstraction having more detail

Testbench

Design to
Verify

Results for
comparison
and analysis

Known-good
results

Application of Verilog Testbenches (VEE7)

20-25

Results for Comparison


You can compare the current test results with those of a known good simulation.

To compare a refined (RTL) design to a previous behavioral version of the design


Account for differences of data type and propagation delay.

To compare a recently modified design to the previously verified design version.

A truly sophisticated testbench would check the response of the design under test throughout the
simulation, and as soon as it detected an error, output detailed data to help the debugging effort.

Verilog Application Workshop

20-26

Manufacturing Test Vectors for ASICs


You can capture stimulus/response vectors for manufacture test of your device.
Carefully consider at what point in the cycle you want to sample the response.

Design to

Testbench

Verify
Test Data

op1
op2
Manufacturing
test vectors

clk
strobe
Strobe Here

Application of Verilog Testbenches (VEE7)

20-27

Manufacturing Test Vectors for ASICs


Although ASIC design methodologies may rely upon scan insertion and Automatic Test Program
Generation (ATPG) for manufacturing test, it can be useful to add some functional test vectors to the
vector set. A testbench could capture stimulus and response in a format suitable for a manufacturing test.
Remember to account for propagation delays. You must sample the response when you expect it to be
stable perhaps very late in the clock period.

Verilog Application Workshop

20-28

Summary

Input methods
Pseudo-code
Processor code

Output methods
Errors and warnings
Visualization output
Results for comparison and analysis
ASIC manufacturing test vectors

Application of Verilog Testbenches (VEE7)

20-29

Summary

Verilog Application Workshop

20-30

This page left intentionally blank

Structural Modeling
VSM2

21-1

Notes

Verilog Application Workshop

21-2

Aims and Topics

Aims
Learn about the full capabilities of Verilog for structural and gate level
modeling.

Topics
Built-in primitives
Module instantiation options
Strength modeling

Structural Modeling (VSM2)

21-3

Terms and Definitions


Structural Modeling

Describing the functionality of a device in terms of gates

Verilog Primitives

Language-defined functional models for simple logic functions

Verilog Application Workshop

21-4

Structural Modeling
A purely structural model contains only instantiated modules and primitives and their
interconnections. Examples include:
Schematic capture

Post-synthesis netlist

ASIC/FPGA cell library models


a

sela

sel

out

nsel

selb

module mux (
input a, b, sel,
output out
);
wire nsel, sela, selb;
IV U32 ( .A(sel), .Z(nsel) );
AN2 U33 ( .A(a), .B(nsel), .Z(sela) );
AN2 U34 ( .A(b), .B( sel), .Z(selb) );
OR2 U35 ( .A(sela), .B(selb), .Z(out) );
endmodule
Structural Modeling (VSM2)

21-5

Structural Modeling
A structural model is equivalent to a schematic. You instantiate and connect predefined components to
create a more complex component.

Verilog Application Workshop

21-6

Verilog Primitives
Verilog primitives include
pre-defined basic logic functions.
You instantiate and connect them
almost like hierarchical modules:
Primitives do not require an
instance name

Primitives do not have port


names
Outputs before inputs

Primitive Name Functionality


and
or
not
buf
xor
nand
nor
xnor

sela
sel

out

nsel

Logical And
Logical Or
Inverter
Buffer
Logical Exclusive Or
Logical And Inverted
Logical Or Inverted
Logical Exclusive Or Inverted
module mux (
input a, b, sel,
output out
);
wire nsel, sela, selb;
not (nsel, sel);
and (selb, sel, b);
and (sela, nsel, a);
or (out, sela, selb);
endmodule

selb

Structural Modeling (VSM2)

21-7

Verilog Primitives
Verilog provides predefined primitives for basic logical functions.
Most ASIC and FPGA component libraries utilize primitives.

Verilog Application Workshop

21-8

Primitive Pins Are Expandable


Input width is automatically defined by the number of nets connected.

in1

out

and (out, in1, in2);


in2

in1
in2
in3
in1
in2
in3
in4

out

and (out, in1, in2, in3);

out

and (out, in1, in2, in3, in4);

Structural Modeling (VSM2)

21-9

Primitive Pins Are Expandable


The number of pins for a primitive gate is defined by the number of nets connected to it. You do not need
to instantiate a different logical function whenever the numbers of inputs or outputs to that function
change.
All gates (except not and buf) can have a variable number of inputs, but only one output.
The not and buf gates can have a variable number of outputs, but only one input.

Verilog Application Workshop

21-10

Conditional Primitives
Conditional primitives have three terminals: output, input, and enable.
When disabled, outputs are at high impedance.
Verilog has four types of conditional primitives:
Primitive Name

Functionality

bufif1
bufif0
notif1
notif0

Conditional buffer with logic 1 as enabling input


Conditional buffer with logic 0 as enabling input
Conditional inverter with logic 1 as enabling input
Conditional inverter with logic 0 as enabling input

Structural Modeling (VSM2)

21-11

Conditional Primitives

Verilog Application Workshop

21-12

Conditional Primitives (2)


bufif1

bufif0

data

data

out

enable

out

enable
bufif0 (out, data, enable)

bufif1 (out, data, enable)

enable

enable

data

bufif1

bufif0

data

Note: Verilog uses the symbols L and H to represent partially unknown logic values.

Structural Modeling (VSM2)

21-13

Conditional Primitives (2)


Each conditional primitive has one data output, one data input, and one control input.
Verilog has three unknown logic values:

X represents a complete unknown. Value can be logic 1, 0, or Z.

L represents a partial unknown. Value can be logic 0 or Z, but not 1.

H represents a partial unknown. Value can be logic 1 or Z, but not 0.

Verilog Application Workshop

21-14

Primitive Instantiation

Optionally omit instance name


Specify outputs before inputs
and (out, in1, in2, in3, in4); // unnamed instance
buf b1 (out1, out2, in); // named instance

Optionally specify primitive delay


notif0 #3.1 n1 (out, in, cntrl); // delay specified

Optionally specify signal strength


not (strong1, weak0) n2 (inv, bit); // strength
not (strong1) #2.5 n3 (op, ip);

// strength & delay

Important
For primitives the # character specifies a delay.

Structural Modeling (VSM2)

21-15

Primitive Instantiation
You must specify all the outputs of the primitive before specifying its inputs.
It is optional to specify an instance name for a primitive instantiation.
You can specify an optional delay to define the intrinsic delay of the primitive. In other words, a signal
takes the specified delay time before a change in input is reflected at the output. Without the delay
specification, the primitive operates at zero delay.
You can specify optional signal strengths to any signals that a primitive drives.
If you need to specify both strength and delay, the strength value comes first.
In addition to built-in primitives, you can create User Defined Primitives (UDPs). UDPs are covered in
the appendix, User Defined Primitives.

Verilog Application Workshop

21-16

Module Instantiation
A module instance must have an instance name.
Positional mapping: Port map order follows port declaration order

Named mapping: Port map order is independent of port declaration order


module comp (
output o1, o2,
input i1, i2
);
. . .
endmodule
module test;
comp c1 (Q,R,J,K); // Positional mapping
comp c2 (.i2(K),.o1(Q),.o2(R),.i1(J)); // Named mapping
comp c3 (Q,,J,K); // One port left unconnected
comp c4 (.i1(J),.o1(Q)); // Named, two unconnected ports
endmodule

Structural Modeling (VSM2)

21-17

Module Instantiation
A module instance must have an instance name.
For positional port mapping, the port map order follows the port declaration order.
For named port mapping, the port map order is independent of the port declaration order. You specify
the port name followed by the local net or register that connects to that port:

.port_name(signal_name)
You can leave a port unconnected in a module instantiation. Most simulators issue an associated warning
message.

Verilog Application Workshop

21-18

Array of Instances
You can instantiate an array of instances.
For an instance array, an instance name is required (even for primitives)
module driver1 (
input
en,
input [2:0] in,
output [2:0] out
);
// Separate primitive instantiations
bufif0 u2 (out[2], in[2], en);
bufif0 u1 (out[1], in[1], en);
bufif0 u0 (out[0], in[0], en);
endmodule

modules are equivalent


instance names are different
u2 versus u[2]

module driver2 (
input
en,
input [2:0] in,
output [2:0] out
);
// Array of primitive instantiations
bufif0 u[2:0] (out[2], in[2], en);
endmodule

Structural Modeling (VSM2)

21-19

Array of Instances
The syntax for an instance array is:

<name> <instance_name> <range> (<ports>);


The two examples above have identical functionality. The elaborator distributes vector signals among
the array instances. The vector width and connected port width total must match.
The instance names generated by the range specification are exactly like the names used to reference
bit-selects of a vector net. For example:

wire [2:0] out, in;


buf b[2:0] (out, in)
generates these instances:
buf b[2] (out[2], in[2]);
buf b[1] (out[1], in[1]);
buf b[0] (out[0], in[0]);

Verilog Application Workshop

21-20

Instance Array Ranges


Identical left and right indices create a single instance.
You may associate an instance name with only one range.
module oops;
wire y1, a1, b1;
wire [3:0] a2, b2, y2, a3, b3, y3;
comp u1 [5:5] (y1, a1, b1); // One instance of comp
comp m1 [0:3] (y2, a2, b2);
comp m1 [4:7] (y3, a3, b3); // Illegal! m1 already used
endmodule

Structural Modeling (VSM2)

21-21

Instance Array Ranges

The example illustrates an array of 1 instance of module comp, and an illegal attempt to
specify an array of instances of module comp on more than one line using the same instance
name m1

Verilog Application Workshop

21-22

The generate Construct


Verilog-2001 provides a way to repetitively and conditionally generate structure.
Place generate items between the generate and endgenerate keywords

Generate items consist of:


Generate case, for and if statements and generate begin...end blocks
Declarations of genvar loop index variables
Anything that goes into a module (for example module instances) except a:
port, parameter of any kind, another generate, or specify block

All generate expressions must be constant expressions

Generate constructs constitute a new level of scope:


for loop instances: blockname[index_value].instancename

generate
genvar var;
for (var=const_expr;
const_expr; var=const_expr)
begin: blockname
gen_item
end
endgenerate

generate
if (const_expr)
gen_item
else
gen_item
endgenerate

generate
case (const_expr)
const_expr: gen_item
default
: gen_item
endcase
endgenerate

Structural Modeling (VSM2)

21-23

The generate Construct

Verilog Application Workshop

21-24

Logic Strength Modeling


Verilog provides multiple levels of logic strengths.
This allows better modeling of hardware behavior, e.g. tri-state buses.
You can give a strength to a primitive instance that applies to any signals it drives.
and (strong0, weak1) a1 (out, a, b);
You can display the strength and value of a net with the %v format specifier.
$monitor ($time,,"output = %v", f);

Supply
Strong
Pull
Large
Weak
Medium
Small
High Z

Level

Type

%v formats

7
6
5
4
3
2
1
0

Drive
Drive (default)
Drive
Capacitive
Drive
Capacitive
Capacitive
Impedance

Su0
St0
Pu0
La0
We0
Me0
Sm0
Hi0

Su1
St1
Pu1
La1
We1
Me1
Sm1
Hi1

Specification
supply0, supply1
strong0, strong1
pull0, pull1
large
weak0, weak1
medium
small
highz0, highz1
Structural Modeling (VSM2)

21-25

Logic Strength Modeling


Logic strength modeling is an important aspect of Verilog modeling. This level of detail is typically only
used by component modelers, such as FPGA or ASIC library developers, but circuit designers who
simulate with these detailed models must be aware of the possibilities.
Common examples of situations when you need logic strengths to model accurately include:

Open collector output (pullup required)

Multiple tri-state drivers to a single node

MOS charge storage

ECL Gates (emitter dotting)

The primitive strength specification syntax is:

<primitive_name> [strength] [delay] [instance] (<ports>);


Examples:

nand (strong1,pull0) #(2:3:4) n1 (o,a,b); // strength & delay


or (supply0,highz1) (out,in1,in2,in3);

// no instance name

The capacitive strengths (large, medium, small) apply only to nets of type trireg and to tran primitives.

trireg (small) t1;

Verilog Application Workshop

21-26

Resolving Strengths
The highest strength level overrides all other drivers.

strong1, pull0

a
out
b

as output

bs output

out

strong1
pull0
pull0
strong1
pull0
HiZ
HiZ

strong0
weak1
strong0
weak1
HiZ
weak1
HiZ

strongX
pull0
strong0
strong1
pull0
weak1
HiZ

weak1, strong0

Structural Modeling (VSM2)

21-27

Resolving Strengths

Verilog Application Workshop

21-28

Review
1. What is structural modeling in Verilog?
2. What are the two ways that module ports can be connected? Which is safer?
3. What does an array of instances do?
4. When are instance names optional?

Structural Modeling (VSM2)

21-29

Review

Verilog Application Workshop

21-30

This page left intentionally blank

Modeling Delay
VMD2

22-1

Notes

Verilog Application Workshop

22-2

Aims and Topics

Aims
Understand how to model simple delays for simulations and gate level models

Topics
Lumped delays
Distributed delays
Path delays
Specify timing blocks
Intra-assignment delays

Modeling Delay (VMD2)

22-3

Terms and Definitions


Module Path

A path across a module that connects a module input (an input or an inout port)
with a module output (an output or an inout port)

Path Delay

The delay associated with a particular path

Verilog Application Workshop

22-4

Delay Modeling Types


You can model delays in three ways:
1
Lump the entire delay
at the last gate.

noror ASIC cell

a
b

n1

net1

o1

2
Distribute the delay
across each gate.

out

Use a specify block


to specify pin-to-pin
delays for each path.

Typical delay specification:


delay from a to out = 2
delay from b to out = 3
delay from c to out = 1
Modeling Delay (VMD2)

22-5

Delay Modeling Types

You can lump the delay onto the last gate driving the output. Lumped delay is:
Easy to model
Accurate only in simple cases

You can distribute delays across the gates:


More accurate than lumped delay methodology, but still, not always accurate

You can specify module path delays in a specify block:


Easy to model
Exactly match the delay specification
Allows different delays for all transitions between 0, 1, and z
Separates timing from functionality
Most commonly used delay type

Verilog Application Workshop

22-6

Lumped Delay
Lumped delays place all the delay on the last gate.
This is simple to implement...

But does not allow for different path delays

a
b
#3

out

path delay as modeled


a->out is 3
b->out is 3
c->out is 3

c
`timescale 1ns/1ns
module noror (
input a, b, c,
output out
);
nor n1 (net1, a, b);
or #3 o1 (out, c, net1);
endmodule

Modeling Delay (VMD2)

22-7

Lumped Delay
You can model propagation delay across devices by lumping the delay onto the last gate in a model. This
is an easy method of modeling delay. However, there is a loss of control multiple paths to a single
output share the delay. If you use lumped delay, it is best to use the worst-case delay (usually the largest
value).
In the example above the delay that defines the path from b to out is also used for the paths from a to
out and from c to out.

Verilog Application Workshop

22-8

Distributed Delays
Distributed delays divide the delay over more than one gate.
This allows different delays for different paths

Delays accumulate along the path

a
#2
b
#1

out

path delay as modeled


a->out is 3
b->out is 3
c->out is 1

c
`timescale 1ns/1ns
module noror (
input a, b, c,
output out
);
nor #2 n1 (net1, a, b);
or #1 o1 (out, c, net1);
endmodule
Modeling Delay (VMD2)

22-9

Distributed Delays
Distributed delays allow you to have different delays for different paths to the same output. This example
splits delay among multiple gates. The delay from a to out and from b to out is 2 + 1. Distributing
delays on a real structural model can quickly become complex. Note too, that it is still not possible to
represent different delays from different pins of the same primitive.

Verilog Application Workshop

22-10

Module Path Delays


With a specify block, you can specify individual module path (input to output) delays.

`timescale 1ns/1ns
module noror (
input a, b, c,
output out
);
nor n1 (net1, a, b);
or o1 (out, c, net1);

a
b
c

specify
(a => out) = 2;
(b => out) = 3;
(c => out) = 1;
endspecify

n1

net1

o1

out

path delays
a->out is 2
b->out is 3
c->out is 1

endmodule

Modeling Delay (VMD2)

22-11

Module Path Delays


Module path delays specify the delays from inputs to outputs of a module. You can accurately specify
individual input to individual output delays.

Verilog Application Workshop

22-12

Accurate Delay Control


You can specify rise, fall, and turn-off delays for gates and module paths:
rise any transition ending in 1

fall any transition ending in 0

turn-off any transition ending in z


and #(2,3) (out, in1, in2, in3);
bufif0 #(3,3,7) (out, in, ctrl);
specify
(in => out) = (1, 2);
(a => b) = (5, 4, 7);
endspecify

// rise, fall
// rise, fall, turn-off
// rise, fall
// rise, fall, turn-off

You can specify minimum, typical, and maximum values for each delay
or #(3.2:4.0:6.3) o1(out, in1, in2); // min:typ:max
not #(1:2:3, 2:3:5) (o,in);
// min:typ:max for rise, fall
specify
// min:typ:max for rise, fall, and turnoff
(b => y) = (2:3:4, 3:4:6, 4:5:8);
endspecify

Modeling Delay (VMD2)

22-13

Accurate Delay Control


Delay specification defines the propagation delay through a gate or module. Any change in the inputs is
reflected at the output only after this delay. Without a delay specification, the delay on a primitive is 0.
You can specify rise, fall, and turn-off delays for primitives and for module paths (turn-off delay does
not apply to primitive outputs that do not turn off).

Rise delays apply to transitions ending in 1.

Fall delays apply to transitions ending in 0.

Turn-off apply to transitions ending in z.

You can specify minimum, typical, and maximum values for each delay.

Verilog Application Workshop

22-14

The Specify Block


The specify block defines module timing data
Separates timing information from
functionality
Typical tasks for specify block include:
Define module timing paths

`timescale 1ns/1ns
module noror (
input a, b, c,
output out
);
nor n1 (net1, a, b);
or o1 (out, c, net1);
specify
(a => out) = 2;
(b => out) = 3;
(c => out) = 1;
endspecify

Assign delays to those paths

Perform timing checks

Define path pulse filtering limits

You cannot declare module parameters in a


specify block
Specify blocks use a special specify
parameter (specparam) (more later)

endmodule

Modeling Delay (VMD2)

22-15

The Specify Block


A specify block separates the module timing from the module function. The specify block can remain
the same for different levels of abstraction.
A specify block is bounded by the keywords specify and endspecify, and must appear within a
module boundary.
The keyword specparam is short for specify parameter and should not be confused with module
parameters (keyword parameter).

You declare and use a module parameter (parameter) only inside a module and outside a
specify block.

You declare and use a specify parameter (specparam) only inside a specify block.
Verilog-2001 permits declaration and use within a module.

Typical tasks you perform inside a specify block:

Describe timing paths across the module and assign delays to those paths.

Describe timing checks to ensure that the timing constraints of the device are met.

Define the pulse filtering limits for the module or for particular paths across a module.

Note: Synthesis tools ignore all simulation timing. This is not how you specify timing constraints to
a synthesis tool.

Verilog Application Workshop

22-16

Parallel and Full Connection Module Paths


=> : Parallel connection must be between ports of the same size
*> : Full connection connects all listed inputs to all listed outputs

Parallel Module Path


a
input
bits

Full Module Path

q
output
bits

qb
2 paths
Bit-to-bit connections
Use => to define path

input
bits

qb

output
bits

4 paths
Bit-to-vector connections
Use *> to define path
(a, b *> q, qb) = 15;

(a, b => q, qb) = 15;

is equivalent to:

is equivalent to
(a
(b
(a
(b

(a => q) = 15;
(b => qb) = 15;

=>
=>
=>
=>

q) = 15;
q) = 15;
qb) = 15;
qb) = 15;
Modeling Delay (VMD2)

22-17

Parallel and Full Connection Module Paths


A parallel connection describes a timing path between each bit in the source to each corresponding bit in
the destination. Parallel timing paths can be created only between one source and one destination where
each signal contains the same number of bits.
A full connection describes a timing path between every bit in the source and every bit in the destination.
The module path source does not need to have the same number of bits as the module path destination.
Here are some examples that specify path delays:
// Path delay specified from a to out and from b to out.
(a, b => out) = 2.2;
// Rise and Fall delay specified from r to o1 and o2.
(r *> o1, o2) = (1, 2);
// Path delays specified from a[1] to b[1] and from a[0] to b[0].
(a[1:0] => b[1:0]) = 3; // parallel connection
// Path delays specified for all paths from a to o.
(a[7:0] *> o[7:0]) = 6.3; // full connection

Verilog Application Workshop

22-18

State Dependent Path Delays


A state-dependent path delay is applied only when the condition is true.
module jexor (
input a, b,
output op
);
xor (op, a, b);
specify
if (a) (b=>op)
if (!a) (b=>op)
if (b) (a=>op)
if (!b) (a=>op)
endspecify

=
=
=
=

(5:6:7);
(5:7:8);
(4:5:7);
(5:7:9);

a
op
b

endmodule
Note: not an if statement no else is allowed.

Modeling Delay (VMD2)

22-19

State Dependent Path Delays


In the example above the time from a or b to op is dependent on the state of the other input.

Verilog Application Workshop

22-20

Specify Block Parameters


You cannot declare or use module parameters inside a
specify block. To use a constant in a specify block:
The specparam keyword declares specify
parameters

module noror (
input a, b, c,
output op
);

Verilog-1995: Must declare and use only in


specify block

nor n1 (net1, a, b);


or o1 (op, c, net1);

Verilog-2001: Can also declare and use as a


module item. Can assign to a module
parameter:

specify
specparam aop = 2,
bop = 3,
cop = 1;
(a => op) = aop;
(b => op) = bop;
(c => op) = cop;
endspecify

parameter my_parameter =
my_specparam; // Verilog-2001

You cannot override specify parameters as you


can module parameters

You cannot assign a module parameter to a


specify parameter

endmodule

specparam my_specparam =
my_parameter; // NO!

Modeling Delay (VMD2)

22-21

Specify Block Parameters


To declare specify block parameters, use the specparam keyword. The following summarizes the
differences between module parameters and specify parameters:
Module Parameter

Specify Parameter

Use the parameter keyword

Use the specparam keyword

Must declare outside specify blocks

Must declare inside specify block (Verilog-1995)

Must use outside specify blocks

Must use inside specify blocks (Verilog-1995)

Can override values using defparam Can override values only using SDF annotation
Replicated with each module instance Not replicated with each module instance
Verilog-1995:
specify_item ::= specparam_declaration | ...
specparam_declaration ::= specparam list_of_specparam_assignments ;
list_of_specparam_assignments ::=
specparam_assignment { , specparam_assignment }
specparam_assignment ::= identifier = constant_expression | ...

Verilog-2001:
module_item ::= { attribute_instance } specparam_declaration | ...
specify_item ::= specparam_declaration | ...
specparam_declaration ::= specparam [ range ] list_of_specparam_assignments ;
list_of_specparam_assignments ::=
specparam_assignment { , specparam_assignment }
specparam_assignment ::= identifier = constant_mintypmax_expression | ...

Verilog Application Workshop

22-22

Inertial and Transport Delay Modes

Inertial delay mode: path delays smaller than intrinsic gate delay are swallowed

Transport delay mode: every change at input is reflected at output


Inertial Versus Transport Delays
in

out
delay = 2 ns

Input Waveform
Note rejection of pulses that
are shorter than intrinsic delay.

Inertial out

Note the transport of all input


changes to output changes.

Transport out
0 1 2 3 4 5 6 7 8 9 10 11 ...
time in ns

Note: Different simulators use default delay modes, and may require command-line options or
simulator-specific compiler directives to manipulate the delay mode.
Modeling Delay (VMD2)

22-23

Inertial and Transport Delay Modes


In the example above the intrinsic delay of the gate is 2ns. In inertial delay mode, a pulse of 1 ns in length
will not appear on the output. In pure transport delay mode, all pulses, regardless of their length, will
appear on the output. You can define pulse filtering limits.

Verilog Application Workshop

22-24

Path Pulse Control


For transport delay mode you can use the PATHPULSE$ specparam to control pulse
handling on module paths. You can specify module-wide and path-specific controls:
PATHPULSE$ =
( reject_mintypmax_limit [ , error_mintypmax_limit ] ) ;
PATHPULSE$input_terminal$output_terminal =
( reject_mintypmax_limit [ , error_mintypmax_limit ] ) ;
Verilog-1995 used onevent pulse filtering. For Verilog-2001 you can select ondetect.
pulsestyle_onevent

pulsestyle_ondetect

specify
(inp => outp) = 5 ;
specparam
PATHPULSE$inp$outp = (2,4) ;
pulsestyle_onevent outp ;
endspecify

specify
(inp => outp) = 5 ;
specparam
PATHPULSE$inp$outp = (2,4) ;
pulsestyle_ondetect outp ;
endspecify

outp

outp

outp
(delayed)

outp
(delayed)

0 1 2 3 4 5 6 7 8

0 1 2 3 4 5 6 7 8

Modeling Delay (VMD2)

22-25

Path Pulse Control


You can override global pulse control by declaring specialized specparams that use the prefix
PATHPULSE$.
The PATHPULSE$ specparam narrows the scope of module path pulse control to a specific module or
to particular paths within modules.
If you want error_value and reject_value to be identical, specify only one value.

PATHPULSE$ = 3;
is the same as:
PATHPULSE$ = (3, 3);
Verilog-1995 uses the onevent method of pulse propagation. The simulator propagates an input pulse that
meets the reject limit but does not meet the error limit, with its value changed to the unknown state. The
output pulse appears with the expected delay.
Verilog-2001 gives you the option to select the ondetect method of pulse propagation. The output pulse
appears immediately upon detection of the too-short pulse width, thus more clearly indicating for debug
purposes the point at which the error is detected.

Verilog Application Workshop

22-26

Negative Pulse Detection


What if the delayed pulse leading edge is later than the delayed pulse trailing edge?
Verilog-1995 does not propagate this pulse. Verilog-2001 gives you the option.
noshowcancelled
specify
(inp => outp) = (6,3) ;
noshowcancelled outp ;
endspecify

showcancelled
specify
(inp => outp) = (6,3) ;
showcancelled outp ;
endspecify

outp

outp

outp
(delayed)

outp onevent
(delayed)
0 1 2 3 4 5 6 7 8

ondetect

0 1 2 3 4 5 6 7 8

Modeling Delay (VMD2)

22-27

Negative Pulse Detection


A delayed trailing edge delay that precedes the delayed leading edge delay constitutes a negative pulse.
The default simulator behavior is the "noshowcancelled" method. This method cancels the delayed
leading edge upon determining that the delayed trailing edge would precede it, and does not propagate
the rejected pulse.
You can specify the "showcancelled" method for specific module outputs. This method transitions the
preceding trailing edge to the X state, and the following leading edge from the X state, and does
propagate this X-state pulse.
You can specify either the on-event or the on-detect method of pulse filtering for this X-state pulse.

Verilog Application Workshop

22-28

Intra-Assignment Delay
// model of flip flop with timing
reg [3:0] q;
always @ (posedge clock)
#5 q1 <= d; // simple delay

Procedural delay cannot acceptably


model hardware delays:
delay make assignment
meanwhile miss next trigger

// model of flip flop with


// intra assignment delay timing
reg [3:0] q2;
always @ (posedge clock)
q2 <= #5 d;

Use intra-assignment delays to model


clock-to-out delays
sample schedule assignment
continue executing

#20
#5

Acceptable and faster executing


(but still less accurate) than
module path delays

clock
d
q1
q2

Modeling Delay (VMD2)

22-29

Intra-Assignment Delay
The problem with the q1 variable is that it is assigned 5 time units after the rising edge of the clock. The
d input to the flip flop may change during this period after the rising edge of the clock.
The intra assignment delay more accurately models this by sampling the d input at the clock edge and
assigning q2 with the sampled version after 5 time units.

Verilog Application Workshop

22-30

Intra-Assignment Delay: Blocking and Non-Blocking


Blocking assignments still need to block,
even if they are placed intra-assignment.
a
= #1 b;
sample block update

a <= #1 b;
sample schedule update continue

$monitor($time,"a=%b b=%b c=%b d=%b",a,b,c,d);

0
2
10
12

a=x
a=x
a=1
a=1

b=x
b=x
b=x
b=0

c=x
c=x
c=1
c=1

d=x
d=0
d=0
d=0

module delay_test;
reg a,b,c,d;
initial
begin
a = #10 1b1;
b = #2 1b0;
end
initial
begin
c <= #10 1b1;
d <= #2 1b0;
end
endmodule

Modeling Delay (VMD2)

22-31

Intra-Assignment Delay: Blocking and Non-Blocking


Intra-assignment delay using the blocking assignment will wait for the assignment to be made before
continuing with the next assignment. Hence the variable a is assigned at time 10 and the variable b is
assigned 2 time units later.
The flow of the procedure is blocked until the assignment is made- hence the term blocking assignment.
Using the non-blocking assignment, the assignment is scheduled to occur at the relevant time. Hence
variable c is scheduled to be updated at time 10 and variable d is scheduled to be updated at time 2. The
flow of the procedure is not blocked. Hence the term non-blocking.

Verilog Application Workshop

22-32

Annotating SDF Timing Data


The standard delay format (SDF, IEEE Std. 1497) is a standard format for providing
timing data for specparam values, module path and interconnect delays, timing checks,
and timing constraints (simulation tools do not use the timing constraints).
Timing delay calculators generate SDF data using estimates of the parasitics of an
ASIC layout. Fully routed ASICs provide the best estimates.
The Verilog standard provides a means to annotate this data onto a Verilog design:
$sdf_annotate (
"sdf_file"

(required) SDF file

module_instance (optional) annotation scope


"config_file"

(optional) configuration file

"log_file"

(optional) log file

"mtm_spec"

(optional) which factored data to annotate


MINIMUM TYPICAL MAXIMUM TOOL_CONTROL

"scale_factors" (optional) scale multipliers in min:typ:max format


"scale_type" ); (optional) what to apply scale factors to:
FROM_MINIMUM FROM_TYPICAL FROM_MAXIMUM FROM_MTM

Modeling Delay (VMD2)

22-33

Annotating SDF Timing Data


The SDF standard describes the configuration file.
Only the SDF filename argument is required. You can omit any or all subsequent arguments. You can
replace omitted arguments with comma placeholders to provide later arguments.
The annotator applies the scale factors (by default 1:1:1) to the specified scale type (by default the
respective min:typ:max SDF data) and then annotates the selected set of factored data (by default those
the user has chosen to use upon tool invocation).
You can alternatively define most of these options in the configuration file.
You can invoke $sdf_annotate as many times as you want, for example with different files for
different scopes.

Verilog Application Workshop

22-34

Review
1. Model the following circuit:
1.2:1.6:1.8
a
1.1:1.6:1.7
b

c
0.6

2. Give the code for the following circuit. Do you see any problems with such a circuit
from (i) a simulation point of view (ii) a synthesis point of view? Can you fix them?
4b0001

4
4

Modeling Delay (VMD2)

22-35

Review

Verilog Application Workshop

22-36

Timing Checks
TC1

23-1

Notes

Verilog Application Workshop

23-2

Timing Checks
Objectives:
Following study of this section, you should be able to specify timing checks for your
module definitions.

Timing Checks (TC1)

23-3

Timing Checks
This section provides an overview of the Verilog timing checks as described by the year 2001 standard.
It provides sufficient technical detail to enable you to incorporate the timing checks into your module
definitions.

Verilog Application Workshop

23-4

Overview
You use timing checks to verify that signals obey timing constraints.

Stability window checks


$setup
$hold
$setuphold
$recovery
$removal
$recrem

Setup data sufficiently before active clock edge


Hold data sufficiently after active clock edge
Combined setup and hold check permits a negative time limit
Remove asynchronous control sufficiently before active clock edge
Remove asynchronous control sufficiently after active clock edge
Combined recovery and removal check permits a negative time limit

Event interval checks


$nochange
$width
$period
$skew
$timeskew
$fullskew

Second signal does not change while first signal in specified state
Pulse width is sufficiently long
Period is sufficiently long
Time between two signals is sufficiently short
Time between two signals is sufficiently short (variation)
Time between two signals is sufficiently short (variation)
Timing Checks (TC1)

23-5

Overview
You use timing checks to verify that signals obey timing constraints. All timing checks are variations of
the same theme: the simulator notes the simulation time of the reference event, and then at the data event
verifies that the time between the events is either sufficient or not too much.
You place the timing check within a specify block and provide arguments to specify the reference event,
data event, and time limit(s). Timing checks start with the ($) character, but are not system tasks. You
cannot place system tasks within a specify block.
The events are value transitions of port signals. You can further qualify the transitions with the posedge
or negedge keywords. Most timing checks also accept edge descriptors such as edge 01. You can
conditionalize the events using the &&& operator and a conditionalizing scalar expression. Some timing
checks alternatively accept conditionalizing expressions as a separate argument. Some timing checks
accept a negative time limit.
For each timing check, you can optionally provide the name of a reg that the simulator toggles each time
it violates the timing check. You can use this "notifier" to trigger procedural blocks containing your
response (if any) to the timing check violation. Almost all ASIC vendors use notifiers in their simulation
libraries to cause the output of the UDP modeling the synchronous device to transition to the X state.
Timing checks are of two main groups: with the first group, you verify that one signal is stable with
respect to another signal for some specified time window; with the second group, you verify that the time
interval between two transitions is either sufficient or not too much.

Verilog Application Workshop

23-6

Stability Window Checks


Stability window checks all do approximately the same thing:
1. Start a check window at the occurrence of a reference event
2. End the check window some specified simulation time later
3. Report a data event that occurs within the check window

Timing Checks (TC1)

23-7

Stability Window Checks

Verilog Application Workshop

23-8

Setup and Hold Checks


$setup ( data_event , reference_event , timing_check_limit [ , notify_reg ] ) ;
Transition data sufficiently before active clock edge

A violation is: data < clock < data + limit


data
setup
clk
$setup ( data, posedge clk, 6 ) ;

$hold ( reference_event , data_event , timing_check_limit [ , notify_reg ] ) ;


Hold data sufficiently after active clock edge

A violation is: clock <= data < clock + limit


data
hold
clk
$hold ( posedge clk, data, 2 ) ;
Timing Checks (TC1)

23-9

Setup and Hold Checks


The setup check verifies that data is set stable sufficiently before an active clock edge. Note that both
endpoints of the time window are not part of the violation region. A setup check will not report a
violation for simultaneous clock and data. A setup check cannot report a violation for a limit of zero.
The hold check verifies that data is held stable sufficiently after the active clock edge. Note that only the
exact end of the time window is not part of the violation region. A hold check will report a violation for
simultaneous clock and data. A hold check cannot report a violation for a limit of zero.
You can qualify either or both events with the posedge or negedge keywords or the edge control
specifiers.
You can conditionalize either or both events with the &&& operator and a scalar expression.

Verilog Application Workshop

23-10

Setup and Hold Checks


$setuphold (data_event , reference_event , timing_check_limit , timing_check_limit [ , [
notify_reg [ , [ stamptime_condition ] [ , [ checktime_condition ] [ , [ delayed_reference
] [ , delayed_data ] ] ] ] ] ) ;
Combines setup and hold checks

Permits a negative setup limit or a negative hold limit

Accepts separate conditionalization arguments

A setup violation (if both limits positive) is: data < clock <= data + limit

A hold violation (if both limits positive) is: clock <= data < clock + limit
data
setuphold
clk
$setuphold ( posedge clk, data, 6, 2 ) ;
data
setuphold
clk
$setuphold ( posedge clk, data, 9, -1,,,, data_dly ) ;
Timing Checks (TC1)

23-11

Setup and Hold Checks


The $setuphold system task combines setup and hold checks, and also:

Permits one or the other limit (but not both) to be negative if the sum of these limits is greater than
zero by more than the simulation precision. The simulator adjusts the negative limit upward to
zero plus the simulation precision, adds the same amount to the other limit, and delays the
appropriate reference signal or data signal, so that it can perform the check using positive limits.
You can (and should) provide signal names for the delayed versions, and drive internal module
logic with the delayed versions, to enable correct functional operation of your design.

Permits you to conditionalize the stamptime (reference) event and/or checktime (data) event using
arguments separate from the event description.

Note that the exact start of the setup window and the exact end of the hold window are not part of the
violation region. A $setuphold check will report a violation for simultaneous clock and data if both limits
are positive. A $setuphold check cannot report a violation when both limits are zero.

Verilog Application Workshop

23-12

Recovery and Removal Checks


$recovery ( reference_event , data_event , timing_check_limit [ , notify_reg ] ) ;
Set asynchronous control inactive sufficiently before active clock edge

A violation is: control <= clock < control + limit


rst_
recovery
clk

$recovery ( posedge rst_, posedge clk, 3 ) ;

$removal ( reference_event , data_event , timing_check_limit [ , notify_reg ] ) ;


Hold asynchronous control active sufficiently after active clock edge

A violation is: clock < control < clock + limit


rst_
removal
clk

$removal ( posedge rst_, posedge clk, 4 ) ;


Timing Checks (TC1)

23-13

Recovery and Removal Checks


The recovery check verifies that the model recovers from an asynchronous control sufficiently before an
active clock edge. Note that the exact end of the time window is not part of the violation region. A
recovery check will report a violation for simultaneous clock and control. A recovery check cannot report
a violation for a limit of zero.
The removal check verifies that the asynchronous control is removed sufficiently after the active clock
edge. Note that both endpoints of the time window are not part of the violation region. A removal check
will not report a violation for simultaneous clock and control. A removal check cannot report a violation
for a limit of zero.
You can qualify either or both events with the posedge or negedge keywords or the edge control
specifiers.
You can conditionalize either or both events with the &&& operator and a scalar expression.

Verilog Application Workshop

23-14

Recovery and Removal Checks


$recrem ( reference_event , data_event , timing_check_limit , timing_check_limit [ , [
notify_reg ] [ , [ stamptime_condition ] [ , [ checktime_condition ] [ , [ delayed_reference
] [ , delayed_data ] ] ] ] ] ) ;
Combines recovery and removal checks

Permits a negative recovery limit or a negative removal limit

Accepts separate conditionalization arguments

A recovery violation (if both limits positive) is: control <= clock < control + limit

A removal violation (if both limits positive) is: clock < control <= clock + limit
rst_
recrem
clk

$recrem ( posedge rst_, posedge clk, 3, 4 ) ;


rst_
recrem
clk

$recrem ( posedge rst_, posedge clk, 8, -1,,,, rst_dly_ ) ;


Timing Checks (TC1)

23-15

Recovery and Removal Checks


The $recrem system task combines recovery and removal checks, and also:

Permits one or the other limit (but not both) to be negative if the sum of these limits is greater than
zero by more than the simulation precision. The simulator adjusts the negative limit upward to
zero plus the simulation precision, adds the same amount to the other limit, and delays the
appropriate reference signal or data signal, so that it can perform the check using positive limits.
You can (and should) provide signal names for the delayed versions, and drive internal module
logic with the delayed versions, to enable correct functional operation of your design.

Permits you to conditionalize the stamptime (reference) event and/or checktime (data) event using
arguments separate from the event description.

Note that the exact start of the recovery window and the exact end of the removal window are part of the
violation region. A $recrem check will report a violation for simultaneous clock and control if both limits
are positive. A $recrem check cannot report a violation when both limits are zero.

Verilog Application Workshop

23-16

Event Interval Checks


Event interval checks all do approximately the same thing:
1. Start a check window at the occurrence of a first event
2. End the check window at the occurrence of a second event
3. Report a violation if:
A third event occurs during the window ($nochange)
The window is too narrow ($width, $period)
The window is too wide ($skew, $timeskew, $fullskew)

Timing Checks (TC1)

23-17

Event Interval Checks

Verilog Application Workshop

23-18

Nochange Checks
$nochange ( reference_event , data_event , start_edge_offset , end_edge_offset [ ,
notify_reg ] ) ;
Data is stable while reference is at specified state

A violation is:
(reference leading edge - offset) < data < (reference trailing edge + offset)
clk
nochange
rst_
$nochange ( posedge clk, rst_, 0, 0 ) ;

Timing Checks (TC1)

23-19

Nochange Checks
The $nochange timing check reports a timing violation if the data event occurs during the specified level
of the reference signal. You can increase (with positive offsets) or decrease (with negative offsets) either
or both edges of that time window. Note that both endpoints of the time window are not part of the
violation region.
You can qualify the reference event with the posedge or negedge keywords, but not with the edge control
specifiers, for example not edge 01.
You can qualify the data event with the posedge or negedge keywords or the edge control specifiers.
You can conditionalize either or both events with the &&& operator and a scalar expression.

Verilog Application Workshop

23-20

Width and Period Checks


$width ( controlled_reference_event , timing_check_limit [ , threshold, notify_reg ] ) ;
Second edge (of opposite type) occurs not too soon after first edge

A violation is: threshold < width < limit


rst_
width
$width ( negedge rst_, 6, 0, nreg ) ;

$period ( controlled_reference_event , timing_check_limit [ , [ notify_reg ] ] ) ;


Second edge (of same type) occurs not too soon after first edge

A violation is: period < limit


clk
period
$period ( posedge clk, 15 ) ;

Timing Checks (TC1)

23-21

Width and Period Checks


You must provide the $width check a reference event that is an edge. You can provide the posedge or
negedge qualifiers or an edge specifier such as edge 01. Note that the threshold is by default 0, but if you
provide a notifier argument, you must also provide a threshold argument (even if it is 0).
You must provide the $period check a reference event that is an edge. You can provide the posedge or
negedge qualifiers or an edge specifier such as edge 01.
You can conditionalize either or both events with the &&& operator and a scalar expression.

Verilog Application Workshop

23-22

Skew Checks
$skew ( reference_event , data_event , timing_check_limit [ , notify_reg ] ) ;
Data event occurs sufficiently soon after reference event
Resets waiting period with each new reference event

Violation is: (reference + limit) < data

Reports violation each time data event occurs after limit


Does not report violation if data event never occurs!
clk
skew
clka
$skew ( posedge clk, posedge clka, 1 ) ;

Timing Checks (TC1)

23-23

Skew Checks
You can qualify either or both events with the posedge or negedge keywords or the edge control
specifiers.
You can conditionalize either or both events with the &&& operator and a scalar expression.

Verilog Application Workshop

23-24

Skew Checks
$timeskew ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] [ , [
event_based_flag ] [ , remain_active_flag ] ] ] ) ;
Report violation once at limit if data event did not occur

With event_based_flag: Report violation once if data event occurs after limit

With remain_active_flag: Report all event-based violations

With both flags: Exactly like $skew


clk
skew
clka
$timeskew ( posedge clk, posedge clka, 1 ) ;

$fullskew ( reference_event , data_event , timing_check_limit , timing_check_limit [ , [


notify_reg ] [ , [ event_based_flag ] [ , remain_active_flag ] ] ] ) ;
Like $timeskew but either event can be first and each has its own skew limit to the
second event

Timing Checks (TC1)

23-25

Skew Checks
With the event_based_flag and remain_active_flag both set, the $timeskew check is identical to the
$skew check.
You can qualify either or both events with the posedge or negedge keywords or the edge control
specifiers.
You can conditionalize either or both events with the &&& operator and a scalar expression.

Verilog Application Workshop

23-26

Example JKFF
primitive UDP_JKFF ( output
reg Q, input J, input K, input
CLK, input RSTN, input SETN,
input FLAG ) ;
table
// J K C R S F : s : out
? ? ? 0 ? ? : ? : 0 ;
? ? ? 1 0 ? : ? : 1 ;
? ? ? p 1 ? : ? : - ;
0 0 p 1 1 ? : ? : - ;
0 1 r 1 1 ? : ? : 0 ;
0 1 p 1 1 ? : 0 : - ;
1 0 r 1 1 ? : ? : 1 ;
1 0 p 1 1 ? : 1 : - ;
1 1 r 1 1 ? : 0 : 1 ;
1 1 r 1 1 ? : 1 : 0 ;
? ? n ? ? ? : ? : - ;
* ? ? ? ? ? : ? : - ;
? * ? ? ? ? : ? : - ;
? ? ? ? ? * : ? : X ;
endtable
endprimitive

module jkff ( output Q, output QN,


input J, input K, input CLK , input
RSTN, input SETN ) ;
reg flag ;
UDP_JKFF ( qt, J, K, CLK, RSTN,
SETN, flag ) ;
buf ( Q, qt ) ;
not ( QN, qt ) ;
wire condition = (~RSTN & ~SETN) ;
specify
...
endspecify
endmodule

Timing Checks (TC1)

23-27

Example JKFF
The module definition separately buffers the Q and QN outputs for two reasons:

A UDP can have only one output, so you must either instantiate two UDPs or generate the second
output yourself.

You separately buffer outputs to ensure that you can provide each output with a path delay
independent of other path delays.

Verilog Application Workshop

23-28

Example JKFF
specify
specparam tPD = 12:15:20 ;
specparam tPERIOD = 33 ;
specparam tWCLK0 = 20 ;
specparam tWRSTN = 25 ;
specparam tWSETN = 25 ;
specparam tSU
= 20 ;
specparam tSURSTN = 20 ;
specparam tSUSETN = 25 ;
specparam tH
= 2 ;
(CLK,RSTN,SETN *> Q,QN) = tPD ;
$period ( posedge CLK, tPERIOD, flag ) ;
$width ( negedge CLK, tWCLK0, 0, flag ) ;
$width ( negedge RSTN, tWRSTN, 0, flag ) ;
$width ( negedge SETN, tWSETN, 0, flag ) ;
$setuphold ( posedge CLK &&& condition, J &&& condition,
flag ) ;
$setuphold ( posedge CLK &&& condition, K &&& condition,
flag ) ;
$recovery ( posedge RSTN, posedge CLK, tSURSTN, flag )
$recovery ( posedge SETN, posedge CLK, tSUSETN, flag )
endspecify

tSU, tH,
tSU, tH,
;
;

Timing Checks (TC1)

23-29

Example JKFF
You can provide specparams with either single values or values in the min:typ:max format.
Do not confuse a module timing path with a functional path. For convenience this specify block defines
the timing path (CLK,RSTN,SETN *> Q,QN), but of course no functional paths exist originating at
negedge CLK or posedge SETN.

Verilog Application Workshop

23-30

Summary
You should now be able to specify timing checks for your module definitions:

Stability window checks


$setup
$hold
$setuphold
$recovery
$removal
$recrem

Setup data sufficiently before active clock edge


Hold data sufficiently after active clock edge
Combined setup and hold check permits a negative time limit
Remove asynchronous control sufficiently before active clock edge
Remove asynchronous control sufficiently after active clock edge
Combined recovery and removal check permits a negative time limit

Event interval checks


$nochange
$width
$period
$skew
$timeskew
$fullskew

Second signal does not change while first signal in specified state
Pulse width is sufficiently long
Period is sufficiently long
Time between two signals is sufficiently short
Time between two signals is sufficiently short (variation)
Time between two signals is sufficiently short (variation)
Timing Checks (TC1)

23-31

Summary

Verilog Application Workshop

23-32

Review
1. Which timing check(s) accept a negative limit?
2. Can you qualify all events in all timing checks with edge specifiers such as edge 01?
3. For which timing check(s) must you always qualify events?
4. When does $skew report a violation?

Timing Checks (TC1)

23-33

Review
1. The $setuphold and $recrem timing checks accept one negative limit. The other limit must be
sufficiently positive that the sum of the two limits exceeds zero by more than the simulation
precision.
2. You cannot qualify the reference event of the $nochange check with edge specifiers such as edge
01. You can qualify this event with the posedge or negedge keywords. You can use edge
specifiers to qualify all other events in all other timing checks.
3. For the $width and $period timing checks you must provide qualified events.
4. The $skew timing check reports a violation each time the data event occurs more than the limit
after the most recent reference event. It does not report a violation if the data event never occurs.

Verilog Application Workshop

23-34

This page left intentionally blank

Modeling Memories
VMM2

24-1

Notes

Verilog Application Workshop

24-2

Aims and Topics

Aims
Issues with modeling memories in Verilog

Topics
Simple ROM and RAM models
Scalable memory models
Using bidirectional ports
Learn how to model a bidirectional port in Verilog

Modeling Memories (VMM2)

24-3

Terms and Definitions


LSB

Least significant bit.

MSB

Most significant bit.

Verilog Application Workshop

24-4

Modeling a Memory Device


A memory device must do two things:

Declare a memory of appropriate size.

Provide some level of access to its contents, such as:


Read only
Read and write
Write and simultaneous read
Multiple reads, simultaneous to a single write
Multiple simultaneous reads and writes, with some method of ensuring
consistency

Modeling Memories (VMM2)

24-5

Modeling a Memory Device

Verilog Application Workshop

24-6

Simple ROM Model


my_rom_data
timescale 1ns/10ps
module myrom (
input
enb_,
input
[3:0] addr,
output reg [3:0] data
);
reg [3:0] mem [0:15];
initial
$readmemb ("my_rom_data", mem);
always @(addr or enb_)
if (enb_ == 0)
data = mem[addr];

0000
0101
1100
0011
1101
0010
0011
1111
1000
1001
1000
0001
1101
1010
0001
1101

endmodule
ROM data is stored
in a separate file
Modeling Memories (VMM2)

24-7

Simple ROM Model


The ROM model shown above uses a one dimensional array of reg vectors. The data for the ROM is
read from a separate file, shown on the right. This common method of storing ROM data keeps it separate
from the ROM model itself. The $readmemb task is detailed in the Simulation Control chapter.

Verilog Application Workshop

24-8

Simple RAM Model


module mymem (
input read, write,
input [3:0] addr,
inout [3:0] data
);
reg [3:0] mem [0:15];
//write
always @(posedge write)
mem[addr] = data;

4 X 16 reg array

Write on positive edge of write

//read
assign data = (read ? memory[addr] : 4bz);

Drive read data


when read true

endmodule

Note: Simulation models for internal RAM/ROM usually supplied by technology vendor

Modeling Memories (VMM2)

24-9

Simple RAM Model


RAM models are slightly more complicated than ROM models because they must have both read and
write capability, usually with the same data bus. The modeling technique must accommodate the
bidirectional bus. In the example above, when the read port is not enabled, the model no longer drives
the bus, causing it to revert to a high impedance Z value if the bus is not driven by a write value. This
avoids conflict when writing to the RAM.

Verilog Application Workshop

24-10

Scalable Memory Device


You can scale memory models with the use of parameters.
module scalable_ROM
#(
parameter integer wordsize = 8, // width
parameter integer addrsize = 8 // depth
)(
input [addrsize:1] addr,
output [wordsize:1] data
);
Verilog-2001 power operator
reg [wordsize:1] mem [0:2**addrsize-1];
assign data = mem[addr];
endmodule

Modeling Memories (VMM2)

24-11

Scalable Memory Device


This example illustrates how you can easily define a read-only memory device that you can parameterize
for word size and number of address bits.
This example declares the starting memory address zero instead of one because it addresses the memory
directly with the address line. You can alternatively start the memory at address one and address it as
follows:
reg [wordsize:1] mem [1 : words]; // memory starts at word 1
// address must be incremented to address all words in memory
assign data = mem[addr + 1];

Verilog Application Workshop

24-12

Loading a Memory
You need to preload a ROM and perhaps initialize a RAM.
You can do this from an external file...
$readmemb("mem_file.txt", mema)

Or using a loop
for (i=0; i < memsize; i = i+1)
mema[i] = {wordsize{1b0}}

Modeling Memories (VMM2)

24-13

Loading a Memory
You can load a ROM or RAM with data by using a $readmem task. For a ROM, this data would be the
actual content at startup. For a RAM, you can initialize the device, saving valuable simulation time by
not requiring separate write cycles for each loaded word.

Verilog Application Workshop

24-14

Using Bidirectional Ports


Declare bidirectional ports using the inout keyword.

Always connect your inout port to a net (not a register)

Drive an inout port from only one direction at a time


Design logic around the inout port to avoid bus contention

module mymem (
input read, write,
input [3:0] addr,
inout [3:0] data
);
...
assign data = (read ? memory[addr] : 4bz);
...

Modeling Memories (VMM2)

24-15

Using Bidirectional Ports


You declare an inout port to enable driving data from either direction. The port data type defaults to
the net data type. You cannot directly connect a register data type to the inout port on either side of the
module boundary, so the simulator can determine the resulting value of multiple drivers of the net. You
cannot make a procedural assignment to a net, but you can continuously assign a register data type to it
outside of a procedural block, or connect it to a primitive.
You must design logic around the inout port to ensure proper operation. For example, you cannot drive
write data onto the bidirectional data bus of a RAM model while you are using the bus to read RAM data.
When using the port as an input, you must disable the output logic.

Verilog Application Workshop

24-16

Bidirectional Ports Using Primitives


en_a_b
b1

bus_b

bus_a
b2

en_b_a
When en_a_b = 1,
primitive b1 is
enabled and the
value on bus_a is
transferred to bus_b

module bus_xcvr (
input en_a_b, en_b_a,
inout bus_a, bus_b
);
bufif1 b1 (bus_b, bus_a, en_a_b);
bufif1 b2 (bus_a, bus_b, en_b_a);

When en_b_a = 1,
primitive b2 is
enabled and the
value on bus_b is
transferred to bus_a

endmodule

Modeling Memories (VMM2)

24-17

Bidirectional Ports Using Primitives


The en_a_b and en_b_a inputs control the enabling and disabling of the bufif1 primitives.
If you assert both controls simultaneously, you will get unpredictable results.
Truth table for conditional primitive:enable

data

bufif1

Verilog Application Workshop

24-18

Bidirectional Ports Using Continuous Assignment


en_a_b
b1

bus_b

bus_a
b2

en_b_a

module bus_xcvr (
input en_a_b, en_b_a,
inout bus_a, bus_b
);
assign bus_b = en_a_b ? bus_a : bz;
assign bus_a = en_b_a ? bus_b : bz;
endmodule

When en_b_a = 1,
this assignment
drives the value of
bus_b onto bus_a
When en_a_b = 1,
this assignment
drives the value of
bus_a onto bus_b

Modeling Memories (VMM2)

24-19

Bidirectional Ports Using Continuous Assignments


The en_a_b and en_b_a control inputs select the values driven onto bus_b and bus_a by the
continuous assignments. Each continuous assignment drives either the value of the opposite bus, or a
Hi-Z. The simulator resolves the resulting value of multiple drivers of a net.
If you assert both controls simultaneously, you will get unpredictable results.

Verilog Application Workshop

24-20

Modeling Memory Ports


Test Bench

RAM cell
rd
databus
data
reg
wr

module ram_cell (
input rd, wr,
inout databus
);
reg datareg;

When rd = 1 the
value of datareg is
assigned to databus

assign databus = rd ? datareg : bz;


always @(negedge wr)
datareg <= databus;

When wr deasserts,
the value of databus
is written to datareg

endmodule

Modeling Memories (VMM2)

24-21

Modeling Memory Ports


This memory cell stores data on the falling edge of wr. The module using this memory cell can drive
write data onto the data bus while wr is high. You must assure that the write data persists long enough
for the write to take place.
The memory cell drives read data onto the databus whenever rd is high. As this is a single-port memory
model, the results of asserting wr and rd at the same time are unpredictable.

Verilog Application Workshop

24-22

Review
1. What Verilog construct do you use to define a memory array?
2. How can you load a memory with data?
3. How can you send values through a bidirectional port (an inout)?
4. Given the RAM cell below, write a simple testbench to exercise the design.
module ram_cell (
input rd, wr,
inout databus
);
reg datareg;
assign databus = rd ? datareg : bz;
always @(negedge wr)
datareg <= databus;
endmodule

Modeling Memories (VMM2)

24-23

Review

Verilog Application Workshop

24-24

User Defined Primitives


VDP2

A-1

Notes

Verilog Application Workshop

A-2

Aims and Topics


Aims

Learn how to build logic using user-defined primitives.

Topics

Understand Verilog composite libraries.

Understand functional modeling of ASIC libraries.

Learn about the use of UDPs in ASIC library models.

Understand how to model timing in ASIC libraries.

(VDP2)

A-3

Terms and Definitions


UDP

User-Defined Primitives behave just like a built-in Verilog


primitive. You specify the functionality with a table.

Verilog Application Workshop

A-4

What is a UDP?
Verilog has over two dozen gate level primitives for modeling structural logic. In addition
to these primitives Verilog has user defined primitives (UDPs) that extend the built in
primitives by allowing you to define logic in tabular format.
UDPs are useful for AISC library cell design as well as small scale chip and medium scale
chip design.
You can use UDPs to augment the set of predefined primitive elements.

UDPs are self contained, they do not instantiate other modules.

UDPs can represent sequential as well as combinational elements.

UDP behavior is described in a truth table.

To use a UDP, you instantiate like a built-in primitive

(VDP2)

A-5

What is a UDP?

UDPs permit the user to augment the set of predefined primitive elements.

UDPs are a very compact way of representing logic.

UDPs can reduce pessimism because an x on an input doesnt automatically translate to an x on


an output as it does with built in primitives.

UDPs can represent sequential as well as combinational elements.

UDP behavior is described in a truth table.

A UDP can replace the logic of many primitives. Thus, the simulation time and the memory
requirements can be reduced significantly compared to running the separate primitives.
Behavioral models of the same logic may be even faster depending on the simulator.

Verilog Application Workshop

A-6

UDP Features

UDPs can have only one output.

UDPs can have 1 to 10 inputs.

All ports must be scalar and no bidirectional ports are allowed.

The Z logic value is not supported.

The output port must be listed first in the port list.

The UDP output terminal can be initialized to a known value at the start of
simulation.

UDPs cannot be synthesized.

(VDP2)

A-7

UDP Features

UDPs can have only one output. Thus, if the functionality requires more than one output, then the
additional primitives need to be connected to the output of the UDP, or several UDPs can be used
together.

UDPs can have 1 to 10 inputs. However, the memory requirements increase dramatically as the
number of inputs increases from 5. The table below shows the memory requirement per definition
for the number of inputs.
# inputs

Memory (k bytes)

1-5

<1

17

56

187

10

623

All ports must be scalar and no bidirectional ports are allowed.

The z logic value is not supported. It is mapped to x.

The output terminal of a sequential UDP can be initialized to a known value at the start of
simulation using the initial statement.

Verilog Application Workshop

A-8

Combinational Example: 2-1 Multiplexer


This is the
name of the
primitive.

The output port


must be the first
port.

primitive multiplexer (o, a, b, s);


output o;
input a, b, s;
table
// a b s : o
0 ? 1 : 0;
1 ? 1 : 1;
? 0 0 : 0;
? 1 0 : 1;
These entries
0 0 x : 0;
reduce
1 1 x : 1;
pessimism.
endtable
endprimitive

UDP definitions occur outside of a module.

The output becomes x for any input combination not specified in the table.

(VDP2)

A-9

Combinational Example: 2-1 Multiplexer

The ? in the table represents iteration over 0, 1, or x logic values.

The first two entries say that if s = 1 then, irrespective of the value of the input b, the value on
the output o will be the same as that of input a.

The next two entries say that if s = 0 then, irrespective of the value of the input a, the value on
the output o will be the same as that of input b.

The last two entries are added to reduce pessimism. We say that if both the inputs, a and b, have
the same logic value, then even if sel = x, the output o will have the same value as inputs a or
b. This behavior cannot be modeled using Verilog built-in primitives.

Verilog Application Workshop

A-10

Combinational Example: Full Adder


You can implement the full adder with only two combinational UDPs.
Cin
A
B

G1

Sum

G2

G4

G5

Cin
A
B

table

a b ci : co
1 1 ? : 1;
1 ? 1 : 1;
? 1 1 : 1;
0 0 ? : 0;
0 ? 0 : 0;
? 0 0 : 0;

endtable
endprimitive

Sum

U_ADDR2_C

Cout

Cout

G3

// FULL ADDER CARRY-OUT TERM


primitive u_addr2_c (co,a,b,ci);
output co;
input a, b, ci;

U_ADDR2_S

// FULL ADDER SUM TERM


primitive u_addr2_s (s,a,b,ci);
output s;
input a, b, ci;
table // a b
0
0
0
0
1
1
1
1
endtable
endprimitive

ci
0
0
1
1
0
0
1
1

:
0
1
0
1
0
1
0
1

s
:
:
:
:
:
:
:
:

0;
1;
1;
0;
1;
0;
0;
1;

(VDP2) A-11

Combinational Example: Full Adder


The full adder can be implemented using only two combinational UDPs instead of five Verilog built-in
primitives.

For a large number of instantiations of the full adder, the memory requirements are greatly
reduced.

The number of events greatly decreases. Using built-in primitives, events propagate through three
primitives to the carry-out. Using UDPs, an event must propagate through only one primitive.

A ? symbolizes a 0, 1, or x.

Verilog Application Workshop

A-12

Level-Sensitive Sequential Example: Latch


primitive latch (q, clock, data);
output q;
reg q;
input clock, data;
initial q = 1b1;
table
// clock data state next_state
0
1 : ? :
1 ;
0
0 : ? :
0 ;
1
? : ? :
- ;
endtable
endprimitive

Note the use of a


register for storage.
The output is
initialized to 1b1.

Notice the additional field


used to specify a next state.
The ? is used to represent
dont care conditions in
the inputs and current state.

(VDP2) A-13

Level-Sensitive Sequential Example: Latch

The latch behaves as follows:


When the clock input is 0, the value on the data input is transferred to the output.
When the clock input is 1, there is no change in the output.

A next state value of - means that there will be no change on the output.

The output must be declared as a reg to store the previous value.

The statement initial q = 1b1; is the sequential UDPs initialization statement. It causes
the output terminal of the UDP to have a value of 1 at the start of simulation.
This type of power-on initialization is rarely used in real components, but is useful for testing the
functionality of your UDP.

Verilog Application Workshop

A-14

Edge-Sensitive Sequential Example: D Flip-Flop


primitive d_edge_ff (q, clk, data);
output q;
input clk, data;
reg q;
table
// clk data state next
(01) 0 : ? : 0 ;
(01) 1 : ? : 1 ;
// reduce pessimism
(0x) 0 : 0 : - ;
(x1) 0 : 0 : - ;
(0x) 1 : 1 : - ;
(x1) 1 : 1 : - ;
// ignore inactive clock edge
(?0) ? : ? : - ;
(1x) ? : ? : - ;
//ignore data transitions
? (??) : ? : - ;
endtable
endprimitive

(VDP2) A-15

Edge-Sensitive Sequential Example: D Flip-Flop

The table has edge terms representing transitions on inputs.

At most, one input transition may be specified in any table entry statement.

If any input transitions are specified, all must be specified.

In each timestep, level entries take precedence over edge entries because they are processed last.

Verilog Application Workshop

A-16

Shorthand To Improve Readability


Verilog has symbols that can be used in the UDP table to improve readability.
Symbol

Interpretation

Explanation

0 or 1

(01)

0->1 transition

(10)

1->0 transition

(01) or (0x) or (x1)

Any positive edge, including unknowns

(10) or (1x) or (x0)

Any negative edge, including unknowns

(??)

Any known value

Any transition

(VDP2) A-17

Shorthand to Improve Readability


Edge-Sensitive sequential example - D flip-flop - rewritten using shorthand notation:primitive d_edge_ff_sh (q, clk, data);
output q;
input clk, data;
reg q;
table
// clk data state next
r
0 : ? : 0 ;
r
1 : ? : 1 ;
// reduce pessimism
p
0 : 0 : - ;
p
1 : 1 : - ;
// ignore inactive clock edge
n
? : ? : - ;
//ignore data transitions
?
* : ? : - ;
endtable
endprimitive

Verilog Application Workshop

A-18

Example: Flip-Flop With Synchronous Clear


primitive u_ff_p_cl (q, clk, data, clr);
input clk, data, clr;
output q;
reg q;
table
// clk data clr state next
r
? 1 : ? : 0 ;
r
0 ? : ? : 0 ;
r
1 0 : ? : 1 ;
// reduce pessimism
p
0 ? : 0 : - ;
p
? 1 : 0 : - ;
p
1 0 : 1 : - ;
// ignore inactive clock edge
n
? ? : ? : - ;
//ignore data transitions
?
* ? : ? : - ;
?
? * : ? : - ;
endtable
endprimitive

(VDP2) A-19

Example: Flip-Flop with Synchronous Clear

Verilog Application Workshop

A-20

Example: Subtractor Borrow-Out Term


This example produces the borrow-out term for a subtraction of a - b, based on the
values of a and b and borrow-in term bi, where bi = 0 implies the previous stage is
borrowing from this one. An output bo = 0 implies this stage will borrow from the next.
primitive u_sub_c
output bo;
input bi, a, b;
table
//a b bi bo
0 1 ? : 0; //
0 ? 0 : 0; //
? 1 0 : 0; //
1 0 ? : 1; //
? 0 1 : 1; //
1 ? 1 : 1; //
endtable
endprimitive

(bo, a, b, bi);

a<b, borrow
a<=b, bi=0, borrow
a<=b, bi=0, borrow
a>b, dont borrow
a>=b, bi=1, dont borrow
a>=b, bi=1, dont borrow

(VDP2) A-21

Example: Subtractor Borrow Out Term

Verilog Application Workshop

A-22

Example: Latch With Enable and Clear


This latch is transparent when the enable g is high. The clear cl is only enabled when g
is low.
primitive u_latch_cl (q, d, g, cl);
output q;
input d, g, cl;
reg q;
table
//d g cl q
qnext
0 1 ? : ? : 0; // transparent 0
1 1 ? : ? : 1; // transparent 1
? 0 1 : ? : 0; // clear
0 ? 1 : ? : 0; // pessimism
1 ? 0 : 1 : -; // pessimism
0 ? ? : 0 : -; // pessimism
? 0 0 : ? : -; // no change
endtable
endprimitive

(VDP2) A-23

Example: Latch With Enable and Clear

Verilog Application Workshop

A-24

Example: Register Using Notifier


The following example is of a positive edge-triggered D flip-flop with an asynchronous
clear, complete with timing checks and path delays. The model uses a UDP and inputs
into it the value of a notifier.
timescale 1 ns/1 ns
module dff_nt (q, ck, d, rst);
input ck, d, rst;
output q;
reg nt;
u_ffd_rb i1 (q, d, ck, rst, nt);
specify
specparam tsu = 2;
(posedge ck => q) = (2:3:4);
$setup (d, posedge ck, tsu, nt);
endspecify
endmodule

primitive u_ffd_rb (q,d,cp,rb,nt);


output q; reg q;
input d, cp, rb, nt;
table
//d cp rb nt : q : qnext
0 r ? ? : ? : 0; // clk 0
0 p ? ? : 0 : -;
1 r 1 ? : ? : 1; // clk 1
1 p 1 ? : 1 : -;
? ? 0 ? : ? : 0; // reset
? ? n ? : 0 : -;
? ? p ? : ? : -;
? n ? ? : ? : -; // clk
* ? ? ? : ? : -; // d
? ? ? * : ? : x; // notify
endtable
endprimitive

(VDP2) A-25

Example: Register Using Notifier

Verilog Application Workshop

A-26

Summary

UDPs allow you to create your own primitives to extend those built-in to Verilog
Behavior is defined using a table
UDPs are instantiated like a built-in primitive

They are a compact, efficient method of describing logic functions


Both combinational and sequential behavior can be described
UDPs are self-contained
Many built-in primitives can be replaced by a single UDP

There are some restrictions on using UDPs, including: There must be a separate UDP for every output
The Z value is not supported, hence UDP ports cannot be bi-directional
UDPs are not synthesizeable

(VDP2) A-27

Summary

Verilog Application Workshop

A-28

Review Answers
QVA2

B-1

Notes

Verilog Application Workshop

B-2

Verilog Application
1. What is Verilog?
2. How is Verilog implementational independent and why is this an advantage?
3. What level of Verilog is used in :
a. Testbenches
b. Synthesizable design
c. Net list

(QVA2)

B-3

Verilog Application
1. Verilog is a Hardware Description Language (HDL) - a programming language with special
constructs for modeling hardware, such as timing; abstraction; serial and concurrent behavior.
2. Verilog is implementational independent because behavioral and RTL descriptions are not
specific to a particular technology or vendor. The actual technology for the implementation of the
design does not need to be specified until an RTL description is synthesized.
3.
a. Behavioral level Verilog is used in testbenches
b. Register Transfer Level (RTL) Verilog is used in synthesizable design
c. Structural level Verilog is used in net lists

Verilog Application Workshop

B-4

Verilog Language Introduction


1. What is the basic building block of a Verilog design?
2. How is data passed between Verilog procedures?
3. When compiling a set of Verilog files, what is normally compiled first?
4. Write the code to instantiate the following module:

ALU1
data
ac_out
opcode
clock
reset

ALU
a_in
y_out
b_in
op_in
z_out
clk
rst

alu__out
zero

(QVA2)

B-5

Verilog Language Introduction


1. The module is the basic building block in Verilog.
2. Data is passed between procedures by variables.
3. When compiling a set of Verilog files, the file containing the testbench module is normally
compiled first, because this frequently contains compiler directives. These directives provide
additional information for the compiler/simulator which may affect the compilation of other files
in the set.
4. Instantiation using named port connection
ALU ALUl ( .a_in(data), .b_in(ac_out), .op_in(opcode),
.clk(clock), .rst(reset), .y_out(alu_out),
.z_out(zero) ) ;
Instantiation could also be made with ordered port connection, but this is less readable and more
error-prone than named port connection. Also in this case, we do not know the order in which the
ports of the module ALU are declared, so we cannot used ordered port connection.

Verilog Application Workshop

B-6

Data Types and Logic System


1. What is the primary difference between a net and a register type?
2. The AND operator is &. Code the following hardware using (i) a reg type (ii) a
wire type

a
c

3. How may bits wide is an integer type?


4. What are the 4 logic values in the Verilog Value System
5. Rewrite the following statement using a hexadecimal literal:aval = 8b11010011;

(QVA2)

B-7

Data Types and Logic System


1. A net type is continuously driven, behaving like a real wire driven by a logic gate. A register type,
however, represents storage, storing a value until a new one is assigned. In the language, register
types can only be assigned from procedural statements and net types can only be assigned from
continuous assignment statements.
2.

(i) reg type


reg b;
...
always @(a or c)
b = a & c;

(ii) wire type


wire b;
...
assign b = a & c;

wire b = a & c;

3. An integer type has 32 bits


4. The 4 values in the Verilog Value System are 1, 0, x, z.
5. aval = 8hd3;
Verilog Application Workshop

B-8

Verilog Operators
1. How many bits is the result of a logical && operation?
2. What is the difference between && and &, if any?
3. What must you do to values you replicate with the replication operator?
4. Given
regx = 4b0101;
what is the value of:bus = { 2{regx[3:1], {3{1b0, regx[0]}}} };
5. If regb is defined as a four bit signed number as shown below, give the code for
an arithmetic binary division by two. Hint: the sign bit (or most significant bit) must
remain intact.
reg [3:0] regb;

(QVA2)

B-9

Verilog Operators
1. The && logical operator reduces each operand to a single bit (1b0, 1b1 or 1bx), then ANDs
these bits together to give a single bit result.
2. & does a bit-by-bit AND of its operands, from LSB to MSB, producing a result which is the same
width as the longest operand.
&& reduces each operand to a single bit, then ANDs these bits to give a single bit result.
3. Operands to which you must apply the replication operator must be sized.
For example: {3{'b1}} is illegal because 'b1 is not sized, {3{1'b1}} is OK.
4. Given regx = 4b0101; then
bus = { 2{regx[3:1], {3{1b0, regx[0]}}} };
can be evaluated as follows:bus = { 2{3b010, {3{1b0, 1b1}}} };
bus = { 2{3b010, {3{2b01}}} };
bus = { 2{3b010, 6b010101} };
bus = { 2{9b010010101} };
bus = 18b010010101010010101;
5. A divide by 2 operation is equivalent to shifting regb right 1 bit. A shift operator could be used,
but this would insert a 0 in the MSB of the result, losing any sign information and making the
result always positive. We need to shift regb right 1 bit and maintain the value of the MSB:-

regb = {regb[3], regb[3:1]};

Verilog Application Workshop

B-10

Procedural Statements
1. If more than one condition of an if..else statement is true, which condition
takes priority?
2. Are if, case and for statements continuous or procedural statements?
3. Code the following conditional logic:-

a
b

mux
mux
1b0

1
0

<

ctrl
f

4b0110

(QVA2) B-11

Procedural Statements
1. if conditions are evaluated in the order in which they appear, so the first condition which evaluates
to true takes priority over

2. if, case and for statements are procedural statements.


3. The condition on f has the highest priority and so must be checked first, after which the condition
on ctrl is checked.
always @(a or b or c or f or ctrl)
if (f < 4'b0110)
d = a & b;
else if (ctrl)
d = 1'b0;
else
d = c;

Verilog Application Workshop

B-12

Continuous and Procedural Statements


1. What happens if multiple procedural assignments are made to the same variable?
2. Is a conditional assignment statement continuous, procedural or both?
3. Why should you not create combinational feedback loops?
4. Code the following hardware using (i) a continuous assignment and (ii) using a
procedure.

a[3:0]

d[4:0]

b[3:0]
0
c[4:0]
add

(QVA2) B-13

Continuous and Procedural Statements


1. When multiple procedural assignments are made to the same variable, assignments made later in
the execution of the procedure overwrite earlier assignments. Therefore the last assignment made
is the one which takes effect.
2. A conditional assignment can be used as both a procedural and continuous assignment statement.
3. A combinational feedback loop creates a delay-less infinite program loop in simulation, which
will "lock up" the simulator. In hardware terms, a combinational feedback loop is very dangerous
since the behavior depends upon the delay in the feedback loop, which may be impossible to
control or predict.
4.

i) Continuous assignment
assign d = (add == 1) ? a + b : c;

ii) Procedural assignment


always @(a or b or c or add)
d = (add == 1) ? a + b : c;

Verilog Application Workshop

B-14

Procedural Statements and the Simulation Cycle


1. Within the simulation cycle, what is one loop known as?
2. How is time advanced in a simulation?
3. Name three methods of timing control?
4. What is the difference in updating a variable when using:
i) A non-blocking assignment?
ii) A blocking assignment?
5. Where are compiler directives like timescale placed?

(QVA2) B-15

Procedural Statements and the Simulation Cycle


1. Within the simulation cycle, one loop is know as a delta cycle.
2. Time is advanced by the execution of a delay statement, which schedules an event to occur at a
future point in simulation time. When there is nothing else to do at the current simulation time,
the simulator advances time until a scheduled event is found.
3. Timing can be controlled by edge-triggers @(<variable>); delays #<delay> or
level-sensitive control wait(<expression>).
4.
i) In non-blocking assignment, variable update is scheduled, i.e. it occurs during the variable
update phase of the current simulation delta cycle.
ii) In blocking assignment, variable update happens immediately, in the procedure execution
phase of the current simulation delta cycle.
5. Compiler directives are placed before the module to which the directive is to be applied.

Verilog Application Workshop

B-16

Blocking and Non-Blocking Assignment


1. What is the primary difference between blocking and non-blocking assignments?
2. Where should non-blocking assignments used?
3. Where should blocking assignments used?
4. How should blocking assignments be used in sequential procedures?

(QVA2) B-17

Blocking and Non-Blocking Assignment


1. Non-blocking assignments are scheduled - they take effect during the variable update phase of the
current simulation delta cycle. Blocking assignments are immediate, taking place during the
procedure execution phase.
2. Non-blocking assignments should be used for describing synchronous logic.
3. Blocking assignment should be used for describing combinational logic.
4. Blocking assignment can be used in sequential procedures, but should only be used for temporary
variables, i.e. variables which are first written to and then read from in the course of the sequential
procedure execution.

Verilog Application Workshop

B-18

Verilog Coding Styles


1. What are the two types of procedure used for RTL code?
2. How do we infer registers for synthesis?
3. What is behavioral modeling used for?
4. How do you define the states for an FSM?

(QVA2) B-19

Verilog Coding Styles


1. In RTL code, procedures are either combinational or sequential.
2. Registers are inferred on all non-blocking assignments in a sequential procedure.
3. Behavioral modeling is used for testbench design and simulation models. Occasionally
behavioral modeling may be used for initial block/system modelling; algorithm development etc.
4. The states of a FSM are defined as constants:
localparam WAITING = 0, STATE1 = 1, STATE2 = 2,

Verilog Application Workshop

STATE3 = 3;

B-20

Verilog Sample Design


1. How can you change the value of a module parameter?
2. What are the basic functional blocks of a test fixture?
3. Using a module parameter, write code that creates a clock stimulus.

(QVA2) B-21

Verilog Sample Design


1. You can override the value of a parameter in a module instantiation statement using the #
character. The defparam statement can also be used to over-ride parameter values
2. The basic functional blocks of a test bench are:i)

Instantiation of the Design Under Test (DUT)

ii) Stimulus and control to apply stimuli to data and control inputs
iii) Response generation and verification to capture output values and check their correctness
3. We have to declare our clock variable: declare a parameter for the clock period; initialize the
clock and then write code to create the clock waveform:// parameter declaration
parameter PERIOD = 10;
// clock declaration
reg clock;
//clock initialization
initial clock = 1b0;
// clock waveform
always #(PERIOD/2) clock = ~clock;

Verilog Application Workshop

B-22

Definition of RTL Code


1. Find and fix the coding mistakes in the following procedures intended for
synthesis:always @(posedge clk or negedge rst) // one
if (rst)
q <= 1b0;
else
always @(posedge clk or d) // two
q <= d;
if (rst)
q <= 1b0;
else
q <= d;

always @ (posedge reset) // three


if (reset)
q <= 1b0;
always @ (posedge clk)
q <= d;

always @(posedge clk) // four


if (clk)
q = d;
else
q = 1b1;

always @(posedge clk or posedge rst) // five


begin
if (rst)
q <= 1b1;
else
q <= d;
always @(ctrl | s) // six
if (rst)
if (ctrl)
p <= 1b0;
op = s;
else
else
p <= c;
op = 1b0
end
end

(QVA2) B-23

Definition of RTL Code


one:

if condition checks for rst high, but procedure is triggered by negedge rst.

two:

d should not be in the sequential procedure event list.

three: Reset and sequential functionality for q should be in the same procedure.
four: Use non-blocking assignment. Test for clk is meaningless, should test reset (synchronous)
five: Assignments to p and q must be made from within a single if statement, not two.
six:

or keyword should be used between variables in the event list, not the OR operator (|),
although (ctrl | s) is simulatable, triggering when event occurs on the expression.

always @(posedge clk or negedge rst) // one


if (!rst)
q <= 1b0;
else
always @(posedge clk) // two
q <= d;
if (rst)
q <= 1b0;
else
q <= d;
always @ (posedge clk or posedge reset)
// three
if (reset)
q <= 1b0;
else
q <= d;

always @(posedge clk) // four


if (reset)
q <= d;
else
q <= 1b1;

always @(posedge clk or posedge rst) // five


begin
if (rst) begin
q <= 1b1;
p <= 1b0;
always @(ctrl or s) // six
end
if (ctrl)
else begin
op = s;
q <= d;
else
p <= c;
op = 1b0
end
end
end

Verilog Application Workshop

B-24

Synthesis of Mathematical Operators


1. In what two ways may the synthesis tool implement mathematical operators?
2. What are two disadvantages to directly instantiating macrocells instead of using
mathematical operators?
3. How would you implement the following expression in hardware using just one two
input adder? Give the hardware and also the code.
y = a + b + c;

(QVA2) B-25

Synthesis of Mathematical Operators


1. An operator may be built using discrete gates from the target technology library, or it may be
replaced by a macro-cell, an optimized implementation of the operator pre-built by the
technology vendor and supplied with the technology library.
2. Directly instantiating macro-cells will make the code less readable, and specific to the technology
in which the macro-cell is supplied.
3. To perform 2 additions on a single resource, we have to use sequential logic and spread the
addition over 2 clock cycles. On the first clock cycle we can add a and b and save the result in a
register. On the second clock cycle we add c to the saved result. All we need is a way of tracking
which clock cycle we are in, and we can do this with a toggling bit sel, which must also be
registered.
module oneadd (
input a, b, c, clk, rst,
output reg y
);
reg sel;

rst

always @(posedge clk or posedge rst)


if (rst) begin
y
<= 1'b0;
sel <= 1'b1;
end
else begin
if (sel)
y <= a + b;
else
y <= y + c;
sel <= ~sel;
end
endmodule

c
b

Verilog Application Workshop

+
0
1

clk
rst

sel
clk
B-26

Synthesis Coding Styles


1. What sort of hardware structure are inferred by both case and if statements, by
default, in Verilog?
2. How could you change a case statement in order that its implementation does not
result in a priority structure?
3. If you are not using a synthesis attribute, how can you assure coverage of all
conditions for a case statement?
4. Give the code for an asynchronously and synchronously resettable flip-flop as
shown in the diagram below?
async_reset
1b0

sync_reset
clock

(QVA2) B-27

Synthesis Coding Styles


1. By default, both case and if statements synthesize to prioritized structures - a stack of muxes
where the mux with the highest priority is inferred from the first condition tested by the if or
case statement.
2. If a case statement is written such that its conditions do not overlap, synthesis tools may recognize
this and implement a non-prioritized structure. You can add a parallel-case synthesis attribute to
the case statement to force the synthesis tool to implement a non-prioritized case without a
priority encoder.
3. A default clause can be used in a case statement to ensure coverage of all conditions, without
using synthesis directives.
4. Assuming both resets are active-high:always @(posedge clock or posedge async_reset)
if (async_reset)
q <= 1'b0;
else
if (sync_reset)
q <= 1'b0;
else
q <= d;

Verilog Application Workshop

B-28

Advanced Synthesis Coding Styles


1. Under what conditions does a blocking assigned reg variable infer a register in
synthesis? If it doesnt infer a register, what does happen to it in synthesis?
2. How do you infer tristate gates for synthesis?
3. Under what conditions is a for loop synthesizable?

(QVA2) B-29

Advanced Synthesis Coding Styles


1. A blocking assigned reg variable will infer a register in synthesis if the variable is read before
it is written in the execution of a sequential procedure. If the variable is written before being read,
then it is a temporary variable which will be optimized away in synthesis.
2. The assignment of a variable to z under some condition will infer a tri-state gate in synthesis.
Specifically:
assign data_bus = enable ? write_data : 8'bz;
3. A for loop is synthesizable if the number of iterations is fixed and can be determined at compile
time. For loops are unrolled in synthesis, and if the number of iterations is variable or not known
at compilation, the loop cannot be unrolled.

Verilog Application Workshop

B-30

Task and Functions


1. Write a function that adds two four-bit unsigned numbers and returns an unsigned
five-bit result, and write a call to the function.
2. Which type of subprogram can contain event control?
3. Can logic synthesis infer sequential logic from statements in a function?
4. Write the count_from task to produce the following stimulus. The function
of the task is to load a_bus with a value (passed as a parameter) and to increment
a_bus for 3 clock cycles. The task also controls the select signal.
start

finish

start

module testbench;
reg clk;
reg [3:0] a_bus;
reg select;

finish

clock

initial clk = 1b0;


always #50 clk = !clk;

clock
select
select
a_bus[3:0]
a_bus[3:0]

5
4

6
5

initial
begin
count_from(4d4);
count_from(4d2);
end
endmodule

7
6

(QVA2) B-31

Tasks and Functions


1. Function must add unsigned data, so we dont have to worry about sign extension.
// function declaration
function [4:0] add4;
input
[3:0] a, b;
begin
add4 = a + b;
end
endfunction

module
input
output
reg

add4fun (a_bus, b_bus, result);


[3:0] a_bus, b_bus;
[4:0] result;
[4:0] result;

// function declaration
always@(a_bus or b_bus)
result = add4(a_bus, b_bus);
endmodule

2. Tasks can contain event control.


3. A function synthesizes to combinational logic.
4. count_from task to right.

task count_from;
input [3:0] number;
begin
// start of task body
@ (posedge clk);
a_bus <= number;
@ (negedge clk);
select <= 1'b1;
repeat (3)
begin
@ (posedge clk);
a_bus <= a_bus + 4'b1;
end
select <= 1'b0;
@ (negedge clk);
end // end of task body
endtask

Verilog Application Workshop

B-32

System Control
1. Which two system tasks display the steady state values of the argument list?
2. Which is better to use when creating test vectors? $display or $strobe?
3. How would you cater with opening 35 files?
4. What is the output of the following piece of code?
module test;
reg [3:0] a;
initial
begin
a <= 11; // 4b1011
a = 4b0011;
$display("display", a);
$strobeb("strobe", a);
end
endmodule

(QVA2) B-33

Support for Verification


1. $monitor and $strobe display the steady state values of the argument list. These tasks wait
until just before the advance of simulation time to capture and output signal values.
2. $strobe is better to use when creating test vectors because it captures the steady state value of
a variable, rather than the instantaneous value captured by $display.
3. Since you can only have 31 output files simultaneously open at a time, you will need to
dynamically open and close files during the simulation to write to 35 files. Files can be opened
and closed using the $fopen and $fclose system tasks.
4. The $display will output the result of the blocking assignment in decimal format. The
$strobe will output the result of the non-blocking assignment in binary format.
display 3
strobe 1011

Verilog Application Workshop

B-34

Structural Modeling
1. What is structural modeling in Verilog?
2. What are the two ways that module ports can be connected? Which is safer?
3. What does an array of instances do?
4. When are instance names optional?

(QVA2) B-35

Structural Modeling
1. A structural model is equivalent to a schematic, only containing instantiated modules and wire
connections. Structural modeling is used for block diagrams, schematics, post-synthesis netlists
and ASIC/FPGA cell library models.
2. Module ports can be connected by positional or named port mapping. Named port mapping is
safer because it explicitly identifies which port is mapped to which connection.
3. An array of instances creates a number of module instantiations from one instantiation statement,
e.g. a primitive can be instantiated on each bit of a bus in one statement rather than having a
separate instantiation statement for each bit in the bus.
4. Instance names are optional only when instantiating primitives.

Verilog Application Workshop

B-36

Modeling Delay
1. Model the following circuit:
1.2:1.6:1.8
a
1.1:1.6:1.7
b

c
0.6

2. Give the code for the following circuit. Do you see any problems with such a circuit
from (i) a simulation point of view (ii) a synthesis point of view? Can you fix them?
4b0001

4
4

(QVA2) B-37

Modeling Delay
1.

module xoror(p, a, b, c);


output p;
input a, b, c;
xor x1 (net1, a, b);
or o1 (p, c, net1);
specify
(a => p) = (1.2:1.6:1.8);
(b => p) = (1.1:1.6:1.7);
(c => p) = (0.6);
endspecify
endmodule

2. Note we use an initial block to initialize a and prevent a being stuck at 4bx. Note also
non-blocking assignment used to increment a and re-trigger the procedure when a changes. If
blocking assignment is used, the procedure will not detect any event on a and will not trigger.
module delayadd (a);
output [3:0] a;
reg [3:0] a;
initial
a = 4'b0000;
always @(a)
a <= a + 4b0001;
endmodule

Simulation issues: we have delay-less combinational feedback,


which causes an infinite simulation loop. This could be fixed by
added intra-assignment delay to the increment
a <= #10 a + 4'b0001;
Synthesis issues: The initial block is not synthesizable so a cannot
be initialized in this way. The intra-assignment delay is also not
synthesizable. Without these, the remaining code is synthesizable
but will be implemented with combinational feedback - the
functionality and timing depends on the net delay in the feedback
loop and the propagation delay through the incrementor.
Verilog Application Workshop

B-38

Modeling Memories
1. What Verilog construct do you use to define a memory array?
2. How can you load a memory with data?
3. How can you send values through a bidirectional port (an inout)?
4. Given the RAM cell below, write a simple testbench to exercise the design.

module ram_cell(databus, rd, wr);


inout [3:0] databus;
input rd, wr;
reg
[3:0] datareg;
assign databus = rd ? datareg : bz;
always @(negedge wr)
datareg <= databus;
endmodule

(QVA2) B-39

Modeling Memories
1. A memory is declared in Verilog as a 2-dimensional register array.
2. You can load a memory model with data using the $readmemh or the $readmemb system
tasks, or by using procedural assignments.
3. Because an inout must be a net data type on both sides, you can only drive values onto it with
a primitive, submodule, or continuous assignment. You must also be careful to ensure that
conflicting values are not driven onto it from either side.
4. databus is an inout port and so must be driven by a continuous assignment or primitive. In the
example below, write values are set up from a procedure in reg type data. drive is used to
control a conditional continuous assignment to drive either data or z onto the wire dataio.
module tb_ram_cell ();
// simple ram_cell testbench
wire [3:0] dataio;
reg [3:0] data;
reg read, wrte, drive;
ram_cell U1 (.databus(dataio),
.rd(read), .wr(wrte));
initial
begin
//init
{read, wrte, drive} = 3'b010;
#10;
//write
data = 4'b1010;
drive = 1'b1;
// continued next column

// from previous column


#5;
wrte = 1'b0;
#5;
wrte = 1'b1;
drive =1'b0;
//read
#5;
read = 1'b1;
#5;
read = 1'b0;
end
// drive wire dataio when drive = 1b1
assign dataio = drive ? data : 4'bz;
endmodule

Verilog Application Workshop

B-40

Verilog Application Workshop

B-41

Verilog Application Workshop

B-42

This page left intentionally blank

RTL Templates
VRT1

C-1

Notes

Verilog Application Workshop

C-2

Objectives
Objectives

To list RTL synthesizeable templates


Multiplexers
Decoders
Bus Logic Splitting and Reordering
Comparators
Flip Flops
Resettable Flip Flops
Latches
Tri State Drivers
Counter

(VRT1) C-3

Multiplexers
// 1. using an always

a
always@(a or b or sel)

1
c

if (sel == 1b1)

c = a;
else

sel

c = b;

// 2. using the conditional operator


wire c = sel ? a : b;

Caution
// 3. using the case statement
always @ (a or b or sel)
case (sel)

Use default assignments to prevent


latches: every if has an else,
every case has a default

1b1: c = a;
1b0: c = b;
endcase

(VRT1) C-4

Priority Decoders

// 1. using a case statement

sel

always @ (sl or a or b or c)

2b10

case (sel)

2b11
2

2b11: d = a;

2b10: d = b;

default:d = c;
endcase

// 2. using an if statement
always @ (sl or a or b or c)
if (sel == 2b11)

d
1

d = a;
else if (sel ==2b10)
d = b;
else
d = c;
endcase

Caution
1. Both case and if statements result in
priority structures.
2. The order of the variables determines the
priority

(VRT1) C-5

Parallel Priority Decoders

// using a synthesis directive


always @ (sl or a or b or c)
case (sel) // parallel_case
2b11: d = a;

sel

2b10: d = b;

default:d = c;
endcase

2b0x

2b10

2b11

(VRT1) C-6

Bus Logic, Splitting and Reordering

// A1. using a wire


wire [3:0] d = ({4{enable}} & c);

enable

// A2. using a reg

c[3:0]

d[3:0]
4

reg [3:0] d;
always @ (c or enable)
d = c & {4{enable}};

// B1. using a wire


wire [2:0] e = {a[1],b[3:2]};

a[3:0]

reg [2:0] e;

e = {a[1],b[3:2]}

// B2. using a reg

3
b[3:0]

always @ (a or b)

e = {a[1],b[3:2]};

(VRT1) C-7

Comparators

// 1. using a wire
wire d;

a[3:0]
4

assign d = (a == c);

c[3:0]
// 2. using a reg

d
1

reg d;
always @ (a or c)
d = (a == c);

(VRT1) C-8

D Type Flip Flop

// 1. positive edge triggered D flip flop

always @ (posedge clock)

q <= d;

clock

// 2. negative edge triggered D flip flop

always @ (negedge clock)

q <= d;

clock

Caution
Use non-blocking assignments (<=) in
sequential procedures.

(VRT1) C-9

Resettable D Type Flip Flops

// 1. synchronously resettable D flip flop

1b0
q

always @ (posedge clock)

if (reset)
q <= 1b0;

reset

else
q <= d;

// 2. asynchronously resettable D flip flop

clock

reset

always @ (posedge clock or posedge reset)


if (reset)

q <= 1b0;
else
q <= d;

clock

(VRT1)

C-10

Data Enabled and Clock Gated Flip Flops

// 1. data enabled flip flop

always @ (posedge clock)


if (enable)
q <= d;

d
enable
clock

// 2. D flip flop with gated clock


wire gclk = (clock && enable);

always @ (posedge gclk)

q <= d;

Caution

clock
enable

gclk

enable signal must be glitch free

(VRT1)

C-11

Latches

// 1. latch
always @ (enable or d)

if (enable)

q = d;

enable

// 2.resettable latch

reset

always @ (enable or d or reset)


if (reset)

q = 1b0;

else if (enable)
q = d;

enable

(VRT1)

C-12

Tri-state Drivers
// 1. using a reg

enable

reg y;
always @ (d or enable)
if (enable)

y = d;
else
y = 1bz;

// 2. using a wire
wire y;
assign y = enable ? d : 1bz;

// 3. using a primitive
bufif1 (y,d,enable);

(VRT1)

C-13

Counter
3 bit asynchronously resettable counter which counts 0, 1, 2, 3, 4, 5, 0, 1, 2, ... etc.
reset
3b001
3b000
// 3 bit asynchronously resettable

// partial range counter


always @ (posedge clock or posedge reset)

count

1
0

enable

if (reset)

count <= 3b0;


else

3b101

if (count == 3b101)

clock

count <= 3b0;


else
count <= count + 3b001;

(VRT1)

C-14

This page left intentionally blank

Verilog-2001
V2K1

D-1

Notes

Verilog Application Workshop

D-2

IEEE Std. 1364-2001


Objectives:
Following study of this section, you should be ready to incorporate the new Verilog-2001
features into your Verilog design and testbench.
Multi-dimensional arrays

Re-entrant tasks

generate statement

Configurations

Enhanced timing

Enhanced file I/O

More ...

(V2K1)

D-3

IEEE Std. 1364-2001


This section provides an overview of the major changes and new features of the year 2001 standard. This
section provides sufficient information, that providing you are familiar with the year 1995 standard, you
can incorporate the new features into your design and testbench. This section does not fully redocument
the new features. For that you should refer to the standard itself.

Verilog Application Workshop

D-4

Enhanced Unsized Constant Extension


2.5.1 Integer constants
Verilog-1995:
Width of unsized literal is 32 bits
Left-fill with
0 if leftmost bit is 0, 1
Z, X if leftmost bit is Z, X (respectively)
Left-extend rvalue with 0 to meet lvalue width
reg [63:0] data;
data =

'bz; // data is 'h00000000zzzzzzzz

data = 64'bz; // data is 'hzzzzzzzzzzzzzzzz


Verilog-2001:
Width of unsized literal is width of containing expression
reg [63:0] data;
data =

'bz; // data is 'hzzzzzzzzzzzzzzzz

data = 32'bz; // data is 'h00000000zzzzzzzz


(V2K1)

D-5

Enhanced Unsized Constant Extension

Verilog Application Workshop

D-6

Attributes
2.8 Attributes
New tokens: (* *)
Verilog-2001 standardizes a means to specify tool specific information
Prefix to declaration, module item, statement, port connection

Suffix to operator (including Verilog function name in expression)

Does not define specific attributes


Other standards define specific attributes
Vendors can define proprietary attributes

Vendors previously accommodated commands in comments (pragmas)


/*before*/ case (1'b1) /* ambit synthesis case = parallel */
/*after*/ (* synthesis, parallel_case *) case (1'b1)

(V2K1)

D-7

Attributes
Synthesis vendors have historically defined pragmas (tool directives called metacomments hidden
within Verilog comments) to at least partially control the operation of the tool. Those vendors will
undoubtedly continue to also honor the pragmas.

Verilog Application Workshop

D-8

Variable Declaration Assignment


3.2.2 Variable declarations
Verilog-1995:
Variable initialization only in procedural block
reg clk; initial clk = 0;
Verilog-2001:
Adds variable initialization in declaration
reg clk = 0;

(V2K1)

D-9

Variable Declaration Assignment


Verilog-1995:
reg_declaration ::=
reg [range] list_of_register_identifiers ;
list_of_register_identifiers ::=
register_name { , register_name }
Verilog-2001:
reg_declaration ::=
reg [ signed ] [ range ] list_of_variable_identifiers ;
list_of_variable_identifiers ::=
variable_type { , variable_type }
variable_type ::=
variable_identifier [ = constant_expression ]
| variable_identifier dimension { dimension }

Verilog Application Workshop

D-10

Enhanced Signed Arithmetic


3.2.2 Variable declarations
New reserved word: signed
New operators: <<< >>>
New system functions: $signed $unsigned
Verilog-1995:
unsigned: based literal, net, reg, time
signed: unbased literal, integer
Verilog-2001:
signed keyword treats literal, function, net, reg as signed
32'shFDB97531
function signed [31:0] alu;
wire signed [15:0] addr;
reg signed [31:0] data;
arithmetic right shift operators maintain the sign of a value

$signed and $unsigned system functions cast value


(V2K1) D-11

Enhanced Signed Arithmetic


The parser interprets an integer with no base specifier as a signed value in 2's complement form.
intA = -12 / 3 ;

The left operand is a 32-bit signed value 12, negated.


The expression result is -4.

The parser interprets an integer with an unsigned base specifier as an unsigned value.
intA = -d12 / 3 ;

The left operand is a 32-bit unsigned value 12, negated.


The expression result is 1431655761.

The parser interprets an integer with an signed base specifier as an signed value.
intA = -4'sd12 / 3 ;

The left operand is a 4-bit pattern of 12 (1100) interpreted as a signed


number (-4) and then negated (4).
The expression result is 1.

Verilog Application Workshop

D-12

Enhanced Implicit Declarations


3.5 Implicit declarations
Verilog-1995:
Implicit net declarations only in port expressions and terminal lists
reg s, b, a ;
/*wire y;*/ // not needed
mod i1 ( y, s, b, a ) ;
Verilog-2001:
Adds net declarations as target of continuous assignment
/*wire y;*/ // not needed
assign y = s ? b : a ;
Not in Verilog-2001 but most vendors implemented it anyway. Is in Verilog-2005.

(V2K1) D-13

Enhanced Implicit Declarations


Important
The IEEE Std. 1364-2001 omitted this feature. Most software vendors implemented it anyway. The
Verilog-2005 standard requires it.

Verilog Application Workshop

D-14

Multi-dimensional Arrays
3.10 Arrays
Verilog-1995:
You can declare one-dimension arrays of integer, reg, and time
Use arrays of reg to model memories
Use arrays of integer and time in your testbench
Verilog-2001:
You can declare arrays of any variable or net type

You can declare any number of dimensions


reg [7:0] mem [0:255] [0:3] ; // Four 256x8 memories
reg array3D [7:0] [0:255] [0:3] ; // 3-D array of bits

(V2K1) D-15

Multi-dimensional Arrays
Verilog-1995:
reg_declaration ::= reg [range] list_of_register_identifiers ;
time_declaration ::= time list_of_register_identifiers ;
integer_declaration ::= integer list_of_register_identifiers ;
list_of_register_identifiers ::= register_name { , register_name }
register_name ::=
register_identifier
| memory_identifier [upper_limit_constant_expression :
lower_limit_constant_expression ]

Verilog-2001:
reg_declaration ::= reg [ signed ] [ range ] list_of_variable_identifiers ;
time_declaration ::= time list_of_variable_identifiers ;
integer_declaration ::= integer list_of_variable_identifiers ;
list_of_variable_identifiers ::= variable_type { , variable_type }
variable_type ::=
variable_identifier [ = constant_expression ]
| variable_identifier dimension { dimension }
real_declaration ::= real list_of_real_identifiers ;
realtime_declaration ::= realtime list_of_real_identifiers ;
list_of_real_identifiers ::= real_type { , real_type }
real_type ::=
real_identifier [ = constant_expression ]
| real_identifier dimension { dimension }

Verilog Application Workshop

D-16

Local Parameters
3.11.2 Local parameters - localparam
New reserved word: localparam
Verilog-1995:
You can declare module parameters keyword parameter
These are constants you can change during elaboration
Use module parameters to parameterize each instance of the module
You can modify an instances parameters with the defparam keyword
You can modify an instances parameters with a parameter value assignment
Verilog-2001:
You can also declare local parameters keyword localparam
These are constants you cannot change

(V2K1) D-17

Local Parameters
A localparam is identical to a parameter except that you cannot modify a localparam with the
defparam statement or by the ordered or named parameter value assignment.
Verilog-1995:
module_item_declaration ::= parameter_declaration | ...
block_item_declaration ::= parameter_declaration | ...
parameter_declaration ::= parameter list_of_param_assignments ;

Verilog-2001:
module_parameter_port_list ::=
# ( parameter_declaration { , parameter_declaration } )
module_item ::= ...
| { attribute_instance } parameter_declaration ...
| { attribute_instance } local_parameter_declaration
block_item_declaration ::= ...
| { attribute_instance } parameter_declaration ...
| { attribute_instance } local_parameter_declaration
parameter_declaration ::=
parameter [ signed ] [ range ] list_of_param_assignments ;
| parameter integer list_of_param_assignments ;
| parameter real list_of_param_assignments ;
| parameter realtime list_of_param_assignments ;
| parameter time list_of_param_assignments ;
local_parameter_declaration ::=
localparam [ signed ] [ range ] list_of_param_assignments ;
| localparam integer list_of_param_assignments ;
| localparam real list_of_param_assignments ;
| localparam realtime list_of_param_assignments ;
| localparam time list_of_param_assignments ;

Verilog Application Workshop

D-18

Enhanced Specify Parameters


3.11.3 Specify parameters
Verilog-1995:
You can declare a specparam only in a specify block

You can assign a constant expression to a specparam

You can annotate a specparam with an SDF annotator

Verilog-2001:
You can also declare a specparam as a module item

You can also assign an min/typ/max expression to a specparam

(V2K1) D-19

Enhanced Specify Parameters


Use a specparam instead of a literal constant in your path delays and timing checks, so that you can
easily update the values of multiple path delay and timing check statements that utilize the same constant.
Your SDF annotator can annotate the value of a specparam and utilize the specparam value as a factor
in the calculation of new values to annotate to path delays and timing checks.
Verilog-1995:
specify_item ::= specparam_declaration | ...
specparam_declaration ::= specparam list_of_specparam_assignments ;
list_of_specparam_assignments ::=
specparam_assignment { , specparam_assignment }
specparam_assignment ::= specparam_identifier = constant_expression | ...

Verilog-2001:
module_item ::= { attribute_instance } specparam_declaration | ...
specify_item ::= specparam_declaration | ...
specparam_declaration ::= specparam [ range ] list_of_specparam_assignments ;
list_of_specparam_assignments ::=
specparam_assignment { , specparam_assignment }
specparam_assignment ::=
specparam_identifier = constant_mintypmax_expression | ...

Verilog Application Workshop

D-20

Power Operator
4.1.5 Arithmetic operators
New operator: **
Verilog-2001 adds the power ** operator
Operation similar to C pow() function

Result is unsigned if both operands are unsigned

Result is real if either operand is real, integer, or signed


module ram ( data, addr, write );
parameter WIDTH_A = 5, WIDTH_D = 8 ;
inout [WIDTH_D-1:0] data ;
input [WIDTH_A-1:0] addr ;
input write ;
reg [WIDTH_D-1:0] mem [1:2**WIDTH_A] ;
always @(posedge write) mem[addr] = data ;
assign data = write ? 'bz : mem[addr] ;
endmodule

(V2K1) D-21

Power Operator
The result is unsigned if both operands are unsigned.
The result is real if either operand is real, integer, or signed.
The result is unspecified if the first operand is zero and the second operand is non-positive.
The result is unspecified if the first operand is negative and the second operand is not an integral value.
Verilog-1995:
binary_operator ::=
+ | - | * | / | % | == | != | === | !== | && | || | ...

Verilog-2001:
binary_operator ::=
+ | - | * | / | % | == | != | === | !== | && | || | ** | ...

Verilog Application Workshop

D-22

Indexed Vector Part Selects


4.2.1 Vector bit-select and part-select addressing
Verilog-1995 defines vector bit and part selects
Select a vector bit with an expression
vect [ expr ]

Select a vector part with constant expressions


vect [ const_expr : const_expr ]

Verilog-2001 adds indexed vector part select


Select a vector part using an index variable and a width constant
vect [ base_expr +: const_width_expr ] // base to base + (width-1)
vect [ base_expr -: const_width_expr ] // base to base - (width-1)
reg [15:0] big_vect;
big_vect[ 0 +:8] == big_vect[ 7:0]
big_vect[15 -:8] == big_vect[15:8]
reg [0:15] little_vect;
little_vect[ 0 +:8] == little_vect[0 : 7]
little_vect[15 -:8] == little_vect[8 :15]

(V2K1) D-23

Indexed Vector Part Selects


Verilog-1995:
net_lvalue ::= ...
| net_identifier [ msb_constant_expression : lsb_constant_expression ]
| net_identifier [ expression ] | ...
reg_lvalue ::= ...
| reg_identifier [ msb_constant_expression : lsb_constant_expression ]
| reg_identifier [ expression ] | ...
primary ::= ...
| identifier [ msb_constant_expression : lsb_constant_expression ]
| identifier [ expression ] | ...

Verilog-2001:
net_lvalue ::= ...
| hierarchical_net_identifier [ constant_expression ] { [ constant_expression ] }
| hierarchical_net_identifier [ constant_expression ] { [ constant_expression ] }
[ constant_range_expression ]
| hierarchical_net_identifier [ constant_range_expression ] | ...
constant_range_expression ::=
constant_expression
| msb_constant_expression : lsb_constant_expression
| constant_base_expression +: width_constant_expression
| constant_base_expression -: width_constant_expression
variable_lvalue ::= ...
| hierarchical_variable_identifier [ expression ] { [ expression ] }
| hierarchical_variable_identifier [ expression ] { [ expression ] }
[ range_expression ]
| hierarchical_variable_identifier [ range_expression ] | ...
primary ::= ...
| hierarchical_identifier [ expression ] { [ expression ] }
| hierarchical_identifier [ expression ] { [ expression ] } [ range_expression ]
| hierarchical_identifier [ range_expression ] | ...
range_expression ::=
expression
| msb_constant_expression : lsb_constant_expression
| base_expression +: width_constant_expression
| base_expression -: width_constant_expression
Verilog Application Workshop

D-24

Array Bit and Part Selects


4.2.2 Array and memory addressing
Verilog-2001 adds memory word bit-select and part-select addressing
Refer to clause 4.2.1 (Vector bit-select and part-select addressing)
reg [7:0] array2D [0:255] [0:255] ;
wire array3D [255:0] [255:0] [7:0];
array2D [10] [3] [sel] // variable bit select
array3D [10] [3] [sel] // variable word select
array2D [14] [1] [3:0] // lower 4 bits of word at [14][1]
array3D [14] [1] [3:0] // illegal - not a memory!

(V2K1) D-25

Array Bit and Part Selects


Having selected a memory word, you can then in the same statement apply bit-select and part-select to
the memory word. This is an improvement over Verilog-1995, which required you to first assign the
memory word to a vector and then apply the bit-select or part-select to the vector.

Verilog Application Workshop

D-26

Alternative Event OR Operator


9.7.4 Event or operator
Verilog-1995: Event OR operator is or
always @ ( s or b or a )
y = s ? b : a ;
Verilog-2001: Event OR operator can also be ,
always @ ( s, b, a )
y = s ? b : a ;

(V2K1) D-27

Alternative Event OR Operator


You can use either the or reserved word or a comma character (,) as an event OR operator. You can use
these tokens interchangeably within a sensitivity list.
To inadvertently use the bit-wise ( | ) or boolean ( || ) OR operators instead of the event ( or ) OR operator
in a sensitivity list is a common mistake. The parser will not necessarily report an error, as you may
legally use such an expression of signals in a sensitivity list.
Verilog-1995:
event_control ::=
@ event_identifier
| @ ( event_expression )
event_expression ::=
expression
| event_identifier
| posedge expression
| negedge expression
| event_expression or event_expression

Verilog-2001:
event_control ::=
@ event_identifier
| @ ( event_expression )
| @*
| @ (*)
event_expression ::=
expression
| hierarchical_identifier
| posedge expression
| negedge expression
| event_expression or event_expression
| event_expression , event_expression
Verilog Application Workshop

D-28

Implicit Event Expression List


9.7.5 Implicit event_expression list
Verilog-1995 requires an explicit event expression list
always @ ( s or b or a )
y = s ? b : a ;
Verilog-2001 permits an implicit event expression list
Automatically adds to list all identifiers appearing in assignment rvalues.
always @ *
y = s ? b : a ;

(V2K1) D-29

Implicit Event Expression List

Verilog Application Workshop

D-30

Re-enterable Tasks and Recursive Functions


10.2.1 Task declarations
10.3.1 Function declarations
New reserved word: automatic
Verilog-1995 tasks and functions are static
Each invocation uses the same local variables

Multiple simultaneous invocations overwrite values

Verilog-2001 tasks and functions can be dynamic


Each invocation creates new local variables

You can re-enter tasks and recurse functions


factorial = in > 1 ? factorial(in-1) * in : in ;

(V2K1) D-31

Re-enterable Tasks and Recursive Functions


The automatic reserved word makes a task reentrant. The simulator dynamically allocates task items
with each invocation. Dynamically allocated task items exist only during the life of the task invocation.
You cannot access them outside the task definition.
The automatic reserved word makes a function recursive. The simulator dynamically allocates function
items with each invocation. Dynamically allocated function items exist only during the life of the
function invocation. You cannot access them outside the function definition.
// iteration mimics recursion
function [31:0] factorial ;
input [31:0] in ;
integer i ;
begin
factorial = 1 ;
for ( i = in; i>1; i=i-1 )
factorial = factorial * i ;
end
endfunction
// true recursion
function automatic [31:0] factorial ;
input [31:0] in ;
factorial = in > 1 ?
factorial(in-1) * in : in ;
endfunction

Verilog Application Workshop

D-32

Combined Port/Data Type Declarations


10.2.1 Task declarations
10.3.1 Function declarations
12.3.3 Port declarations
Verilog-2001 permits you to combine port declarations and data type declarations into
one statement.
Verilog-1995:
module mux8 ( y, s, b, a ) ;
output [7:0] y ;
reg
[7:0] y ;
...
Verilog-2001:
module mux8 ( y, s, b, a ) ;
output reg [7:0] y ;
...
(V2K1) D-33

Combined Port/Data Type Declarations


Verilog-1995:
module_item_declaration ::= ...
| input_declaration
| inout_declaration
| output_declaration | ...
input_declaration ::= input [range] list_of_port_identifiers ;
inout_declaration ::= inout [range] list_of_port_identifiers ;
output_declaration ::= output [range] list_of_port_identifiers ;
Verilog-2001:
module_item ::= ...
| port_declaration ; | ...
port_declaration ::=
| {attribute_instance} input_declaration
{attribute_instance} inout_declaration
| {attribute_instance} output_declaration
input_declaration ::=
input [ net_type ] [ signed ] [ range ] list_of_port_identifiers
inout_declaration ::=
inout [ net_type ] [ signed ] [ range ] list_of_port_identifiers
output_declaration ::=
output [ net_type ] [ signed ] [ range ] list_of_port_identifiers
| output [ reg ] [ signed ] [ range ] list_of_port_identifiers
| output reg [ signed ] [ range ] list_of_variable_port_identifiers
| output [ output_variable_type ] list_of_port_identifiers
| output output_variable_type list_of_variable_port_identifiers

Verilog Application Workshop

D-34

ANSI-style Port Lists


10.2.1 Task declarations
10.3.1 Function declarations
12.3.4 List of ports declarations
Verilog-2001 permits you to enter combined port declarations and data type declarations
in the header.
Verilog-1995:
module mux8 ( y, s, b, a ) ;
output [7:0] y ;
reg
[7:0] y ;
...
Verilog-2001:
module mux8 ( output reg [7:0] y, ... ) ;

(V2K1) D-35

ANSI-style Port Lists


You can use either the list of ports syntax or the list of port declarations syntax in the module header,
but you cannot mix the two syntaxes within a single module header.
If you use the list of port declarations syntax, you need to completely describe the port. You need to
include the port direction, width, net or variable type, and whether the port is signed or unsigned. You
make these declarations with the same syntax as you would with the list of ports syntax, but you do so
within the module header instead of after the module header.
Verilog-1995:
module_declaration ::=
module_keyword module_identifier [ list_of_ports ] ;
{ module_item }
endmodule
Verilog-2001:
module_declaration ::=
{ attribute_instance } module_keyword module_identifier
[ module_parameter_port_list ]
[ list_of_ports ] ;
{ module_item }
endmodule
| { attribute_instance } module_keyword module_identifier
[ module_parameter_port_list ]
[ list_of_port_declarations ] ;
{ non_port_module_item }
endmodule

Verilog Application Workshop

D-36

Constant Functions
10.3.5 Use of constant functions
Verilog-1995:
You can use constant expressions to parameterize a model
Array depth, vector width, replication
parameter WIDTH_A = 5, WIDTH_D = 8 ;
reg [WIDTH_D-1:0] mem [1:2**WIDTH_A] ;

Verilog-2001:
You can also use constant functions to parameterize a model
You can use them anywhere you would use a constant expression
parameter DEPTH = 32, width = 8 ;
reg [log2(DEPTH)-1:0] mem [1:2**WIDTH_A] ;

(V2K1) D-37

Constant Functions
Constant functions are normal Verilog functions that contain no construct or reference that the elaborator
cannot resolve. In general that means that a constant function definition:

Cannot exist inside a generate scope

Cannot make a hierarchical reference

Cannot invoke non-constant functions

Cannot invoke system functions

Cannot invoke system tasks that cannot be ignored

Cannot reference parameters not previously defined

Cannot reference nonlocal variables

As a further restriction, you cannot within the definition of a constant function itself, replace a constant
expression with a call to a constant function.
Verilog-1995

Verilog-2001

constant_primary ::=
number
| parameter_identifier
| constant_concatenation
| constant_multiple_concatenation

constant_primary ::=
number
| parameter_identifier
| constant_concatenation
| constant_multiple_concatenation
| constant_function_call
| ( constant_mintypmax_expression )
| genvar_identifier
| specparam_identifier

Verilog Application Workshop

D-38

Verilog Generate
12.1.3 Generated instantiation
New reserved words: generate endgenerate genvar
Verilog-2001 adds:
Conditional (case, if) generation
Instances, functions, tasks, variables, and procedural blocks

Iterative (for) generation


Instances, variables, and procedural blocks (no functions or tasks)
// gray to binary
generate
genvar i;
for (i=0; i<SIZE; i=i+1) begin:bit
assign bin[i] = ^gray[SIZE-1:i];
end
endgenerate

(V2K1) D-39

Verilog Generate
Place your generated instances, functions, tasks, variables, and procedural blocks between the generate
and endgenerate reserved words (you may not include parameters, ports, or specify blocks).
Declare genvar index variables for your generate for loops. You can declare them either inside or outside
the generate statement. You can assign only integer values to them, and only within a for loop. These
variables disappear after elaboration and are not available during simulation.
Iteratively generate statements using the for construct. Declare a named block within the for construct
this becomes the name of an array of scopes to match the iterations of the for construct. Inside this
named block place your generated instances, variables, and procedural blocks (you cannot define tasks
and function within a generate for construct).
Conditionally generate statements using case and if constructs.
generate
if ( (a_width < 8) || (b_width < 8) )
CLA_multiplier #(a_width,b_width)
u1 ( a, b, product ) ;
else
WALLACE_multiplier #(a_width,b_width)
u1 ( a, b, product ) ;
endgenerate

Verilog Application Workshop

D-40

Parameter Value Assignment by Name


12.2.2.2 Parameter value assignment by name
For a parameterizable module definition:
module ram ( ... ) ;
parameter DEPTH = 256;
parameter WIDTH = 8;
...
endmodule

Verilog-1995 permits parameter value assignment by ordered list


You cannot assign subsequent parameters after skipping a parameter

Work around by reassigning the initial values to parameters you do not modify
ram #(256,16) ram1 ( ... ) ;

Verilog-2000 adds parameter value assignment by name


You can reassign any parameter values in any order

This can also make your code more readable


ram #(.WIDTH(16)) ram1 ( ... ) ;
(V2K1) D-41

Parameter Value Assignment by Name


Verilog-1995:
parameter_value_assignment ::= # ( expression { , expression } )

Verilog-2001:
parameter_value_assignment ::= # ( list_of_parameter_assignments )
list_of_parameter_assignments ::=
ordered_parameter_assignment { , ordered_parameter_assignment }
| named_parameter_assignment { , named_parameter_assignment }
ordered_parameter_assignment ::= expression
named_parameter_assignment ::= . parameter_identifier ( [expression ] )

Verilog Application Workshop

D-42

Verilog Configurations
13. Configuring the contents of a design
New reserved words: config cell design endconfig -incdir include instance liblist
library use
Verilog-2001 adds a new design building block called a configuration that you can
provide in a library map file.
include /hm/me/libmap.txt ;
library techlib techlib.v ;
library projlib projlibdir/ ;
library testlib . ;
config rtl ;
design testlib.top ;
default liblist testlib projlib techlib ;
cell alu liblist projlib techlib ;
cell cpu use techlib.cpu ;
instance top.u1.d5 liblist projlib techlib ;
instance top.u1.d6 use dff:config ;
endconfig

(V2K1) D-43

Verilog Configurations
The standard describes the library map file, and also describes configurations, which may reside in the
library map file or in a separate source file.
The primary purpose of the library map file is to contain an order list of library declarations. Each library
declaration names a library and maps source to that library. You can define the source path names with
wildcard characters. The compiler places in a library called work any source you compile that it does not
find mapped to a library. The elaborator by default searches the libraries in their declared order to resolve
module references. The simulator vendor must provide a way to specify on the command line a library
list that overrides this default order.
A configuration is a set of rules governing how the elaborator determines which representation of the
module to bind to an instance. You can define configuration(s) for the top level module(s) in your design.
Any configuration can utilize lower level configurations, bindings, and ordered library search lists (you
may not provide a binding or a library list for an instance located within a utilized lower level
configuration). Where you provide both a binding and a library list, the binding overrides the library list.
Where you provide a binding or a library list on both a module definition basis and a module instance
basis, the instance-specific information overrides the more global information. The elaborator searches
the libraries in their listed order to resolve module references. Where no specific binding and no library
list exist, the elaborator searches only within the library of the unit making the reference.
The IEEE Std. 1364-2001 provides no means to maintain more than one representation of a module
within a single library. You must maintain your disparate representations (for example; gate, rtl,
behavioral) in separate libraries. Use the optional [library.] prefix to specify a binding from a specific
library, and use the optional [:config] suffix (config is currently a literal string) to specify the binding
of a configuration when the configuration has the same name as a module.

Verilog Application Workshop

D-44

On-detect Pulse Error Propagation


14.6.4 Detailed pulse control capabilities
New reserved words: pulsestyle_onevent pulsestyle_ondetect
Verilog-1995 defines pulse filtering equivalent to the on-event method
Verilog-2001 adds the on-detect method of pulse filtering
pulsestyle_onevent

pulsestyle_ondetect

specify
(inp => outp) = 5 ;
specparam
PATHPULSE$inp$outp = (2,4) ;
pulsestyle_onevent outp ;
endspecify

specify
(inp => outp) = 5 ;
specparam
PATHPULSE$inp$outp = (2,4) ;
pulsestyle_ondetect outp ;
endspecify

outp

outp

outp
(delayed)

outp
(delayed)

0 1 2 3 4 5 6 7 8

0 1 2 3 4 5 6 7 8
(V2K1) D-45

On-detect Pulse Error Propagation


The simulator measures pulse width at module outputs and filters to the X state those pulses that are at
least as wide the reject limit but not as wide as the error limit.
The default simulator behavior is the on-event method. This method transitions the output to and from
the X state without changing the specified module path delay of either transition.
You can specify the on-detect method for specific module outputs. This method transitions the output
to the X state with no delay, and from the X state with the specified module path delay, thus generating
a potentially more noticeable X state of longer duration.

Verilog Application Workshop

D-46

Negative Pulse Detection


14.6.4 Detailed pulse control capabilities
New reserved words: showcancelled noshowcancelled
Verilog-1995 defines negative pulse detection equivalent to the noshowcancelled
method
Verilog-2001 adds the showcancelled method of negative pulse detection
noshowcancelled
specify
(inp => outp) = (6,3) ;
noshowcancelled outp ;
endspecify

showcancelled
specify
(inp => outp) = (6,3) ;
showcancelled outp ;
endspecify

outp

outp

outp
(delayed)

outp onevent
(delayed)
0 1 2 3 4 5 6 7 8

ondetect

0 1 2 3 4 5 6 7 8

(V2K1) D-47

Negative Pulse Detection


A delayed trailing edge delay that precedes the delayed leading edge delay constitutes a negative pulse.
The default simulator behavior is the noshowcancelled method. This method cancels the delayed
leading edge upon determining that the delayed trailing edge would precede it, and does not propagate
the rejected pulse.
You can specify the showcancelled method for specific module outputs. This method transitions the
preceding trailing edge to the X state, and the following leading edge from the X state, and does
propagate this X-state pulse.
You can specify either the on-event or the on-detect method of pulse filtering for this X-state pulse.

Verilog Application Workshop

D-48

Enhanced Timing Constraint Checks


15.2.3 $setuphold
Verilog-2001 adds event conditionalization and negative setup or hold limits
data

$setup

setup
clk

Transition data sufficiently before active clock edge


Violation if data transition between clock - limit and clock
data

$hold

hold
clk

Hold data sufficiently after active clock edge


Violation if data transition between clock and clock + limit
$setuphold

data
setuphold
clk

Combines setup and hold checks


Permits a negative setup limit or a negative hold limit
Accepts separate conditionalization arguments
(V2K1) D-49

Enhanced Timing Constraint Checks


The setup check verifies that data is set stable sufficiently before an active clock edge. Note that both
endpoints of the time window are not part of the violation region. The violation region when both limits
are positive is:

clock - limit < data < clock


The hold check verifies data is held stable sufficiently after the active clock edge. Note that the exact end
of the time window is not part of the violation region. The violation region when both limits are positive
is:

clock <= data < clock + limit


$setuphold (data_event, reference_event, timing_check_limit [ , [ notify_reg [ , [ stamptime_condition
] [ , [ checktime_condition ] [ , [ delayed_reference ] [ , [ delayed_data ] ] ] ] ] ] ) ;
The $setuphold system task combines setup and hold checks, and also:

Permits one or the other limit (but not both) to be negative if the sum of these limits is greater than
zero by more than the simulation precision. The simulator adjusts the negative limit upward to
zero plus the simulation precision, adds the same amount to the other limit, and delays the
appropriate reference signal or data signal, so that it can perform the check using positive limits.
You can optionally provide signal names for the delayed versions, and you should drive internal
module logic with the delayed versions to enable correct functional operation of your design.

Permits you to conditionalize the stamptime (reference) event and/or checktime (data) event using
arguments separate from the event description.

Verilog Application Workshop

D-50

New Timing Constraint Checks


15.2.4 $removal, 15.2.6 $recrem
New system tasks: $removal $recrem

$recovery

rst_
recovery
clk

Set asynchronous control inactive sufficiently before active clock edge


Violation if clock between control inactive and control inactive + limit

$removal

rst_
removal
clk

Hold asynchronous control active sufficiently after active clock edge


Violation if control goes inactive between clock and clock + limit

$recrem

rst_
recrem
clk

Combines recovery and removal checks


Permits a negative recovery limit or a negative removal limit
Accepts separate conditionalization arguments
(V2K1) D-51

New Timing Constraint Checks


The recovery check verifies that the model recovers from an asynchronous control sufficiently before an
active clock edge. Note that the exact end of the time window is not part of the violation region. The
violation region when both limits are positive is:

clock - limit < control <= clock


The removal check verifies that the asynchronous control is removed sufficiently after the active clock
edge. Note that both endpoints of the time window are not part of the violation region. The violation
region when both limits are positive is:

clock < control < clock + limit


$recrem ( reference_event, data_event, timing_check_limit, timing_check_limit [ , [ notify_reg ] [ , [
stamptime_condition ] [ , [ checktime_condition ] [ , [ delayed_reference ] [ , [ delayed_data ] ] ] ] ] ] ) ;
The $recrem system task combines recovery and removal checks, and also:

Permits one or the other limit (but not both) to be negative if the sum of these limits is greater than
zero by more than the simulation precision. The simulator adjusts the negative limit upward to
zero plus the simulation precision, adds the same amount to the other limit, and delays the
appropriate reference signal or data signal, so that it can perform the check using positive limits.
You can optionally provide signal names for the delayed versions, and you should drive internal
module logic with the delayed versions to enable correct functional operation of your design.

Permits you to conditionalize the stamptime (reference) event and/or checktime (data) event using
arguments separate from the event description.

Verilog Application Workshop

D-52

New Timing Constraint Checks


15.3.2 $timeskew
15.3.2 $fullskew
New system tasks: $timeskew $fullskew
Verilog-2001 adds the $timeskew and $fullskew system tasks

$skew

clk
skew
clka

Reports violation each time data event occurs after limit


Does not report violation if data event never occurs
$timeskew
Reports violation once at limit if data event did not occur
With event_based_flag: Reports only when data event occurs after limit
With remain_active_flag: Reports all event-based violations
$fullskew extends $timeskew with this additional feature:
Either event can be first and each has its own skew limit to the second event
(V2K1) D-53

New Timing Constraint Checks


With the event_based_flag and remain_active_flag both set, the new $timeskew check is identical to the
existing $skew check.
$skew ( reference_event, data_event, timing_check_limit [ , [ notify_reg ] ] ) ;
$timeskew ( reference_event, data_event, timing_check_limit [ , [ notify_reg ] [ , [ event_based_flag ] [
, [ remain_active_flag ] ] ] ] ) ;
$fullskew ( reference_event, data_event, timing_check_limit, timing_check_limit [ , [ notify_reg ] [ , [
event_based_flag ] [ , [ remain_active_flag ] ] ] ] ) ;

Verilog Application Workshop

D-54

C-Style File I/O


17.2 File input-output system tasks and functions
New system functions: $ferror $fgetc $fgets $fread $fscanf $fseek $ftell $rewind
$sformat $sscanf $ungetc
New system tasks: $fflush $swrite $swriteb $swriteh $swriteo
Verilog-1995:
32 channels using integer multi-channel descriptor (MCD)

Output ASCII using $fdisplay $fmonitor $fstrobe $fwrite

No input beyond $readmemb $readmemh

No filesystem manipulation

Verilog-2001 adds another I/O system in parallel with MCD:


With bit 31 set, MCD becomes file descriptor (FD)

Reduces MULTI channel descriptor to 31 channels

Becomes SINGLE channel descriptor for another 231 channels

Supports C-style I/0 functions for ASCII and binary data


(V2K1) D-55

C-Style File I/O


$fclose ( fd ) ;

// close a file

errcode

= $ferror ( fd, str ) ;

// get error code and description

char

= $fgetc ( fd ) ;

// get a character

errcode

= $fgets ( str, fd ) ;

// get a string

$fflush ( [ fd ] ) ;

// flush output buffer(s)

fd

= $fopen ( "filename", type ) ;

// open a file

errcode

= $fread ( reg, fd ) ;

// read binary data to a reg

errcode

= $fread ( mem, fd [ , [start] [ , [count] ] ] );

// read binary data to an array of reg

errcode

= $fscanf ( fd, format, args ) ;

// read formatted data from a file

errcode

= $fseek ( fd, offset, operation ) ;

// reposition the file pointer

position

= $ftell ( fd ) ;

// get the file pointer position

errcode

= $sscanf ( str, format, args ) ;

// read formatted data from a string

errcode

= $rewind ( fd ) ;

// rewind the file pointer

length

= $sformat ( reg, format, args ) ;

// format data to a string

$swrite ( reg, args ) ;


errcode

= $ungetc ( c, fd ) ;

// format data to a string


// unget (put back) a character

Verilog Application Workshop

D-56

SDF Annotation
17.2.9 Loading timing data from an SDF file
New system task: $sdf_annotate
Verilog-2001:
Formally defines an already de-facto standard

Defines mapping between SDF and Verilog


path delays, specparams, timing checks

Refer to IEEE Std. 1497-2001


Standard Delay Format for Electronic Design Process

(V2K1) D-57

SDF Annotation
The IEEE Std. 1364-2001 clause 17.2.9 (Loading timing data from an SDF file) formally defines the
built-in SDF annotation that most simulator vendors have already previously provided. A
$sdf_annotate() system task takes the following arguments, of which only the first is required. You can
omit any trailing arguments and can substitute a comma placeholder for any other omitted argument.
Default values are in bold font.
"sdf_file"

SDF file

module_instance

Scope at which to apply relative SDF instance paths { current scope }

"config_file"

Configuration file

"log_file"

Log file

"mtm_spec"

Value to annotate { MINIMUM TYPICAL MAXIMUM TOOL_CONTROL }

"scale_factors"

Scaling to apply to scale_type { 1.0:1.0:1.0 }

"scale_type"

Values to scale { FROM_MINIMUM FROM_TYPICAL FROM_MAXIMUM


FROM_MTM }

The annotator starts with the "scale_type" values, applies the "scale_factors", then annotates the result to the
"mtm_spec".

Verilog Application Workshop

D-58

Enhanced PLA Modeling


17.5 PLA modeling system tasks
For Verilog-1995 the input and output terms are scalar variables
$async$and$array ( mem, { i7, i6, i5, i4, i3, i2, i1, i0 }, { o3, o2, i1, o0 } ) ;
For Verilog-2001 the input terms can be any expression and the output terms can be any
variable lvalue
$async$and$array ( mem, in_wire, out_reg ) ;

(V2K1) D-59

Enhanced PLA Modeling


Use the PLA modeling system tasks to simplify PLA modeling. Declare an array of reg as wide as the
number of input terms and as deep as the number of output terms. Load the memory using the
$readmemb() or $readmemh() system tasks. For the array format, a 0 ignores the associated input
and a 1 uses the associated input. For the plane format, a 0 complements the input, a 1 uses the
input, a Z or ? ignores the input, and a X takes the worst case [the standard does not define what
this means] of the input value. You call the async array type once to set up a continuous relationship and
you call the sync array type every time you want to update the output terms.

Verilog Application Workshop

D-60

Standard Random Number Generator


17.9.3 Algorithm for probabilistic distribution functions
Verilog-1995 defines distribution functions without describing their algorithms
Verilog-2001 defines C code for the pseudorandom number generator and the distribution
functions
Simulators can generate the standard pseudorandom sequence

Users can safely intermix simulators during regression tests

(V2K1) D-61

Standard Random Number Generator


Verilog built-in system tasks generate a pseudorandom sequence of integer numbers ($random) and
standard distributions of long numbers. Provided identical initial seeds and other parameters,
Verilog-2001 guarantees that compliant simulators generate exactly the same sequence, thus enabling
you to exactly duplicate tests with different compliant simulators.

$random ( [ seed ] ) ;
$dist_chi_square ( seed , degree_of_freedom ) ;
$dist_erlang ( seed , k_stage , mean ) ;
$dist_exponential ( seed , mean ) ;
$dist_normal ( seed , mean , standard_deviation ) ;
$dist_poisson ( seed , mean ) ;
$dist_t ( seed , degree_of_freedom ) ;
$dist_uniform ( seed , start , end ) ;

Verilog Application Workshop

D-62

Invocation Option Tests


17.10 Command line input
New system functions: $test$plusargs $value$plusargs
$test$plusargs ( string )
Returns true (not zero) if any plusarg prefix contains the string
verilog top.v +VERBOSITY=2
$test$plusargs ( "VERBOSITY" ) ;
$value$plusargs ( string, variable )
Returns true (not zero) if any plusarg matches the format string

Reads formatted data into provided variable


verilog top.v +VERBOSITY=2
$value$plusargs ( "VERBOSITY=%d", verbosity ) ;

(V2K1) D-63

Invocation Option Tests

Verilog Application Workshop

D-64

Extended VCD Files


18 Value change dump (VDC) files
New system tasks: $dumpports $dumpportsall $dumpportsoff $dumpportson
$dumpportslimit $dumpportsflush
Verilog-1995 system tasks support value change dump
Dumps value change data in ASCII format

Limited to a single set of signals at a time

Verilog-2001 adds system tasks specifically for port data


Supports multiple dump files

Dumps port change values, direction, and strength

Dumps EVCD closing time (end of simulation)

(V2K1) D-65

Extended VCD Files


$dumpfile [ ( [ pathname ] ) ] ;

Open VCD dump file { dump.vcd }

$dumpvars [ ( levels [ , scopes and/or variables ] ) ] ;

Specify scopes and/or variables


{ all levels, all signals }

$dumpall;

Dump all current values

$dumpoff

Suspend dump

$dumpon;

Resume dump

$dumplimit ( filesize );

Limit file byte size

$dumpflush;

Flush output buffer

$dumpports [ ( [ scopes] [ , pathname ] ) ] ;

Specify scopes and EVCD dump file


{ current, dumpports.vcd }

$dumpportsall [ ( [ pathname ] ) ] ;

Dump all current values, etc.

$dumpportsoff [ ( [ pathname ] ) ] ;

Suspend dump

$dumpportson [ ( [ pathname ] ) ] ;

Resume dump

$dumpportslimit ( filesize [ , pathname ] ) ;

Limit file byte size

$dumpportsflush [ ( [ pathname ] ) ] ;

Flush output buffer

Verilog Application Workshop

D-66

Disable Implicit Net Declarations


19.2 `default_nettype
New default net type: none
Verilog-1995 permits implicit net declarations
Use a previously undeclared identifier in a port expression or terminal list

Becomes the default net type (initially a wire)

You change the default net type with `default_nettype


tri tri0 tri1 triand trior trireg wand wire wor

Verilog-2001 adds implicit net declarations as the target of a continuous assignment


Verilog-2001 adds the default net type none
Set this as the default net type with `default_nettype none

Undeclared signals become a syntax error


Reduces potential for typographical error

(V2K1) D-67

Disable Implicit Net Declarations


You implicitly declare a net when you use a previously undeclared identifier in a port expression or
terminal list or as the lvalue of a continuous assignment. That net by default becomes a wire. You set the
value of the `default_nettype directive to change that default net type. The Verilog-2001 standard adds
the none type. When you set the default net type to none you require explicit declaration of all nets, thus
reducing the potential for typographical error.
Note: All Verilog compiler directives start with the grave accent (sometimes called a backtick).
You should be aware that some fonts cannot render this character properly and display it as an
acute accent (a forward tick).

Verilog Application Workshop

D-68

Enhanced Conditional Compilation


19.3.2 `undef
19.4 `ifdef `else `elsif `endif `ifndef
New directives: `ifndef `elsif
Verilog-2001 adds the `undef directive to undefine a previously defined macro
`undef MYMACRO
Verilog-2001 adds the `ifndef and `elsif directives to simplify nesting conditionally
compiled blocks
1995

2001

`ifdef defined
`ifdef notdefined
// cannot undef
`endif
`else
`define defined
`endif

`ifndef defined
`define defined
`elsif notdefined
`undef notdefined
`endif

(V2K1) D-69

Enhanced Conditional Compilation


Spelling `elsif with an extra e (as in `elseif) is a common error you should watch for.

Verilog Application Workshop

D-70

New `line Directive


19.7 `line
New directive: `line
Verilog-2001 adds the `line directive to document the file and line number of the original
source code
`line number "filename " level

(V2K1) D-71

New `line Directive


Almost all compilers maintain the file name and current line so that they can report the location of an
error. An application (such as a crude code coverage measurement tool) could annotate or instrument the
original source, causing the compiler to report confusing information as to the location of an error.
With the line number (`line) compiler directive you can reset the line number and file name and provide
some information about the level of include files. Presumably you would specify information that is
correct for the original source file. Upon encountering the `line directive, the compiler will replace its
current information with whatever you have specified.
You can specify this directive anywhere within the Verilog source, and as frequently as you choose.
Provide the line number of the next line, the pathname of the file, and a level to indicate:

0 No include file entered or exited


1 An include file has been entered
2 An include file has been exited

Verilog Application Workshop

D-72

Summary
You should now be ready to incorporate the new Verilog-2001 features into your Verilog
design and testbench.
Multi-dimensional arrays

Re-entrant tasks

generate statement

Configurations

Enhanced timing

Enhanced file I/O

More ...

(V2K1) D-73

Summary

Verilog Application Workshop

D-74

This page left intentionally blank

SystemVerilog-2005
SV2K5

E-1

Notes

Verilog Application Workshop

E-2

IEEE Std. 1800-2005


Objectives:
Following study of this section, you should be aware of the major features that
SystemVerilog-2005 adds to the Verilog-2001 hardware design language:
Design features
Convenience features with which to code more concisely (with fewer mistakes)
Synthesis features to more clearly state your intentions to synthesis tools
Interfaces to encapsulate inter-block communication

Verification features
New block type to encapsulate test programs Constrained randomization
New block type encapsulate signal timing

Property assertions

Process synchronization

Functional coverage

Templated classes

Direct programming interface

Overloaded operators

(SV2K5)

E-3

IEEE Std. 1800-2005


This training module provides an overview of the major enhancements and additions that
SystemVerilog provides over the Verilog-2001 standard. This training module is only an
overview. To effectively utilize these new features you may want additional training.

Verilog Application Workshop

E-4

SystemVerilog Design Features


Among the design features that SystemVerilog extends and adds are:
Literal Values

Data Types

Arrays

Declarations

Operators

Procedural Statements

Processes

Tasks and Functions

Hierarchy and Connectivity

Interfaces

(SV2K5)

E-5

SystemVerilog Verification Features

Verilog Application Workshop

E-6

Literal Values
SystemVerilog adds syntax with which to define literal:
integer and logic values
unsized, unbased single-bit values fill all bits to any size with specified value
0

time values
Write as an integer (e.g. 40ps) or fixed-point (e.g. 0.1ns) value followed
immediately by the time unit without an intervening space
New time unit step (e.g. 1step) refers to simulation precision

string values
\v (vertical tab) \f (form feed) \a (bell) \x41 (hex number)
\ escapes newline to continue string on following line
assignment to any integral type is right justified (Verilog standard)
assignment to unpacked array of byte is left justified

(SV2K5)

E-7

Literal Values

Verilog Application Workshop

E-8

Literal Values (continued)

array values (somewhat similar to C initializers)


nested replication operators
int n[1:2][1:3] = {{0,1,2},{3{4}}};
int n[1:2][1:6] = {2{{3{4, 5}}}};
index key and default value
int n[1:3]= {1:1, default:0};

structure values
member key and type key and default value
typedef struct {int i, logic l, real r} s_t;
s_t s = {logic:x, r:1.2, default: 0};
nested braces must reflect array structure and replication must cover all members
typedef struct {int i, ia[4];} s_t;
s_t s[1:0][2:0] = {2{{3{42,{2{38,-5}}}}}};

(SV2K5)

E-9

Literal Values (continued)

Verilog Application Workshop

E-10

Data Types
SystemVerilog adds and enhances data types :
Adds bit, byte, shortint, int, longint 2-state integer types, logic 4-state type,
shortreal floating-point type, void type, chandle (C pointer) type, string type
string methods len(), putc(), getc(), substr(), etc.

alias events, trigger them with a delay, wait for their triggered state

define enumerations (enum), structures (struct), unions (union), classes (class)


enum int {bronze=3, silver, gold} medal;
struct {bit [7:0] opcode; bit [23:0] addr;} instruction;
union {int i; shortreal f;} number;

define a named type with typedef


typedef int unsigned uint32_t;

cast statically (newType(expr)) and dynamically ($cast(dest_var,src_expr))

(SV2K5) E-11

Data Types
SystemVerilog supports the C built-in types, but to avoid confusion renames long to longint
and float to shortreal and specifies that an int is always 32 bits and a longint is always 64
bits. These are all 2-state types (integer is still a 4-state type). Similarly to C, SystemVerilog
also provides enumerations (enum) and structures (struct), and users can define types using
typedef.
SystemVerilog adds bit, string, chandle, and class data types and enhances the event type.
SystemVerilog discerns between an object and its type. The type defines the permitted values
and operations, but not the simulation semantics (such as strength resolution). Thus a net
(wire) and variable (var) can both be of the logic data type, but act differently.
You can define modules and interfaces to take data types as a parameter (similarly to C++
class templates).

Verilog Application Workshop

E-12

Arrays
SystemVerilog adds and enhances array types:
Packed and unpacked arrays
Packed dimensions are before object name and unpacked dimensions after
Packed dimensions are bit, logic, reg types and can be treated as a single vector
logic [3:0][7:0] mem [1:256];
Dynamic arrays that user can resize during runtime

Any one unsized unpacked array dimension (must size other dimensions
bit [8:5][4:2]A[][1:0] = new[2]; A = new[3](A);
Associative arrays

Index can be any 2-state type for which there is an equality operator
event e; event eA[MyClass]; MyClass c = new; eA[c] = e;
Queues

One unpacked dimension that automatically resizes as needed


int i1,i2; int q[$]; q.push_front(i1); q.push_front(i2);
(SV2K5) E-13

Arrays
SystemVerilog refers to dimensions declared before the object name as a packed array and to
dimensions declared after the object name as a unpacked array. The packed array is what the
Verilog standard refers to as the vector width, but in SystemVerilog can be any number of
dimensions.
Verilog:

vector
reg [31:0]

dimensions
mem [1:255]

SystemVerilog:

packed
reg [3:0][7:0]

unpacked
mem [1:255]

A packed array is simply a mechanism for dividing a bit or logic vector into conveniently
accessed elements. Although you cannot pack integer types, you can use a packed array as if
it were an integer type, and can take bit and part selects of an integer as if it were a
one-dimensional packed array.
Unpacked arrays can be of of any data type. Each unpacked dimension can be a fixed or
unfixed size. You can procedurally change the size of one of the dimensions of an unpacked
array. To assign an unpacked array to another unpacked array, the array structure must be
identical. To assign a packed array to an unpacked array you need to explicitly cast the type.
SystemVerilog also has:

Dynamic arrays User can resize during runtime

Associative arrays Dynamically resized, element associated with an index of a declared type

Queues Dynamically resized FIFO or LIFO


Verilog Application Workshop

E-14

Declarations
SystemVerilog adds and enhances declarations:
You can drive a variable with a single continuous assignment

You can declare automatic variables in static subprograms

You can declare static variables in automatic subprograms

You can declare a const local constant in an automatic scope

You can declare a net of any 4-state data type

You can declare global variables outside of a module or interface or program

You can declare variables in unnamed blocks

You can alias multiple names for a single net

You can set the type (as well as the value) of a module parameter upon instantiation

You can get the type of an expression and use that type in another expression

(SV2K5) E-15

Declarations
SystemVerilog permits you to drive a variable with a single continuous assignment or with one
or more procedural assignments (but not both). For this purpose, elements of an unpacked
array or structure are treated as separate variables. As the reg keyword no longer means a
register object, SystemVerilog adds the logic data type that you can apply to either a net (e.g.
wire) or a variable (var).
SystemVerilog permits the static keyword in an automatic subprogram to declare a static
variable, and the automatic keyword in an static subprogram to declare an automatic variable.
SystemVerilog adds the const local constant. While a localparam is a static module constant
set during elaboration, const can be an automatic local constant set during simulation.
SystemVerilog discerns between the kind of a declaration and the type of a declaration. The
kind of the declaration defaults to variable (var) and to declare a net you need to specify the
kind of net (e.g. wire). The type of the declaration defaults to logic and to declare any other
type you need to specify the type (e.g. bit). SystemVerilog permits a net to be of any 4-state
type, including arrays and structures containing only 4-state elements.
SystemVerilog data declared outside any module, interface or program have static lifetime and
global scope.
SystemVerilog permits variable declarations in unnamed blocks. These variables are
inaccessible outside of the block scope.
SystemVerilog adds the alias statement to create multiple names for one physical entity.
SystemVerilog permits you to specify a data type as a module parameter that can be changed
on a per-instance basis. You can declare (and override) module parameters using a parameter
port list syntax similar to the port list syntax.
SystemVerilog adds the type operator to extract the type of its expression operand.
Verilog Application Workshop

E-16

Operators
SystemVerilog adds and enhances operators:
Assignment operators (always blocking)
if ( (a=b) ) ++b;

Wildcard equality and inequality operators


(4b0100 ==? 4b01ZX) // true

String concatenation and replication


string m = "Hello"; m = {m, " There"}; // Hello There

Array and structure assignment patterns

Non-member operator overloading to support user-defined data types


bind + function myType operatorPlus(myType, myType);

Stream operators to pack/unpack integral elements L2R {>>} or R2L {<<}


int j={"A","B","C","D"}; j={<< byte {j}}; // DCBA

The set membership operator inside to operate on singular values sets

The pattern match operator matches for use in case, if, and conditional expressions
(SV2K5) E-17

Operators
SystemVerilog adds the C assignment (e.g. +=) and increment/decrement (e.g. ++) operators.
These are blocking assignments.
SystemVerilog adds wildcard inequality operators (==? !=?) that treat Z and X values in the
right operand as positions to not be compared.
SystemVerilog provides a built-in implicitly imported std package that users can add to.
SystemVerilog supports (rvalue only) string concatenation and replication.
SystemVerilog supports array and structure assignment patterns.
You can bind some operators to a function that implement that operation for your user-defined
data type.
For the situation where bit reordering is required, SystemVerilog provides stream operators to
pack or unpack integral types in left-to-right {>>} or right-to-left {<<} order. You can specify
the slice size and you can operate on aggregates of integral types.
SystemVerilog adds pattern matching to case and if statements and conditional expressions.
A pattern is a nesting of tagged union and structure expressions with identifiers, constant
expressions, and the wildcard pattern .* at the leaves.
SystemVerilog supports singular value sets and the inside membership operator (an aggregate
type is an unpacked array, structure or union; a singular type is anything else). The operator
performs an equality (==) comparison with nonintegral set elements and a wildcard equality
(==?) comparison with integral set elements. Set elements may also be a unpacked array of
singular types.
Verilog Application Workshop

E-18

Procedural Statements
SystemVerilog adds a final block that executes at the end of simulation.
Must execute in zero time (like a function call). Useful to print diagnostics.
SystemVerilog adds the C-like do...while, break, continue, and return keywords.
SystemVerilog adds the priority and unique keywords to qualify case or if.
The priority keyword checks that at least one branch condition is true.
The unique keyword checks that exactly one branch condition is true.
case match expressions may be value sets (use inside operator) or patterns (use matches)
SystemVerilog checks that any block name at the block end matches the block name.
begin: myBlk statements... end: myBlk
SystemVerilog adds an iff qualifier to the @ event control.
always @(posedge clk iff enabled)

(SV2K5) E-19

Procedural Statements

Verilog Application Workshop

E-20

Processes
SystemVerilog adds process block keywords to indicate the designers intent:
An always_comb block always represents combinational logic

An always_latch block always represents latch logic

An always_ff block always represents sequential logic

SystemVerilog enhances the fork...join construct:


join_any continues parent process execution when any subprocess completes

join_none continues process execution without waiting for subprocess completion

wait fork waits for all subprocesses to complete

disable fork terminates all subprocesses

SystemVerilog provides fine-grained process control with the process class:


class process;
enum state { FINISHED, RUNNING, WAITING, SUSPENDED, KILLED };
static function process self(); // get handle to self
function state status();
function void kill();
task await(); // illegal to await completion of self
function void suspend();
task resume();
endclass
(SV2K5) E-21

Processes
To prevent inadvertent latch inference, SystemVerilog adds always_comb, always_latch and
always_ff blocks to guarantee execution semantics and indicate the designers intent.
SystemVerilog provides fine-grained process contol with the process class. Every process is
associated with an object of this class. Processes can retrieve their handle with the static
process::self() method and store it, and any process with access to this handle can use it to
obtain the status of the process, suspend and resume and kill it, and await its completion.

Verilog Application Workshop

E-22

Tasks and Functions


SystemVerilog adds several features related to subprograms:
Functions can return void data type

Functions can have output and inout ports

Subprograms can take arguments by reference (ref) as well as by value

Subprograms can have default argument values

Static subprograms can declare automatic variables

Automatic subprograms can declare static variables

Subprograms do not need begin...end around multiple statements

Subprograms can return before completion

Subprogram calls can bind argument values by name as well as by position

You can import subprograms to (and export subprograms from) a foreign language

(SV2K5) E-23

Tasks and Functions


The direction of a formal argument defaults to input. Any specification of direction applies to
subsequently listed arguments until respecified.
The type of a formal argument defaults to logic. Any specification of type applies to
subsequently listed arguments until respecified.
You may declare specific formal arguments and local variables automatic within a static
subprogram (also static within an automatic subprogram).
You can pass any variable (but not nets) by reference (ref) to an automatic (but not static)
subprogram. You must assume that the referenced variable is automatic and not use it in a
manner reserved for static variables. The automatic variable can potentially no longer exist
upon return from a time-consuming task.
Subprograms may not modify const ref formal arguments.
You can can omit begin .... end and place multiple statements within the subprogram.
You can return from a subprogram before it completes.
You may call a function with output, inout, or non-const ref arguments only as an expression
in a procedural statement.
To call a function as a procedural statement, you may declare a function return type void or
cast away the value with void'(func(...)).

Verilog Application Workshop

E-24

Hierarchy and Connectivity


SystemVerilog offers several features related to design hierarchy:
Compilation-unit scope, visible to elements of a vendor-defined compilation unit

Importing data, type, class, task, and function declarations from a package
import p::*;

Nested module declarations (to keep submodule definitions out of global space)

Relaxed port declaration and connection rules


Port expression can be any concatenation of any part selection of any data type
Shares variables between modules using reference (ref) port qualifier
Permits continuous assignment to variables

Implicit .name and .* port connection (if variable and port have the same name)
mod mod1(.clk(clk1), .din, .dout), mod2(.clk(clk2), .*);

Module-based time unit and time precision (alternative to compiler directive)


timeunit 100ps; timeprecision 10fs;

(SV2K5) E-25

Hierarchy and Connectivity

Verilog Application Workshop

E-26

Interfaces
Interfaces capture inter-block communication to promote design refinement and reuse.
A named bundle of nets, parameters, constants, variables, functions and tasks
Whose element types you can optionally pass as a per-instance parameter
To which you can control access by defining modports (views)

Optionally containing processes (initial/always blocks, continuous assignments)

Instantiate and bind to ports and access through port name or instance name.
module top;
bit clk = 0;
my_IF IF();
memMod mem(.*);
cpuMod cpu(.*);
endmodule : top
interface my_IF;
logic req, gnt;
logic [7:0] addr,data;
logic [1:0] mode;
logic start, rdy;
endinterface: my_IF

module memMod (
interface IF,
input bit clk );
logic avail;
always @(posedge clk)
IF.gnt <= IF.req & avail;
endmodule: memMod

module cpuMod (
interface IF,
input bit clk
);
...
endmodule: cpuMod
(SV2K5) E-27

Interfaces
SystemVerilog provides the interface construct to encapsulate inter-block communication
Separating the inter-block communication from the block implementation facilitates iterative
block refinement and reuse. A SystemVerilog interface is:

A named bundle of nets, parameters, constants, variables, functions and tasks


Whose element types you can optionally pass as a per-instance parameter
To which you can control access by defining modports (views)

Optionally containing processes (i.e. initial/always blocks, continuous assignments)

You instantiate an interface as you would a module. You bind an interface to a port as a single
item (rather than as all the variables etc. it represents). You access interface elements through
the interface instance name (from the instantiating module) or through the port instance name
(from an instantiated submodule).
You can declare a virtual interface, a handle to which you can throughout the simulation
assign to different interfaces without changing the code that accesses the interface elements
(those interface elements must be similarly named, though would presumably be differently
implemented).
An interface can make available (import) a subprogram to modules. The interface can export
that subprogram from some other module (all interface directions are with respect to the
modules using the interface). Using the extern forkjoin construct, the interface can export a
task (but not a function) from multiple instances of the same module (the task definition must
contain code to ensure that only one of the instances writes task outputs upon return).

Verilog Application Workshop

E-28

SystemVerilog Verification Features


Among the verification features that SystemVerilog offers are:
Classes

Enhanced Scheduling Semantics

Constrained Randomization

Interprocess Synchronization

Clocking Blocks

Program Blocks

SystemVerilog Assertions (SVA)

Data-Oriented Functional Coverage

Direct Programming Interface (DPI)

(SV2K5) E-29

SystemVerilog Verification Features

Verilog Application Workshop

E-30

Classes
You model dynamic objects (cells, packets) with classes.
SystemVerilog classes closely parallel C++ classes, with:

Constructors

Static members

Data hiding

Class inheritance (is a...)

Class aggregation (has a...)

Class templates

Abstract classes

Virtual methods

class Packet;
local bit [3:0] command; // private data
local bit [40:0] address;
local bit [4:0] master_id;
local integer time_requested;
local integer time_issued;
local integer status;
task clean(); // public interface methods
command
= IDLE;
address
= 0;
master_id = 5'bx;
endtask
task issue_request( int delay );
... // send request to bus
endtask
function integer current_status();
return status;
endfunction
function new(); // constructor
clean();
endfunction
endclass : Packet

(SV2K5) E-31

Classes
A class is a user-defined type that may include member properties (data) and member
subprograms (methods) to manipulate the data.
You define a class to represent a kind of an object. For example, engineers commonly define
a class to represent a packet. The packet properties may include a command field, an address
field, a sequence number, a time stamp, and a payload. The packet methods may include
subprograms to initialize the packet, set the command, read the packets status, or check the
sequence number. Each instance of the packet has these member properties and methods.
The features of a SystemVerilog class are a subset of the features of a C++ class:
You use object handles instead of class instances or class pointers. All class objects are
dynamic objects, automatically deleted when they go out of scope. This automatic
garbage collection prevents memory leaks. You may not assign a handle of an
unrelated type to a class handle.

Verilog Application Workshop

E-32

Enhanced Scheduling Semantics


To permit predictable interactions in a zero-delay environment, SystemVerilog adds
four new regions (shown in bold) to each Verilog simulation time instant:
Preponed
PLI control point (currently undefined). Sample variables.
Pre-active
PLI control point (cbAtStartOfSimTime)
Start of iterative regions
Active
Execute scheduled processes
Inactive
Execute rescheduled (#0) processes
Pre-NBA
PLI control point (cbNBASynch)
NBA
Update nonblocking assignments
Post-NBA
PLI control point (cbReadWriteSynch)
Observed
Evaluate property expressions
Post-observed PLI control point (currently undefined)
Reactive
Execute action blocks and program blocks
Re-inactive
Execute rescheduled (#0) action blocks and program blocks
Pre-postponed PLI control point (cbAtEndOfSimTime)
End of iterative regions
Postponed
PLI control point (cbReadOnlySynch)
(SV2K5) E-33

Enhanced Scheduling Semantics


Only the SystemVerilog constructs schedule events in the Observed through Re-inactive
regions.
SystemVerilog evaluates triggered property expressions in the Observed region. This
evaluation occurs only once in any simulation time instant.
SystemVerilog schedules execution of action blocks and program blocks in the Reactive
region.
Note: The IEEE 1364-2001 standard for Verilog does not actually mention any of these regions by
name. It implies [5.3] the existence of Active, Inactive, NBA, and monitor regions. It implies
[27.33.2] the Pre-active, Post-NBA, and Postponed callback regions. One needs to go to the
Verilog-2005 standard to find callbacks implying the Pre-NBA and Pre-postponed regions.

Verilog Application Workshop

E-34

Constrained Randomization
Constrained random variables can direct tests toward scenarios you have not thought of.
SystemVerilog provides these capabilities:
Simple randomization of unsigned integers of up to 32 bits

Randomization of scope variables with in-line constraints that may be weighted and
may involve multiple random variables, with ability to order constraint resolution

Randomization of class object hierarchies with capability to enable and disable


randomization of individual properties and enable and disable individual class
constraints.

Constructs to randomize execution of procedural statements

class MyRand;
rand bit [1:0] x;
constraint c1 {x != 2b00;}
endclass : MyRand
class MyXRand extends MyRand;
constraint c2 {x inside {[0:2]};}
endclass : MyXRand

MyXRand xr1 = new;


initial begin
int success;
success = xr1.randomize();
$display("x is %b", xr1.x);
end

(SV2K5) E-35

Constrained Randomization
Use of random values can make your test environment more effective because the random
values can steer your tests toward scenarios that you might not have imagined. However, you
do need to constrain the random values to useful sets or ranges to also make your tests
reasonably efficient.
SystemVerilog provides these mechanisms to generate random values:
You can use $urandom to generate 32-bit unsigned random values, and $urandom_range to
restrict those values to a range.
You can use std::randomize() to randomize any set of integral scope variables. With
std::randomize() you can provide an in-line constraint block. In the constraint block, you
specify constraints and can specify an order for the solver. Constraint expressions may involve
relationships between the values of random variables and may provide weights to sets or
ranges of values. The weights can be variables that you change during simulation.
You can use the built-in randomize() class method to (without arguments) randomize all
integral properties of the class instance hierarchy declared rand or randc or (with arguments)
to randomize only the specified class properties. With class randomization, you can also
predefine constraint blocks as class members. You can enable and disable these class or
individual constraint blocks using their built-in constraint_mode() method, and can enable
and disable randomization of a class or individual variable using their built-in rand_mode()
method. All classes also implement the built-in pre_randomize() and post_randomize()
callbacks that you can reimplement to do whatever you want to do just before and after the
randomization.
You can use the randcase and randsequence constructs to randomize execution of procedural
statements.

SystemVerilog provides for object and thread stability. Adding new objects or threads after
previous ones in the same block does not affect the random values of previous ones.
Verilog Application Workshop

E-36

Interprocess Synchronization
SystemVerilog adds synchronization mechanisms:
A built-in semaphore class with:
function new(int keyCount=0);
task get(int keyCount=1);
function int try_get(int keyCount=1);
task put(int keyCount=1);

A built-in mailbox class with:


function new(int bound=0);
task put(singular message);
function int try_put(singular message);
task get(ref singular message);
function int try_get(ref singular message);
function int num();

Create and initialize


Get keys (blocking)
Get keys (nonblocking)
Put keys back
Create and initialize
Put message (blocking)
Put message (nonblocking)
Get message (blocking)
Get message (nonblocking)
Check for message

Enhanced event with


->> [ delay_or_event_control ]
hierarchical_event_identifier.triggered
wait_order()
= == != === !==

Trigger delay option


triggered property
Wait event sequence
Alias and compare

(SV2K5) E-37

Interprocess Synchronization
To model a complex system or a reactive testbench, you need synchronization and
communication mechanisms.
SystemVerilog adds a built-in semaphore class for synchronization and mutual exclusion to
shared resources, and a built-in mailbox class for communication between processes, and
enhances the event type with a persistent triggered state and some operations.
A semaphore is conceptually a holder of keys. When you create the semaphore you initialize
it with a certain number of keys. You code your processes to get keys before utilizing the
limited resource. You can choose to block the process execution until it gets the keys. You
code your processes to put the keys back when they have finished utilizing the resource.
A mailbox is conceptually a queue of messages. When you create the mailbox you initialize it
to a limited or unlimited size. You code your processes to put messages at the front of the
mailbox. You can choose to block the process execution until room is available in the mailbox.
You code your processes to get messages from the back of the mailbox. You can choose to
block the process execution until a message is available. The message can be any type except
unpacked array, unpacked structure or unpacked union.
The nonblocking event trigger emits the referenced event in the nonblocking assignment
region of the simulation cycle.
The value of the events triggered property persists throughout the simulation time step.
You can use this property as an argument to wait().
The wait_order construct suspends the calling process until all of the specified events are
emitted. If in order, it executes the pass block of the optional action block. If not in order, it
executes the fail block of the optional action block.
Verilog Application Workshop

E-38

Clocking Blocks
A clocking block separately captures a set of signals timing requirements:
The clocking event

Input sampling skew with respect to the clocking event

Output driving skew with respect to the clocking event


default clocking cb1 @(posedge clk);
default input #1step output #0ns;
inout data; // must use default skews
input ready, enable = top.mem1.enable;
input #3ns addr;
output negedge ack;
endclocking : cb1
default drive

ack drive

default sample
addr sample

(SV2K5) E-39

Clocking Blocks
SystemVerilog adds the clocking construct to specify a set of timing requirements for a set
of signals. The clocking block construct is a key element of a cycle-based verification
methodology it frees the user from specifying the sample and drive time for each assignment.
For each clocking block, the user specifies a clock expression and can specify default and
signal-specific sample and drives skews with respect to that clock. The user can define
multiple clocking blocks and specify which to use on a per-assignment basis. The user can
optionally nominate a default clocking block for use with any cycle delays that do not
otherwise specify an associated clocking block.
Signals and clock events may appear in multiple clocking blocks.
To avoid races when #0 skews are specified, clocking block inputs are sampled in the
Observed region and clocking block outputs are driven in the NBA region.
Sampling is otherwise done in the Preponed region.
You cannot directly reference a hierarchical signal through a clocking block. You need to
declare a clocking block alias for the hierarchical expression (which may contain bit-selects,
part-selects and concatenations):
input instruction = { opcode, regA, regB[3:1] };

You can use the clocking block name in an event control:


@cb1 // equivalent to @(posedge clk)

A stand-alone cycle delay refers to the default clocking block:


##2; // equivalent to repeat(2) @(posedge clk);

Verilog Application Workshop

E-40

Program Blocks
A program block separately captures testbench data, subprograms, and processes.
Its restrictions and scheduling semantics help minimize races:
Cannot contain always blocks, UDPs, modules, interfaces, or other programs

Can assign program variables only with blocking assignments

Can assign nonprogram variables only with nonblocking assignments

Can access program variables only from programs

Executes in Reactive region after all design events are processed

You define and instantiate a program block very similarly to a module:


module top;
test t1 (port_map);
dut d1 (port_map);
endmodule : top

program test (input..., output...);


...
endprogram : test

module dut (input..., output...);


...
endmodule : dut

(SV2K5) E-41

Program Blocks
The program block:

Captures testbench data and subprograms

Executes in the Reactive region to minimize races

Modules and programs use similar port declaration and mapping syntax.
Nested programs with no ports or top-level programs that are not explicitly instantiated are
implicitly instantiated once, using the same instance and declaration name.
A program can have initial and final blocks but not always blocks.

Verilog Application Workshop

E-42

SystemVerilog Assertions (SVA)


With SystemVerilog Assertions (SVA) you specify and verify design properties.
You can place concurrent assertions almost anywhere in the design hierarchy.
Synthesis tools ignore SVA
You can use the same assertions for dynamic analysis (simulation) and static
analysis (formal verification tools).
During simulation, you can also capture property coverage data.
immediate assertion

concurrent assertion

always_comb
if (sel==0)
mux_out = in0;
else if (sel==1)
mux_out = in1;
else
assert (0)
else
$error("Bad mux select");

property abcd;
@(posedge clk)
a ##1 b |=> c ##1 d;
endproperty
A1: assert property (abcd);

(SV2K5) E-43

SystemVerilog Assertions (SVA)


An assertion asserts that a property of the design holds. You use assertions mainly to verify
design properties. You can also use covers to measure how completely the test environment
exercises the properties, and for static formal verification, you can use assumptions to
generate setup sequences on design inputs. These are all part of SVA.
SystemVerilog has both immediate and concurrent assertions:

You make an immediate assertion statement in a procedural block. You assert that a boolean
expression is at that point true.

You make a concurrent assertion within the scope of an interface, module, or program. You assert
that a design property holds. You define the property as a sequence of design states, and specify
a clock with which to sample the design states. Your property definition may utilize other
(potentially predefined, even parameterized) sequences and properties, each of which may have a
different clock.
You can place a concurrent assertion as a procedural statement in an always or initial block.
If in an initial block, it is checked only once at the first clock. It can inherit its clock from the
procedural block. It will inherit enabling from its surrounding conditional statement (if any),
if no timing control preceeds it in the block. This placement of an assertion does not suspend
block execution.
You can place an assertion after the expect keyword as a procedural statement. This placement
of an assertion does suspend block execution until the assertion passes or fails.

You can associate an action block with each assertion. The pass part of the block executes if the
assertion passes, and the fail part of the block executes if the assertions fails. You can use $info,
$warning, $error and $fatal system tasks to associate a severity with assertion failure.

Verilog Application Workshop

E-44

Data-Oriented Functional Coverage


Coverage is a measure of how completely the test environment exercises the design.
Data-oriented functional coverage focuses on design variables and expressions:
You can cover integral variables and expressions
Automatically binned, or if user-defined bins, then:
Can bin by value, value or range set, value or range transition set
Can also declare default bin and illegal and ignored values, sets and ranges

You can cover cross-products (combinations) of integral variable values


Automatically binned, or if user-defined bins, then:
Can define filtering of values and bins that partake in the cross

covergroup cg @(posedge clk);


a: coverpoint var_a {
bins a1 = { [0:63] };
bins a2 = { [64:127] };
bins a3 = { [128:191] };
bins a4 = { [192:255] }; }
b: coverpoint var_b {
bins b1 = {0};
bins b2 = { [1:84] };

bins b3 = { [85:169] };
bins b4 = { [170:255] }; }
c : cross a, b {
bins c1 = ! binsof(a) intersect
{[100:200]};
bins c2 = binsof(a.a2) || binsof(b.b2);
bins c3 = binsof(a.a1) && binsof(b.b4);
}
endgroup
(SV2K5) E-45

Data-Oriented Functional Coverage


Coverage is a measure of the percentage of verification objectives that have been met. You use
this metric to evaluate the progress of your verification efforts, in order to redirect further
efforts toward areas of the design that are less well tested.
Coverage is in two general categories: tool-instrumented code (lines, statements, blocks,
expressions) coverage; and user-defined functional (design behavior) coverage. All coverage
described by the SystemVerilog standard refers to functional coverage.
Functional coverage measures how well the test environment exercises user-defined design
behavior. Functional coverage requires a structured approach to verification and (often
painstaking) manual effort.
With SystemVerilog functional coverage, you can:

Cover integral variables and expressions

Cover combinations of integral variable values

Define coverage bins (or use automatic binning)

Associate bins with sets of values, transitions, or cross products

Filter conditions at multiple levels

Specify events and sequences to trigger coverage sampling

Make procedural statements to enable/disable and query coverage

Verilog Application Workshop

E-46

Direct Programming Interface (DPI)


DPI is an interface between SystemVerilog subprograms and foreign language functions.
Each side (layer) is separately defined (currently only C foreign layer defined)

The SystemVerilog layer is totally unaware of the foreign layer


Calls in SystemVerilog obey SystemVerilog semantics
Data is restricted to SystemVerilog types
Cannot interface between class member methods

Make an import declaration to enable calls to foreign functions


Maps a SystemVerilog subprogram call to a foreign language implementation
import "DPI-C" pure function real sin(real);

Make an export declaration to make subprograms available to foreign calls


Maps a SystemVerilog subprogram implementation to a foreign language call
export "DPI-C" task mySVTask;

(SV2K5) E-47

Direct Programming Interface


The Direct Programming Interface (DPI) is an interface between SystemVerilog and a foreign
programming language that maps subprogram calls in either language to subprogram
implementations in the other language. The standard defines the SystemVerilog layer and the
foreign language layer separately: SystemVerilog does not know or care that its subprograms
are called or implemented in some other language. The standard currently defines only a C
foreign layer.
To enable SystemVerilog code to call a foreign language function, you make an import
declaration. You can import (map) a foreign language function multiple times to multiple
SystemVerilog names (each potentially with different default argument values). Imported
subprograms have the same semantics as in SystemVerilog: tasks do not return a value;
functions do not consume time.
To enable foreign language code to call your SystemVerilog subprograms, you make an
export declaration. You can export (map) a SystemVerilog subprogram to only one C
function, as the C function resides in the global (extern) namespace. However, you can map
multiple SystemVerilog subprograms in different scopes to the same C function call if the
SystemVerilog subprograms all have the same signature.
An imported C function is aware of the SystemVerilog scope from which it is called and can
change that scope to call a SystemVerilog subprogram exported from some other scope.
As neither layer is aware of the other layers current object, you cannot import or export
class member methods.
Data passed between the two layers is restricted to SystemVerilog data types. Arrays, structs,
and vectors are passed by reference. Small types are passed by value. Function returns are
passed by value, thus are restricted to the small types.
Verilog Application Workshop

E-48

Summary
The IEEE standard for SystemVerilog (1800) is a substantual enhancement to the IEEE
standard for Verilog (1364)
Pages:
Sections:
Appendices:
Keywords:

Verilog-2001
791
27
8
123

SystemVerilog adds
664
30
11
97

Implementing and using SystemVerilog is a huge effort for vendors and designers
Some vendors may not yet support some language constructs

Most users will adopt SystemVerilog features only as needed

(SV2K5) E-49

Summary
SystemVerilog is an enhancement to Verilog-2001. A SystemVerilog compiler must accept all
Verilog constructs. SystemVerilog deprecates only the defparam and assign/deassign
keywords.
Having reserved new keywords means that a SystemVerilog compiler might not compile
an existing Verilog design. For example, if you have a data out signal named do, then
a SystemVerilog compiler cannot compile the design, as do is a SystemVerilog
keyword.
As SystemVerilog is an enhancement to Verilog-2001, to optimally implement your designs
in SystemVerilog, you need to also be comfortably familiar with Verilog-2001.

Verilog Application Workshop

E-50

This page intentionally left blank.

Verilog Language and Application

Verilog Application Workshop

E-52

Index
Symbols

# - see delay
$display 18.15, 18.19, 18.23
$fclose 18.35
$fdisplay 18.38
$finish 18.27
$fmonitor 18.38
$fopen 18.35
$fstrobe 18.38
$fstrobeb 19.31
$fwrite 18.38
$monitor 18.23
$random 19.19
$readmemb 18.39
$readmemh 18.39
$realtime 18.21, 18.26
$stime 18.21
$stop 18.27
$strobe 18.19
$time 18.21, 18.26
$timeformat 18.25
$write 18.15
-> trigger 19.25
@ - file input format 18.41
@ - timing control 8.27
define 18.9
ifdef 18.11
include 18.7
timescale 8.33, 18.5
undef 18.10

begin...end 6.5
behavioral modeling 2.14, 10.1310.16
bit-wise operators 5.7
blocking assignment 8.7, 9.59.19
clocked procedure 9.9, 13.31
combinational procedure 9.15
intra-assignment delay 22.31, 22.32
register inference in synthesis 16.7

C
case 6.176.26
full 15.2915.34
parallel 15.23
synthesis 15.1915.34
clocked procedures
synthesis 13.1913.32
combinational logic
synthesis 13.713.18
comments 3.25
compilation 3.23
concatenation 5.23
conditional operator 5.21, 7.15
constant
see parameter
continuous assignment
see assign

define
see define
A
defparam 4.40
abstraction levels 2.132.18
delay 8.31
always 3.13, 6.9, 8.5
intra-assignment delay 22.29
arithmetic operators 5.5
delay modeling 22.5
array 4.43
distributed 22.9
assign 4.234.27, 7.57.8, 12.20
inertial versus transport 22.23
synthesis 13.15
lumped 22.7
assignment
min, typ, max 22.13
incomplete 13.11
path
intra-assignment delay 22.29
see specify
see also blocking and non-blocking assignment rise and fall times 22.13
delta cycle 8.11

Verilog Application Workshop


MSSIVE/7.3

Cadence Design Systems, Inc.

inout ports 3.5, 24.15


input ports 3.5
integer 4.33

equality operators 5.175.20


event control 6.9, 8.27
event list 3.15
complete 13.7
incomplete 13.9
event trigger 19.25

J
join
see fork

file

latch
synthesis 13.13, 16.11
library 3.19
literals 4.19
integer 4.33
logic strength modeling 21.25
logic value system 4.5
logical operators 5.9
loop 6.276.32
for 6.27
repeat 6.29
synthesis 6.31
while 6.29
lumped delays 22.5

input 18.3918.42
output 18.3518.38, 20.17
comparison results 20.25
test vectors 20.27
visualization 20.19
for loop 6.27
fork 19.2119.24
format specifiers 18.17
function 17.517.30
call 17.9
declaration 17.7
issues 17.23
marker 17.11
multiple calls 17.25

macro
see define
MCD
see multi-channel descriptor
memories
modeling 24.11
module 3.5
instantiation 3.73.12, 12.25, 14.17, 21.17
array of instances 21.19
multi-channel descriptor (MCD) 18.3518.38

gate-level modeling
see structural modeling

H
hierarchy
connecting 3.73.12

I
if 6.136.16
synthesis 15.17
ifdef
see ifdef
include
see include
incomplete assignment 13.11, 13.25
indentation 3.25
initial 3.13
synthesis 15.35
initialization 4.6, 19.8

Verilog Application Workshop


MSSIVE/7.3

N
name
rules 3.27
negedge 6.9, 13.19
net type 4.7, 4.234.27
conflict resolution 4.27
non-blocking assignment 8.5, 8.98.23, 9.79.19
clocked procedure 9.11, 10.11, B.20
intra-assignment delay 22.31, 22.32

ii

Cadence Design Systems, Inc.

operator 5.3
arithmetic 5.5
synthesis 14.314.18
bit-wise 5.7
concatenation 5.23
conditional 5.21, 7.15
equality 5.19
difference between logical and case 5.17
logical 5.9
precedence 5.27
relational 5.15
replication 5.25
shift 5.13
unary reduction 5.11
output ports 3.5

reduction operators 5.11


register type 4.7, 4.294.34
relational operators 5.15
repeat loop 6.29
replication 5.25
reset
asynchronous in synthesis 13.21
synchronous in synthesis 13.21
resource sharing 14.914.13
RTL modeling 2.14, 10.910.20
example 12.912.20
rules 13.513.32

S
shift operators 5.13
simulation
cycle 8.118.23
initialization 19.7
specify 22.11
conditional path delays 22.19
features 22.15
full path 22.17
parallel paths 22.17
parameter 22.21
path delays 22.18
specparam 22.21
state machine 15.915.16
stimulus 19.1119.24
clock generation 19.35
strength modeling
see logic strength modeling
strings 19.27
structural modeling 2.14, 21.521.28
synthesis directives 15.2515.34
system task
$display 18.15
$fclose 18.35
$fdisplay 18.38
$fmonitor 18.38
$fopen 18.35
$fstrobe 18.38
$fwrite 18.38
$monitor 18.23
$random 19.19
$readmemb 18.39
$readmemh 18.39

P
parameter 4.7, 4.37, 12.11
compared to specparam 22.22
defparam 4.40
overriding 4.39
see also specparam
path delays 22.11
PATHPULSE$ 22.26
ports
inout(bidirectional) 3.5, 24.15
input 3.5
named connection 3.9
ordered connection 3.11
output 3.5
unconnected 3.10, 3.12
posedge 6.9, 13.19
primitives 21.721.16
conditional 21.11
instantiation 21.15
see also UDP
procedural assignments 6.7, 7.11
procedure
always 6.5, 8.5
see also always
initial 6.5
see also initial
named 8.5

Verilog Application Workshop


MSSIVE/7.3

iii

Cadence Design Systems, Inc.

$realtime 18.21
$stime 18.21
$strobe 18.19
$time 18.21
$timeformat 18.25
$write 18.15
formating 18.17

types
choosing the correct type 4.35
see net, register or parameter
summary of rules 4.45

U
UDP A.4
combinational A.9
edge-sensitive A.15, A.18
level sensitive A.13
ult 6.17
unary reduction operator 5.12
unknown logic values 21.13
user defined primitive
See UDP

T
task 17.5, ??17.30
call 17.15
declaration 17.13
disabling 17.19
issues 17.23
multiple calls 17.25
static 17.21
testbench use 19.37
without timing controls 17.17
testbench 2.21, 10.510.8
example 12.2112.30
organisation 19.9
pseudo-code driven 20.520.14
testbench output
see system task or file output
timescale
see timescale
timing control 8.258.35
event based 8.27
wait 8.29
tristates 16.13

Verilog Application Workshop


MSSIVE/7.3

V
variable
hierarchical access 19.29
vector 4.11
bit length 4.15
bit order 4.13
capture and playback 19.3119.34

W
wait 8.29
while loop 6.29
wire 4.234.27
work library 3.19

iv

Cadence Design Systems, Inc.

You might also like