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 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
4
Agenda
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
5
Verification Environment
6
Definitions
Checks correctness
Creates stimulus
Testbench Verification Environment
Test
Executes transactions
Transactor
Scoreboard
Checker
Driver
Assertions
Monitor
Supplies data to the DUT
DUT
SystemVerilog Testbench with VCS
Identifies transactions Observes data from DUT
Methodology Introduction
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
7
Methodology Introduction
Testbench Design
Start with a fully randomizable testbench
Then with minimal code changes:
Run many randomized simulation runs Analyze cumulative coverage and coverage holes Add constrained stimulus to fill coverage holes
Finally:
Make few directed tests to hit the remaining holes
SystemVerilog Testbench with VCS
05/07/2007
8
Coverage-Driven Verification
9
Measure progress using functional coverage
% Coverage
With VIP
Coverage-Driven Methodology
Productivity gain Directed Methodology
Goal
Self-checking random environment development time
Time SystemVerilog Testbench with VCS
05/07/2007
Key Benefits: Testbench Environment
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
10
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 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
14
Debug: Getting Started
Invoke DVE
> simv –gui -tbug
Source code tracing
Active threads Local variables
SystemVerilog Testbench with VCS
15
05/07/2007
Getting Started
16
Documentation and Support
SystemVerilog documentation
Examples
Email Support:
http://solvnet.synopsys.com
Testbench Discussion Forum
[email protected]
On-line knowledge database
$VCS_HOME/doc/examples
http://verificationguild.com
SystemVerilog LRM
www.Accellera.org or www.eda.org/sv
SystemVerilog Testbench with VCS
05/07/2007
> vcs -doc
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 blocks 2. Create testbench program 3. Create top module 4. Compile and run
top.sv
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
An interface encapsulates this communication
Connectivity (signals) Directional information (modports) Timing (clocking blocks) Functionality (routines, assertions, initial/always blocks)
An interface can be:
Top level net-lists are too verbose and error prone
Connected at compile-time (default) Connected at run-time – virtual interfaces
An interface can not:
Be hierarchical, or extended Device 1
SystemVerilog Testbench with VCS
05/07/2007
interface
Device 2
Testbench Environment -- Interfaces Before Interfaces
The RTL code was connect with a netlist mem
cpu top
module mem ( input bit req, bit clk, bit start, wire [1:0] mode, wire [7:0] addr, inout wire [7:0] data, output bit gnt, bit rdy); … module top;
module cpu ( input bit clk, bit gnt, bit rdy, inout wire [7:0] data, output bit req, bit start, wire [1:0] mode, wire [7:0] addr); …
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
21
Testbench Environment -- Interfaces
22
Named Bundle of Signals
The RTL code is connected with bundled signals
mem
simple_bus clk
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; module top; endinterface 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; endinterface: simple_bus
Label on end 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 output inout modport MASTER (output input inout endinterface: simple_bus
module cpu(simple_bus.MASTER sb, input bit clk); … endmodule SystemVerilog Testbench with VCS
addr, gnt, mode, start, req, rdy, data); addr, gnt, start, mode, req, rdy, data);
module mem(simple_bus.SLAVE sb, input bit clk); … endmodule
05/07/2007
Testbench Environment -- Interfaces Adding Timing
25 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; logic reset;
reset request[1:0] grant[1:0] clock
clocking cb @(posedge clk); input grant; // TB input output request; // TB output endclocking modport DUT (input clk, input request, reset, output grant); modport TB (clocking cb, output reset); endinterface: arb_if SystemVerilog Testbench with VCS
arb.sv
// Design under test // Synch signals // Async signals
05/07/2007
Testbench Environment -- Interfaces 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
26
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
Previous
Current
SystemVerilog Testbench with VCS
design assertions testbench $monitor Next 05/07/2007
Testbench Environment - Program Block 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
28
Testbench Environment – Program
Create testbench program: test.sv
program test(arb_if.TB arbif); initial begin // Asynch drive reset arbif.reset <= 0; #15ns arbif.reset <= 1; #35ns arbif.reset <= 0; ns!
// Synch drive request ##1 arbif.cb.request <= 1; ##1 arbif.cb.request <= 0; wait (arbif.cb.grant == 1); end endprogram Wait 1 clock cycle
SystemVerilog Testbench with VCS
29 Step 2
clk reset request 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
Common mistake: forgetting “cb.” in signal reference Error: arbif.request not visible via modport 05/07/2007
Using the Clocking Block
30
Synchronous Signal Access
Clocking Block signals are referenced by prepending the clocking block name to the signal:
All drives must use non-blocking assignment arbif.cb.request <= 1; value = arbif.cb.grant;
// drive // 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; @(posedge arbif.cb.grant); @(negedge arbif.cb.grant); wait (arbif.cb.grant==1);
// // // // //
continue continue continue wait for no delay
on any edge of grant on posedge on negedge expression if already true
Wait for N clock cycles with ##n – blocking statement ##2 arbif.cb.request <= 0;
SystemVerilog Testbench with VCS
// Wait 2 cycles // then assign 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 before clock SystemVerilog Testbench with VCS
Drive outputs at clock 05/07/2007
Testbench Environment – Top Block
33 Step 3
Create top module module top; bit clk; test t1 (.*); arb d1 (.*); arb_if arbif(.*); always #50 clk = !clk; endmodule
The syntax .* connect ports and signals with same names SystemVerilog Testbench with VCS
// Synchronous TB program test(arb_if.TB arbif); … endprogram
module arb(arb_if.DUT arbif, bit clk); // Some logic here… endmodule interface arb_if (input bit clk); … endinterface: arb_if
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; parameter TIMEOUT = 1_000_000;
module state_machine(…); fsm_state_t state, next_state; endmodule program test; fsm_state_t state; initial #TIMEOUT $finish; endprogram SystemVerilog Testbench with VCS 05/07/2007
root.sv
dut.sv
test.sv
Testbench Environment -- Communication
DUT visibility
The program block can see all signals & routines in the design
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
A module can not see anything in program block
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
35
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; a1: assert (arbif.cb.grant==1); end
SystemVerilog Assertion
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”); end
SystemVerilog Testbench with VCS
05/07/2007
Custom message
Testbench Environment – Compile and Run
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
38
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 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; integer i; int i; byte b8; shortint s; longint l;
// // // // // //
2-state bit 0 or 1 4-state, 32-bits, signed Verilog-1995 2-state, 32-bit signed integer 2-state, 8-bit signed integer 2-state, 16-bit signed integer 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
41
SV Language Basics
42
SystemVerilog Data Types
User defined types
Useful type
Use typedef to create a synonym for another type
typedef bit [31:0] uint; typedef bit [0:5] bsix_t; // Define new type bsix_t my_var; // Create 6-bit variable
Use classes instead!
Define a structure with multiple variables typedef struct {bit [7:0] opcode; bit [23:0] addr; } 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; Print the default: nstate = IDLE; endcase symbolic name $display(“Next state is %0s”, nstate.name); nstate = fsmstate_t’(i); // cast integer to enum 05/07/2007
SystemVerilog Testbench with VCS
SV Language Basics Fixed Size Arrays
44 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
bytes[0][3] bytes[0] bytes[1] bytes[2]
bytes[0][1][6]
Use bit & word subs together with fixed arrays
7 65 4 3 21 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 7 65 4 3 21 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 7 65 4 3 21 0 7 65 4 3 21 0
bit [3:0][7:0] bytes [0:2]; SystemVerilog Testbench with VCS
// 3 entries of packed 4 bytes 05/07/2007
SV Language Basics Dynamic Arrays
45 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[]; d = new[5]; foreach (d[j]) d[j] = j; b = d; b[0] = 5; $display(d[0],b[0]); d = new[20](d); d = new[100]; d.delete(); SystemVerilog Testbench with VCS
// Two dynamic arrays // Make array with 5 elements // Initialize // Copy a dynamic array // // // // //
See both values (0 & 5) Expand and copy Allocate 100 new integers Old values are lost Delete all elements 05/07/2007
SV Language Basics Queues
type name [$];
Flexible – size can easily change
FAST!
46
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} q.insert(4, b); // {0,1,2,3,4,5,6} q.delete(1); // {0,2,3,4,5,6} q.push_front(7); // {7,0,2,3,4,5,6} j = q.pop_back(); // {7,0,2,3,4,5} q.push_back(8); // {7,0,2,3,4,5,8} j = q.pop_front(); // {0,2,3,4,5,8} $display(q.size); // “6” foreach (q[i]) $display(q[i]);
SystemVerilog Testbench with VCS
05/07/2007
Insert Insert Delete Insert j = 6 Insert j = 7
before s[2] whole queue element #1 at front at back
Checking Results with Queues 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
47
SV Language Basics Associative Arrays
48 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; reg[7:0] mydata[string]; Standard array
// Print full array foreach(aa[i]) $display(i,,aa[i]); Associative array
All memory allocated, even unused elements
SystemVerilog Testbench with VCS
Unused elements don’t use memory
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
LRM requires a queue
SystemVerilog Testbench
int q[$] = {1,3,5,7}, tq[$]; IEEE changed array const from {0,1} to ’{0,1} int d[] = {9,1,8,3,4}; (VCS issues Warning for int f[6] = {1,6,2,6,8,6}; old usage) $display(q.sum, q.product); // 16 105 tq = q.min(); // {1} 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} with VCS 05/07/2007
SV Language Basics Strings
50 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(); reset_l = 1’b0; #100 reset_l = 1’b1; endtask
function int add2(int n); return n + 2; endfunction
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
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.
Change storage default for programs
SystemVerilog Testbench with VCS
program automatic test; task is_automatic();
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, default type is logic
Watch out for ref 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
Key Topics
Verify the arbiter’s reset Verify arbiter handles simple requests and grants Verify proper handling of request sequences
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
Executable Code Communication between blocks
SystemVerilog Testbench with VCS
Properties: Variables behavioral blocks Methods: tasks (always, initial), and functions tasks, functions Ports or crosscalls, module task calls mailboxes, semaphores, etc.
05/07/2007
OOP Basics
60
Terminology Blueprint for a house
Class
A complete house Address of a house Light switches Turn on/off switches
Object
Type-safe pointer to an object – can not be corrupted
Properties
An object is an instance of a class
Handle
Programming element “containing” related group of features and functionality Encapsulates functionality Provides a template for building objects Can be used as data structures
Variables contained in the instance of the class
Methods
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 public by default
class Transaction; // 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 endclass program automatic test; endprogram
SystemVerilog Testbench with VCS
05/07/2007
In a class, methods are always automatic
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 Coding style: don’t call new in declaration
Declare first 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 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
SystemVerilog Testbench
if (tr.done) // No longer needed? tr = null; // clear handle with VCS 05/07/2007
63
Where are all the objects?
64
A transactor can be an object too! Scoreboard holds transactions
Extended class
Compares transactions
Test
Executes transactions
Transactor Drives transactions into the DUT
Verification Environment
Self Check
Monitor
Driver DUT
SystemVerilog Testbench with VCS
Checker
05/07/2007
Puts data into transactions
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 tr = new(); endprogram
initial tr = new(5); // dst uses default endprogram 05/07/2007
SystemVerilog Testbench with VCS
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; static int count = 0; int id; … function new(); id = count++; endfunction endclass
SystemVerilog Testbench with VCS
Using a id field can help keep track of transactions as they flow through test
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 … Thing t1, t2; initial begin t1 = new(); t1.data = 1; t2 = new(); t2.data = 2; t2 = t1; t2.data = 5; $display(t1.data); end
SystemVerilog Testbench with VCS
t1 // Two handles // Allocate first thing
data=1
// Allocate second t2 // Second Thing is lost // Modifies first thing // Displays “5”
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 … Thing t1, t2; initial begin t1 = new(); t1.data = 1; t2 = new(); t2.data = 2; t2 = t1; t2.data = 5; $display(t1.data); end
SystemVerilog Testbench with VCS
t1 // Two handles // Allocate first thing
data=1
// Allocate second t2 // Second Thing is lost // Modifies first thing // Displays “5”
05/07/2007
data=2
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 … Thing t1, t2; initial begin t1 = new(); t1.data = 1; t2 = new(); t2.data = 2; t2 = t1; t2.data = 5; $display(t1.data); end
SystemVerilog Testbench with VCS
t1 // Two handles // Allocate first thing
data=1
// Allocate second t2 // Second Thing is lost // Modifies first thing // Displays “5”
05/07/2007
data=2
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 … Thing t1, t2; initial begin t1 = new(); t1.data = 1; t2 = new(); t2.data = 2; t2 = t1; t2.data = 5; $display(t1.data); end
SystemVerilog Testbench with VCS
t1 // Two handles // Allocate first thing
data=5
// Allocate second t2 // Second Thing is lost // Modifies first thing // Displays “5”
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 body
id=5 body
stuff
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
How do I share code between classes?
Add extra Properties (data members) Add extra Methods Change the behavior of a method
Common code can be grouped into a base class
Instantiate a class within another class Inherit from one class to another (inheritance/derivation)
Inheritance allows you to ‘add’ extra:
73
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; reg [31:0] src, dst, data[1024], crc; endclass
Transaction src
dst
data crc class BadTr extends Transaction; rand bit bad_crc; endclass
BadTr bt; bt = new; bt.src = 42; bt.bad_crc = 1; SystemVerilog Testbench with VCS
BadTr bad_crc
BadTr = Transaction + bad_crc
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(); crc = src ^ dst ^ data.xor; endfunction endclass
Transaction src
dst
data crc calc_crc
class BadTr extends Transaction; rand bit bad_crc; function void calc_crc(); crc = super.calc_crc(); if (bad_crc) crc = ~crc; endfunction endclass SystemVerilog Testbench with VCS
05/07/2007
BadTr bad_crc calc_crc
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
program class Transaction; program good_test; BadTest; function void calc_crc(); Transaction tr; virtual function void calc_crc(); BadTr bt = new; endclass task task main(); main(); assert(tr.randomize()); assert(bt.randomize()); class BadTr extends Transaction; my_driver.send(tr); my_driver.send(bt); rand bit bad_crc; endtask endtask functionfunction virtual void calc_crc(); void calc_crc(); endprogram endprogram endclass 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; reg [31:0] crc; function void calc_crc(); endclass class BadTr extends Transaction; bit bad_crc; function void calc_crc(); endclass
task main(); Transaction tr; BadTr bt; tr = new(); bt = new(); tr.calc_crc(); bt.calc_crc(); tr = bt; tr.calc_crc(); endtask
Oops, this extended object just used base class method! SystemVerilog Testbench with VCS
05/07/2007
Transaction src
dst
data crc calc_crc
BadTr bad_crc calc_crc
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; reg [31:0] crc; virtual function void calc_crc(); endclass class BadTr extends Transaction; bit bad_crc; virtual function void calc_crc(); endclass Virtual method so… ‘tr’ is really ‘bt’ => BadTr => call BadTr.calc_crc(); SystemVerilog Testbench with VCS
task main(); Transaction tr; BadTr bt; tr = new(); bt = new(); tr.calc_crc(); bt.calc_crc(); tr = bt; tr.calc_crc(); endtask
05/07/2007
Transaction src
dst
data crc calc_crc
BadTr bad_crc calc_crc
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(); endclass class BadTr extends Transaction; bit bad_crc; virtual function void calc_crc(); endclass
src, dst
Base
bad_crc
Extend
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 if ($cast(b2, tr)) // Check if legal Run-time check b2.calc_crc(); SystemVerilog Testbench with VCS 05/07/2007
Inheritance
Why do I want all this complexity?
80
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
Object variables are randomized by randomize()
rand – returns values over the entire range randc – random cyclic value up to 16 bits 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
SystemVerilog Testbench with VCS
05/07/2007
SIM
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]}; } constraint c_long { data.size > 5000; } SystemVerilog Testbench with VCS
Disable this with: handle.c_long.constraint_mode(0) 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
constraint c_0 { src dist {0:=30, [1:3]:=60}; dst dist {0:/30, [1:3]:/60}; }
Distributions do not have to add up to 100%
SystemVerilog Testbench with VCS
05/07/2007
Value 0 1 2 3 Value 0 1 2 3
Dist 30/210 60/210 60/210 60/210
Dist 30/90 20/90 20/90 20/90
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;}; driveBus(t); end SystemVerilog Testbench with VCS
05/07/2007
src==2000 dst>10
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
05/07/2007
Randomization
91
Constraint constructs in SystemVerilog
Conditional operator:
x < other_object.y;
References to rand object data members in the constraints get solved simultaneously
Variable ordering:
->
Short version of “if” Ex: (mode == SMALL) -> (data.size < 10);
Global Constraints:
Behaves like a procedural “if”, except the conditionals are evaluated bi-directionally. Equivalent to implication.
Implication Operator:
if … else if … else
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
Array size Single element Multiple elements
SystemVerilog Testbench with VCS
class C; rand bit [5:0] a[]; constraint cc { // Output a.size inside {[1:5]}; a[0] = 1; array[0] > 0; a[1] = 2; foreach (a[i]) a[2] = 33; if (i > 0) a[i] > a[i-1]); a[3] = 39; } a[4] = 40; function void pre_randomize; a.delete; // Needed in 2005.06 endfunction endclass
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 simultaneously x[] in 1:8 y[] in 2:9
SystemVerilog Testbench with VCS
class E; rand bit [15:0] x[10], y[10]; constraint size_cons { foreach (x[i]){ x[i] > 0; x[i] < y[i]; foreach (y[i]) y[i] inside {[1:9]}; } endclass 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; 9. ‘h09 20. ‘h14 constraint c { 85. ‘h55 -70. ‘hba first + second < 8’h40; } -20. ‘hec -32. ‘he0 endclass
Make instances rand
Don’t call randomize() in new() constructor
Test may want to change constraints first
Use rand_mode to make a variable random / non-random
Or they won’t be randomized
class Nesting; rand SubClass data; endclass
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; rand int size; constraint c { size inside {[1:10]};} endclass
class Bigger extends Base; constraint c { size inside {[1:1000]};} 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); 8: len = $urandom_range(3, 5); 1: len = $urandom_range(6, 7); endcase
// 10%: 0, 1, or 2 // 80%: 3, 4, or 5 // 10%: 6 or 7
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
Data Generation Create stream of transactions
Port0
port0
port1
port1
DUT
---
---
port7
port7
Functional Coverage Sent transactions to all ports? FIFO overflow checked? SystemVerilog Testbench with VCS
05/07/2007
SelfChecking Check received transactions
Threads
100
Fork / Join The execute() task runs in parallel with the begin-end block. The tasks generate() and check() run serially.
fork
join
SystemVerilog Testbench with VCS
fork
join_any
05/07/2007
fork execute(); begin generate(); check(); end join_none
fork
join_none
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 Can
are atomic operations, no possible race conditions
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(); Driver d = new(); initial begin fork Allocate mailbox g.main(); d.main(); join end endprogram class Generator; Transaction t; task main; repeat (10) begin t = new(); assert(t.randomize()); mbx.put(t); end endtask Put data into mailbox endclass SystemVerilog Testbench with VCS
Get data from mailbox class Driver; Transaction t; task main; repeat (10) begin mbx.get(t); @(posedge busif.cb.ack); busif.cb.addr <= t.addr; busif.cb.kind <= t.kind; … end endtask
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
Think
of 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; Allocate a semaphore, 1 key available initial begin 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; sem.put(1); When done, replace key 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; -> ev; @ev; wait (ev.triggered);
driver = new(ev); SystemVerilog Testbench with VCS
// // // // // // //
Declare event Trigger an event Block process, wait for future event Block process, wait for event, including this timeslot Reduces race conditions Pass event into task 05/07/2007
Communication Between Threads
108
Event Example Main Testbench event gen_done[4]; Generator gen[4]; initial begin // Instantiate testbench foreach (gen[i]) gen[i] = new(gen_done[i]); // Run transactors gen[i].main(); …
Generator transactor class Generator; event done; // Pass event from TB function new (event done); this.done = done endfunction task main( ); fork begin // Create transactions -> done; end join_none endtask
// Wait for finish foreach (gen[i]) wait(gen_done[i].triggered); endclass end 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
SystemVerilog Testbench with VCS
DUT
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
Allow grouping of signals by function
Create a handle to an interface
Advanced topic
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
enable_3 soc_3 data_3[7:0]
RX_3
SystemVerilog Testbench with VCS
4x4 ATM Switch
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; input en; endclocking : Rcb
// Relative to // testbench
modport DUT (output en, // DUT connection input data, soc, clav); modport TB (clocking Rcb); endinterface : Rx
SystemVerilog Testbench with VCS
// TB connection
05/07/2007
Virtual Interfaces
116
Binding signals to a physical interface
STEP 2: Connect the interface Interface instances
module top; 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; virtual Rx.TB Rx;
& modport
function new(virtual Rx.TB Rx); this.Rx = Rx; // Initialize VI endfunction task sendCell(); Rx.Rcb.soc <= 0; ... endtask
// Drive signal w/clocking block
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
apb_trans
apb_gen
scoreboard
mas2scb
apb_mbox
apb_master
SystemVerilog Testbench with VCS
DUT
05/07/2007
mon2scb
apb_monitor
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; endgroup
// Measure coverage
Transaction tr = new(); CovKind ck = new();
// Instantiate transaction // Instantiate group
initial begin repeat (32) begin assert(tr.randomize()); ifc.cb.kind <= tr.kind; ifc.cb.data <= tr.data; ck.sample(); @ifc.cb; end end endprogram SystemVerilog Testbench with VCS
// Run a few cycles // Transmit transaction // onto interface // Gather coverage // Wait a cycle
05/07/2007
Sample HTML Reports
SystemVerilog Testbench with VCS
123
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
Embed covergroup in a class
Easy way to cover a subset of the members of a class
For efficiency, put coverage groups in “static” objects
You must instantiate the coverage group to gather results
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; endgroup function new; cg = new; endfunction endclass
SystemVerilog Testbench with VCS
Members x and y will be sampled on the active edge of the ifc.cb clock.
05/07/2007
125
Automatic Bin Creation (Example 1) bit [3:0] x, y; covergroup Cov1; coverpoint x; coverpoint y; endgroup … Cov1 c1 = new(); x = 1; y = 8; c1.sample(); x = 2; c1.sample(); x = 15; y = 9; c1.sample();
SystemVerilog Testbench with VCS
126
Level where coverage “counts”
05/07/2007
Automatic Bin Creation (Example 2) 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
127
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; coverpoint port_number { bins lo = {[0:1]}; // bins hi[] = {[4:$]}; // bins misc = default; // bins t1 = (0=>1), (0=>2), } endgroup SystemVerilog Testbench with VCS
0: 1: 2: 3: 4: 5: 6: 7:
1 bin for 2 values 4 separate bins Unspecified values (0=>3); // transitions
05/07/2007
lo lo misc misc hi_4 hi_5 hi_6 hi_7
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 Coverage holes
bit [3:0] x, y; covergroup Cov1; coverpoint x { bins s[] = {[0:4]}; } coverpoint y; endgroup … Cov1 c1 = new(); x = 1; y = 8; c1.sample(); x = 2; c1.sample(); x = 15; Out of bounds y = 9; value ignored c1.sample(); SystemVerilog Testbench with VCS
05/07/2007
Cross Coverage
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
130
Defining the Sample Event
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
131
@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; endgroup Write_cg wcg; initial begin wcg = new(); // Apply stimulus here #10000 $finish; end endprogram SystemVerilog Testbench with VCS
SVA
module mem(simple_bus sb); bit [7:0] data, addr; event write_event; cover property (@(posedge clk) write_ena==1) -> write_event; // Other logic here endmodule
05/07/2007
Coverage
133
Databases
VCS writes coverage data to a binary database file
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 );
The database file is named simv. db
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 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
135
More Complete Class Example
136
Classes are containers of data objects, transactors, generators, verification environments, etc.
Data Members
Constraint Block
Procedural Code Coverage Group
SystemVerilog Testbench
class packet; typedef enum {WRITE, READ} transtype_t; rand bit [`ADDR_WIDTH:0]addr; rand bit [`DATA_WIDTH-1:0] data[]; rand transtype_t trans_type; constraint addr_c { addr inside {[0:8’hBF]}; } constarint data_c { data.size <= 1024; }
task display(); $display(“ %s, %h”, pkt.trans_type.name(), a endtask covergroup pktCov; coverpoint addr,data,trans_type; endgroup endclass 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 Random Generation
Add constraints
Directed Testcase
Minimal Code Modifications SystemVerilog Testbench with VCS
Many runs, different seeds
Functional Coverage
Identify holes 05/07/2007
Capture Input Stimulus and Randomize 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 class packet; rand bit [31:0]addr; rand bit [7:0] data[]; rand transtype_t trans_type; endclass
SystemVerilog Testbench with VCS
Basic Test program automatic test; packet pkt; initial begin pkt = new(); repeat(50) begin pkt.randomize(); transmit(pkt); end end endprogram 05/07/2007
138
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 rand rand rand
bit [31:0]addr; bit [7:0] data[]; transtype_t trans_type; 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) 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[]; ... rand transtype_t trans_type;
Implication Constraints
constraint addr_c { (trans_type == WRITE) -> addr != 8'hBB; addr inside {[0:8’hBF]}; } endclass
SystemVerilog Testbench with VCS
05/07/2007
140
Directed Random Testing 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
141
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
class packet; rand address_e addrTyp; . . constraint custom_c; endclass
SystemVerilog Testbench with VCS
Test with 20% READ trans
constraint packet::custom_c { trans_type dist {WRITE:=80, READ:=20 program automatic test; packet pkt; initial begin pkt = new(); pkt.randomize(); transmit(pkt); end endprogram 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 What Are We Going to Discuss?
Reference Verification Methodology
Testbench Structure
Simple Testbench Building Blocks
SystemVerilog Testbench with VCS
05/07/2007
148
Testbench Methodology - Architecture
149
Layers
Constrained random tests
Test
Tests
Scenario
Generators
Functional
Transactor
Self Check
Checker
Command
Driver
Assertions
Monitor
Signal
SystemVerilog Testbench with VCS
DUT
05/07/2007
Functional Coverage
Testbench Methodology - Overview
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
150
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
Transaction Data models
Transaction objects
Variant data Error protection properties Standard methods Constraints Objects vs. procedures Transaction response
Interfaces
Reusable transactors
Transactor Categories
Master vs. slave Driver vs. monitor
SystemVerilog Testbench with VCS
Transaction interface Physical interface Sub-layering
Starting & stopping Notifications Integrating scoreboards Adding functional coverage Injecting errors Customization and extensibility
05/07/2007
152
Data & Transactions
153
Implementation
Data modeled using classes
Packets Frames Cells Instructions Pixels Samples
class Transaction; rand enum {READ, WRITE} kind; rand bit [ 7:0] sel; rand bit [31:0] addr; rand bit [31:0] data; endclass
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 here Duplicated here
Accumulated here
Freed here
Generators
Transactor
Scoreboard
Checker
Driver
Assertions
Monitor
Freed here
SystemVerilog Testbench with VCS
DUT
05/07/2007
Created here
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
SystemVerilog Testbench with VCS
Interface object
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 mac.get(tr);
mac.put(tr);
gmii_phy phy.get(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
Few instances
Bus-functional models Functional layer components Generators 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
Reactive Transactor – Slave
Initiate transactions Supply data to other side Example: AHB master, Ethernet Tx 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); task main(); forever begin mgen.get(t); // process transaction t mdrv.put(t); end endclass
generator (xactor)
transactor (xactor)
driver (xactor)
SystemVerilog Testbench with VCS
05/07/2007
DUT
Generators
Randomizable objects
161
Data streams Configuration Error injection Election
Atomic generators
atomic generator
Modifying constraints Run-time generator control Inserting directed stimulus
blueprint Copy
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 disturbances here
Not here eth_gen
SystemVerilog Testbench with VCS
mac_layer
Generate MII-level disturbances here
mii_phy
05/07/2007
Randomize DUT & TB Configuration Configurations
Generated by verification environment
verif_env cfg_gen
eth_gen
mac_layer
mii_phy
eth_gen
mac_layer
mii_phy
eth_gen
mac_layer
mii_phy
eth_gen
mac_layer
mii_phy
Generates one instance
Used to build
class cfg; ... endclass
SystemVerilog Testbench with VCS
ahb_mstr Downloaded into DUT via...
05/07/2007
163
Self-Checking Functionality
Entirely DUT-specific
Can only detect errors
Detected errors identified in planning stage Each error detection mechanism part of coverage model
Can be implemented in different ways
Transfer function + Scoreboard Reference model
Ensure that opportunity to check error existed No error was actually found
Maybe in different language
Off-line Assertions
Self-Checking methodology is a full day topic
SystemVerilog Testbench with VCS
05/07/2007
164
Generator Design
165
Controllable Aspects
Good controllable random generators don't "just happen"
Plan for trivial testcases
Generate only 1 object Generate simple objects
Plan for corner cases
Design constraint controls
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
Extend base environment to implement DUT-specific environment
Basic flow is:
Randomize test configuration descriptor Allocate and connect environment components Download test configuration into DUT
pre-test run-test post-test
Start components 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!
Where do I go next?
167
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 [email protected]
THANK YOU!!!
SystemVerilog Testbench with VCS
05/07/2007