Monday, June 22, 2009

Making Data Generation Effective and Efficient

Continuing on benefits for those who are used to working with RTL language and building on a methodology-based logging mechanism, we will next look into the aspects of data or payload generation mechanism that are facilitated via a comprehensive VMM verification methodology.

Data generation coupled with transaction mechanism to deliver data to the DUT is the central activity in creation of testcases in any verification environment. A well thought out base infrastructure can help immensely with the efficiency of overall verification effort.

The synthesizable subsets of language such as Verilog, VHDL, and SystemVerilog require design and verification engineers to deal with bits, vectors of bits, and integers. The use of enum and struct allows the level of abstraction to move up a bit but the elements of these enums and structs must themselves be bits, bit vectors, and integers.

In working with testbenches, one has to move up the level of abstraction using models without such restrictions and allowing working with data items such as packets, frames, instructions, and commands.

In SystemVerilog, struct and class can model packets, frames, instructions, and commands. For example, one type ATM cell is modeled using a struct as follows:

typedef struct {
bit [11:0] vpi;
bit [15:0] vci;
bit [2:0] pt;
bit clp;
bit [7:0] hec;
bit [7:0] payload[48];
} atm_cell

The same ATM cell can be described using class as follows:

class atm_cell;
bit [11:0] vpi;
bit [15:0] vci;
bit [2:0] pt;
bit clp;
bit [7:0] hec;
bit [7:0] payload[48];
endclass: atm_cell

The key differences between the use of struct, as may be familiar to an RTL user, and class are the following: i) a struct being an integral type leads to allocation of memory when declared whereas class is a dynamic type and memory is not allocated until it is instantiated. ii) a class may also include tasks and functions written to operate on its contents; we will look into this aspect a bit more later, and iii) class instances can be moved around by moving their references as opposed to integral data types such as struct where you have to move the entire data item. This results in run-time efficiency.

One would like to create large number of such ATM cells of different types for verification purposes. Random stimulus generation in SystemVerilog has evolved far beyond the use of $random system task and verification methodology such as VMM abstract it up further to provide ease of use in the key task of data or payload generation in the verification environment.

The vmm_data base class provides a standard set of properties and methods and we will talk about this more later. The same ATM cell data looks as follows with vmm_data:

class atm_cell extends vmm_data;
……
rand bit [11:0] vpi;
rand bit [15:0] vci;
rand bit [2:0] pt;
rand bit clp;
rand bit [7:0] hec;
rand bit [7:0] payload[48];
……
endclass: atm_cell

Going beyond the class definition of ATM cell, there are several things to note here:

1. In this definition, an existing class vmm_data is being extended; vmm_data is a base class that provides a standard set of properties and methods that are useful in creating verification environment. We had discussed benefits of class and all of those benefits such as modeling of operations, transformations, alteration of default behavior, and efficient movement of instances are applicable here.

2. With extension of vmm_data, you can easily control randomization of data values. With appropriate added code to the class variable, one can always achieve this but a lots of background work has already been done with vmm_data thereby making life easier for the verification engineer.

3. With the specification of fields of typical data items such as a packet as an extension of vmm_data, it is easy to create a set of random packets while constraining the values within legal or illegal limits as needed for the verification task. In contrast, traditional testbenches would require one procedure per transaction. You can constrain the fields to take up value within specified limits. These are called constraints ; a constraint to limit value of the field pt to be greater than 3 would look something like this:
constraint pt_constraint1 {pt > 3}

4. You may notice some dots at the front and the end part of class definition as an extension of vmm_data. Additional properties and methods, that operate over the ATM cell packet data, are added there. For example, you would need printing capabilities for the packet and a vmm_log, discussed in previous blog, object can be added about this packet. This can added as an instance of vmm_log base class named “ATM_CELL”:
static vmm_log log = new (“ATM_CELL”, “ATM_CELL”);

5. You will have to add a display method for the ATM cell data to display appropriate fields of the packet when packet is generated or delivered at an interface. This is one of the methods you will typically add to vmm_data.

6. There are four other methods that are typically added to a vmm_data item: constructor, allocator, copy, and compare. The constructor of the object makes a call to the parent constructor class’ new() method, a new instance of data transaction is created via the allocate() , and copy() method allows copying of data object, and compare() method allows checking for equality of two copies of the data object. We will get into the details of methods that go with objects in a future discussion.

Once you have added these properties and methods, a vmm_data class would look something as listed below. The code pieces for methods have been left out for now and will be brought in the discussion of methods for data creation objects.

class atm_cell extends vmm_data;
//create a log class for printing facilities
static vmm_log log = new (“ATM_CELL”,“ATM_CELL”);
rand bit [11:0] vpi;
rand bit [15:0] vci;
rand bit [2:0] pt;
rand bit clp;
rand bit [7:0] hec;
rand bit [7:0] payload[48];

//add a constraint to pt
constraint pt_constraint1 {pt > 3;}

//add a display() method here for atm_cell
//add a constructor()method for atm_cell
//add an allocate() method for atm_cell
//add a copy() method for atm_cell
//add a compare() method for atm_cell

endclass: atm_cell


Once the data object is created and filled up appropriately to provide a sequence of ATM cells, how do we transfer that information to the DUT? Also, we will need to be able to collect data coming out of DUT into a vmm_data object for further analysis to help validation at higher-level. These bring in the concepts of transactors and channel. We will continue our discussions in upcoming blog articles on verification methodology keeping RTL engineers in mind.