• No results found

SystemVerilog Testbench

N/A
N/A
Protected

Academic year: 2021

Share "SystemVerilog Testbench"

Copied!
167
0
0

Loading.... (view fulltext now)

Full text

(1)

Introduction to

(2)

2

Agenda

Introduction

Methodology Introduction

Getting Started

Testbench Environment

Language Basics

OOP Basics

Randomization

Controlling Threads

Virtual Interfaces

Functional Coverage

Coverage Driven Verification

(3)

3

By the end of this class, you should be able to:

Lecture Objectives

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!

(4)

4

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 for Verification

(5)

5

Agenda

Introduction

Methodology Introduction

Getting Started

Testbench Environment

Language Basics

OOP Basics

Randomization

Controlling Threads

Virtual Interfaces

Functional Coverage

Coverage Driven Verification

(6)

6

Verification Environment

Definitions

DUT

Driver

Monitor

Supplies data

to the DUT

Observes

data

from DUT

Assertions

Transactor

Executes

transactions

Identifies

transactions

Checker

Checks

correctness

Creates

stimulus

Test

Scoreboard

Verification

Environment

Testbench

(7)

7

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

(8)

8

Methodology Introduction

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:

(9)

9

Coverage-Driven Verification

Time

%

C

ov

er

age

Goal

Directed

Methodology

Measure progress using functional coverage

Self-checking

random environment

development time

Coverage-Driven

Methodology

Productivity

gain

With

VIP

(10)

10

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

(11)

11

Agenda

Introduction

Methodology Introduction

Getting Started

Testbench Environment

Language Basics

OOP Basics

Randomization

Controlling Threads

Virtual Interfaces

Functional Coverage

Coverage Driven Verification

(12)

12

What are We Going to Discuss?

Getting Started

SystemVerilog Testbench Verification Flow

Compiling and Running in VCS

(13)

13

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

Getting Started

Compiling and Running with VCS

(14)

14

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

Getting Started

Legacy Code Issues

// 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)

(15)

15

Debug: Getting Started

Invoke DVE

> simv –gui -tbug

Source code tracing Local variables Active threads

(16)

16

Getting Started

SystemVerilog documentation

Examples

 $VCS_HOME/doc/examples

Email Support:

[email protected]

On-line knowledge database

http://solvnet.synopsys.com

Testbench Discussion Forum

 http://verificationguild.com

SystemVerilog LRM

 www.Accellera.org or www.eda.org/sv

Documentation and Support

(17)

17

Agenda

Introduction

Methodology Introduction

Getting Started

Testbench Environment

Language Basics

OOP Basics

Randomization

Controlling Threads

Virtual Interfaces

Functional Coverage

Coverage Driven Verification

(18)

18

Testbench Environment

Someone gives you a DUT, now what?

How Should You Connect to DUT

reset

request[1:0] grant[1:0] clock

(19)

19

Testbench Environment

top.sv

clock

test.sv

arb.sv

1.

Create DUT interface with

modports and clocking

blocks

2.

Create testbench program

3.

Create top module

4.

Compile and run

(20)

20

Testbench Environment -- Interfaces

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:

(21)

21

top

Testbench Environment -- Interfaces

Before Interfaces

The RTL code was connect with a netlist

cpu

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); mem 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);

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

(22)

22

simple_bus clk

top

Testbench Environment -- Interfaces

Named Bundle of Signals

cpu interface simple_bus; logic req, gnt; logic [7:0] addr; wire [7:0] data; logic [1:0] mode; logic start, rdy; endinterface mem module mem( simple_bus sb, input bit clk); endmodule module top; logic clk = 0; always #10 clk = !clk; simple_bus sb(); mem m1(sb, clk); cpu c1(sb, clk); module cpu( simple_bus sb, input bit clk); endmodule

(23)

23

Testbench Environment -- Interfaces

Referencing Signals in Interface

Use hierarchical names for interface signals in a module

Signals with multiple drivers must be wire

Signals driven by procedural assignment must be logic

interface simple_bus; logic req, gnt;

logic [7:0] addr; wire [7:0] data; logic [1:0] mode; logic start, rdy;

endinterface: simple_bus

module cpu(simple_bus sb, input bit clk); logic addr_reg; always @(posedge clk) sb.addr <= addr_reg; endmodule : cpu Label on end statement

(24)

24

Testbench Environment -- Interfaces

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, input bit clk);

module mem(simple_bus.SLAVE sb, input bit clk);

(25)

25

Testbench Environment -- Interfaces

Adding Timing

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;

clocking cb @(posedge clk);

input grant; // TB input output request; // TB output 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

Step 1

reset request[1:0] grant[1:0] clock

arb.sv

(26)

26

Testbench Environment -- Interfaces

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

(27)

27

SystemVerilog Scheduling

 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

SystemVerilog Scheduling Details

clock

data

REGION

ACTIVITY Next Previous

Prepone Active Observed Reactive Postpone

design

sample assertions testbench $monitor

Current

 Assertion and testbench events can trigger more design evaluations in this time slot

(28)

28

Testbench Environment - 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

(29)

29

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;

// Synch drive request

##1 arbif.cb.request <= 1; ##1 arbif.cb.request <= 0; wait (arbif.cb.grant == 1); end

endprogram

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

Step 2

Wait 1 clock cycle

Common mistake: forgetting “cb.” in signal reference

Error: arbif.request not visible via modport

clk reset request

(30)

30

Using the Clocking Block

Clocking Block signals are referenced by

pre-pending the clocking block name to the signal:

Assignment will happen at next active clock edge

Time will NOT advance unless you use #1 or ##1

Synchronous Signal Access

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);

arbif.cb.request <= 1; // drive value = arbif.cb.grant; // sample

(31)

31

Driving, Sampling, Synchronizing

Synchronize to active clock edge specified in clocking block

Synchronize to any edge of signal

Wait for N clock cycles with ##n – blocking statement

Signal Synchronization

@arbif.cb; // continue on posedge of arb_if clk repeat (3) @arbif.cb; // Wait for 3 posedges

@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

##2 arbif.cb.request <= 0; // Wait 2 cycles // then assign

(32)

32

Testbench Timing

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;

SystemVerilog Testbench in Simulation

clock

Sample inputs before clock Drive outputs at clock

Design

Testbench

(33)

33

Testbench Environment – Top Block

Create top module

// Synchronous TB

program test(arb_if.TB arbif); endprogram module top; bit clk; test t1 (.*); arb d1 (.*); arb_if arbif(.*); always #50 clk = !clk; endmodule

module arb(arb_if.DUT arbif, bit clk);

// Some logic here… endmodule

Step 3

interface arb_if (input bit clk);

endinterface: arb_if The syntax .* connect ports

(34)

34

Testbench Environment - Scoping

Scoping Rules

`timescale 1ns/1ns

typedef enum {IDLE, RUN, WAIT} fsm_state_t; parameter TIMEOUT = 1_000_000;

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

module state_machine(…);

fsm_state_t state, next_state; endmodule

program test;

fsm_state_t state;

initial #TIMEOUT $finish;

root.sv

dut.sv

(35)

35

Testbench Environment -- Communication

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

(36)

36

SV Language Basics

Check signal values

program test (arb_if arbif); initial begin

arbif.cb.request <= 1; repeat (2) @arbif.cb;

a1: assert (arbif.cb.grant==1); end

SystemVerilog Assertion

Check a SVA procedurally

Non-blocking statement

“test.sv", 7: top.t1.a1: started at 55ns failed at 55ns Offending '(arbif.cb.grant == 1)‘

(37)

37

SV Language Basics

Check signal values

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

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)

Custom message

(38)

38

> vcs -sverilog -debug

root.sv top.sv arb_if.sv test.sv arb.sv > simv –gui -tbug

Testbench Environment – Compile and Run

Compile and run

Run with debugger

(39)

39

Agenda

Introduction

Methodology Introduction

Getting Started

Testbench Environment

Language Basics

OOP Basics

Randomization

Controlling Threads

Virtual Interfaces

Functional Coverage

Coverage Driven Verification

(40)

40

SV Language Basics

SystemVerilog basics

 Data types  Arrays  Subroutines  Interfaces

This class assumes you already know most Verilog-1995

and 2001 constructs

(41)

41

Basic SystemVerilog Data Types

reg [31:0] r; // 4-state logic [7:0] w; // 4-state

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 Data Types

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

(42)

42

SV Language Basics

User defined types

Use typedef to create a synonym for another type

Define a structure with multiple variables

Use union for merged storage

SystemVerilog Data Types

typedef bit [31:0] uint;

typedef bit [0:5] bsix_t; // Define new type

bsix_t my_var; // Create 6-bit variable

typedef union {int i; shortreal f; } num_t; num_t un;

un.f = 0.0; // set n in floating point format typedef struct {bit [7:0] opcode;

bit [23:0] addr; }

instruction; // named structure type instruction IR; // define variable

Use classes instead!

Useful type

(43)

43

SV Language Basics

Enumerated type

Explicitly typed and scoped (program or class-level)

Can only create variables at class level, not typedef 

Allows compile time error checking

SystemVerilog Data Types

// 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; endcase

$display(“Next state is %0s”, nstate.name);

nstate = fsmstate_t’(i); // cast integer to enum

Print the symbolic

(44)

44

SV Language Basics

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

Fixed Size Arrays

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[1] bytes[2] bytes[0] 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 7 6 5 4 3 2 1 0

type name [constant];

bytes[0][3] bytes[0][1][6]

Use bit & word subs together with fixed arrays

(45)

45

SV Language Basics

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

Dynamic Arrays

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

type name [ ];

(46)

46

SV Language Basics

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

Queues

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 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]);

type name [$];

F

AST

(47)

47

Checking Results with Queues

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 Tr1 @1000 Tr4 @2000

DUT

Driver

Monitor

Transactor

Checker

(48)

48

SV Language Basics

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];

Associative Arrays

// Print full array foreach(aa[i]) $display(i,,aa[i]);

type name [*];

All memory allocated, even unused elements Associative array Standard array Unused elements don’t use memory

(49)

49

SV Language Basics

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

Array Methods

int q[$] = {1,3,5,7}, tq[$]; int d[] = {9,1,8,3,4}; int f[6] = {1,6,2,6,8,6}; $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} LRM requires

a queue

IEEE changed array

const from {0,1} to ’{0,1} (VCS issues Warning for old usage)

(50)

50

SV Language Basics

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));

(51)

51

SV Language Basics

Tasks and Functions

task reset(); reset_l = 1’b0; #100

reset_l = 1’b1; endtask

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); print_sum(my_array, );

Default value Function can never contain blocking statements or calls to tasks Void functions do not return a value

function int add2(int n); return n + 2;

(52)

52

SV Language Basics

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.

Tasks and Functions

program automatic test; task is_automatic();

Change storage default for programs

(53)

53

SV Language Basics

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

Tasks and Functions

task T3(a, b, output bit [15:0] u, v); Default dir is input,

default type is logic

a, b: input logic

u, v: output bit [15:0]

Watch out for ref followed by input…

(54)

54

Lab 1

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

(55)

55

Agenda

Introduction

Methodology Introduction

Getting Started

Testbench Environment

Language Basics

OOP Basics

Randomization

Controlling Threads

Virtual Interfaces

Functional Coverage

Coverage Driven Verification

(56)

56

OOP Basics

What Are We Going to Discuss?

What is OOP

Terminology

An example class

Default methods for classes

Static attribute

Assignment and copying

Inheritance

(57)

57

Introduction to 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

(58)

58

OOP Basics

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

(59)

59

OOP Basics

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 (always, initial), tasks, functions Methods: tasks and functions Communication between blocks Ports or cross-module task calls

calls,

mailboxes, semaphores, etc.

(60)

60

OOP Basics

Class

 Programming element “containing” related group of features and functionality

 Encapsulates functionality

 Provides a template for building objects  Can be used as data structures

Object

 An object is an instance of a class

Handle

 Type-safe pointer to an object – can not be corrupted

Properties

 Variables contained in the instance of the class

Methods

 Tasks/functions (algorithms) that operate on the properties in this instance of the class

Terminology

Blueprint for a house A complete house Light switches Turn on/off switches Address of a house

(61)

61

OOP Basics

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

Class Example

Variables & methods are public by default

In a class, methods are always automatic

(62)

62

OOP Basics

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

 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

Creating an Object From a Class

Declare first then construct

(63)

63

OOP Basics

Call new(), assigned values to the object

properties

 Handles have the default value of null

 Using a null handle is an error

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

Working with Objects

(64)

64

Where are all the objects?

Drives

transactions

into the DUT

Scoreboard holds

transactions

Extended

class

Self Check

Verification

Environment

Executes

transactions

Compares

transactions

Puts data

into

transactions

A transactor can be an object too!

Driver

Monitor

DUT

Checker

Transactor

(65)

65

OOP Basics

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

(66)

66

OOP Basics

Initializing Class Properties

program automatic test1; class Transaction; bit [31:0] src, dst; function new(); src = 5; dst = 3; endfunction endclass Transaction tr; initial tr = new();

program automatic test2; class Transaction;

bit [31:0] src, dst;

function new (int src, int dst=3);

this.src = src; // Disambiguate this.dst = dst; endfunction endclass Transaction tr; initial

tr = new(5); // dst uses default

Initialize the class properties in the constructor when the

object is created

(67)

67

Static attribute

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

Using a id field can help keep track of transactions as they

(68)

68

Assignment is not a copy

Assignment of one handle to another only affects

the handles. It does not copy data

class Thing; int data; endclass

Thing t1, t2; // Two handles initial begin

t1 = new(); // Allocate first thing t1.data = 1;

t2 = new(); // Allocate second t2.data = 2;

t2 = t1; // Second Thing is lost t2.data = 5; // Modifies first thing $display(t1.data); // Displays “5”

end

data=1 t1

(69)

69

Assignment is not a copy

Assignment of one handle to another only affects

the handles. It does not copy data

class Thing; int data; endclass

Thing t1, t2; // Two handles initial begin

t1 = new(); // Allocate first thing t1.data = 1;

t2 = new(); // Allocate second t2.data = 2;

t2 = t1; // Second Thing is lost t2.data = 5; // Modifies first thing $display(t1.data); // Displays “5” end data=1 t1 t2 data=2

(70)

70

Assignment is not a copy

Assignment of one handle to another only affects

the handles. It does not copy data

class Thing; int data; endclass

Thing t1, t2; // Two handles initial begin

t1 = new(); // Allocate first thing t1.data = 1;

t2 = new(); // Allocate second t2.data = 2;

t2 = t1; // Second Thing is lost

t2.data = 5; // Modifies first thing $display(t1.data); // Displays “5” end data=1 t1 t2 data=2

(71)

71

Assignment is not a copy

Assignment of one handle to another only affects

the handles. It does not copy data

class Thing; int data; endclass

Thing t1, t2; // Two handles initial begin

t1 = new(); // Allocate first thing t1.data = 1;

t2 = new(); // Allocate second t2.data = 2;

t2 = t1; // Second Thing is lost t2.data = 5; // Modifies first thing $display(t1.data); // Displays “5”

end

data=5

t1

(72)

72

How to copy objects

Assigning handles does not change objects

To copy the data, pass it into new:

This is a shallow copy, only data in top object is copied.

Your new() is not called!

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.

t2 = new t1; id=5 body t2 t1 stuff id=5 body t1 stuff id=5 body t2

(73)

73

Inheritance

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

(74)

74

Inheritance

Add additional functionality to an existing class

class Transaction;

reg [31:0] src, dst, data[1024], crc; endclass

Extended a class with new fields

class BadTr extends Transaction; rand bit bad_crc;

endclass BadTr = Transaction + bad_crc Transaction src data BadTr bad_crc dst crc BadTr bt; bt = new; bt.src = 42; bt.bad_crc = 1;

(75)

75

Inheritance

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

Override existing fields to a class

class BadTr extends Transaction; rand bit bad_crc;

function void calc_crc(); crc = super.calc_crc(); if (bad_crc) crc = ~crc; endfunction endclass Transaction src data dst crc BadTr bad_crc calc_crc calc_crc

(76)

76

program good_test; Transaction tr; task main(); assert(tr.randomize()); my_driver.send(tr); endtask class BadTr extends Transaction;

rand bit bad_crc;

function void calc_crc(); class Transaction;

function void calc_crc(); endclass

Inheritance

Create a transactor that works with a base object

Extend the transaction class to inject errors

Send these into the transactor from the test

Error injection

class Driver;

task send(Transaction tr); tr.calc_crc();

// Drive interface signals endtask

endclass

class Transaction;

virtual function void calc_crc(); endclass

class BadTr extends Transaction; rand bit bad_crc;

virtual function void calc_crc();

program BadTest; BadTr bt = new; task main(); assert(bt.randomize()); my_driver.send(bt); endtask

(77)

77

Transaction BadTr src data dst crc bad_crc calc_crc calc_crc

Overriding Methods

By default, a method is found using the handle type

What happens when extended object is referenced

by a base handle?

Inheritance allows methods to be overridden

task main(); Transaction tr; BadTr bt; tr = new(); bt = new(); tr.calc_crc(); bt.calc_crc(); tr = bt; tr.calc_crc(); endtask class Transaction; reg [31:0] crc;

function void calc_crc(); endclass

class BadTr

extends Transaction; bit bad_crc;

function void calc_crc(); endclass

Oops, this extended object just used base class method!

(78)

78

Transaction BadTr src data dst crc bad_crc calc_crc calc_crc task main(); Transaction tr; BadTr bt; tr = new(); bt = new(); tr.calc_crc(); bt.calc_crc(); tr = bt; tr.calc_crc(); endtask

Polymorphism

Allow a single name refer to many methods

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

Virtual

– lookup method at runtime, not compile

The object’s type is used to find the right method

(79)

79

Handle Assignment

Handles for base and extended class

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

Extend

src, dst Base

bad_crc

The handles for the base and extended classes are

not interchangeable

A base handle can not access extended properties

Transaction tr; BadTr bt, b2;

bt = new(); // Allocate extended object tr = bt; // Assign to base handle tr.calc_crc(); // Calculate CRC

b2 = tr; // Error! Not allowed

$cast(b2, tr); // Allow assign if ($cast(b2, tr)) // Check if legal

b2.calc_crc(); Compile check

(80)

80

Inheritance

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

(81)

81

Agenda

Introduction

Methodology Introduction

Getting Started

Testbench Environment

Language Basics

OOP Basics

Randomization

Controlling Threads

Virtual Interfaces

Functional Coverage

Coverage Driven Verification

(82)

82

Randomization

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

(83)

83

Randomization

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

(84)

84

Randomization

Randomization Example

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

rand

: rolling dice

randc

: dealing cards

(85)

85

Randomization

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.

Returns a 1 upon success, 0 on failure

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 ?

Always check randomize()

(86)

86

Randomization

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

User-Created Test:

- subset of legal stimulus vectors - subset of legal stimulus sequences

Your Testbench:

- all legal stimulus vectors - all legal stimulus sequences

(87)

87

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; }

Randomization

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

Disable this with:

(88)

88

constraint c_0 {

src

dist

{0:=30, [1:3]:=60};

dst

dist

{0:/30, [1:3]:/60};

}

Randomization

Distributions

dist

constraint

Distribution weights can be variables or constants

Weighted probabilities

:=

assigns weight to each element

:/

divides weight evenly in range

Distributions do not have to add up to 100%

Value Dist 0 30/90 1 20/90 2 20/90 3 20/90 Value Dist 0 30/210 1 60/210 2 60/210 3 60/210

(89)

89

Randomization

In-Line Constraints and Distributions

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

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]}; }

endclass src: 50-100, 1000-1500

dst<10

src==2000 dst>10

(90)

90

Randomization

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

SystemVerilog requires a strong constraint solver!

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: * % /

}

(91)

91

Randomization

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

(92)

92

Randomization

Create a random array

 Constrain its size, individual elements, or all elements class C;

rand bit [5:0] a[]; constraint cc { a.size inside {[1:5]}; array[0] > 0; foreach (a[i]) if (i > 0) a[i] > a[i-1]); }

function void pre_randomize;

a.delete; // Needed in 2005.06 endfunction endclass // Output a[0] = 1; a[1] = 2; a[2] = 33; a[3] = 39; a[4] = 40;

Array constraints

Array size Single element Multiple elements

(93)

93

Randomization

Set valid on 3 cycles out of 5

Two foreach loops with relationships

Constraints solved

simultaneously

x[] in 1:8

y[] in 2:9

Array Constraints

class ValidOn;

rand bit valid[5];

constraint cv

{valid.sum == 32’d3;}

endclass

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]}; }

(94)

94

Randomization

Watch out for signed variables

What are legal values for first and second?

Make instances rand

 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);

Tricks and Techniques

class Nesting;

rand SubClass data; endclass

class Environment;

rand byte first, second; constraint c { first + second < 8’h40; } endclass first second 9. ‘h09 20. ‘h14 85. ‘h55 -70. ‘hba -20. ‘hec -32. ‘he0

(95)

95

Randomization

Need to modify a constraint in a test?

Use a variable in the constraint

Extend the base class to override original constraint

Use constraint_mode() to turn it off

More Tricks and Techniques

class Base;

rand int size;

constraint

c

{

size inside {[1:10]};}

endclass

class Bigger extends Base;

constraint

c

{

size inside {[1:1000]};}

endclass

rand int size;

int

max_size

= 100;

constraint c {

(96)

96

Randomization

Want to randomize without a class?

Use randcase or $urandom_range

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

Procedural randomization

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

References

Related documents

Inhalation and potential exposure to eyes, hands, or other body parts if contact is made with broken tile, and/or during procedures involving the cutting of products, and/or

PRESET LEVEL SETTING RANGE PREWARN FEATURE INPUT MODE INPUT SIGNAL COUNT SPEED COUNT MODE COUNT RANGE TYPE OF OUTPUT OUTPUT TIME WRITE RESET MODE RESET INPUT INHIBITION PRESCALE

The figure below shows the circuit diagram used to interface 16-bit output port.. Two latches are used to connect 16 LEDs with

Source Data: US Bureau of Economic Analysis, Trucost Environmental Register (validated environmental performance data of 4,800 companies and suppliers), natural capital valuation

This pattern has been largely repeated in studies of rural mobilities, which have been dominated by migration (e.g., Blekesaune et al. Migration is an important area of rural

Just below the Data Version field, users will see a second new field, Last Updated, which tells users when the collection, or an item in the collection, was last updated either via

Pre-construction Conference A pre-construction conference between the assisted homeowner, contractor, and the Rehabilitation Coordinator will be conducted to ensure that all

The TNI/TNIEG security metrics include the security riskindex, the evaluation structure for network security services, the minimum strength of mechanism requirement, the