You are on page 1of 54

Oops and Randomization

06/30/09

Mohit Gupta

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

AGENDA
Oops
class, object, static vs global variables, this operator, access to objects properties, modification of objects, copying objects, Public, private, local and const members, inheritance, virtual methods, virtual class, polymorphism, callbacks

randomization
what to randomize, random variables, constraint blocks, inside and dist operators, conditional constraint, variable ordering, constraint_mode, rand_mode, in-line constraint, pre_randomize and post_randomize, tips and techniques, iterative contraints, rand_sequence, random stability.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

Class
What does a class contains?
Class encapsulates the data together with the routines , which manipulate the data.

Where to define a class?


A class can be defined in a program, module, package, or outside any of these.

Why Class?
The goal of the testbench is to apply stimulus and check result. The data that flows into and out of the design is grouped together into transactions. In Oops transaction is an object of a class.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

Constructing an object
Objects are created by calling a new() method.
How does SystemVerilog know which new function to call? It looks at the type of the handle on the left side of the assignment. e.g.

Avoid declaring a handle and calling the constructor, new, all in one statement. You may want to initialize objects in a certain order, but if you call new in the declaration, you wont have this control.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

Static Vs Global Variables


By default every object of a class has local copy of the class variables, that are not shared by with any other object. What if sometimes you need a variable that is shared by all objects of a certain type? Without OOP, you would probably create a global variable. Then you would have a global variable that is used by one small piece of code, but is visible to the entire testbench. In SV with Oops , you can declare the variable as static. Static variable is shared between all instances of the class, but its scope is limited to the class. Why you need a variable to be shared among different objects? Typical example is to keep a running count of the number of transactions that have been created.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

Static variable example


Following example illustrate few important points. Any number of BusTran objects will share the same copy of static variable count.

The variable id is not static, so every BusTran has its own copy.
Just make sure that static variable is initialized before the first object is constructed.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

Class routines declaration


A routine can be defined inside or outside the class. A routine in a class always uses automatic storage, so you dont have to worry about remembering the automatic modifier. For defining a routine outside a class, the prototype of the routine should be declared inside the class with the keyword extern. e.g.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

What is this
When you use a variable name, SystemVerilog looks in the current scope for it, and then in the parent scopes until the variable is found. But what if you are deep inside a class and want to unambiguously refer to a classlevel object? The this keyword is used to unambiguously refer to class properties or methods of the current instance. e.g.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

Referring a variable out of scope


Inside a classs routines, you can use local variables, class variables, or variables defined in the program. If you forget to declare a variable, SystemVerilog looks up the higher scopes until it finds a match.

This can cause subtle bugs if two parts of the code are unintentionally sharing the same variable, perhaps because you forgot to declare it in the innermost scope.
e.g

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

Compilation order issue


Sometimes you need to compile a class that includes another class that is not yet defined. The declaration of the included classs handle causes an error, as the compiler does not recognize the new type. Declare the class name with a typedef statement, as shown below :

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

10

Passing objects to routines


What happens when you pass a scalar (nonarray, nonobject) into a routine? If you use the ref keyword, SV passes the address of the scalar, so the routine can modify it. If you dont use the ref keyword, SV copies the scalars value into the argument variable, so any changes to the argument dont affect the original value. But above is not fully true for the objects and handles, why? A routine can modify an object, even if the handle argument does not have a ref modifier. As shown, transmit can write a timestamp into the

object.
If you dont want an object modified in a routine, pass a copy of it so that the

original data is untouched.


Presentation_ID 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential

11

Modifying a handle in a task


A common coding mistake is to forget to use ref on routine arguments that you want to modify, especially handles. e.g. In the following code, the argument b is not declared as ref, so any change to it is not be seen by the calling code.

Even though create_packet modified the argument bt, the handle b remains null.
You need to declare the argument bt as ref.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

12

Modifying objects in flight


What is the issue with the generator code given below, intended to create and send n transaction ?

A very common mistake is forgetting to create a new object for each transaction in the testbench. The solution is to to create a new BusTran during each pass through the loop as given below.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

13

Coping objects : with new()


Copying an objects with new(), creates a shallow copy. If the class contains a handle to another class, only the top level object is copied by new, not the lower level one. What is the problem with the following example?

Both BusTran objects point to the same Statistics object and both have the same id Why? Objects and handles before copy with new

Objects and handles after copy with new

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

14

Coping objects : writing own copy function


Writing own copy function in each class allows you to create deep copy of an object. For making a deep copy, you can call the copy function of all the contained objects.

e.g.

Objects and handles after deep copy

The downside of making your own copy function is that you need to keep it up to date as you add new variables forget one and you could spend hours debugging to find the missing value.
15

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

Public, private,local and const members


SV provides three types of data members : public, local, private. In SV, by default all class properties and methods are public, available to anyone who has access to the objects name. A local member is available only to methods inside the class and these local members are not visible within subclasses i.e. the extended classes. A protected class property or method has all of the characteristics of a local member, except that it can be inherited; it is visible to subclasses.

Class members can be identified as either local or protected and class properties can be further defined as const, and methods can be defined as virtual.
class properties allow two forms of read-only variables: global constants and instance constants. Global constant class properties are those that include an initial value as part of their declaration. Instance constants do not include an initial value in their declaration, only the const qualifier. This type of constant can be assigned a value at run-time, but the assignment can only be done once in the corresponding class constructor.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

16

Inheritance
Inheritance in SV is more or the less similar to vera. Inheritance is the process of creating a new subclass that inherits the members of the parent class by extending the parent class. The mechanism provided by SystemVerilog is called Single-Inheritance, that is, each class is derived from a single parent class. The super keyword is used from within a derived class to refer to members of the parent.

When you start extending classes, there is one rule about constructors (new function) to keep in mind. If your base class constructor has any arguments, the extend constructor must have a constructor and must call the bases constructor on its first line.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

17

Inheritance
Always declare routines inside a class as virtual so that they can be redefined in an extended class.

This applies to all tasks and functions, except the new function, which is called when
the object is constructed, so there is no way to extend it.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

18

Type Casting in Oops


Type casting or conversion refers to changing an entity of one data type into another. In OOP, the easiest way to think about type casting is to consider a base class and an extended class as in last example. Continuing the previous example : Transaction tr; BadTr bad, b2;

If you assign an extended handle to a base handle, nothing special is needed as all the members of base class exists in the extended class.
But what if you are copying a base object into an extended handle, it fails. e.g.

It is not always illegal to assign a base handle to an extended handle. It is allowed when the base handle actually points to an extended object. $cast routine checks the type of object, not just the handle.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

19

Type Casting in Oops


you use $cast as a task, SystemVerilog checks the type of the source object at runtime and gives an error if it is not compatible.

You can eliminate this error by using $cast as a function and checking the result 0 for incompatible types, and non-0 for compatible types.
e.g.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

20

Virtual methods :
For virtual methods, SystemVerilog uses the type of the object, not the handle to decide which routine to call.

e.g. From previous example :

If the routines were not defined as virtual, SV would use the type of the handle (Transaction), not the object. That last statement would call Transaction::calc_crc probably not what you wanted.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

21

Abstract classes
Virtual class & methods are a way of creating a template, From such a template, real classes are derived.

A base class sets out the prototype for the subclasses. Since the base class is not intended to be instantiated, it can be made abstract by specifying the class to be virtual.
virtual class BasePacket; Abstract classes can also have virtual methods, which should be overwritten by derived class. A virtual method overrides a method in all the base classes. An abstract class can contain methods for which there is only a prototype and no implementation (pure virtual). An abstract class cannot be instantiated, it can only be derived. Methods of normal classes can also be declared virtual. In this case, the method must have a body. If the method does have a body, then the class can be instantiated, as can its subclasses.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

22

Polymorphism Example
.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

23

Struct Vs Classes
class differs from struct in following ways: 1) SystemVerilog struct are strictly static objects and SystemVerilog objects (i.e.,

class instances) are exclusively dynamic, their declaration doesnt create the
object; that is done by calling new. 2) SystemVerilog structs are type compatible so long as their bit sizes are the same, thus copying structs of different composition but equal sizes is allowed. In contrast,

SystemVerilog objects are strictly stronglytyped. Copying an object of one type


onto an object of another is not allowed. 3) SystemVerilog objects are implemented using handles, thereby providing C-like pointer functionality. But, SystemVerilog disallows casting handles onto other data

types, thus, unlike C, SystemVerilog handles are guaranteed to be safe.


4) SystemVerilog objects form the basis of an Object-Oriented data abstraction that provides true polymorphism. Class inheritance, abstract classes, and dynamic casting are powerful mechanisms that go way beyond the mere encapsulation

mechanism provided by structs.


Presentation_ID 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential

24

Callbacks
A verification environment should be usable by all tests with no changes. The key requirement is that this testbench must provide a hook where the test program can inject new code without modifying the original classes. e.g. driver may want to do the following: Inject errors Drop the transaction Delay the transaction Synchronize this transaction with others Put the transaction in the scoreboard Gather functional coverage data.

This can be achieved through callbacks.

Driver has to just call the callbacks


method defined for each test .

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

25

Creating a callbacks
A callback task is created in the top-level test and called from the driver,the lowest level of the environment.

The driver does not have to have any knowledge of the test it just has to use a generic class that the test can extend.
e.g.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

26

Injecting disturbances : example


Below example use the previous driver callback class to drop one transaction, every 100 transaction randomly :

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

27

Randomization

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

28

What to Randomize
When you think of randomizing the stimulus to a design, the first thing you may think of are the data fields. You need to think broadly about all design input such as the following. Device configuration Environment configuration Primary input data Encapsulated input data Protocol exceptions Delays

Transaction status
Errors and violations

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

29

Random variables
SV provides two types of random variables : rand , randc. Variables declared with the rand keyword are standard random variables. Their values are uniformly distributed over their range. For example: rand bit [3:0] y; Variables declared with the randc keyword are random-cyclic variables that cycle through all the values in a random permutation of their declared range. Random-cyclic variables can only be of type bit or enumerated types. The basic idea is that randc randomly iterates over all the values in the range and that no value is repeated within an iteration. When the iteration finishes, a new iteration automatically starts. E.g randc bit [1:0] y;

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

30

Constraint blocks
Constraints blocks are very similar to vera. Following class shows the example of a constraint block with simple expression :

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

31

Constraint Block with inheritance


A constraint in a derived class that uses the same name as a constraint in its parent classes overrides the base class constraints. For example:

An instance of class A constrains x to be less than zero whereas an instance of class B constrains x to be greater than zero. The extended class B overrides the definition of constraint c.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

32

Constraint Block (inside operator)


Constraints support integer value sets and the set membership operator. The negated form of the inside operator denotes that expression lies outside the set:

!(expression inside { set }).

You can parametrize the constraint block by defining CONGEST_ADDR as parameter.


Presentation_ID 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential

33

Constraint Block (dist operator)


The dist operator allows you to create weighted distributions so that some values are chosen more often than others.

The weights are not percentages and do not have to add up to 100.
The := operator specifies that the weight is the same for every specified value in the range, while the :/ operator specifies that the weight is to be equally divided between all the values.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

34

Constraint Block (dist operator)


The values and weights can be constants or variables. You can use variable weights to change distributions on the fly or even to eliminate choices by setting the weight to zero.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

35

Conditional constraint
All constraint expressions are active in a block. What if you want to have an expression active only some of the time?

SV supports two implication operators, -> and if-else.


When you are choosing from a list of expressions, such as an enumerated type, the implication operator, ->, lets you create a case-like block. constraint c { mode == small -> len < 10; mode == large -> len > 100; } If you have a true-false expression, the if-else operator may be better.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

36

Variable Ordering
Sometimes it is desirable to force certain combinations to occur more frequently. E.g. consider the following example : class B; rand bit s; rand bit [31:0] d; constraint c { s -> d == 0; } endclass What is the problem with the above example? The Probability of s being true is 33 , which is practically zero. The solutions is : force the variable ordering class B;
rand bit s;
rand bit [31:0] d; constraint c { s -> d == 0; } constraint order { solve s before d; }

endclass

Variable ordering can be used to force selected corner cases to occur more frequently than they would otherwise.
Presentation_ID 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential

37

Controlling constraint blocks


At run-time, you can use the constraint_mode() routine to turn constraints on and off. When used with handle.constraint, this method controls a single constraint. When used with just handle, it controls all constraints for an object.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

38

Controlling Random Variables (rand_mode)


SV provides the predefined rand_mode() method to control whether a random variable is active or inactive. When a random variable is inactive, it is treated the same as if it had not been declared rand or randc. All random variables are initially active. When called as a function, rand_mode() returns the current active state of the specified random variable.It returns 1 if the variable is active (ON) and 0 if the variable is inactive (OFF). Syntax for using is : class rand_mode_ex; rand bit [3:0] rvar1; rand bit [3:0] rvar2; endclass Initial begin rand_mode_ex rndCl = new(); rndCl.rand_mode(0); //all variables will be non rand rndCl.randomize(); rndCl.rand_mode(1); //all variable will be rand rndCl.rvar1.rand_mode(0); //rvar1 : non rand, rvar2 : rand end
Presentation_ID 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential

39

In-line constraints
SV allows you to add an extra constraint using randomize() with. This is equivalent to adding an extra constraint to any existing ones in effect.

Note that inside the with{} statement, SystemVerilog uses the scope of the class. That is why Above example used just addr, not t.addr.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

40

Pre-randomize and post-randomize


Sometimes you need to perform an action immediately before every randomize call or immediately afterwards. For example, you may want to set some nonrandom class variables (such as limits) before randomization starts, or you may need to calculate the error correction bits for random data. SV allows you to use built-in pre_randomize() and post_randomize() functions, that are automatically called by randomize() before and after computing new random values.
class Myxypair extends Xypair; function void pre_randomize(); super.pre_randomize(); $display("pre_randomized value\n"); $display("x=%d y=%d",x,y); endfunction function void post_randomize(); super.post_randomize(); $display("post_randomize value\n"); $display("x=%d y=%d",x,y); endfunction endclass

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

41

Constraints Tips and Techniques


How can you create constrained-random tests that can be easily modified? There are several tricks you can use. 1. Use constraints with variables instead of constants : Specify bounds of an array using variables instead of hardocded values. use variables in the dist constraint to turn on and off values and ranges. e.g. constraint c_size { c.size inside {[1:max_size]}; constraint c_read { read_cmd dist {READ8 := read8_wt, READ16 := read16_wt, READ32 := read32_wt};

}
2. Use non random values to hit particular corner cases. Define the variables to be random. Use rand_mode to enable and disable randomness as per the requirement.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

42

Constraints Tips and Techniques


class Packet; rand bit [7:0] length; rand bit [7:0] payload[];

constraint c_valid {length > 0;


payload.size == length;} endclass Packet p; initial begin

p = new();
// Randomize all variables assert (p.randomize()); $display("Simple randomize"); // Make length nonrandom then randomize packet p.length.rand_mode(0); p.length = 42; assert (p.randomize()); $display("Randomize with rand_mode");

end

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

43

Constraints Tips and Techniques


3. Checking values using constraints : If you randomize an object and then modify some variables, you can check that the object is still valid by checking if all constraints are still obeyed. Call handle.randomize(null) and SystemVerilog treats all variables as nonrandom (state variables) and just ensures that all constraints are satisfied. 4. By turning constraint on/off : You can generate different flavors of stimulus by using constraint_mode to turn on/off different constraints as per the testcase requirement.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

44

Constraints Tips and Techniques


5. Specifying a constraint in a test with external constraints : Generally at the environment modeling stage we are not sure about the constraints. Leave hooks in your environment to define the constraints , later in the test case. e.g. class Packet;
rand bit [7:0] length; rand bit [7:0] payload[]; constraint c_valid {length > 0; payload.size == length;} constraint c_external;

endclass

program test;
constraint Packet::c_external {length == 1;} ...

endprogram

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

45

Iterative constraint
Iterative constraints allow arrayed variables to be constrained in a parameterized manner using loop variables and indexing expressions.

Using the foreach constraint creates many constraints and slow down simulation.
The easiest array constraint to understand is the size function. You are specifying the number of elements in a dynamic array or queue.
class dyn_size; rand reg [31:0] d[];

constraint d_size {d.size inside {[1:10]}; }


endclass

Always remember to specify upper bound while using size function with inside. You can send a random array of data into a design, but you can also use it to control the flow.

If you have an interface that has to transfer four data words.


The words can be sent consecutively or over many cycles. A strobe signal tells when the data is valid. You can use sum method of arrays as shown in following example :

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

46

Iterative constraint
parameter MAX_TRANSFER_LEN = 10; class StrobePat; rand bit strobe[MAX_TRANSFER_LEN]; constraint c_set_four { strobe.sum == 3h4; } endclass

initial begin

StrobePat sp;
int count = 0; // Index into data array sp = new(); assert (sp.randomize); foreach (sp.strobe[i]) begin

bus.cb.strobe = sp.strobe[i];
// If strobe is enabled, drive out next data word if (sp.strobe[i]) bus.cb.data = data[count++]; end end
Presentation_ID 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential

47

Scenario Generation (randsequence)


SV provides randsequence to generate some interesting stream of transactions. Basically randsequence describes the grammer of the transaction.

Consider the following example :


initial begin
for (int i=0; i<15; i++) begin randsequence (stream) stream cfg_read io_read endsequence end // for : cfg_read := 1 | io_read := 2 | mem_read := 5; : { cfg_read_task; } | { cfg_read_task; } cfg_read; : { io_read_task; } | { io_read_task; } io_read;

mem_read : { mem_read_task; } | { mem_read_task; } mem_read;

end Above example generates a sequence stream, which can be either cfg_read, io_read or mem_read. The random sequence engine randomly picks one.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

48

randsequence
SV allows following inside randsequence items : If-else in production items.

Repeat production statements.


break and return can be used for aborting the production

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

49

In-line random variable control


In-line random variable control : The randomize() method can be used to temporarily control the set of random and state variables within a class instance or object. When the randomize method is called with no arguments, it assigns new values to all random variables in an objectthose declared as rand or randc. When randomize is called with arguments, those arguments designate the complete set of random variables within that object; all other variables in the object are considered to be non-random. e.g.
class CA;
rand byte x, y; byte v, w; constraint c1 { x < v && y > w );

endclass
CA a = new; a.randomize(); // random variables: x, y state variables: v, w a.randomize( x ); // random variables: x state variables: y, v, w a.randomize( v, w ); // random variables: v, w state variables: x, y

a.randomize( w, x ); // random variables: w, x state variables: y, v

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

50

Randomization of scope variables


SV also provides the randomization of non-class variables. The scope randomize function, std::randomize(), enables users to randomize data in the current scope, without the need to define a class or instantiate a class object. e.g. module stim; bit [15:0] addr;

bit [31:0] data;


function bit gen_stim(); bit success, rd_wr; success = randomize( addr, data, rd_wr ); // call std::randomize return rd_wr ; endfunction endmodule The scope randomize function returns 1 if it successfully sets all the random variables to valid values, otherwise it returns 0.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

51

Random Stability
What is random stability ? To understand let us discuss about PRNG (Pseudorandom number generators).

Verilog has a single PRNG that is used for the entire simulation.
Testbenches often have several stimulus generators running in parallel, creating data for the design under test. If two streams share the same PRNG, they each get a subset of the random values.

What happens when one of the a class changes?

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

52

Random Stability
This approach changes the values used not only by Gen1, but also by Gen2.

In SystemVerilog, there is a separate

PRNG for every object and thread,


Changes to one object dont affect the random values seen by others.

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

53

THANK YOU

Presentation_ID

2006 Cisco Systems, Inc. All rights reserved.

Cisco Confidential

54

You might also like