Monday, December 7, 2009

Importance of Methodology in SoC Power Management Verification

Power management techniques that leverage voltage as a handle are being extensively used in power sensitive designs. These techniques include: Power Gating (PG), Power Gating with Retention (RPG), Multiple Supply Voltages (MSV), Dynamic Voltage Scaling (DVS), Adaptive Voltage Scaling (AVS), Multi-Threshold CMOS (MTCMOS), and Active Body Bias (ABB). The use of the power management techniques also imply new challenges in validation and testing of designs as new power states are created.

It is important that the lessons learned from validating power management of a design are captured as part of verification methodology and reused in later designs or future versions of the same design. Also, parts of established verification methodology can reused to address tasks needed in power management validation.

Power sequencing protocol is a good example of a task that appears in all power managed designs. Power sequencing typically follows a well-defined set of steps in designs that use power gating and state retention. These set of steps include:

• Disabling or gating the clock
• Saving state of registers in either special registers or in memory that is not powered off
• Enabling isolation for the block that has been powered off
• Disabling power to the block using a power switch
• Enabling power at the end of power gated mode
• Restoring saved register values
• Disabling isolation of the block
• Enabling the gated clock

This sequence or a simple variation sequence depending upon whether state retention is used or not is used in all power gated designs and potentially in different power-modes of the same design. The verification involves following a set of rules and routines to validate the sequence and can be part of infrastructure for verification of all power managed designs.

Another example can be the use of VMM Register Abstraction Layer (RAL) in the context of power management verification. VMM RAL is an application package to create abstract model of registers and memories inside a design that can used in the context of SystemVerilog based verification. It includes:
• Pre-defined tests to verify implementation of registers and memories
• Functional coverage model to ensure various bits of register have been tested

Power management software routines exercise various power modes of the design setting relevant bits in power control registers. VMM RAL can be used to manage this process through tests exercise various power modes through the setting of appropriate bits in power control registers and a coverage model can ensure that various power modes of the design have been exercised.

Power management verification should be seen as an extension of established verification methodology rather than a start from scratch. It does bring new elements like power-aware simulation (which can be seen as additional features in an existing simulator), dealing with specialized power-related signals and controls, and special power-related cells like switches, level-shifters, and isolation logic but these can be dealt with in the context of a verification methodology that builds upon an existing one.

Friday, October 16, 2009

SystemC TLM2.0 and SystemVerilog Verification Methodologies

TLM2.0 is the version 2.0 of Open SystemC (IEEE 1666) Initiative (OSCI) [1] standard and it is a layer on top of SystemC which itself is based on C++ language. TLM stands for Transaction-level Modeling which is an abstraction layer above RTL with the primary goal to accelerate simulation by avoiding detailed pin-level events that occur in RTL simulation.

In recent times, we have seen SystemVerilog based methodologies extend support for SystemC TLM2.0 standard. For example, Synopsys’ VMM Release 1.2 [2] supports TLM2.0 by adding remote procedure call functionality between components and extending support to SystemC modules.

TLM 2.0 is used in virtual platform models that are typically created to validate a system-on-a-chip (SoC) with multiple processor cores, busses, software stacks running on cores, and specialized digital and analog hardware IP blocks. These virtual platforms can accurately model functionality and registers in the SoC design without dealing with clocks and pins and are fast enough to boot software part of the system that may be available long before the creation of system RTL.

TLM provides mechanisms that can described as the glue that ties various IPs together in carrying out virtual platform simulation of the SoC. Some of the use cases of a virtual platform based on TLM are:
• Software Development
• Software Performance Evaluation
• Architectural Analysis
• Hardware Verification

The users of SystemVerilog based methodologies such as VMM leverage infrastructure and knowledge base to create verification needs for validating SoCs. The hardware verification task is similar to the virtual platform development in the sense that the verification works typically gets started even before the RTL may be available.

TLM2.0 core interfaces and sockets (mechanism for interoperability) can connect to VMM channels and notification. With the support of TLM2.0 in SystemVerilog based verification methodologies enables either building of or leveraging existing hardware verification environment early in the SoC design process that can be used to validate the SoC virtual platform model and then used later in validating the SoC at the RTL level.

Virtual platform that is created to accomplish key tasks of early software development, performance evaluation, and architectural analysis leverages and helps solidify a verification infrastructure based on SystemVerilog to be reused later in RTL validation also. Both the virtual platform and the verification teams can benefit from this connection.

[1] www.systemc.org
[2] www.vmmcentral.org

Wednesday, September 9, 2009

Key SystemVerilog Resources on the Web

There were some suggestions from readers to have a listing of resources/references for SystemVerilog (SV) and associated methodologies. Here is a list of some these resources that I have used in the past:

· SV Language Standardization, LRM, and Extensions: http://www.systemverilog.org/

· Free SV Language Reference Manual on Web: http://www.eda.org/sv/SystemVerilog_3.1a.pdf

· Verification Methodology Manual (VMM) for SV: http://www.vmmcentral.org/

· Open Verification Methodology(OVM) for SV: http://www.ovmworld.org/

· Blogs:
o Verification Martial Arts: http://www.vmmcentral.org/vmartialarts/

o Verification Guild: http://verificationguild.com/

o Guide to SV-VMM: http://learn-systemverilog.blogspot.com/

· SystemVerilog Books:
o By Janick Bergeron (Review content of the books at this link)
http://books.google.com/books?id=ZWZAkWkNy3cC&printsec=frontcover&dq=SystemVerilog+Manual&source=gbs_similarbooks_s&cad=1#v=onepage&q=SystemVerilog%20Manual&f=false

o By Bergeron, Cerny, Hunter, and Nightingale (Review contents at this link:)
http://books.google.com/books?id=dcET3kKtmH4C&dq=SystemVerilog+Manual&printsec=frontcover&source=in&hl=en&ei=W8CnSr2hA8vZnAfasdWwBw&sa=X&oi=book_result&ct=result&resnum=12#v=onepage&q=&f=false

o Sutherland, Davidmann, and Flake (Review contents at this link:)
http://books.google.com/books?id=EeIVYPd9iDAC&dq=SystemVerilog+Manual&printsec=frontcover&source=in&hl=en&ei=W8CnSr2hA8vZnAfasdWwBw&sa=X&oi=book_result&ct=result&resnum=11#v=onepage&q=SystemVerilog%20Manual&f=false

Monday, August 3, 2009

Creating Flexible and Consistent Transactions

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 generation and use of transactions facilitated via a comprehensive VMM verification methodology.

Transactors are components of verification environment that interface between different levels of a protocol implementation. Going back to our ATM example, at a higher level, you will generate ATM frames that will eventually be driven on to a physical interface such as Utopia Level-1 or Level-2. An ATM cell generator mechanism that provides such an interface to the Utopia physical interface is a transactor. So generators, drivers, monitors, and checkers are example of such transactors.

Bus functional models (BFMs) are command-layer transactors which include transaction-level interface on one side and physical interface on the other. Other types of transactors include functional-layer and scenario-layer.

Transactors should be flexible and consistent given that they and consistent given that they are likely to be reused in multiple testcases and potentially across different verification environment. For example, a well-designed USB interface verification environment can be used across many designs that use USB interface. Transactors should meet specific needs for various test cases and hence need to be controllable. Also, transactors should be able to be extended to meet needs of a verification environment.

With the goals of creating flexible and consistent transactions, vmm_xactor provides a template from which we can derive various transactors of typical interest in a verification environment. It contains standard properties and methods to configure and control transactors in a way that results in a consistent usage model for all transactors derived from the same base class.

The properties of vmm_xactor class are similar to the vmm_data class as we discussed in a prior blog and the basic methods of the vmm_xactor class include:

· the constructor method, new()
· start_xactor(): controls execution of the main method, forks it off. It can be extended to include protocol specific behavior.
· reset_xactor(): control execution of the main method, terminates it.
· stop_xactor() and some variations of stop to allow blocking and non-blocking conditions, control execution of the main method, terminates it.
· main() is spawned when start_xactor() is called from upper layers and all threads are forked and join in the body if main() task.

So an ATM Utopia layer driving transactor will extend vmm_xactor to define a transactor as follows:


class utopia1_driver extends vmm_xactor;

//declare property members of the utopia1_layer_driver such as channels, interfaces

function new (string inst, int stream_id = -1, …);
//standard constructor specific code
endfunction: new

virtual function void start_xactor();
super.start_xactor();
//any utopia1_driver specific code
endfunction: start_xactor

virtual function void reset_xactor();
super.reset_xactor();
//any utopia1_driver specific code
endfunction: reset_xactor

virtual function void stop_xactor();
super.stop_xactor();
//any utopia1_driver specific code
endfunction: stop_xactor

virtual protected task main();
super.main();
// code for main functionality of utopia1_driver
forever begin
//generate transaction
//drive transaction
endtask: main

endclass: utopia1_driver

Physical interfaces when specified use “virtual modport interface” that allows each instance of transactor to be connected to a specific interface instance without hardcoding signal naming.

class utopia1_driver extends vmm_xactor;

virtual atm_if.utopia1 sigs;
:
endclass: utopia1_driver

The traditional BFMs are physical-level BFMs and are tied to specific physical-level interface. With vmm_transactor, BFMs need not be tied to physical interfaces but can purely be implementation independent transaction-level BFM.

Transaction-level interface also requires a concept of vmm_channels to remove higher-level layers from the physical interface details. Channel is a conduit that is used to exchange information between transactors and we will next look into channels and transaction-level interfaces

The latest release of VMM (VMM 1.2) also implements a set of transport interface classes based on OSCI TLM 2.0 standard that provide standard transaction-level modeling communication methods. This adds remote procedure call functionality between components and extends support to SystemC modules. As a result, one can now easily integrate reference models written in SystemC with TLM-2.0 transport interface directly in your VMM testbench. As we go further in this blog, we will look into also relevant SystemC developments and how this plays into system-level verification using a SystemVerilog verification methodology.

Tuesday, July 7, 2009

On Methods Associated with Data Generation

Tasks and functions form the core of the code in various functional verification environments. For example, for bus functional models, you will need tasks such as read, write, request, and grant working over the interface. For data such as packets, cells, and frame to be delivered over an interface defined through a bus functional model, you need methods to copy and compare the data, and to display the data as and when appropriate.

We go back to the previous blog article that talks about efficient data generation using the VMM approach, and now talk about some of the methods associated with data item like the ATM cell.

One of the first methods that we need is called the constructor method for the ATM cell object; this is needed in object-oriented programming to be able to create a new instance of the object such as the ATM cell. Here, we just need to call its parent class’ constructor method called new() which is predefined for us. So defining the constructor methods is fairly mechanical and looks something like this:

//constructor method for the atm_cell class
function new();
super.new(log);
endfunction: new

There is an allocate() method for vmm_data to create a new instance of data transaction. It allocates a new instance of the same type as the object instance and returns a reference to the instance.

//allocate() method for the atm_cell class
function vmm_data allocate(vmm_data to = null);
atm_cell transaction = new;
return transaction;
endfunction: allocate

Typically, for any data item that we create, we will need a printing utility to able to display the relevant portions of the data item being generated. We can define a display method for printing information regarding the ATM cell being generated.

//display method for the atm_cell class
//to print a prefix message followed by vpi and vci fields
function string psdisplay (string prefix-msg);
$sformat (psdisplay, “ %s : [%d :%d]”,
prefix-msg, this.vpi, this.vci);
endfunction: psdisplay

Just like the constructor and allocate methods, the definition of the copy method is fairly mechanical and only has a section of code that is specific to the data item being defined. It copies the current value of the object instance into the specified object instance. If no object instance is specified then a new instance is allocated. The copy method for the ATM cell looks as follows:

//copy method for the atm_cell class
function vmm_data copy (vmm_data to = null);
atm_cell cell_copy;
if (to == null)
cell_copy = new();
else if (!$cast(cell_copy, to)) begin
‘vmm_fatal (this.log, “Not an ATM cell”);
cell_copy = null;
return;
end
super.copy_data(cell_copy);
cell_copy.vpi = this.vpi;
cell_copy.vci = this.vci;
cell_copy.pt = this.pt;
cell_copy.clp = this.clp;
cell_copy.hec = this.hec;
for (i=0; i < 48; i++)
cell_copy.payload[i] = this.payload[i];

copy = cell_copy;

endfunction: copy

The ATM cell specific parts of the copy code are highlighted in red and the rest of the code remains the same for all data copy methods. These are carried out after a call to the base class copy_data method which takes care of all of base member copying. The copy method can create a duplicate of the main transaction. Often, you create a copy of the transaction and alter some fields for generating appropriate transactions.

Similar to the copy method, each data item typically should provide a compare method to allow comparison of data items. It compares the current value of the object instance with the current value of specified object instance and returns TRUE if identical and FALSE if different. If case the value is different then a descriptive text of first difference found is also returned in the specified string. The kind argument may be used to implement different comparison functions i.e., full compare, compare of random fields etc.

//compare method for the atm_cell class
function vmm_data compare (input vmm_data to,
output string diff,
input int kind = -1);
atm_cell cell;
if (to == null) begin
‘vmm_fatal(log, “Cannot compare a NULL reference”);
return 0;
end
else if (!$cast(cell, to) begin
‘vmm_fatal(log, “Not an ATM cell instance compare”);
return 0;
end
if (cell.vpi != this.vpi) begin
$sformat(diff, “vpi %0d != %0d”, this.vpi, cell.vpi);
return 0;
end
if (cell.vci != this.vci) begin
$sformat(diff, “vci %0d != %0d”, this.vci, cell.vci);
return 0;
end
if (cell.pt != this.pt) begin
$sformat(diff, “pt %0d != %0d”, this.pt, cell.pt);
return 0;
end
if (cell.clp != this.clp) begin
$sformat(diff, “clp %0d != %0d”, this.clp, cell.clp);
return 0;
end
if (cell.hec != this.hec) begin
$sformat(diff, “hec %0d != %0d”, this.hec, cell.hec);
return 0;
end
for (i=0; i < 48; i++) begin
if (cell.payload[i] != this.payload[i])
$sformat(
diff, “payload[%0d] %0d != %0d”, i, this.payload[i], cell.payload[i]);
return 0;
end
return 1;
endfunction: compare


Once you have added these properties and methods, a vmm_data class would look something as listed below. 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.


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




//constructor method for the atm_cell class
function new();
super.new(log);
endfunction: new

//allocate() method for the atm_cell class
function vmm_data allocate(vmm_data to = null);
atm_cell transaction = new;
return transaction;
endfunction: allocate

//display method for the atm_cell class
//to print a prefix message followed by vpi and //vci fields
function string psdisplay (string prefix-msg);
$sformat (psdisplay, “ %s : [%d :%d]”,
prefix-msg, this.vpi, this.vci);
endfunction: psdisplay

//copy method for the atm_cell class
function vmm_data copy (vmm_data to = null);
atm_cell cell_copy;
if (to == null)
cell_copy = new();
else if (!$cast(cell_copy, to)) begin
‘vmm_fatal (this.log, “Not an ATM cell”);
cell_copy = null;
return;
end
super.copy_data(cell_copy);
cell_copy.vpi = this.vpi;
cell_copy.vci = this.vci;
cell_copy.pt = this.pt;
cell_copy.clp = this.clp;
cell_copy.hec = this.hec;
for (i=0; i < 48; i++)
cell_copy.payload[i] = this.payload[i];
copy = cell_copy;

endfunction: copy

//compare method for the atm_cell class
function vmm_data compare (input vmm_data to,
output string diff,
input int kind = -1);
atm_cell cell;
if (to == null) begin
‘vmm_fatal(log, “Cannot compare a NULL reference”);
return 0;
end
else if (!$cast(cell, to) begin
‘vmm_fatal(log, “Not an ATM cell instance compare”);
return 0;
end
if (cell.vpi != this.vpi) begin
$sformat(diff, “vpi %0d != %0d”, this.vpi, cell.vpi);
return 0;
end
if (cell.vci != this.vci) begin
$sformat(diff, “vci %0d != %0d”, this.vci, cell.vci);
return 0;
end
if (cell.pt != this.pt) begin
$sformat(diff, “pt %0d != %0d”, this.pt, cell.pt);
return 0;
end
if (cell.clp != this.clp) begin
$sformat(diff, “clp %0d != %0d”, this.clp, cell.clp);
return 0;
end
if (cell.hec != this.hec) begin
$sformat(diff, “hec %0d != %0d”, this.hec, cell.hec);
return 0;
end
for (i=0; i < 48; i++) begin
if (cell.payload[i] != this.payload[i])
$sformat(diff, “payload[%0d] %0d != %0d”, i, this.payload[i], cell.payload[i]);
return 0;
end
return 1;
endfunction: compare


endclass: atm_cell

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.

Thursday, May 28, 2009

Simplifying Management of Debug Statements

The importance of debug statements or simulation messages cannot be overstated in the context of efficient simulation process management. All of the components of a typical testbench such as transactors, assertions, monitors, scoreboards, and testcases use messages to indicate progress, important events, warnings, errors or potential efforts, and abnormal or normal completion of simulation. These indicators along with additional information to help diagnose the problems play a huge role in efficient simulation process management.

A common practice as used in the context of Verilog or VHDL simulation management is to either implement a simulation logging module with appropriate tasks to indicate notes, warnings, and errors or ensure results by parsing simulation output.

An implementation of logging module helps simulation keep track of its own progress and allows consistency of messages coming from various sources. However, this needs to be carefully thought out given a number of different possible sources of these messages in a given simulation environment, different severities associated with these debug messages, and multiple message types associated with each source. Any implementation of consistent and robust simulation messaging service requires a lot of effort and careful thinking to help enable efficient simulation process management.

It is great to see that all of this has been captured in the construction of vmm_log class (think of it as a module for reporting events and important occurrences) in VMM thus allowing to keep our focus on the main simulation tasks i.e., creation of appropriate testcases to reach the goals of functional coverage. Several convenient macros have been created simplifying use of the vmm_log class to report notes, warnings, errors, debug messages, and fatal issues.

For example, if you are working with the verification of PCI interface where data link layer implements sequencing of transaction layer packets and protects the contents of the packets using a 32-bit CRC. You want to be kept informed of the number of packets received so far and when computed CRC does not match received CRC, you will like to issue an error message. These two types of messages can be serviced as follows:

`vmm_note(log, $psprintf(“Received TLP packet number %d at time %d”, pcount, $time));
:
:
if (computedCRC != receivedCRC)
`vmm_error (log, $psprintf (“PCIXactor:Received CRC %h does not match computed CRC %h for packet number %d at time %d”, receivedCRC, computedCRC, pCount, $time) );

While transfer of packets are happening at one interface, we could be also be monitoring events to ensure adherence to the protocol. For example, a target must assert DEVSEL before any other response within 1 to 3 clocks following the address phase or else an error could be indicated as follows:

`vmm_error(log, $psprintf(“PCIChecker: At time %d the target erroneously asserted STOP or TRDY before asserting DEVSEL”, $time));

In the code examples above, log is simply an instance of vmm_log class. The underlying VMM infrastructure has several built-in handles and one of them counts message as an error if the logging severity is set to error. As a result, in our example, PCI errors would automatically increment the error count and simulation can be aborted when combined errors from different sources exceed certain threshold.

This simplifies simulation process management immensely. There is consistent messaging from different components of testbench while providing complete programmability of message types and severities along with typical simulation handles used in simulation process.

As a verification consultant, I always come across engineers who have been successfully doing verification using Verilog over the years and question any switch of methodology given the TTM pressures they face with every product. They are aware of some of limitations of their current methodology but want clear pointers to the features of any new methodology that help alleviate existing pain points. Being a long time Verilog user myself, I think VMM’s logging infrastructure is one such pointer. It is simple yet very effective in improving the overall simulation process management.

It will be great to hear about your experiences with management of debug statements during the course of verification process and the importance it plays in overall verification efficiency.