Introduction to
SystemVerilog for Testbench
Agenda 2
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Lecture Objectives 3
By the end of this class, you should be able to:
Develop self checking testbenches using VCS and
SystemVerilog
How to connect your Design to a SV testbench
How to perform random constrained testing
How to take advantage of powerful concurrency
How to implement Functional Coverage
Look for
coding tips!
SystemVerilog Testbench with VCS 05/07/2007
Introduction 4
SystemVerilog for Verification
Based on IEEE P1800-2005 Standard
Detailed in Language Reference Manual
Verification-specific language features
Constrained random stimulus generation
Functional coverage
SystemVerilog Assertions (SVA)
SystemVerilog Testbench with VCS
Agenda 5
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS
Verification Environment 6
Definitions
Checks Testbench
Creates correctness
stimulus Verification
Environment Identifies
Executes Test transactions
transactions
Transactor Scoreboard Checker Observes
Supplies data data
to the DUT from DUT
Driver Assertions Monitor
DUT
SystemVerilog Testbench with VCS
Methodology Introduction 7
To maximize design quality
Provides guidance:
Find bugs fast!
Identify the best practices
Make the most of Synopsys tools
Methodology
One verification environment, many tests
Minimize test-specific code
Reuse
Across tests
Across blocks
Across systems
Across projects
SystemVerilog Testbench with VCS
Methodology Introduction 8
Testbench Design
Start with a fully randomizable testbench
Run many randomized simulation runs
Analyze cumulative coverage and coverage holes
Then with minimal code changes:
Add constrained stimulus to fill coverage holes
Finally:
Make few directed tests to hit the remaining holes
SystemVerilog Testbench with VCS 05/07/2007
Coverage-Driven Verification 9
Measure progress using functional coverage
Coverage-Driven Productivity
With
Methodology gain
VIP
Goal Directed
% Coverage
Methodology
Self-checking
random environment
development time
Time
SystemVerilog Testbench with VCS 05/07/2007
Key Benefits: Testbench Environment 10
Environment Creation takes less time
Testbench is easy constrain from the top level file
All Legal Device Configurations are tested
Regression can select different DUT configurations
Configuration object is randomized and constrained
Enables reuse
SystemVerilog Testbench with VCS 05/07/2007
Agenda 11
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Getting Started 12
What are We Going to Discuss?
SystemVerilog Testbench Verification Flow
Compiling and Running in VCS
Documentation and support
SystemVerilog Testbench with VCS 05/07/2007
Getting Started 13
Compiling and Running with VCS
Compile:
vcs -sverilog –debug top.sv test.sv dut.sv
-sverilog Enable SystemVerilog constructs
-debug Enable debug except line stepping
-debug_all Enable debug including line stepping
Run:
simv +user_tb_runtime_options
-l logfile Create log file
-gui Run GUI
-ucli Run with new command line debugger
-i cmd.key Execute UCLI commands
See the VCS User Guide for all options
SystemVerilog Testbench with VCS 05/07/2007
Getting Started 14
Legacy Code Issues
SystemVerilog has dozens of new reserved keywords such as
bit, packed, logic that might conflict with existing Verilog code
Keep your Verilog-2001 code separate from SystemVerilog
code and compile with:
vcs –sverilog new.v +verilog2001ext+.v2k old.v2k
or
vcs +systemverilogext+.sv old.v new.sv
// Old Verilog-1995/2001 legacy code
integer bit, count;
initial begin
count = 0;
for (bit = 0; bit < 8; bit = bit + 1)
if (adrs[bit] === 1'bx)
count = count + 1;
end
SystemVerilog Testbench with VCS 05/07/2007
Debug: Getting Started 15
Invoke DVE > simv –gui -tbug
Source
code
tracing
Active
threads
Local
variables
SystemVerilog Testbench with VCS 05/07/2007
Getting Started 16
Documentation and Support
SystemVerilog documentation > vcs -doc
Examples
$VCS_HOME/doc/examples
Email Support:
vcs-support@synopsys.com
On-line knowledge database
http://solvnet.synopsys.com
Testbench Discussion Forum
http://verificationguild.com
SystemVerilog LRM
www.Accellera.org or www.eda.org/sv
SystemVerilog Testbench with VCS 05/07/2007
Agenda 17
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment 18
How Should You Connect to DUT
Someone gives you a DUT, now what?
reset
request[1:0]
grant[1:0]
clock
arb.sv
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment 19
Steps to hook up a DUT to a Testbench
1. Create DUT interface with
modports and clocking top.sv
blocks
2. Create testbench program
3. Create top module
4. Compile and run
test.sv arb.sv
clock
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment -- Interfaces 20
Introduction
The complexity of communication between
blocks requires a new design entity
Top level net-lists are too verbose and error prone
An interface encapsulates this communication
Connectivity (signals)
Directional information (modports)
Timing (clocking blocks)
Functionality (routines, assertions, initial/always blocks)
An interface can be:
Connected at compile-time (default)
Connected at run-time – virtual interfaces
An interface can not:
Be hierarchical, or extended Device 1 interface Device 2
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment -- Interfaces 21
Before Interfaces
The RTL code was connect with a netlist
mem cpu
top
module mem ( module cpu (
input bit req, input bit clk,
bit clk, bit gnt,
bit start, bit rdy,
wire [1:0] mode, inout wire [7:0] data,
wire [7:0] addr, output bit req,
inout wire [7:0] data, bit start,
output bit gnt, wire [1:0] mode,
bit rdy); wire [7:0] addr);
… …
module top;
logic req, gnt, start, rdy;
bit clk;
always #10 clk = !clk;
logic [1:0] mode;
logic [7:0] addr;
wire [7:0] data;
mem m1(req, clk, start, mode, addr, data, gnt, rdy);
cpu c1(clk, gnt, rdy, data, req, start, mode, addr);
endmodule
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment -- Interfaces 22
Named Bundle of Signals
The RTL code is connected with bundled signals
simple_bus
clk
mem cpu
top
interface simple_bus; module mem( module cpu(
logic req, gnt; simple_bus sb, simple_bus sb,
logic [7:0] addr; input bit clk); input bit clk);
wire [7:0] data; … …
logic [1:0] mode; endmodule endmodule
logic start, rdy;
endinterface module top;
logic clk = 0;
always #10 clk = !clk;
simple_bus sb();
mem m1(sb, clk);
cpu c1(sb, clk);
endmodule
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment -- Interfaces 23
Referencing Signals in Interface
Use hierarchical names for interface signals in a module
module cpu(simple_bus sb, input bit clk);
logic addr_reg;
always @(posedge clk)
sb.addr <= addr_reg;
endmodule : cpu
interface simple_bus;
logic req, gnt;
logic [7:0] addr;
wire [7:0] data;
logic [1:0] mode;
logic start, rdy; Label on end
endinterface: simple_bus statement
Signals with multiple drivers must be wire
Signals driven by procedural assignment must be logic
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment -- Interfaces 24
Dividing an Interface
Not every device has the same access to an interface
Restrict signal access & direction with modport
interface simple_bus;
logic req, gnt;
logic [7:0] addr;
wire [7:0] data;
logic [1:0] mode;
logic start, rdy;
modport SLAVE (input addr, gnt, mode, start,
output req, rdy,
inout data);
modport MASTER (output addr, gnt, start, mode,
input req, rdy,
inout data);
endinterface: simple_bus
module cpu(simple_bus.MASTER sb, module mem(simple_bus.SLAVE sb,
input bit clk); input bit clk);
… …
endmodule endmodule
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment -- Interfaces 25
Adding Timing Step 1
An interface can use a clocking block to control timing
Directions are relative to program block
interface arb_if (input bit clk);
logic [1:0] grant, request; reset
logic reset; request[1:0]
grant[1:0]
clocking cb @(posedge clk); clock
input grant; // TB input
output request; // TB output arb.sv
endclocking
modport DUT (input clk,
input request, reset, // Design under test
output grant);
modport TB (clocking cb, // Synch signals
output reset); // Async signals
endinterface: arb_if
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment -- Interfaces 26
Clocking Blocks
Use in the interface, just for testbench
Benefits:
Creates explicit synchronous timing domains
Provides race-free operation if input skew > 0
Your testbench will always drive the signals at the right time!
Functionality:
An interface can contain multiple clocking blocks
There is one clock per clocking block.
Default is “default input #1step output #0;”
“1step” specifies that the values are sampled immediately
upon entering this time slot in Prepone region, before any
design activity
SystemVerilog Testbench with VCS 05/07/2007
SystemVerilog Scheduling 27
SystemVerilog Scheduling Details
Each time slot is divided into 5 major regions (plus PLI)
Prepone Sample signals before any changes (#1step)
Active Design simulation (module), including NBA
Observed Assertions evaluated after design executes
Reactive Testbench activity (program)
Postpone Read only phase
Assertion and testbench events can trigger more design evaluations
in this time slot
clock
data
REGION Prepone Active Observed Reactive Postpone
ACTIVITY sample design assertions testbench $monitor
Previous Current Next
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment - Program Block 28
Program Block
Benefits:
Encapsulates the testbench
Separates the testbench from the DUT
Provides an entry point for execution
Creates a scope to encapsulate program-wide data
Functionality:
Can be instantiated in any hierarchical location
Typically at the top level
Interfaces and ports can be connected in the same
manner as any other module
Leaf node, can not contain any hierarchy, just classes
Code goes in initial blocks & routines, no always blocks
Executes in the Reactive region
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment – Program 29
Create testbench program: test.sv Step 2
program test(arb_if.TB arbif); clk
initial begin reset
// Asynch drive reset request
arbif.reset <= 0;
#15ns arbif.reset <= 1; interface arb_if (input bit clk);
#35ns arbif.reset <= 0; logic grant, request, reset;
ns! clocking cb @(posedge clk);
// Synch drive request input grant;
##1 arbif.cb.request <= 1; output request;
##1 arbif.cb.request <= 0; endclocking
modport TB (clocking cb,
wait (arbif.cb.grant == 1);
output reset);
end endinterface: arb_if
endprogram
Common mistake: forgetting
Wait 1 clock cycle “cb.” in signal reference
Error: arbif.request not
visible via modport
SystemVerilog Testbench with VCS 05/07/2007
Using the Clocking Block 30
Synchronous Signal Access
Clocking Block signals are referenced by pre-
pending the clocking block name to the signal:
All drives must use non-blocking assignment
arbif.cb.request <= 1; // drive
value = arbif.cb.grant; // sample
Assignment will happen at next active clock edge
Time will NOT advance unless you use #1 or ##1
interface arb_if (input bit clk);
logic grant, request, reset;
clocking cb @(posedge clk);
input grant;
output request;
endclocking
modport TB (clocking cb, output reset);
endinterface: arb_if
SystemVerilog Testbench with VCS 05/07/2007
Driving, Sampling, Synchronizing 31
Signal Synchronization
Synchronize to active clock edge specified in clocking block
@arbif.cb; // continue on posedge of arb_if clk
repeat (3) @arbif.cb; // Wait for 3 posedges
Synchronize to any edge of signal
@arbif.cb.grant; // continue on any edge of grant
@(posedge arbif.cb.grant); // continue on posedge
@(negedge arbif.cb.grant); // continue on negedge
wait (arbif.cb.grant==1); // wait for expression
// no delay if already true
Wait for N clock cycles with ##n – blocking statement
##2 arbif.cb.request <= 0; // Wait 2 cycles
// then assign
SystemVerilog Testbench with VCS 05/07/2007
Testbench Timing 32
SystemVerilog Testbench in Simulation
When you are using interfaces with a clocking block:
There is a 1-cycle delay from DUT output to testbench input
“Virtual synchronizer” added to TB input
No delay from testbench output to DUT input
default input #1step output #0;”
clock
Design
Testbench
Sample inputs Drive outputs
before clock at clock
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment – Top Block 33
Step 3
Create top module
module top; // Synchronous TB
bit clk; program test(arb_if.TB arbif);
test t1 (.*); …
arb d1 (.*); endprogram
arb_if arbif(.*);
always #50
clk = !clk; module arb(arb_if.DUT arbif,
endmodule bit clk);
// Some logic here…
endmodule
interface arb_if (input bit clk);
…
The syntax .* connect ports endinterface: arb_if
and signals with same names
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment - Scoping 34
Scoping Rules
SystemVerilog defines a global scope, $root,
outside any module or program
Define global items such as shared enums
Use parameters for global constants, not macros
`timescale 1ns/1ns
typedef enum {IDLE, RUN, WAIT} fsm_state_t; root.sv
parameter TIMEOUT = 1_000_000;
module state_machine(…);
fsm_state_t state, next_state; dut.sv
endmodule
program test;
fsm_state_t state; test.sv
initial #TIMEOUT $finish;
endprogram
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment -- Communication 35
DUT visibility
The program block can see all signals & routines in
the design
A module can not see anything in program block
Use absolute hierarchical path to access DUT
Start with $root, then top-level instance name, DUT, etc.
Use care when calling DUT routines from program
Good practice is to use a function to get info
Don’t try to trigger DUT code
SV accesses ports & XMR signals immediately
(asynchronously)
dstate = top.dut.state; // Immediate XMR sample
dstate = $root.top.dut.state; // Absolute path
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 36
Check signal values
Check a SVA procedurally
Non-blocking statement
program test (arb_if arbif);
initial begin
arbif.cb.request <= 1;
repeat (2) @arbif.cb; SystemVerilog
a1: assert (arbif.cb.grant==1); Assertion
end
in case of error…
“test.sv", 7: top.t1.a1: started at 55ns failed at 55ns
Offending '(arbif.cb.grant == 1)‘
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 37
Check signal values
Optional then & else clauses for success / failure
If SVA failure and no else-clause, a generic error is printed
Use $info, $warn, $error, and $failure for reporting
These are only valid in SVA’s (IEEE-1800)
program test (arb_if arbif);
initial begin
arbif.cb.request <= 1;
repeat (2) @arbif.cb;
a1: assert (arbif.cb.grant==1)
success++;
else
$error(“No grant received”); Custom
end message
SystemVerilog Testbench with VCS 05/07/2007
Testbench Environment – Compile and Run 38
Step 4
Compile and run
> vcs -sverilog -debug
root.sv top.sv arb_if.sv test.sv arb.sv
> simv –gui -tbug
Run with
debugger
SystemVerilog Testbench with VCS 05/07/2007
Agenda 39
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 40
What are We Going to Discuss?
SystemVerilog basics
Data types
Arrays
Subroutines
Interfaces
This class assumes you already know most Verilog-1995
and 2001 constructs
SystemVerilog Testbench with VCS 05/07/2007
Basic SystemVerilog Data Types 41
SystemVerilog Data Types
reg [31:0] r; // 4-state
logic [7:0] w; // 4-state
In SystemVerilog, the old reg type has been extended so it can be driven by
single drivers (gates, modules, continuous assignments) like a wire. It has a
new name logic. It can not have multiple drivers – use a wire.
bit [31:0] b; // 2-state bit 0 or 1
integer i; // 4-state, 32-bits, signed Verilog-1995
int i; // 2-state, 32-bit signed integer
byte b8; // 2-state, 8-bit signed integer
shortint s; // 2-state, 16-bit signed integer
longint l; // 2-state, 64-bit signed integer
Explicit 2-state variables give better performance,
but they will not propagate X or Z, so keep away from DUT
assert(!$isunknown(ifc.cb.data));
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 42
SystemVerilog Data Types
User defined types
Use typedef to create a synonym for another type
Useful
typedef bit [31:0] uint;
type typedef bit [0:5] bsix_t; // Define new type
bsix_t my_var; // Create 6-bit variable
Define a structure with multiple variables
typedef struct {bit [7:0] opcode;
Use classes bit [23:0] addr; }
instead! instruction; // named structure type
instruction IR; // define variable
Use union for merged storage
typedef union {int i; shortreal f; } num_t;
num_t un;
un.f = 0.0; // set n in floating point format
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 43
SystemVerilog Data Types
Enumerated type
Explicitly typed and scoped (program or class-level)
Can only create variables at class level, not typedef
Allows compile time error checking
// Declare single enum variable
enum {RED, BLUE, GREEN} color;
// declare data type
typedef enum {INIT, DECODE, IDLE} fsmstate_t;
fsmstate_t pstate, nstate; // declare variables
int i = 1;
case (pstate)
IDLE: nstate = INIT; // data assignment
INIT: nstate = DECODE;
default: nstate = IDLE; Print the
endcase symbolic
name
$display(“Next state is %0s”, nstate.name);
nstate = fsmstate_t’(i); // cast integer to enum
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 44
Fixed Size Arrays type name [constant];
Fast, static size
Multiple dimensions supported
Out-of-bounds write ignored
Out-of-bounds read returns X, even for 2-state
Array data stored in 32-bit words
int twoD1[0:7][0:23]; // 2D array
int twoD2[8][24]; // same as above
twoD1 = twoD2; // Array copy
if (twoD1==twoD2)… // Array compare
Use bit & word
subs together
bytes[0][3] bytes[0][1][6] with fixed arrays
bytes[0] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0
bytes[1] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0
bytes[2] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0
bit [3:0][7:0] bytes [0:2]; // 3 entries of packed 4 bytes
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 45
Dynamic Arrays type name [ ];
Fast, variable sized with call to new()
Similar to a fixed size array, but size given at run time
Single dimension only, never packed
Out-of-bounds access causes run-time error
int d[], b[]; // Two dynamic arrays
d = new[5]; // Make array with 5 elements
foreach (d[j]) // Initialize
d[j] = j;
b = d; // Copy a dynamic array
b[0] = 5;
$display(d[0],b[0]); // See both values (0 & 5)
d = new[20](d); // Expand and copy
d = new[100]; // Allocate 100 new integers
// Old values are lost
d.delete(); // Delete all elements
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 46
Queues type name [$];
Flexible – size can easily change
Variable size array with automatic sizing, single dimension
Many searching, sorting, and insertion methods (see LRM)
Constant time to read, write, and insert at front & back
Out of bounds access causes run-time error
int q[$] = {0,1,3,6};
int j = 2, b[$] = {4,5};
q.insert(2, j); // {0,1,2,3,6} Insert before s[2]
q.insert(4, b); // {0,1,2,3,4,5,6} Insert whole queue
q.delete(1); // {0,2,3,4,5,6} Delete element #1
q.push_front(7); // {7,0,2,3,4,5,6} Insert at front
FAST!
j = q.pop_back(); // {7,0,2,3,4,5} j = 6
q.push_back(8); // {7,0,2,3,4,5,8} Insert at back
j = q.pop_front(); // {0,2,3,4,5,8} j = 7
$display(q.size); // “6”
foreach (q[i]) $display(q[i]);
SystemVerilog Testbench with VCS 05/07/2007
Checking Results with Queues 47
Queues for Scoreboards
What if transactions get out of order, are dropped or are
corrupted in the DUT?
Store expected transactions in a queue, with a timestamp
Contents are addressable, push/pop
Look up transaction ID on arrival for out-of-order delivery
If actual transaction not found: corrupted data
Periodically scan array for old transactions. Mark them as
dropped and remove
Tr2 @3000
Transactor Tr1 @1000 Checker
Tr4 @2000
Driver Monitor
DUT
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 48
Associative Arrays type name [*];
Great for sparse memories
Dynamically allocated, non-contiguous elements
Accessed with integer, or string index, single dimension
Great for sparse arrays with wide ranging index
Array functions: exists, first, last, next, prev
int aa[*], i; // Print full array
foreach(aa[i])
reg[7:0] mydata[string];
$display(i,,aa[i]);
Standard array Associative array
All memory Unused elements
allocated, even don’t use memory
unused elements
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 49
Array Methods
Search through arrays (fixed, dynamic, queue, assoc.)
Many more methods will be implemented, such as sort…
Returns a queue or scalar
a.sum of single bit values returns 0/1
Unless you compare to wider value: a.sum == 32’h3
Also available: product, and, or, xor
int q[$] = {1,3,5,7}, tq[$]; IEEE changed array
int d[] = {9,1,8,3,4}; const from {0,1} to ’{0,1}
int f[6] = {1,6,2,6,8,6}; (VCS issues Warning for
old usage)
$display(q.sum, q.product); // 16 105
LRM requires
tq = q.min(); // {1}
a queue
tq = q.max(); // {7}
tq = f.unique; // {1,6,2,8}
tq = d.find with (item > 3); // {9,8,4}
tq = d.find_index with (item > 3); // {0,2,4}
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 50
Strings string name;
Arbitrary length array of chars (like C), grows automatically
Compare operators ==, !=, and compare() and icompare()
methods
Use { } for concatenation
Built-in conversion itoa, atoi, atohex, atooct, atobin
string s = “SystemVerilog”;
$display(s.getc(0),, s.toupper());
s = {s, “3.1b”}; // string concat
s.putc(s.len()-1, “a”); // change b-> a
$display(s);
$display(s.substr(2, 5)); // 4 characters
// Create temporary string, note format
my_log($psprintf(“%s %5d”, s, 42));
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 51
Tasks and Functions
task reset();
function int add2(int n);
reset_l = 1’b0;
return n + 2;
#100
endfunction
reset_l = 1’b1;
endtask
Function can never contain blocking statements or calls to tasks
Void functions do not return a value
function void print_sum(ref int a[], input int start=0);
int sum = 0;
for (int j=start; j<a.size; j++)
sum += a[j];
$display(“Sum of array is %0d”, sum);
endfunction
…
print_sum(my_array); Default value
print_sum(my_array, );
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 52
Tasks and Functions
Static vs. Automatic Tasks and Functions
All calls to static routine shares the same storage space within a
module instance. It can’t be reentrant or recursive. (Verilog-1995)
An automatic routine allocates new space for each call. (This is
the default in other languages.) (Verilog-2001)
Class routines are automatic by default, while routines in
modules and program are static by default. (SystemVerilog)
The print_sum example on the previous slide will NOT work
with static storage as sum will only be initialized at time 0.
program automatic test;
Change storage default
for programs task is_automatic();
SystemVerilog Testbench with VCS 05/07/2007
SV Language Basics 53
Tasks and Functions
Argument Passing
Type is sticky, following arguments default to that type
input - copy value in at beginning - default
output - copy value out at end
inout - copy in at beginning and out at end
ref - pass by reference (effects seen right away)
Saves time and memory for passing arrays to tasks & functions
Modifier: const - argument is not allowed to be modified
Default dir is input, Watch out for ref
default type is logic followed by input…
task T3(a, b, output bit [15:0] u, v);
a, b: input logic
u, v: output bit [15:0]
SystemVerilog Testbench with VCS 05/07/2007
Lab 1 54
Verify an arbiter
Objective
Verify the arbiter’s reset
Verify arbiter handles simple requests and grants
Verify proper handling of request sequences
Key Topics
Port list, clocking block, program block, assert, drive samples
and check responses.
Time Allotted
45 minutes
SystemVerilog Testbench with VCS 05/07/2007
Agenda 55
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 56
What Are We Going to Discuss?
What is OOP
Terminology
An example class
Default methods for classes
Static attribute
Assignment and copying
Inheritance
Polymorphism
SystemVerilog Testbench with VCS 05/07/2007
Introduction to OOP 57
What is OOP?
OOP: Object Oriented Programming
Traditional programming deals with data structures and
algorithms separately
OOP organizes transactions and transactors better
Objects group data and algorithms together logically
Routines are actions that work on the grouped data
OOP closely ties data and functions together -
encapsulation
Extend the functionality of existing objects -
inheritance
Wait until runtime to bind data with functions -
polymorphism
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 58
What is OOP?
OOP breaks a testbench into blocks that work together
to accomplish the verification goal
Advantages
• Objects are easily reused and extended
• Allows for complex data structures
• Allows access to advanced SystemVerilog
testbench features
• Variables, functions, and tasks are protected from
side effects or misuse by other code
• Debug small sections of code, one class at a time
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 59
Terminology
HDL OOP
Verilog SystemVerilog
Block definition module class
Block instance instance object
Block name instance name handle
Data Types registers & wires Properties:
Variables
Executable Code behavioral blocks Methods: tasks
(always, initial), and functions
tasks, functions
Communication Ports or cross- calls,
between blocks module task calls mailboxes,
semaphores,
etc.
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 60
Terminology
Blueprint for Class
a house Programming element “containing” related group of features
and functionality
Encapsulates functionality
Provides a template for building objects
Can be used as data structures
A complete Object
house An object is an instance of a class
Address of Handle
a house Type-safe pointer to an object – can not be corrupted
Light Properties
switches Variables contained in the instance of the class
Methods
Turn on/off
switches Tasks/functions (algorithms) that operate on the properties in
this instance of the class
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 61
Class Example Variables & methods are
class Transaction; public by default
// properties (variables)
logic [31:0] src, dst, data[1024], crc;
logic [7:0] kind;
// methods
function void display;
$display(“Tr: %h, %h”, src, dst);
endfunction
function void calc_crc();
crc = src ^ dst ^ data.xor;
endfunction
In a class, methods
endclass
are always automatic
program automatic test;
endprogram
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 62
Creating an Object From a Class
Call new() to create an object
The class constructor allocates memory and initializes variables
Result stored in a handle to the object
You must to call new() for every handle in an array
SystemVerilog uses a predefined new() for every class,
but you can redefine your own
Declare first
Coding style: don’t call new in declaration then construct
Otherwise objects are created before any procedural code
task init;
Transaction tr; // A single handle
Transaction tr_arr[5]; // An array of handles
// Handles are null until initialized
tr = new(); // Create a new object
foreach (tr_arr[i]) // Create an array
tr_arr[i] = new(); // of new objects
endtask
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 63
Working with Objects
Call new(), assigned values to the object
properties
Handles have the default value of null
Using a null handle is an error
Error: null object access in file xx.sv line 38
Every call to the constructor creates a new
object that is independent of all other objects
Properties and methods accessed through handle
Handles are type safe – can’t misused or modified, unlike C
Class Destruction/De-allocation
Automatic Garbage Collection taken care of by SystemVerilog
(like Java, unlike C++)
When an object is no longer being referenced, it is garbage
collected
No segmentation faults from manual memory deallocation
No memory leaks or unexpected side effects
if (tr.done) // No longer needed?
tr = null; // clear handle
SystemVerilog Testbench with VCS 05/07/2007
Where are all the objects? 64
A transactor can be an object too!
Scoreboard holds Verification
Extended transactions Environment
class
Compares
Executes Test transactions
transactions
Transactor Self Check Checker
Drives
transactions Monitor
Driver
into the DUT
Puts data
DUT
into
transactions
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 65
Accessing Class Members
Reference properties by pre-pending the object handle
class Transaction;
bit [31:0] src, dst, data[1024];
bit [7:0] kind;
function void display;
$display(“Tr: %h, %h”, src, dst);
endfunction
endclass
Transaction tr;
initial begin
tr = new();
tr.src = 5;
tr.dst = 7;
tr.display();
end
SystemVerilog Testbench with VCS 05/07/2007
OOP Basics 66
Initializing Class Properties
Initialize the class properties in the constructor when the
object is created
Function type not needed
program automatic test1; program automatic test2;
class Transaction; class Transaction;
bit [31:0] src, dst; bit [31:0] src, dst;
function new(); function new (int src, int dst=3);
src = 5; this.src = src; // Disambiguate
dst = 3; this.dst = dst;
endfunction endfunction
endclass endclass
Transaction tr; Transaction tr;
initial initial
tr = new(); tr = new(5); // dst uses default
endprogram endprogram
SystemVerilog Testbench with VCS 05/07/2007
Static attribute 67
How do I create a variable shared by all objects of a
class, but not make a global?
A static property is associated with the class
definition, not the instantiated object.
It is often used to store meta-data, such as number of
instances created
It is shared by all objects of that class.
class Transaction;
Using a id field can
static int count = 0;
help keep track of
int id;
transactions as they
… flow through test
function new();
id = count++;
endfunction
endclass
SystemVerilog Testbench with VCS 05/07/2007
Assignment is not a copy 68
Assignment of one handle to another only affects
the handles. It does not copy data
class Thing;
int data;
endclass
… t1
Thing t1, t2; // Two handles
initial begin
t1 = new(); // Allocate first thing data=1
t1.data = 1;
t2 = new(); // Allocate second
t2.data = 2; t2
t2 = t1; // Second Thing is lost
t2.data = 5; // Modifies first thing
$display(t1.data); // Displays “5”
end
SystemVerilog Testbench with VCS 05/07/2007
Assignment is not a copy 69
Assignment of one handle to another only affects
the handles. It does not copy data
class Thing;
int data;
endclass
… t1
Thing t1, t2; // Two handles
initial begin
t1 = new(); // Allocate first thing data=1
t1.data = 1;
t2 = new(); // Allocate second
t2.data = 2; t2
t2 = t1; // Second Thing is lost
t2.data = 5; // Modifies first thing
$display(t1.data); // Displays “5” data=2
end
SystemVerilog Testbench with VCS 05/07/2007
Assignment is not a copy 70
Assignment of one handle to another only affects
the handles. It does not copy data
class Thing;
int data;
endclass
… t1
Thing t1, t2; // Two handles
initial begin
t1 = new(); // Allocate first thing data=1
t1.data = 1;
t2 = new(); // Allocate second
t2.data = 2; t2
t2 = t1; // Second Thing is lost
t2.data = 5; // Modifies first thing
$display(t1.data); // Displays “5” data=2
end
SystemVerilog Testbench with VCS 05/07/2007
Assignment is not a copy 71
Assignment of one handle to another only affects
the handles. It does not copy data
class Thing;
int data;
endclass
… t1
Thing t1, t2; // Two handles
initial begin
t1 = new(); // Allocate first thing data=5
t1.data = 1;
t2 = new(); // Allocate second
t2.data = 2; t2
t2 = t1; // Second Thing is lost
t2.data = 5; // Modifies first thing
$display(t1.data); // Displays “5”
end
SystemVerilog Testbench with VCS 05/07/2007
How to copy objects 72
Assigning handles does not change objects
To copy the data, pass it into new: t2 = new t1;
This is a shallow copy, only data in top object is copied.
Your new() is not called!
t1 t1
id=5 id=5
body stuff body stuff
t2 t2
id=5
body
SystemVerilog does not currently support deep
object copy – look for it in a future IEEE version
To do a deep copy of all objects, make a copy() method
for all objects nested inside the class.
SystemVerilog Testbench with VCS 05/07/2007
Inheritance 73
How do I share code between classes?
Instantiate a class within another class
Inherit from one class to another (inheritance/derivation)
Inheritance allows you to ‘add’ extra:
Add extra Properties (data members)
Add extra Methods
Change the behavior of a method
Common code can be grouped into a base class
Additions and changes can go into the derived class
Advantages:
Reuse existing classes from previous projects with less
debug
Won’t break what already works
SystemVerilog Testbench with VCS 05/07/2007
Inheritance 74
Extended a class with new fields
Add additional functionality to an existing class
class Transaction; Transaction
reg [31:0] src, dst, data[1024], crc; src dst
endclass
data crc
class BadTr extends Transaction; BadTr
rand bit bad_crc; bad_crc
endclass
BadTr bt;
bt = new; BadTr =
bt.src = 42; Transaction + bad_crc
bt.bad_crc = 1;
SystemVerilog Testbench with VCS 05/07/2007
Inheritance 75
Override existing fields to a class
Change the current functionality of a class
class Transaction;
reg [31:0] src, dst, data[1024], crc;
function void calc_crc(); Transaction
crc = src ^ dst ^ data.xor; src dst
endfunction
endclass data crc
calc_crc
class BadTr extends Transaction; BadTr
bad_crc
rand bit bad_crc;
function void calc_crc(); calc_crc
crc = super.calc_crc();
if (bad_crc) crc = ~crc;
endfunction
endclass
SystemVerilog Testbench with VCS 05/07/2007
Inheritance 76
Error injection
Create a transactor that works with a base object
Extend the transaction class to inject errors
Send these into the transactor from the test
class Driver;
task send(Transaction tr);
tr.calc_crc();
// Drive interface signals
endtask
endclass
class Transaction; program
program good_test;
BadTest;
function void calc_crc();
virtual function void calc_crc(); Transaction tr;
BadTr bt = new;
endclass task
task main();
main();
assert(tr.randomize());
assert(bt.randomize());
class BadTr extends Transaction; my_driver.send(tr);
rand bit bad_crc; my_driver.send(bt);
endtask
endtask
functionfunction
virtual void calc_crc();
void calc_crc(); endprogram
endclass endprogram
SystemVerilog Testbench with VCS 05/07/2007
Overriding Methods 77
Inheritance allows methods to be overridden
By default, a method is found using the handle type
What happens when extended object is referenced
by a base handle?
class Transaction; task main(); Transaction
reg [31:0] crc; Transaction tr; src dst
function void calc_crc(); BadTr bt;
endclass tr = new(); data crc
bt = new();
class BadTr calc_crc
extends Transaction; tr.calc_crc();
bit bad_crc; bt.calc_crc();
BadTr
function void calc_crc();
bad_crc
endclass tr = bt;
tr.calc_crc(); calc_crc
endtask
Oops, this extended object
just used base class method!
SystemVerilog Testbench with VCS 05/07/2007
Polymorphism 78
Allow a single name refer to many methods
Virtual – lookup method at runtime, not compile
The object’s type is used to find the right method
Analogous to virtual memory that can have many locations
class Transaction; task main(); Transaction
reg [31:0] crc; Transaction tr; src dst
virtual function void BadTr bt;
calc_crc(); tr = new(); data crc
endclass bt = new();
calc_crc
class BadTr tr.calc_crc();
extends Transaction; bt.calc_crc();
BadTr
bit bad_crc; bad_crc
virtual function void tr = bt;
calc_crc(); tr.calc_crc(); calc_crc
endclass Virtual method so… endtask
‘tr’ is really ‘bt’ => BadTr
=> call BadTr.calc_crc();
SystemVerilog Testbench with VCS 05/07/2007
Handle Assignment 79
Handles for base and extended class
The handles for the base and extended classes are
not interchangeable
A base handle can not access extended properties
class Transaction;
reg [31:0] src, dst;
virtual function void calc_crc(); src, dst Base
endclass
class BadTr extends Transaction; bad_crc Extend
bit bad_crc;
virtual function void calc_crc();
endclass
Transaction tr;
BadTr bt, b2;
bt = new(); // Allocate extended object
tr = bt; // Assign to base handle
Compile check tr.calc_crc(); // Calculate CRC
b2 = tr; // Error! Not allowed
$cast(b2, tr); // Allow assign
Run-time check if ($cast(b2, tr)) // Check if legal
b2.calc_crc();
SystemVerilog Testbench with VCS 05/07/2007
Inheritance 80
Why do I want all this complexity?
Driver will treat all transactions the same way
Transaction class knows how to perform actions
Cell.display()
Print ATM cell data if I’m at ATM cell
Print Ethernet MCA data if I’m an Ethernet packet
Print Sonet frame data if I’m a Sonet frame
Print USB packet data if I’m a USB packet
Code calling display doesn’t need to know what type of
cell/packet ‘cell’ handle references
Classes are self-contained, they know how to perform
actions on themselves based on their type
Self-contained, robust, reusable code.
SystemVerilog Testbench with VCS 05/07/2007
Agenda 81
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Randomization 82
What Are We Going to Discuss?
Why use randomization
Randomization options
Randomization of objects
Class constraints and distributions
In-line constraints and distributions
Tricks and techniques
SystemVerilog Testbench with VCS 05/07/2007
Randomization 83
Why Use Randomization?
Automatic stimulus generation
Change the characteristics of the data driving the DUT
Random setting of parameters
Select ports, addresses, operational parameters randomly.
Directed testing detects the bugs you expect.
Random testing detects the bugs you did not expect.
A random test’s behavior depends on the seed
If you run the same test with the same seed, you will get the
same behavior
If you run the same test with many different seeds, you will get
the equivalent of many different tests
SystemVerilog Testbench with VCS 05/07/2007
Randomization 84
Randomization Example rand: rolling dice
randc: dealing cards
program automatic test;
class Transaction;
rand bit [31:0] src, dst, data[]; // Dynamic array
randc bit [2:0] kind; // Cycle through all kinds
constraint c_len
{ data.size inside {[1:1000]}; } // Limit array size
endclass
Transaction tr;
initial begin
tr = new();
assert(tr.randomize());
send(tr);
end
endprogram
SystemVerilog Testbench with VCS 05/07/2007
Randomization 85
Randomization of Objects
Random variables
rand – returns values over the entire range
randc – random cyclic value up to 16 bits
Object variables are randomized by randomize()
The method is automatically available to classes with random
variables.
Always check
Returns a 1 upon success, 0 on failure
randomize()
Optional: pre_randomize() & post_randomize() void
functions which will be called automatically
pre_randomize() – set up random weights
post_randomize() – cleanup calculations like CRC
Remember calc_crc ?
SystemVerilog Testbench with VCS 05/07/2007
Randomization 86
Constraining Randomness
Purely random stimulus takes too long to do something
interesting
Specify the interesting subset of all possible stimulus with
constraint blocks
You can define separate, non-overlapping constraints for different
tests
Constraints and distribution weights can form the basis for a
“test writer interface” to your testbench
Your Testbench:
- all legal stimulus vectors
- all legal stimulus sequences
User-Created Test:
- subset of legal stimulus vectors
- subset of legal stimulus sequences SIM
SystemVerilog Testbench with VCS 05/07/2007
Randomization 87
Class Constraints
Constraint Blocks
Made of relational expressions, not assignments
Constraints can be dynamically enabled/disabled with:
handle.[constraint_name.]constraint_mode(1/0)
Unsolvable or conflicting constraints cause a run-time error
constraint c_default {
data.size <= 1000;
data.size > 0;
kind == 0; // Equivalent, not assignment
cntrl inside {[2:10], 20, 40, [100:107]};
if (test_mode == CONGEST)
dest inside {[src-100:src+100]};
}
Disable this with:
constraint c_long {
handle.c_long.constraint_mode(0)
data.size > 5000;
}
SystemVerilog Testbench with VCS 05/07/2007
Randomization 88
Distributions
dist constraint
Distribution weights can be variables or constants
Weighted probabilities
:= assigns weight to each element
:/ divides weight evenly in range
Value Dist
0 30/210
1 60/210
constraint c_0 {
2 60/210
src dist {0:=30, [1:3]:=60}; 3 60/210
dst dist {0:/30, [1:3]:/60};
} Value Dist
0 30/90
1 20/90
Distributions do not have to add up to 100% 2 20/90
3 20/90
SystemVerilog Testbench with VCS 05/07/2007
Randomization 89
In-Line Constraints and Distributions
Constraints may be defined at the time of randomization
Allows test-specific constraints
Don’t modify the original class for just a single test
In-line constraints are additive with existing class constraints
Supports all SystemVerilog constraints and distributions
class Transaction;
rand bit [31:0] src, dst, data[1024];
constraint valid {src inside{[0:100], [1000:2000]}; } src: 50-100,
endclass 1000-1500
dst<10
initial begin
Transaction t = new();
s = t.randomize() with {src >= 50; src <= 1500; dst < 10;};
driveBus(t);
// force src to a specific value
s = t.randomize() with { src == 2000; dst > 10;}; src==2000
driveBus(t); dst>10
end
SystemVerilog Testbench with VCS 05/07/2007
Randomization 90
SystemVerilog requires a strong constraint solver!
The solver has to handle algebraic factoring, complex Boolean
expressions, mixed integer and bit expressions and more
All constraints interact bidirectionally and are solved
concurrently
Keep in mind rules regarding precedence, sign extension,
truncation and wrap-around when creating constraints
class Parameters;
rand bit [15:0] a, b, c, d, e, f;
constraint c_0 {
(a + b) < 4;
0<c; c<d; d<e; e<150;
f == e % 16’d6; // Restrict width for: * % /
}
endclass
SystemVerilog Testbench with VCS 05/07/2007
Randomization 91
Constraint constructs in SystemVerilog
Conditional operator: if … else if … else
Behaves like a procedural “if”, except the conditionals
are evaluated bi-directionally. Equivalent to implication.
Implication Operator: ->
Short version of “if”
Ex: (mode == SMALL) -> (data.size < 10);
Global Constraints: x < other_object.y;
References to rand object data members in the
constraints get solved simultaneously
Variable ordering: solve x before y;
Otherwise VCS solves all constraints simultaneously
SystemVerilog Testbench with VCS 05/07/2007
Randomization 92
Array constraints
Create a random array
Constrain its size, individual elements, or all elements
class C;
rand bit [5:0] a[];
Array size constraint cc {
a.size inside {[1:5]}; // Output
array[0] > 0; a[0] = 1;
Single element a[1] = 2;
foreach (a[i])
if (i > 0) a[2] = 33;
Multiple elements
a[i] > a[i-1]); a[3] = 39;
} a[4] = 40;
function void pre_randomize;
a.delete; // Needed in 2005.06
endfunction
endclass
SystemVerilog Testbench with VCS 05/07/2007
Randomization 93
Array Constraints
Set valid on 3 cycles out of 5
class ValidOn;
rand bit valid[5];
constraint cv
{valid.sum == 32’d3;}
endclass
Two foreach loops with relationships
Constraints solved class E;
simultaneously rand bit [15:0] x[10], y[10];
x[] in 1:8 constraint size_cons {
foreach (x[i]){
y[] in 2:9 x[i] > 0; x[i] < y[i];
foreach (y[i])
y[i] inside {[1:9]};
}
endclass
SystemVerilog Testbench with VCS 05/07/2007
Randomization 94
Tricks and Techniques
Watch out for signed variables
What are legal values for first and second?
class Environment;
first second
rand byte first, second;
constraint c { 9. ‘h09 20. ‘h14
first + second < 8’h40; 85. ‘h55 -70. ‘hba
} -20. ‘hec -32. ‘he0
endclass
class Nesting;
Make instances rand rand SubClass data;
endclass
Or they won’t be randomized
Don’t call randomize() in new() constructor
Test may want to change constraints first
Use rand_mode to make a variable random / non-random
env.first.rand_mode(0);
Just replace result of randomization for a directed test
SystemVerilog Testbench with VCS 05/07/2007
Randomization 95
More Tricks and Techniques
Need to modify a constraint in a test?
Use a variable in the constraint
rand int size;
int max_size = 100;
constraint c {
size inside {[1:max_size]}; }
Extend the base class to override original constraint
class Base; class Bigger extends Base;
rand int size; constraint c {
constraint c { size inside {[1:1000]};}
size inside {[1:10]};} endclass
endclass
Use constraint_mode() to turn it off
SystemVerilog Testbench with VCS 05/07/2007
Randomization 96
Procedural randomization
Want to randomize without a class?
Use randcase or $urandom_range
randcase
1: len = $urandom_range(0, 2); // 10%: 0, 1, or 2
8: len = $urandom_range(3, 5); // 80%: 3, 4, or 5
1: len = $urandom_range(6, 7); // 10%: 6 or 7
endcase
Good for creating single variable, stateless
code, or nested set of actions
Constrained randomization is easier to modify,
and can make state variables for scoreboard
The bad_crc variable can be used for both
generating stimulus and checking the response
SystemVerilog Testbench with VCS 05/07/2007
Agenda 97
Introduction
Methodology Introduction
Getting Started
Language Basics
Connecting to HDL
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Controlling Threads 98
What Are We Going to Discuss?
The power of parallel threads
Concurrency defined
Creating and controlling threads
Communication between threads
SystemVerilog Testbench with VCS 05/07/2007
The Power of Threads 99
Concurrency is Essential for Verification
Port0 port0
Data Self-
port1 port1
Generation DUT Checking
--- ---
Create stream of
port7 port7 Check received
transactions
transactions
Functional
Coverage
Sent transactions to all
ports?
FIFO overflow checked?
SystemVerilog Testbench with VCS 05/07/2007
Threads 100
Fork / Join fork
execute();
The execute() task runs in parallel begin
with the begin-end block. The tasks generate();
check();
generate() and check() run serially.
end
join_none
fork fork fork
join join_any
join_none
SystemVerilog Testbench with VCS 05/07/2007
Threads 101
Creating and Controlling Threads:
fork / join | join_none | join_any create threads
disable label; terminate just the named block
disable fork; terminate all child threads below the current
context level
Use carefully – may stop more threads than you wanted!
wait fork; suspend a process until all children have completed
execution
wait (expression) suspend a process until the expression is true
Level sensitive
@(edge-exp) suspend a process until the edge-exp value changes
Edge sensitive
SystemVerilog Testbench with VCS 05/07/2007
Threads 102
If there are multiple threads ready to execute at a given
simulation time, their order of execution is
indeterminate
Execution order for threads scheduled at the same time
can be manipulated within the code
// Timeout example
fork : check_block
wait (arbif.cb.grant == 1); // May never complete
#1000 $display(“@%0d: Error, grant never received”, $time);
join_any
disable check_block;
SystemVerilog Testbench with VCS 05/07/2007
Communication Between Threads 103
Mailbox
Exchange messages / objects between two threads
Features
FIFO with no size limit
get/put are atomic operations, no possible race conditions
Can suspend a process
Default mailbox has no data type
Queuing
of multiple threads is fair
mailbox mbx; // Declare a mailbox
mbx = new(); // allocate mailbox
mbx.put(p); // Put p object into mailbox
mbx.get(p); // p will get object removed from FIFO
success = mbx.try_get(p); // Non-blocking version
mbx.peek(p); // Look but don’t remove, can block
success = mbx.try_peek(p); // Non-blocking version
count = mbx.num(); // Number of elements in mailbox
SystemVerilog Testbench with VCS 05/07/2007
Communication Between Threads 104
Mailbox Example
program mailbox_example(…);
mailbox mbx = new();
Generator g = new(); Get data from mailbox
Driver d = new();
initial begin class Driver;
fork Allocate mailbox Transaction t;
g.main();
d.main(); task main;
join repeat (10) begin
end mbx.get(t);
endprogram @(posedge busif.cb.ack);
busif.cb.addr <= t.addr;
class Generator; busif.cb.kind <= t.kind;
Transaction t; …
task main; end
repeat (10) begin endtask
t = new();
assert(t.randomize());
mbx.put(t);
end
endtask
endclass
Put data into mailbox
SystemVerilog Testbench with VCS 05/07/2007
Communication Between Threads 105
Semaphore
Used for mutual exclusion and synchronization.
Features
Variable number of keys can be put and removed
Controlled access to a shared object, such as sharing a bus from models
Thinkof two people wanting to drive the same car – the key is a
semaphore
Be careful – you can put back more keys than you took out!
Syntax
semaphore sem;
sem = new(optional_initial_keycount = 0);
sem.get(optional_num_keys = 1);
sem.put(optional_num_keys = 1);
SystemVerilog Testbench with VCS 05/07/2007
Communication Between Threads 106
Semaphore Example
program automatic test;
semaphore sem;
initial begin Allocate a semaphore, 1 key available
sem = new(1);
…
fork
task sequencer();
sequencer();
repeat($random()%10) @bus.cb;
sequencer();
sendTrans();
join
endtask
end
…
task sendTrans();
sem.get(1);
@bus.cb;
bus.cb.addr <= t.addr;
Wait for bus to be available bus.cb.kind <= t.kind;
bus.cb.data <= t.data;
When done, replace key sem.put(1);
endtask
endprogram
SystemVerilog Testbench with VCS 05/07/2007
Communication Between Threads 107
Events
Synchronize concurrent threads
Features
Synchronize parallel threads
Sync blocks process execution until event is triggered
Events connect triggers and syncs
Can be passed into tasks
event ev; // Declare event
-> ev; // Trigger an event
@ev; // Block process, wait for future event
wait (ev.triggered); // Block process, wait for event,
// including this timeslot
// Reduces race conditions
driver = new(ev); // Pass event into task
SystemVerilog Testbench with VCS 05/07/2007
Communication Between Threads 108
Event Example
Main Testbench Generator transactor
event gen_done[4]; class Generator;
event done;
Generator gen[4]; // Pass event from TB
function new (event done);
initial begin this.done = done
// Instantiate testbench endfunction
foreach (gen[i])
gen[i] = new(gen_done[i]); task main( );
fork
// Run transactors begin
gen[i].main(); // Create transactions
… -> done;
end
// Wait for finish join_none
foreach (gen[i]) endtask
wait(gen_done[i].triggered);
end endclass
SystemVerilog Testbench with VCS 05/07/2007
Lab 2 109
Verify the APB Interface, Part 1
Objective
Write a structured testbench to learn more about classes,
randomization, threads and mailboxes
Verify that a basic transaction can be created, randomized, and
sent through the design
Time Allotted
1 hour
SystemVerilog Testbench with VCS 05/07/2007
Lab 2 110
apb_trans
apb_gen
apb_mbox
apb_master DUT
SystemVerilog Testbench with VCS 05/07/2007
Agenda 111
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Virtual Interfaces 112
What Are We Going to Discuss?
Virtual interfaces
Why are they needed?
Creating virtual interfaces
Connecting to physical interfaces
Using in classes and methods
SystemVerilog Testbench with VCS 05/07/2007
Virtual Interfaces 113
Virtual Interfaces Advanced
Allow grouping of signals by function topic
Create a handle to an interface
Virtual interfaces can be passed to routines with different values.
Promotes reuse by separating testbench from implementation
names
enable_1
soc_1
data_1[7:0]
RX_1
4x4
enable_3
ATM
soc_3
data_3[7:0]
RX_3 Switch
SystemVerilog Testbench with VCS 05/07/2007
Virtual Interfaces 114
The Five Steps to Virtual Interfaces
1. Define physical interfaces
Use clocking blocks and modports
2. Connect the interfaces
Usually in top netlist
3. Create procedural code that uses virtual interface
A generic method that is not tied to any one interface
4. Create virtual interface & connect to physical
Procedural code in testbench
5. Use virtual interfaces with classes and methods
A generic method can operate on many interfaces
SystemVerilog Testbench with VCS 05/07/2007
Virtual Interfaces 115
Virtual Interfaces Syntax
STEP 1: Define a physical interface
// ATM Rx interface
interface Rx (input logic clk);
logic [7:0] data;
logic soc, en, clav;
clocking Rcb @(posedge clk);
output data, soc, clav; // Relative to
input en; // testbench
endclocking : Rcb
modport DUT (output en, // DUT connection
input data, soc, clav);
modport TB (clocking Rcb); // TB connection
endinterface : Rx
SystemVerilog Testbench with VCS 05/07/2007
Virtual Interfaces 116
Binding signals to a physical interface
STEP 2: Connect the interface
Interface
module top; instances
Interface logic clk = 0;
name
Rx Rx0(clk), Rx1(clk), Rx2(clk), Rx3(clk);
Tx Tx0(clk), Tx1(clk), Tx2(clk), Tx3(clk);
atm_switch a1 (Rx0, Rx1, Rx2, Rx3,
Tx0, Tx1, Tx2, Tx3, clk);
test t1 (Rx0, Rx1, Rx2, Rx3,
Tx0, Tx1, Tx2, Tx3, clk);
always #20 clk = !clk;
endmodule : top
SystemVerilog Testbench with VCS 05/07/2007
Virtual Interfaces 117
Define virtual interface
STEP 3: Define procedural code that uses virtual
interface Interface
class Driver; & modport
virtual Rx.TB Rx;
function new(virtual Rx.TB Rx);
this.Rx = Rx; // Initialize VI
endfunction
task sendCell();
Rx.Rcb.soc <= 0; // Drive signal w/clocking block
...
endtask
endclass
SystemVerilog Testbench with VCS 05/07/2007
Virtual Interfaces 118
Using Virtual Interfaces
STEP 4: Define virtual interface & connect to physical
STEP 5: Call routine with virtual interface variables
program automatic test(Rx.TB Rx0, Rx1, Rx2, Rx3, … );
`include “driver.vh”
Driver driver[4];
virtual Rx.TB vRx[4];
initial begin
vRx[0] = Rx0; …
for (int i=0; i<4; i++)
driver[i] = new(vRx[i]);
driver[$random % 4].sendCell(); // Send to random port
end
One variable in the method references different connections.
This allows for a single class to operate on many physical interfaces.
SystemVerilog Testbench with VCS 05/07/2007
Lab 3 119
Verify the APB Interface, Part 2
Objective
Create virtual interfaces for communication between
design and testbench
Time Allotted
1 hour
SystemVerilog Testbench with VCS 05/07/2007
Lab3 120
mon2scb
apb_trans scoreboard
apb_gen mas2scb
apb_monitor
apb_mbox
apb_master DUT
SystemVerilog Testbench with VCS 05/07/2007
Agenda 121
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Functional Coverage Example 122
Have I tried all transaction kinds?
program automatic test(busifc.TB ifc);
class Transaction;
rand bit [31:0] src, dst, data;
rand bit [ 2:0] kind;
endclass
covergroup CovKind;
coverpoint tr.kind; // Measure coverage
endgroup
Transaction tr = new(); // Instantiate transaction
CovKind ck = new(); // Instantiate group
initial begin
repeat (32) begin // Run a few cycles
assert(tr.randomize());
ifc.cb.kind <= tr.kind; // Transmit transaction
ifc.cb.data <= tr.data; // onto interface
ck.sample(); // Gather coverage
@ifc.cb; // Wait a cycle
end
end
endprogram
SystemVerilog Testbench with VCS 05/07/2007
Sample HTML Reports 123
SystemVerilog Testbench with VCS 05/07/2007
Coverage Group 124
Define your coverage model
Encapsulates the coverage specification (bins, transitions)
for a set of coverpoints and cross combinations of
coverpoints
Variables in a group belong together:
Data members of a class
Cross coverage across these variables
Sample them on the same event (trigger)
Write specification once (just like a class definition),
Instantiate many times
covergroup CovKind @(posedge ifc.cb.valid);
coverpoint global;
coverpoint ifc.cb.kind;
The variable global and
endgroup
signal ifc.cb.kind are
…
sampled every posedge
CovKind ck = new;
of ifc.cb.valid signal
SystemVerilog Testbench with VCS 05/07/2007
Embedded Coverage Group 125
Embed covergroup in a class
Easy way to cover a subset of the members of a class
You must instantiate the coverage group to gather results
For efficiency, put coverage groups in “static” objects
A simulation could have 10,000 transactions, but just 1 driver object
SystemVerilog automatically creates bins for cover points
without having to specify the bins explicitly
class Driver;
bit [3:0] x, y;
covergroup cg;
coverpoint x;
coverpoint y; Members x and y will be
endgroup sampled on the active
function new; edge of the ifc.cb clock.
cg = new;
endfunction
endclass
SystemVerilog Testbench with VCS 05/07/2007
Automatic Bin Creation (Example 1) 126
bit [3:0] x, y;
covergroup Cov1;
coverpoint x;
coverpoint y;
endgroup
…
Cov1 c1 = new();
x = 1; Level where
y = 8; coverage “counts”
c1.sample();
x = 2;
c1.sample();
x = 15;
y = 9;
c1.sample();
SystemVerilog Testbench with VCS 05/07/2007
Automatic Bin Creation (Example 2) 127
bit [3:0] x, y;
covergroup Cov1;
coverpoint x;
coverpoint y;
// Divide ranges in 1/2
option.auto_bin_max = 2;
endgroup
…
Cov1 c1 = new();
x = 1;
y = 8;
c1.sample();
x = 2;
c1.sample();
x = 15;
y = 9;
c1.sample();
SystemVerilog Testbench with VCS 05/07/2007
User Defined Coverage Bins for Coverpoints 128
User defined bins for coverage using ranges of values
Bin lo is associated with values of port_number between 0 and 1
Bin hi_4 to hi_7 are associated with values between 4 and 7
Bin misc is associated with values 2 & 3
Transition bin t1 is associated with any value transition (single) of
port_number from 0=>1, 0=>2, 0=>3
logic [2:0] port_number;
covergroup CovPorts; 0: lo
1: lo
coverpoint port_number { 2: misc
3: misc
bins lo = {[0:1]}; // 1 bin for 2 values 4: hi_4
bins hi[] = {[4:$]}; // 4 separate bins 5: hi_5
6: hi_6
bins misc = default; // Unspecified values 7: hi_7
bins t1 = (0=>1), (0=>2), (0=>3); // transitions
}
endgroup
SystemVerilog Testbench with VCS 05/07/2007
Automatic Bin Creation (Example 3) 129
If you create bins with the [] syntax, VCS will not create new bins for
values that are out of bounds
bit [3:0] x, y; Coverage
covergroup Cov1; holes
coverpoint x {
bins s[] = {[0:4]};
}
coverpoint y;
endgroup
…
Cov1 c1 = new();
x = 1;
y = 8;
c1.sample();
x = 2;
c1.sample();
x = 15;
y = 9; Out of bounds
c1.sample(); value ignored
SystemVerilog Testbench with VCS 05/07/2007
Cross Coverage 130
Specified in the coverage group using cross
Cross argument can be a coverpoint or variable
Bins are automatically created for the cross products
bit [3:0] global
class MyClass; Use label for
bit [4:0] y; coverage report
covergroup cg;
cc1: cross y, global;
endgroup
function new;
cg = new;
endfunction
endclass
…
MyClass obj1 = new();
obj1.y = ‘h14;
global = 2;
obj1.cg.sample();
obj1.cg.sample();
obj1.y++;
obj1.cg.sample();
SystemVerilog Testbench with VCS 05/07/2007
Defining the Sample Event 131
Specifying the coverage event
You can specify an event expression in the coverage group
definition. This will be used for all instances of a coverage
definition.
Or use instance.sample();
Valid event expressions
@SV_event;
@(SV_variable);
You can use interface signals, including ones in clocking
blocks
Values are sampled upon occurrence (triggering) of the
coverage event expression
SystemVerilog Testbench with VCS 05/07/2007
Assertion Coverage 132
A covergroup can react to a SystemVerilog Assertion
Use SVA action block to trigger event,
Have covergroup sample on event
program automatic test;
covergroup Write_cg @$root.mem.write_event;
coverpoint $root.mem.data;
coverpoint $root.mem.addr;
option.auto_bin_max = 2; SVA
endgroup
module mem(simple_bus sb);
Write_cg wcg; bit [7:0] data, addr;
event write_event;
initial begin cover property
wcg = new(); (@(posedge clk) write_ena==1)
-> write_event;
// Apply stimulus here
// Other logic here
#10000 $finish; endmodule
end
endprogram
SystemVerilog Testbench with VCS 05/07/2007
Coverage 133
Databases
VCS writes coverage data to a binary database file
The database file is named simv. db
VCS report formats
HTML > urg –dir simv.vdb
Text: > urg –dir simv.vdb –format text
HTML data presented hierarchically using hypertext links
$set_coverage_db_name ( name );
Sets the filename of the coverage database into which
coverage information is saved at the end of a simulation run.
$load_coverage_db ( name );
Load from the given filename the cumulative coverage
information for all coverage group types.
SystemVerilog Testbench with VCS 05/07/2007
Agenda 134
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Starting Point : Design Spec and Test Plan 135
Design Spec:
• A packet consists address in valid address range and variable
sized payload.
• The valid address range is between 0 and 8’hBF.
• Data length support is max 1024 bytes transfers
Test Plan (Partial):
Define 3 address regions as [0:0x3F], [0x40:0x7F]
and[0x80:0xBF].
SystemVerilog Testbench with VCS 05/07/2007
More Complete Class Example 136
Classes are containers of data objects, transactors, generators,
verification environments, etc.
class packet;
typedef enum {WRITE, READ} transtype_t;
Data rand bit [`ADDR_WIDTH:0]addr;
Members rand bit [`DATA_WIDTH-1:0] data[];
rand transtype_t trans_type;
constraint addr_c {
Constraint addr inside {[0:8’hBF]};
Block }
constarint data_c {
data.size <= 1024;
}
Procedural
Code task display();
$display(“ %s, %h”, pkt.trans_type.name(), a
endtask
Coverage
covergroup pktCov;
Group coverpoint addr,data,trans_type;
endgroup
endclass
SystemVerilog Testbench with VCS 05/07/2007
Coverage Driven Verification 137
Start with a fully randomizable testbench
Run many randomized simulation runs
Analyze cumulative coverage and coverage holes
Then with minimal code changes:
Add constrained stimulus to fill coverage holes
Make few directed tests to hit the remaining holes
Constrainable Many runs,
Random Generation different seeds
Directed
Add Testcase Functional
constraints Coverage
Minimal Code Identify
Modifications holes
SystemVerilog Testbench with VCS 05/07/2007
Capture Input Stimulus and Randomize 138
Design Spec: A packet consists of a destination address and a
variable sized payload.
Implementation: Declare variables as rand so constraint solver will
fill with random values.
Packet Class Basic Test
program automatic test;
class packet;
packet pkt;
rand bit [31:0]addr;
rand bit [7:0] data[]; initial begin
rand transtype_t trans_type; pkt = new();
repeat(50) begin
endclass
pkt.randomize();
transmit(pkt);
end
end
endprogram
SystemVerilog Testbench with VCS 05/07/2007
Constrain the Randomness (Design Spec) 139
Design Spec:
• Size of the payload is between 0 and 1024 bytes.
Implementation:
• Without constraints, VCS solver generates random data which may be
illegal and will either be ignored by device or result in errors. Add a new
control field pktSize.
class packet;
rand bit [31:0]addr;
rand bit [7:0] data[];
rand transtype_t trans_type;
rand bit[7:0] pktSize;
constraint packetSize_c {
pktSize inside {[0:1024]};
data.size() == pktSize;
}
endclass
SystemVerilog Testbench with VCS 05/07/2007
Constrain the Randomness (Design Spec) 140
Design Spec:
• The valid address range is between 0 and 8’hBF.
• Address 8’hBB is not writable
Implementation: See below.
class packet;
rand bit [31:0]addr;
rand bit [7:0] data[];
... Implication
rand transtype_t trans_type; Constraints
constraint addr_c {
(trans_type == WRITE) -> addr != 8'hBB;
addr inside {[0:8’hBF]};
}
endclass
SystemVerilog Testbench with VCS 05/07/2007
Directed Random Testing 141
Test Plan:
Test device with WRITE type , data size 20 bytes at address
8’h55.
Implementation:
Override constraint custom_c. Same testbench as before.
constraint packet::custom_c {
pktSize == 20;
trans_type == WRITE;
addr == 8’h55;
}
SystemVerilog Testbench with VCS 05/07/2007
Change Default Distribution 142
Test Case:
Test device with 80% WRITE and 20% READ.
Implementation:
Use distribution constraint to change probability
Minimal declarative changes needed for new testcase
Packet Class Test with 20% READ trans
class packet; constraint packet::custom_c {
rand address_e addrTyp; trans_type dist {WRITE:=80, READ:=20
.
. program automatic test;
constraint custom_c; packet pkt;
initial begin
endclass
pkt = new();
pkt.randomize();
transmit(pkt);
end
endprogram
SystemVerilog Testbench with VCS 05/07/2007
Directed Random Stimulus Generation 143
Test Plan: Inject the device with 50 WRITE packets mostly targeting the
hi_range of addresses.
Implementation: Add a test specific constraint to direct generation to
the area of interest. Create an instance of the packet class in the test and
randomize 50 times.
constraint packet::custom_c {
addr dist {[8’h80:8’hBF] := 90, [0:8’h7F] := 10};
trans_type == WRITE;
}
program automatic test;
packet pkt;
initial begin
pkt = new();
repeat(50) if (pkt.randomize())
transmit(pkt);
end
endprogram
SystemVerilog Testbench with VCS 05/07/2007
Derive Coverage Model From Test Plan 144
Test Plan:
• Define 3 address regions: 0:0x3F, 0x40:0x7F and 0x80:0xBF
• Test with packets of all types = 2 bins
• Test with packets targeted to all address regions = 3 bins
• Test with all permutations of all packets types to all address
regions = 6 bins
• Implementation:
• Do not write directed test for each test item
• Instead map each test item into an executable coverage point
• Run random suite of tests and collect functional coverage.
• Analyze coverage results and to improve functional coverage
either run more random tests or for hard-to-reach coverage
points create a more constrained test (Directed random).
SystemVerilog Testbench with VCS 05/07/2007
Implement Coverage Model 145
covergroup pktCov;
coverpoint trans_type; // Creates 2 bins
coverpoint addr { // Item 2: Creates 3 bins
bins low_range = {[0:0x3F]};
bins mid_range = {[0x40:0x7F]};
bins hi_range = {[0x80:0xBF]};
}
cross trans_type, dst; // Item 5: Creates 6 bins
endgroup
SystemVerilog Testbench with VCS 05/07/2007
Lab 4 146
Implementing Coverage
Objective
Add functional coverage to the APB Interface
Create a constrained random test
Use this test to make directed test
Analyze the functional coverage in URG
Time Allotted
1 hour
SystemVerilog Testbench with VCS 05/07/2007
Agenda 147
Introduction
Methodology Introduction
Getting Started
Testbench Environment
Language Basics
OOP Basics
Randomization
Controlling Threads
Virtual Interfaces
Functional Coverage
Coverage Driven Verification
Testbench Methodology
SystemVerilog Testbench with VCS 05/07/2007
Testbench Methodology 148
What Are We Going to Discuss?
Reference Verification Methodology
Testbench Structure
Simple Testbench Building Blocks
SystemVerilog Testbench with VCS 05/07/2007
Testbench Methodology - Architecture 149
Layers
Constrained random tests
Test Tests
Scenario Generators
Functional Coverage
Functional Transactor Self Check Checker
Command Driver Assertions Monitor
DUT
Signal
SystemVerilog Testbench with VCS 05/07/2007
Testbench Methodology - Overview 150
How do you use these concepts such as OOP and
randomization to build a verification environment?
Synopsys’ Verification Methodology Manual (VMM)
contains guidelines, coding styles, and base
classes
Based on many years of experience
This is an overview to show basic concepts,
highlights of the VMM 2-day class
This does NOT show how to use VMM base classes
SystemVerilog Testbench with VCS 05/07/2007
VMM Methodology 151
Guiding Principles
Maximize design quality
More testcases
More checks
Less code
Approaches
Reuse
Across tests
Across blocks
Across systems
Across projects
One verification environment, many tests
Minimize test-specific code
Assertions
VMM Methodology emphasizes
“Coverage Driven Verification”
SystemVerilog Testbench with VCS 05/07/2007
Transactions and Transactors 152
Transaction Data models Interfaces
Variant data Transaction interface
Error protection Physical interface
properties Sub-layering
Standard methods
Reusable transactors
Constraints
Starting & stopping
Transaction objects Notifications
Objects vs. procedures Integrating scoreboards
Transaction response Adding functional
Transactor Categories coverage
Master vs. slave Injecting errors
Driver vs. monitor Customization and
extensibility
SystemVerilog Testbench with VCS 05/07/2007
Data & Transactions 153
Implementation
class Transaction;
Data modeled using classes rand enum {READ, WRITE}
kind;
Packets rand bit [ 7:0] sel;
Frames rand bit [31:0] addr;
rand bit [31:0] data;
Cells endclass
Instructions
Pixels
Samples
Flows through the verification environment
100,000+ instances created and freed during a
simulation
100+ in existence at any given time
Duplicated only when necessary
SystemVerilog Testbench with VCS 05/07/2007
Data & Transactions 154
Flow
Tests
Created Accumulated Freed
here here here
Generators
Duplicated
here
Transactor Scoreboard Checker
Driver Assertions Monitor
Created
Freed DUT here
here
SystemVerilog Testbench with VCS 05/07/2007
Transactions 155
Generating Transactions
Simple to generate random streams of data
Transaction tr;
tr = new;
assert(tr.randomize());
apb.do(tr);
Can use constraints and solver
Add or override constraints via extensions
Constraints across multiple instances
class my_tr extends Transaction;
constraint available_targets {
sel inside {[0:3]};
if (sel == 0 && kind == READ) {
addr inside {[0:15], 27, 31};
} else {
addr < 31;
}
}
endclass
SystemVerilog Testbench with VCS 05/07/2007
Transactions 156
Transaction Interface
Can use transaction interface object
Transactors connected via objects
sw_driver sw_driver
mbx.put(tr);
apb.write(...);
Mailbox
apb_master
task write(...); mbx.get(tr);
apb_master
Procedural Interface
interface object
SystemVerilog Testbench with VCS 05/07/2007
Transactions 157
Transaction Interface Objects
Can mix and match transactors without
modifications
mii_phy
phy.get(tr);
Test
eth_gen mac_layer
gmii_phy
mac.get(tr); phy.get(tr);
mac.put(tr); phy.put(tr);
xgmii_phy
phy.get(tr);
SystemVerilog Testbench with VCS 05/07/2007
Transactors 158
Building blocks of the verification environment
Transactors modeled using classes
Bus-functional models
Functional layer components
Generators
Few instances
Created at the start of simulation
Remain in existence for duration
Data and transactions flow through them
Scheduling
Transformation
Processing
SystemVerilog Testbench with VCS 05/07/2007
Transactor 159
Categories
Active Transactors – Master
Initiate transactions
Supply data to other side
Example: AHB master, Ethernet Tx
Reactive Transactor – Slave
Transaction initiated by other side
React by supplying requested data
Example: AHB slave
Passive Transactor – Monitor
Transaction initiated by other side
Collect transaction data from other side
Slave monitor example: AHB bus monitor
SystemVerilog Testbench with VCS 05/07/2007
Creating a transactor 160
Main routine contains loop that receives a
transaction, processes it, and sends it out.
class apb_xactor;
function new(mailbox mgen, mdrv); generator
(xactor)
task main();
forever begin
mgen.get(t); transactor
// process transaction t (xactor)
mdrv.put(t);
end
endclass
driver DUT
(xactor)
SystemVerilog Testbench with VCS 05/07/2007
Generators 161
Randomizable objects
Data streams
Configuration
Error injection
Election
Atomic generators atomic generator
blueprint
Modifying constraints Copy
Run-time generator control
Inserting directed stimulus
scenario generator
Scenario generators scenario
Atomic scenarios
Grammar-based scenarios
Defining new scenarios
Modifying scenario distributions
SystemVerilog Testbench with VCS 05/07/2007
Randomizable Aspects 162
Disturbance Injection
Variations specific to a level of abstraction
Delay
Collisions
Abort/Retry
No handshake
Data corruption
Ordering
Should be controlled in relevant transactor
Not at transaction source
Generate MAC-level Generate MII-level
disturbances here disturbances here
Not here
eth_gen mac_layer mii_phy
SystemVerilog Testbench with VCS 05/07/2007
Randomize DUT & TB Configuration 163
Configurations
Generated by verification environment
verif_env
eth_gen mac_layer mii_phy
cfg_gen
eth_gen mac_layer mii_phy
Generates
one instance
eth_gen mac_layer mii_phy
Used to
build
eth_gen mac_layer mii_phy
class cfg;
... ahb_mstr
endclass
Downloaded
into DUT via...
SystemVerilog Testbench with VCS 05/07/2007
Self-Checking Functionality 164
Entirely DUT-specific
Can only detect errors
Detected errors identified in planning stage
Each error detection mechanism part of coverage model
Ensure that opportunity to check error existed
No error was actually found
Can be implemented in different ways
Transfer function + Scoreboard
Reference model
Maybe in different language
Off-line
Assertions
Self-Checking methodology is a full day topic
SystemVerilog Testbench with VCS 05/07/2007
Generator Design 165
Controllable Aspects
Good controllable random generators don't
"just happen"
Design constraint controls
Plan for trivial testcases
Generate only 1 object
Generate simple objects
Plan for corner cases
Scenarios
Synchronization
Plan for directed stimulus
Interruption
Reactivity
SystemVerilog Testbench with VCS 05/07/2007
Verification Environment 166
Execution Flow
All testbenches must have the same execution flow
Some steps may be blank Randomize test
Extend base environment to configuration descriptor
implement DUT-specific
Allocate and connect
environment
environment components
Basic flow is: Download test
pre-test configuration into DUT
run-test Start components
post-test
End-of-test detection threads
(ends when returns)
Stop data generators &
Wait for DUT to drain
Check recorded stats &
sweep for lost data
SystemVerilog Testbench with VCS 05/07/2007
Onward! 167
Where do I go next?
Complete the labs / and QuickStart
($VCS_HOME/doc/examples)
Read the Verification Methodology Manual
Take the VMM-Basic and Advanced classes
Please let us know your feedback on this training
vcs-support@synopsys.com
THANK YOU!!!
SystemVerilog Testbench with VCS 05/07/2007