Vcs Quickstart
Vcs Quickstart
The Native Testbench technology in VCS is currently available to customers as part of a Early Access
program. Using these features requires additional LCA license features. Please contact
[email protected] for more details.
Comments?
E-mail your comments about this manual to
[email protected].
Copyright Notice and Proprietary Information
Copyright © 2006 Synopsys, Inc. All rights reserved. This software and documentation contain confidential and proprietary
information that is the property of Synopsys, Inc. The software and documentation are furnished under a license agreement and
may be used or copied only in accordance with the terms of the license agreement. No part of the software and documentation may
be reproduced, transmitted, or translated, in any form or by any means, electronic, mechanical, manual, optical, or otherwise,
without prior written permission of Synopsys, Inc., or as expressly provided by the license agreement.
Destination Control Statement
All technical data contained in this publication is subject to the export control laws of the United States of America.
Disclosure to nationals of other countries contrary to United States law is prohibited. It is the reader’s responsibility to
determine the applicable regulations and to comply with them.
Disclaimer
SYNOPSYS, INC., AND ITS LICENSORS MAKE NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Registered Trademarks (®)
Synopsys, AMPS, Arcadia, C Level Design, C2HDL, C2V, C2VHDL, Cadabra, Calaveras Algorithm, CATS, CSim,
Design Compiler, DesignPower, DesignWare, EPIC, Formality, HSPICE, Hypermodel, iN-Phase, in-Sync, Leda, MAST,
Meta, Meta-Software, ModelAccess, ModelTools, NanoSim, OpenVera, PathMill, Photolynx, Physical Compiler,
PowerMill, PrimeTime, RailMill, Raphael, RapidScript, Saber, SiVL, SNUG, SolvNet, Stream Driven Simulator,
Superlog, System Compiler, Testify, TetraMAX, TimeMill, TMA, VCS, Vera, and Virtual Stepper are registered
trademarks of Synopsys, Inc.
Trademarks (™)
abraCAD, abraMAP, Active Parasitics, AFGen, Apollo, Apollo II, Apollo-DPII, Apollo-GA, ApolloGAII, Astro, Astro-Rail,
Astro-Xtalk, Aurora, AvanTestchip, AvanWaves, BCView, Behavioral Compiler, BOA, BRT, Cedar, ChipPlanner, Circuit
Analysis, Columbia, Columbia-CE, Comet 3D, Cosmos, CosmosEnterprise, CosmosLE, CosmosScope, CosmosSE,
Cyclelink, Davinci, DC Expert, DC Expert Plus, DC Professional, DC Ultra, DC Ultra Plus, Design Advisor, Design
Analyzer, Design Vision, DesignerHDL, DesignTime, DFM-Workbench, DFT Compiler, Direct RTL, Direct Silicon
Access, Discovery, DW8051, DWPCI, Dynamic-Macromodeling, Dynamic Model Switcher, ECL Compiler, ECO
Compiler, EDAnavigator, Encore, Encore PQ, Evaccess, ExpressModel, Floorplan Manager, Formal Model Checker,
FoundryModel, FPGA Compiler II, FPGA Express, Frame Compiler, Galaxy, Gatran, HDL Advisor, HDL Compiler,
Hercules, Hercules-Explorer, Hercules-II, Hierarchical Optimization Technology, High Performance Option, HotPlace,
HSPICE-Link, iN-Tandem, Integrator, Interactive Waveform Viewer, i-Virtual Stepper, Jupiter, Jupiter-DP, JupiterXT,
JupiterXT-ASIC, JVXtreme, Liberty, Libra-Passport, Library Compiler, Libra-Visa, Magellan, Mars, Mars-Rail, Mars-
Xtalk, Medici, Metacapture, Metacircuit, Metamanager, Metamixsim, Milkyway, ModelSource, Module Compiler, MS-
3200, MS-3400, Nova Product Family, Nova-ExploreRTL, Nova-Trans, Nova-VeriLint, Nova-VHDLlint, Optimum
Silicon, Orion_ec, Parasitic View, Passport, Planet, Planet-PL, Planet-RTL, Polaris, Polaris-CBS, Polaris-MT, Power
Compiler, PowerCODE, PowerGate, ProFPGA, ProGen, Prospector, Protocol Compiler, PSMGen, Raphael-NES,
RoadRunner, RTL Analyzer, Saturn, ScanBand, Schematic Compiler, Scirocco, Scirocco-i, Shadow Debugger, Silicon
Blueprint, Silicon Early Access, SinglePass-SoC, Smart Extraction, SmartLicense, SmartModel Library, Softwire,
Source-Level Design, Star, Star-DC, Star-MS, Star-MTB, Star-Power, Star-Rail, Star-RC, Star-RCXT, Star-Sim, Star-
SimXT, Star-Time, Star-XP, SWIFT, Taurus, Taurus-Device, Taurus-Layout, Taurus-Lithography, Taurus-Process,
Taurus-Topography, Taurus-Visual, Taurus-Workbench, TimeSlice, TimeTracker, Timing Annotator, TopoPlace,
TopoRoute, Trace-On-Demand, True-Hspice, TSUPREM-4, TymeWare, VCS Express, VCSi, Venus, Verification
Portal, VFormal, VHDL Compiler, VHDL System Simulator, VirSim, and VMC are trademarks of Synopsys, Inc.
Service Marks (SM)
MAP-in, SVP Café, and TAP-in are service marks of Synopsys, Inc.
SystemC is a trademark of the Open SystemC Initiative and is used under license.
ARM and AMBA are registered trademarks of ARM Limited.
All other product or company names may be trademarks of their respective owners.
Contents
1. Introduction
iii
Functional Coverage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-18
Running the Test Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-19
FIFO Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-21
Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-28
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-30
iv
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-40
Appendix C. Verification IP
Assertion IP Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-2
The VCS Verification IP (VIP) Library . . . . . . . . . . . . . . . . . . . . . . C-3
v
vi
About This Guide
Audience
This quick start guide consists of several chapters, and will introduce the features
used in testbench and verification development from basic to more advanced in
steps. We will add to these chapters in the future installation of this guide.
• Chapter 2 is intended for engineers experienced with either Verilog or VHDL
and are ready to use new standard languages such as SystemVerilog to
raise the quality and efficiency of their design and verification processes
through advanced constrained-random and functional coverage and
assertion verification. This guide assumes basic knowledge of hardware
design and verification.
• Chapter 3 builds on chapter 2 content and assumes basic understanding of
SystemVerilog as well as design verification experience with either Verilog
or VHDL. This chapter introduces high-level data abstraction such as class
and object oriented programming concepts in the context of VCS supported
mechanisms. New constructs for structured and layered testbench
development are introduced such as interfaces and encapsulation of drivers
and monitors.
Supporting Documentation
The VCS Document Navigator provides an interface to the documentation set.
The navigator is invoked on the command line as follows:
vcs -doc
1-1
With these built-in features, you can code valid constraints on data
and types of activities to stimulate the Design Under Test (DUT).
Once a constraint-random environment is setup, you need to debug
and validate the simulation results. You can also perform functional
coverage analysis to find areas that have not been verified.
Chapter 1: Introduction
1-2
For larger designs under test, such as SOC, and systems which use
industry standard protocols such as PCIExpress, Ethernet, etc.,
users will have access to pre-built and pre-verified verification
components (VIP) that are ready to plug into the testbench
environment. VCS also incorporates pre-built and pre-verified
assertion-based IPs (AIP) which provide protocol coverage and
checks for dynamic simulations.
In the chapters that follow, we will demonstrate how you can use the
features of VCS to verify the FIFO block described in Appendix A.
You do not have to re-architect your environment to take advantage
of the new verification features of VCS. We will also show you how
you can incrementally use these features with your existing
environment.
In this quick start book we will introduce the reader to the testbench
and verification features in steps. Each chapter will introduce the
next set of advanced constructs starting from chapter 2 with basic
constructs. Chapter 3 will introduce high-level abstraction by
introducing object-oriented programing concepts and interfaces. The
readers will be introduced to the concept of structured and layered
1-3
testbench development using the advanced constructs supported in
VCS. This will be extended in the next chapters in the future editions
of this quickstart book.
Chapter 1: Introduction
1-4
2
Using Basic Features in VCS to Verify Your
Design 2
The purpose of this chapter of the quick start guide is to provide a
conciseintroduction to the basic SystemVerilog assertions,
SystemVerilog testbench constructs, DV, functional and code
coverage. A simple FIFO module is used to demonstrate how to
develop a verification environment using SystemVerilog testbench
constructs for constraints and coverage.
2-1
the testbench is through port and boundary connections, thus
avoiding unintended non-structured access to the DUT. The
SystemVerilog program block facilitates this separation. This
program block is similar to a module in Verilog, but is specifically
intended to distinguish between the testbench and the design code.
In general, using a SystemVerilog program block in this way, avoids
race conditions that are usually inherent in simulation tests. In
addition, components and verification specific code blocks such as
constraint blocks, functional coverage, random data variables, etc.,
are referenced within program blocks.
The next few sections provide guidelines and examples of how you
can use the basic features of VCS to verify the FIFO block. The
testbench and verification code will provide you with the steps to
simulate designs with the latest VCS. You can use this structure and
the code with your current design environment to increase the
number of test cases as well as create more complete and complex
routines for testing the DUT.
Verification Architecture
In this section, you will be introduced to the methodology, testbench
constructs and assertion technology used in constructing a
constrainted random verification environment. One of the major
advantages of the new features in VCS is the ability to create a
verification environment in a way that completely separates the
testbench, and its code, from the design under test (DUT). Creating
this type of structure for the testbench reduces the number of errors,
and reduces the time taken to debug both the testbench and the
design code. In this methodology, the connection to the DUT from
the testbench is through port and boundary connections, thus
avoiding unintended non-structured access to the DUT. The
SystemVerilog program block facilitates this separation. This
program block is similar to a module in Verilog, but is specifically
Top-Level
Clock generator
Testbench DUT
(Program (Verilog/
Block) VHDL)
Here the top-level shell contains the clock generator which is passed
to the testbench and the DUT. The DUT can be either Verilog,
SystemVerilog or VHDL. The testbench contains the program block,
which has additional verification features.
fifo_mwrite fifo_mread
m
a
DUT
i
l
(Verilog/VHDL)
b
o
x
queue fifo_check
Program Block
The program block is a SystemVerilog module that is specialized for
verification purposes. Verification objects like constraint blocks,
functional coverage, random signals, etc., which comprise the test
stimulus will be referenced within program blocks. A program block
contains the testbench components for a design. Usually the design
is created in an HDL, such as SystemVerilog, Verilog, or VHDL. The
program block allows you to create a well-defined boundary between
the testbench code and the design code.
program fifo_test (
rst_n,clk,data_in,data_out,push_req_n,pop_req_n,diag_n,empty,full,
almost_empty,almost_full,half_full,error);
One thing to remember here is that the program block drives data to
the DUT’s input and reads data from the DUT’s output, so the port
directions will be opposite to those of the DUT.
The testbench code such as tasks and variables are placed in the
program block as described in the following section.
Let’s assume the FIFO word length or the data field is 16-bits. The
depth of the FIFO can be parameterized at the top. The other field is
called data_rate and it is 16 bits wide. The data_rate specifies how
To generate random data for these two fields, you need to use the
keyword rand. This marks these signals as randomizable data
fields.
The data rate can take values between 1 and 1023. We do not want
to test out all combinations. We want to check cases for low, medium
and high data rates. We want to generate data rates between 1 and
8, 128 and 135, and 512 and 519. We can use the dist construct to
specify this as shown below.
//////////////////////////////////////////
// Definition: Random Write Data Class
//////////////////////////////////////////
class random_write_data;
rand logic [`WIDTH-1:0] data [`DEPTH];
rand logic [15:0] data_rate;
constraint reasonable {
data_rate > 0;
data_rate dist { [1:8] := 10 , [128:135] := 10, [512:519]
:=1 } ;
}
endclass
constraint reasonable {
data_rate > 0;
data_rate dist { [1:8] := 10 , [128:135] := 10, [512:519]
:=1 } ;}
endclass
In this code, constraint is a keyword. Within this block, you can add
any and all necessary constraints. Also, on the dist line the number
after the “:=” specifies the weight. The highest data rate will occur
less frequently than the lower data rates.
You can now use this data_rate variable to test different read/write
data-rates of the FIFO. For very slow data rates, delay will have a
very large value, and for fast data rates, delay will have a low value.
This task first checks that empty becomes asserted within the first
two clock cycles. If empty does not become asserted within two
cycles, VCS will issue a verification error as follows:
All verification checks should have labels for ease of debugging. The
expect statement blocks the task from executing the next line of code
until the check is completed successfully or an error message is
issued. The next five lines of code immediately check that the other
output signals are properly set by the DUT. If they are not set
properly, VCS issues a verification error.
In the FIFO example, you can use a mailbox to send data from the
FIFO read task to the checker. First you need to instantiate and
initialize the mailbox as follows:
Next, in the fifo_read() task, you need to wait until there is data in the
FIFO, then pop a word off of the FIFO, and put it in the mailbox as
follows:
The mailbox has some built-in methods; we are using the put()
method to place data into the mailbox.
Now, the fifo_check() task reads from the mailbox, and checks the
expected data against the actual data. The statement that reads data
from the mailbox is as follows:
mbox.get(tempOut);
The first line of code asserts the push control line of the FIFO. The
second line puts the data generated into the queue. The generated
data (WRITE_DATA) is described in the following sections.
jo
in jo
in_any jo
in_no
n e
When fifo_check() is called, it will continuously wait for data from the
mailbox (which implies data was read from the FIFO), and then
check the data against the expected output.
program fifo_test(....);
// declarations
// tasks
//...
initial begin : main_prog
// instantiation of objects
// ...
fork
fifo_check();
join_none
..
//
end : main_prog
endprogram : fifo_test
Assertions
Assertions help designers and verification teams to catch bugs
faster. With VCS, you can easily add assertions into your design to
check for correct design behavior. Using VCS, you can write
Assertions
2-13
sophisticated assertions from scratch, or you can use the built-in
Checker Library. VCS has a rich set of checkers in its library that you
can easily instantiate in your design to identify bugs.
For our FIFO design example, the FIFO word size is 16 bits with a
depth of 128. We can use a FIFO assertion checker from the library.
Within the checker, there is a useful category value for enabling and
disabling assertions wih the same category value.
You can instantiate the FIFO assertion directly into either the Verilog
or the VHDL design. The assertion can also be put into a separate
file using the bind construct. This works for both Verilog and VHDL
blocks. Here is how you place an FIFO assertion checker into the
sample FIFO block design, with category level of 10:
In Verilog:
SVA_FIFO_inst : assert_fifo
generic map (depth => 128, elem_sz => 16,
coverage_level_1 => 31,
coverage_level_2 => 0,
coverage_level_3 => 31)
port map(clk => TOP_CLOCK, reset_n => rst_n, enq => push_req,
enq_data => data_in, deq => pop_req, deq_data => data_out);
Assertions
2-15
• cov_level_1_3 indicates there was an enqueue followed
eventually by a dequeue.
• cov_level_2_0 reports which FIFO fill levels were reached at
least once.
• cov_level_3_0 indicates the high water mark was reached on an
enqueue.
• cov_level_3_1 indicates there were simultaneous enqueue and
dequeue operations on an empty queue.
• cov_level_3_2 indicates there were simultaneous enqueue and
dequeue operations on a full queue.
• cov_level_3_3 indicates that empty condition was reached on
dequeue.
• cov_level_3_4 indicates that full condition was reached on
enqueue
• Line coverage reports which lines, statements, and blocks for any
instance/module of design were exercised during simulation.
• Condition coverage monitors values taken on by Boolean and
bitwise expressions, such as conditional expressions in if
statements, or conditional concurrent signal assignments.
Option Enables
-cm cond+tgl+line+fsm
Note:
(Location of the makefile is: $VCS_HOME/doc/examples/
nativetestbench/systemverilog/vcs_quickstart)
To run the simulation for 50 tests use the "+NUM" options to simv:
assertCovReport
cmView -b
To run the VHDL version of the FIFO, here is the compile command:
To run the simulation for 50 tests use the "+NUM" options to scsim:
cmView -b
FIFO Results
Let's simulate the FIFO with five sets of data using the command line
below.
The testbench reports the data_rate for each call of the task
fifo_mwrite() and fifo_mread().
VCS Coverage Metrics Release X-2005.06 Copyright (c) 2003 Synopsys, Inc
FIFO_RESET: Task reset_fifo started
FIFO_RESET_CHECK: Task reset_check started
FIFO_CHECK: Task check started
FIFO_MWRITE: Sending 128 words with data_rate of 1 to fifo at: 350
FIFO_MREAD: Reading 128 words with data_rate of 1 from fifo at: 350
FIFO_MWRITE: Sending 128 words with data_rate of 135 to fifo at: 26050
FIFO_MREAD: Reading 128 words with data_rate of 513 from fifo at: 26050
FIFO_MWRITE: Sending 128 words with data_rate of 134 to fifo at: 6605250
FIFO_MREAD: Reading 128 words with data_rate of 135 from fifo at: 6605250
FIFO_MWRITE: Sending 128 words with data_rate of 7 to fifo at: 8346050
FIFO_MREAD: Reading 128 words with data_rate of 3 from fifo at: 8346050
FIFO_MWRITE: Sending 128 words with data_rate of 1 to fifo at: 8448550
FIFO_MREAD: Reading 128 words with data_rate of 135 from fifo at: 8448550
FIFO_MWRITE: Sending 128 words with data_rate of 515 to fifo at: 10189350
FIFO_MREAD: Reading 128 words with data_rate of 130 from fifo at: 10189350
FIFO Results
2-21
At the end of the simulation, VCS reports on the assertion coverage
for the assert_fifo checker:
"/VCS_MX/Linux/packages/sva/assert_fifo.sv", 565:
fifo_test_top.SVA_FIFO_inst.cov_level_1_0.cover_number_of_enqs, 167943
attempts, 768 match, 0 vacuous match
"/VCS_MX/Linux/packages/sva/assert_fifo.sv", 572:
fifo_test_top.SVA_FIFO_inst.cov_level_1_1.cover_number_of_deqs, 167943
attempts, 768 match, 0 vacuous match
"/VCS_MX/Linux/packages/sva/assert_fifo.sv", 579:
fifo_test_top.SVA_FIFO_inst.cov_level_1_2.cover_simultaneous_enq_deq, 167943
attempts, 1 match, 0 vacuous match
"/VCS_MX/Linux/packages/sva/assert_fifo.sv", 587:
fifo_test_top.SVA_FIFO_inst.cov_level_1_3.cover_enq_followed_eventually_by_deq
, 167943 attempts, 547 match, 0 vacuous match
"VCS_MX/Linux/packages/sva/assert_fifo.sv", 715:
fifo_test_top.SVA_FIFO_inst.cov_level_3_1.cover_simultaneous_enq_deq_when_empt
y, 167943 attempts, 0 match, 0 vacuous match
"VCS_MX/Linux/packages/sva/assert_fifo.sv", 724:
fifo_test_top.SVA_FIFO_inst.cov_level_3_2.cover_simultaneous_enq_deq_when_full
, 167943 attempts, 0 match, 0 vacuous match
"VCS_MX/Linux/packages/sva/assert_fifo.sv", 733:
fifo_test_top.SVA_FIFO_inst.cov_level_3_3.cover_number_of_empty, 167943
attempts, 513 match, 0 vacuous match
"/VCS_MX/Linux/packages/sva/assert_fifo.sv", 744:
fifo_test_top.SVA_FIFO_inst.cov_level_3_4.cover_number_of_full, 167943
attempts, 0 match, 0 vacuous match
cover_simultaneous_enq_deq_when_empty
cover_simultaneous_enq_deq_when_full
cover_number_of_full
cover_simultaneous_enq_deq_when_empty
cover_simultaneous_enq_deq_when_full
fifo_mwrite(1);
fork
fifo_mwrite(1);
fifo_mread(1);
@(posedge clk) fifoCvr.sample();
join
The first line writes 128 words into the FIFO with a data_rate of 1.
The next five lines of code performs a simultaneous read and write,
ensuring the cover property
cover_simultaneous_enq_deq_when_full is hit.
FIFO Results
2-23
You can now look at the testbench coverage for 500 tests using this
command:
Coverage Summary
Number of coverage types: 1
Number of coverage Instances: 1
Cumulative coverage: 100.00
Instance coverage: 0.00
===============================================================
= Cumulative report for Cvr
===============================================================
Summary:
Coverage: 100.00
Goal: 90
WD 100.00 90 1
===============================================================
Cross Coverage Goal Weight
===============================================================
RDxWD 100.00 90 1
===============================================================
RD WD # hits at least
=======================================================
HIGH HIGH 2 1
HIGH LOW 11 1
HIGH MED 7 1
LOW HIGH 7 1
LOW LOW 105 1
LOW MED 104 1
MED HIGH 10 1
MED LOW 124 1
MED MED 132 1
=======================================================
FIFO Results
2-25
Coverpoint Coverage report
CoverageGroup: Cvr
Coverpoint: WD
Summary
Coverage: 100.00
Goal: 90
Number of User Defined Bins: 3
Number of Automatically Generated Bins: 0
Number of User Defined Transitions: 0
fifo_test.db
FIFO Results
2-27
Debug
VCS comes with a comprehensive built-in graphical user interface,
called Discovery Visual Environment (DVE). DVE supports graphical
debugging of mixed language designs including Verilog, VHDL, and
SystemVerilog. DVE is an intuitive environment that also supports
assertion debugging. Detailed documentation can be found in the
Discovery Visual Environment User Guide.
"fifo_test.v", 162:
fifo_test_top.test.fifo_check.unnamed$$_1: started at
550000ps failed at 550000ps
Offending '(tempIn == tempOut)'
TEST: FIFO read data 'h5ec3 DID NOT match expected data 'ha13c
You can use the VCS GUI to help you debug the problem.
Debug
2-29
simv -gui
Once the debugger starts, you can set breakpoints in the design or
testbench code, trace drivers, and navigate through the hierarchy
very easily and efficiently.
Summary
As described in this Quick Start Guide, the built-in verification
features of VCS can be used to quickly ramp up new users who are
unfamiliar with the new standard languages, such as SystemVerilog
Hardware Design and Verification Language (HDVL). VCS is leading
the industry to incorporate testbench, assertion and coverage
capabilities needed for today’s design and verification engineering
tasks. With these technologies encapsulated, VCS creates the
framework and foundation for building verification environments at
all levels, from module to cluster-of-modules, chip and system level
verification. VCS’s native support for verification can yield up to a 5x
performance speedup and a 3x reduction in memory usage. VCS
enables the thorough verification of complex SoC designs, in much
less time than with other tools and methods. The result is a far higher
likelihood of first-silicon success, which is the goal of every design
and verification engineer.
3-1
Verification Environment
In previous chapter we introduced the program block as the basic
building block which contains the testbench in SystemVerilog. A
program block will allow creation of a well defined boundary between
the test code and design code that will reduce the time to debug the
design and test code. The abstraction and modeling constructs
simplify the creation and maintenance of test-benches. The ability to
instantiate and individually connect each instance of a program
enables their use as generalized models. A similar design heirarchy
is used in this chapter as well.
Top-Level
Clock generator
Testbench DUT
(Program (Verilog/
Block) VHDL)
Here the top-level shell contains the clock generator which is passed
to the testbench and the DUT. The DUT can be either Verilog,
SystemVerilog or VHDL. The program block will incorporate the
strucutred testbench environment and components.
Figure 3-2
Verification Environment
3-3
Advanced Constructs for Testbench and Design in VCS
This section describes a few more of the advanced constructs added
in VCS 2005.06 and VCS 2006.06(beta) as part of SystemVerilog for
Testbench development, in conjunction with their usage model in a
structured testbench verification environment. There are many
additional constructs and SystemVerilog features in VCS 2006.06.
For details of all the SystemVerilog capabilities in VCS, refer to the
documents listed in the VCS Document Navigator. In this chapter of
the guide we will use the basic structure developed for testbench in
previous chapter to show how easy it is to use the advanced object
oriented constructs in VCS to create scalable and reusable
verification environment.
class Person;
//data or class properties
string name;
integer age;
string gender;
//initialization
function new();
Name = "";
Age = 0;
endfunction;
virtual task speak();
$display("This is a person \n");
endtask
endclass
class Person;
//data or class properties
...
virtual task speak();
endtask
endclass: Person
Now we can define an adult person and a baby with extension of the
Person, note in this case we are overriding the function in the base
class.
Classes and objects benefit users in various ways; above all they
encourage the reuse of software components that are developed for
specific task. Users will also reduce development time and risk
because systematic and modularized development using objects
provides more resilience and reduces code size.
fifo_intf intfFifo(clk);
// declaration and instantiation of of type fifo_intf
modports
Directional information for module ports is provided by using the
modport construct in SystemVerilog. In a verification environment
there are various views and uses for interface signals: some are
driven, such as in driver transactors, some are simply monitored,
such as in monitor transactors. In order to compartmentalize these
different views, modports are declared and defined for each of the
transactor views.
fifo_intf intfFifo(clk);
// declaration and instantiation of type fifo_intf
// pass modport to a program instantiation.
fifo_test test(intfFifo.Fifo_Driver);
Virtual Interface
Virtual interfaces provide a mechanism for separating abstract
models and test programs from the actual signals that make up the
design further promoting code re-use. For example, a network switch
router has many identical ports that operate the same way, say a
10Gbit MII for Ethernet connection. A single virtual interface
declared inside a class that deals with these Ethernet signals can
represent different interface instances at various times throughout
the simulation. A virtual interface can be declared inside as a class
property that can be initialized procedurally or by an argument to the
class constructor.
class fifo_driver
...
virtual fifo_intf v_intf; // full interface instance
...
endclass: fifo_driver
The instantiation of the interface can have several flavors in the
Testbench area:
In a program block:
v_intf = interface_passed_to_program;
Or through the class constructor:
fifo_wr_if = interface_passed_to_program;
b) Through class constructor:
...
initial
intfFifo.rst_n <= 0;
always @(posedge intfFifo.clk)
$display("Cycle is %0 \n",cyc++);
...
Figure 3-3 Timing reference for sample and drive of synchronous signals
interface fifo_intf;
....
endinterface: fifo_intf
Asynchronous Signals
The interface modport construct can be used to define and create
asynchronous ports and signal connections. The signal is defined as
an input or output in a modport declaration:
interface fifo_intf;
modport fifo_Driver(clocking cbDR, output rst_n);
modport fifo_Checker(clocking cbCheck)
....
endinterface: fifo_intf
In this case the signal rst_n is defined as asynchronous with respect
to the clock edges
There are a few sample test files that help introduce various
advanced topics such as using class extension to create new tests
as well as incorporating a SystemC checker object to show the VCS
SystemVerilog to SystemC connection features.
Interface
We have defined an interface for the FIFO. The FIFO interface
encapsulates not only the signals that read and write from the FIFO,
but also the access mechanisms of the FIFO.
The interface also contains a clocking block that defines the signal
timing with respect to the positive edge of the clock. The clocking
block will be only used by the testbench, and not be referenced by
the FIFO itself. The clocking block ensures proper driving and
sampling from the testbench to the FIFO.
fifo_intf intf(clk);
//program instantiation
fifo_test test(intf.tb);
// dut instantiation
DW_fifo_s1_sf_wrap #(WIDTH, DEPTH, ae_level, af_level,
err_mode, rst_mode)
dut (intf.dut);
Using modports ensures that the proper driving and sampling
semantics are used. If the engineer that is writing a test for the FIFO
attempts to drive signal “pop_req_n” asynchronously, then the
engineer will get an error. This prevents incorrect usage of the
interface.
Data Class
Following our example FIFO used in the first chapter let us assume
our FIFO word length is 16-bits. The depth of the FIFO is
parametrizable at the top. We have chosen the other fields for push
(write) or pop (read) data rates.
The “data” field is 16-bits wide. The data_rates for write and read are
16-bit wide as well. In this example we want the “data” field to contain
values such that the highest-order 2 bits are set, and constrain the
operation to push and pop only for the purpose of this exercise. The
code for these constraints would look like this:
class data_tr;
rand logic [15:0] data;
rand logic [15:0] wr_data_rate;
rand logic [15:0] rd_data_rate;
constraint reasonable {
data [15:14] == 2'b11;
wr_data_rate > 0;
wr_data_rate dist { [1:8] := 10, [60:80] := 10 }
rd_data_rate > 0;
rd_data_rate dist { [1:8] := 10, [60:80] := 10 }
}
endclass
Any data type can be declared as random using the ‘rand’ keyword.
Here we have declared the fields of FIFO data as random. We need
to encapsulate our random variables within a class, and we have
called the class “data_tr.” We will also declare integer variables and
called “wr_data_rate” and “rd_data_rate,” and constrain them with a
distribution list. We will use these random variables to test out
different read/write data-rates of the FIFO. For very slow data rates,
delay will have a large value, and for fast data rates, delay will have
a low value. Finally, we create 10 different random values – here is
what the output would look like:
Instead the read and write tasks of the FIFO can be considered as
part of a common function – one of these tasks would not be used in
isolation. So we will encapsulate all of the FIFO-related tasks into a
class. Now to instantiate more than one FIFO we only have to
declare a new instance of our class.
class driver ;
...
task fifo_mwrite ();
..
endtask
endclass: driver
here fifo_mwrite() will drive data into our FIFO, and
fifo_mread() will read data from our FIFO.
class generator ;
rand data_tr rand_tr;
//holder randomized FIFO data(transaction)
virtual task main();
..
FIFO_DATA = get_transaction();
..
endtask: main
function new();
cfg = new();
cfg.randomize();
NUM = cfg.NUM;
$write(" Test configuration for FIFO \n");
Cvr = new();
fifo_gen = new();
endfunction: new
task pre_test;
fork
fifo_reset();
fifo_reset_check();
join_none
start_checker();
endtask: pre_test
task post_test();
@(vintf.cb) Cvr.sample();
endtask: post_test
virtual task test();
repeat(NUM) begin
fifo_gen.main();
fork
fifo_driver.fifo_mwrite();
fifo_driver.fifo_mread();
join
post_test();
end
endtask: test
task run();
build();
pre_test();
test();
endtask: run
endclass: fifo_env
The “pre_test” function resets the FIFO, and then starts the checker
running in the background.
The “test” task randomizes the data object, writes data to the FIFO,
and then reads back the data.
The “post_test” task is called after a single test to sample the data
rates for functional coverage.
The “run” function of fifo_env() calls the build function, pre_test and
then test task. This is the task that is called from the top level
program.
cdata.push_back(FIFO_DATA.data[j]);
In task fifo_mread() whenever data is popped off of the FIFO we
push it into a mailbox:
mbox.put(vintf.cb.data_out);
Now, in the checker class we will pop data off of the mailbox and off
of the queue and compare the two values (which should be the
same):
mbox.get(tempOut);
tempIn = cdata.pop_front();
assert( tempIn == tempOut )
else $write("TEST: FIFO read data 'h%0h DID NOT
match expected data 'h%0h\n",tempOut, tempIn);
Now, if our DUT was more complicated and transmitted out-of-order
data, then it would need searching through the queue to find the
correct value, using the built-in methods of the queue.
interface fifo_if
direction sv_calls_sc
verilog_module fifo_helper
systemc_module fifo_sysc_helper
#include "fifo_if.h"
function nb_push
input int data
task pop
output int data
};
The method “push” is used whenever we want to push data into our
FIFO, and the method “pop” is used whenever we want to pop data
from our FIFO. We have also included a method “status” that returns
the number of free entries in the FIFO.
fifo_test_top.fifo_reference_model.nb_push(FIFO_DATA.data[
j]);
Also, in the checker class, we can compare the output of the
SystemC reference model with the actual output of the DUT:
end
endtask: main
endclass: checker
mailbox mbox;
data_tr FIFO_DATA;
fifo_env fifo_tb_env;
logic [`WIDTH-1:0] cdata[$];
Here all our global data is declared, our mailbox, our random data,
our environment class, and our queue.
my_gen fifo_new_generator;
..
fifo_new_generator= new();
fifo_tb_env = new();
fifo_tb_env.fifo_gen = fifo_new_generator;
fifo_tb_env.run();
end: main_prog
endprogram: fifo_test
The key is that we do not need to modify any of our base classes.
This is all done in the test-specific file “fifo_test_01_extend.v”
If we want another test with different constraints we just copy the file
to “fifo_test_02_my_test.v” and edit that file.
You can instantiate the FIFO assertion directly into either the Verilog,
or the VHDL design. The assertion can also be put in a separate file
using the bind construct. This will work for both Verilog and VHDL
blocks.
Functional Coverage
Functional coverage provides a metric for measuring the progress of
design verification, based on the functional test plan and design
specification. Functional coverage is used in conjunction with the
design code coverage. The main purpose of functional coverage is
to guide the verification process by identifying tested and untested
areas of design and ensuring corner cases are tested. For more
details see the Functional Coverage section on page 2-18.
make verilog_00
For a VHDL version of the testcase, use the command:
make vhdl_00
To run with the extended generator, type:
make verilog_01
make vhdl_01
FIFO Results
Let's simulate the FIFO with the default configuration using the
command line below.
make verilog_00
The testbench reports the data_rate for each call in fifo_driver to the
methods fifo_mwrite and fifo_mread.
You can now look at the testbench coverage for 500 tests using this
command:
Coverage Summary
Number of coverage types: 1
Number of coverage Instances: 1
Cumulative coverage: 100.00
Instance coverage: 0.00
==========================================================
= Cumulative report for fifo_env::Cvr
==========================================================
Summary:
Coverage: 100.00
Goal: 100
FIFO Results
3-35
WD 100.00 100 1
==========================================================
Cross Coverage Goal Weight
==========================================================
RDxWD 100.00 100 1
==========================================================
RD WD # hits at least
=======================================================
HIGH HIGH 3 1
HIGH LOW 1 1
HIGH MED 1 1
LOW HIGH 1 1
LOW LOW 3 1
LOW MED 1 1
MED HIGH 2 1
MED LOW 3 1
MED MED 2 1
=======================================================
==========================================================
HIGH 5 1
LOW 5 1
MED 7 1
==========================================================
==========================================================
HIGH 6 1
LOW 7 1
MED 4 1
==========================================================
fifo_test.db
FIFO Results
3-37
Debug
VCS and later versions come with a comprehensive built-in graphical
user interface, called Discovery Visual Environment (DVE). DVE
supports graphical debugging of mixed language designs including
Verilog, VHDL, and SystemVerilog. DVE is an intuitive environment
that also supports assertion debugging. Detailed documentation can
be found in the Discovery Visual Environment User Guide.
simv -gui
Once the debugger starts, you can set breakpoints in the design or
testbench code, trace drivers, and navigate through the hierarchy
easily and efficiently.
Debug
3-39
Summary
We have introduced the new constructs for testbench and
verification, interfaces, clocking blocks, as well as object-oriented
design constructs in VCS. As described in this Quick Start Guide,
the built-in verification features of VCS can be used to quickly ramp
up new users who are unfamiliar with the new standard languages,
such as SystemVerilog Hardware Design and Verification Language
(HDVL). VCS is leading the industry to incorporate testbench,
assertion and coverage capabilities needed for today’s design and
Summary
3-41
Chapter 3: Using Advanced Features in VCS to Verify Your Design
3-42
A
The FIFO Design Block A
The FIFO design is a synchronous (Single-Clock) FIFO with static
flags. It is fully parameterized and has single-cycle push and pop
operations. It also has empty, half-full, and full flags, as well as
parameterized almost full and almost empty flag thresholds with
error flags.
A-1
Figure A-1 FIFO Design
D W _ f if o _ s 1 _ s f
p u s h _ re q _ n
d a t a _ in
d a ta _ o u t
p o p _ re q _ n
f u ll
a lm o s t _ fu ll
h a lf _ f u ll
a lm o s t _ e m p t y
d ia g _ n
e m p ty
e rro r
c lk rs t_ n
The following sample timing diagram illustrates how the FIFO block
works.
You can find the ASCII version of these files in the following location
in the installation:
$VCS_HOME/doc/examples/nativetestbench/systemverilog/
vcs_quickstart/ under
/basic and /advanced subdirectories
B-1
Files for Using Basic Features in VCS to Verify Your
Design
README
C-1
Assertion IP Library
Today’s designs have to conform to complex functional
specifications. Many of the design components use
industry-standard protocols in order to easily plug and play with other
system components. However these complex protocols such PCIX
standard usually require sophisticated verification environment to
validate the design. In order to fully test compliance to the standard
protocol, the Assertion IP Library components supported in VCS
provides a set of checkers that can be used to verify complex
protocols. The VCS Assertion IP Library contains a set of checkers
that can be used to verify complex protocols. The VCS Assertion IP
Library allows designers to perform functional checks during
simulation, identify and report protocol violations, and capture
assertion coverage data. You can easily augment your verification
environment, the constrained-random stimulus generation and
coverage routines with the assertion IP at the block-level to full
chip-level environment. As mentioned before, these components are
pre-built and pre-verified to comply with the standard protocols. You
can configure the assertion IP according to the functionality of your
design-under-test. Each IP contains set of assertions to monitor the
protocol behavior and coverage targets to aid in finding out more
about how far test cases exercise the respective protocol
functionality.
PCI and PCI-X® 2.0 interface, AMBA 2 AHB and APB, 802.11a-g,
AGP, SMIA, DDR2, OCP 2.0 and LPC.
Chapter C: Verification IP
C-2
Please refer to $VCS_HOME/aip/ directory for complete component
list.