Académique Documents
Professionnel Documents
Culture Documents
Companion Guide
Doulos
Church Hatch
22 Market Place
Ringwood
Hampshire
BH24 1AW
UK
Email: info@doulos.com
Web: http://www.doulos.com
VMM for SystemVerilog
Companion Guide
This Companion Guide provides a handy quick reference for users of the
Verification Methodology Manual (VMM) for SystemVerilog, a professional
book co-authored by verification experts from ARM Ltd. and Synopsys, Inc.
and published by Springer Science and Business Media (ISBN 0-387-25538-
9).
The Companion Guide is not intended to replace either the VMM for
SystemVerilog or a proper training course. It assists the engineer in
identifying the exact signature of a particular method, or the set of methods
they have inherited from a certain base class. It is suitable as a very brief
technical introduction to the aims and structure of the VMM methodology, and
also contains reference information on how to use the VMM Standard Library
®
with the Synopsys VCS solution.
Complete code for the Example VMM System, as outlined on pages 7 to 14,
can be downloaded from the Doulos web site:
http://www.doulos.com/knowhow/sysverilog
1
2
Introduction
The VMM for SystemVerilog describes a flexible, scalable verification
methodology for SystemVerilog users. It is possible to use concepts from the
VMM methodology both in small ad-hoc testbenches for module testing and
in the creation of large, complex high-grade verification environments by
specialized verification engineers.
The VMM for SystemVerilog contains detailed implementation rules and
recommendations to aid in the adoption of this methodology. These rules and
recommendations can also provide useful guidance for those who are new to
complex verification.
The VMM Standard Library provides base classes for key aspects of the
verification environment, an event notification service, and a message
logging service. VMM-compliant test environments must use these base
classes, suitably extended to provide any required custom functionality.
Transaction data in a VMM-compliant testbench are objects of one or more
user-defined classes derived from the provided base class vmm_data. Such
objects are produced by a transactor, which is derived from vmm_xactor.
Some transactors are the source of a data stream, generating data according
to constraints; they are known as generators. Other transactors take data
items from a channel, perform some transformation, then add the item to a
downstream channel; they are said to be functional-level transactors. Some
transactors at the lowest level of the testbench, communicating directly with
the design by means of a pin-level interface, are known as command-level
transactors.
Transactors pass transactions from one to another through channels. A
generator creates a series of data items, then places references to those
date items into a channel. Another transactor can read the next reference
from the channel and perform any required operation on that data before
placing the reference in the next channel. The creation of channels for any
given transaction type is automated by a macro `vmm_channel.
A notification service, based on vmm_notify, gives us much more than is
available using event variables. The operation of the notification is defined at
configuration time, and notification can have status and timestamp
information attached. Notification is used by transactors and channels to
mark activity and for synchronization.
The environment, based on vmm_env, is where all these objects are
instanced. At the top of the object instance hierarchy is the testcase, which
chooses, configures and runs a particular environment. The testcase is
remote from the event-driven world of signals, but has the ability to control
the environment at any level.
3
Introduction
A single source of transactions can feed many consumers using a
vmm_broadcast object. Conversely, multiple sources can be merged into a
single stream of transactions using vmm_scheduler.
The message service, based on vmm_log, provides a mechanism for
reporting interesting activity to output files or the simulator console. Using a
predefined message mechanism gives us consistency (post-processing and
interpretation), localization (identification and control of source),
configurability (control of message severity and type), and control (effect on
simulation behavior). All textual output from a VMM-compliant test
environment should use the message service.
4
Introduction
The diagram below shows the structure of a small VMM-compliant testbench.
The transactors that drive the DUT form a protocol stack, with the simplest
transactions (signal transitions) at the lowest level of DUT interface, and the
most complex (scenarios) coming from the generator at the top. We show
one level of functional-level transactor, but there could be more if required.
Similarly, the monitoring transactors form a protocol stack. Connection to the
DUT is implemented in a standardized way using the SystemVerilog
interface construct – see the extended example, and the section on
Command-level transactors, for more detail.
Environment - vmm_env
Generator Scenario-level
Scenario-level
vmm_atomic_gen Callback scoreboard Callback
vmm_channel
vmm_channel vmm_channel
Transactor Monitor
Command-level
vmm_xactor vmm_xactor
Test harness
Interface Interface
DUT
Note:
Callbacks from a generator use a façade class derived from
atomic_gen_callbacks. Callbacks from other transactors use a façade
derived from vmm_xactor_callbacks.
5
6
Example VMM System
Defining transaction data
We start by describing our transaction data using an extension of vmm_data.
We describe how a transaction is made up, with constraints that define
suitable data values; and we supply necessary methods, including a deep
copy and a method for checking data validity.
function new();
super.new(this.log);
this_packet_num = packet_num;
packet_num++;
endfunction
// Other constraints, functions such as copy() required by VMM, etc.
endclass: packet_trans
7
Example VMM System
`vmm_atomic_gen(packet_trans)
packet_trans_atomic_gen gen;
virtual ex_intf.test V;
packet_trans_channel in_chan;
8
Example VMM System
task main;
packet_trans p;
fork
super.main();
join_none;
forever begin
this.wait_if_stopped_or_empty(this.in_chan);
this.in_chan.get(p);
sendapacket(p);
end
endtask
9
Example VMM System
Creating a channel
We have already created a channel class to transfer our packet_trans data
using the vmm_channel macro. Now we can make an instance of it:
packet_trans_channel in_chan;
The generator produces a stream of data instances, and will put each one
into the channel gen2mas. The master transactor uses the get() method
of the channel to retrieve data and stimulate the design.
10
Example VMM System
The monitor watches signal activity for transactions and logs them on the
scoreboard to which it is connected by another channel instance mon2scb.
function dut_env::new();
super.new("DUT_ENV");
endfunction
gen.stop_after_n_insts = 20;
endfunction: build
11
Example VMM System
Within the build method we are registering callbacks with each transactor. In
short, each time a transactor does anything it should call a function to provide
a hook for optional related actions. In this case it is to add the transaction to
the scoreboard and to establish coverage of transactions, but callbacks can
also modify or drop data, or insert some directed test data using the
inject() method that should be found in every transactor.
We fill in the start() method with actions necessary to get our testbench
going:
task dut_env::start();
super.start();
gen.start_xactor();
mst.start_xactor();
mon.start_xactor();
scb.init();
endtask: start
12
Example VMM System
Test program:
program testprogram;
initial begin
end
endprogram: testprogram
13
Example VMM System
Test harness:
14
Quick Reference Listings
Several kinds of base class are defined in the VMM Standard Library.
vmm_data is a template for data objects/transactions that are manipulated
by the system. Transaction data objects are likely to be created and
destroyed dynamically, in large numbers, during normal operation of the
testbench.
vmm_env, vmm_xactor and vmm_channel (including vmm_broadcast
and vmm_scheduler) are a base for components of the testbench. They
create, convey and transform objects based on vmm_data. Objects of these
types are likely to be created once only, as part of the environment’s build
procedure, and together form the verification environment.
Macros `vmm_atomic_gen and `vmm_scenario_gen simplify the creation
of generators – derivatives of vmm_xactor designed to generate streams of
transactions based on random constraints.
vmm_notify and vmm_log respectively allow control and reporting of what is
going on.
15
vmm_data Base class
This is the base class from which all user-defined transaction data types
should be derived. It provides a set of methods that all data or transaction
descriptors need, such as for copying, comparing and checking. Virtual
methods in bold must be overridden in all derived classes.
class vmm_data;
16
Creating an extension of vmm_data
• First, decide what data you need in your transaction. There are no
restrictions on user-defined data that can be added to an extension of
vmm_data, but all data fields that represent part of a transaction must
be declared rand so that their values can be randomized if required.
The section Class Properties/Data Members in chapter 4 of the VMM
book gives more detail of appropriate ways to model transaction data.
• Create constraints that control the randomization of your data fields.
You are free to design these constraints to determine the content,
distribution and validity of your randomly generated data. You should
name the constraints in a consistent way so it is easier to document and
extend them. The VMM stipulates a few simple rules concerning these
user-defined constraints; you can find these rules in chapter 4 of the
book.
• Write virtual method definitions for the base class methods that must be
overridden: copy, compare, allocate, is_valid, psdisplay.
Details of the standard design patterns for these methods can be found
in the VMM book, and the utility rvmgen (described at the end of this
guide) can construct a code skeleton to save you some work.
• Although it is not mandatory, any non-trivial derivative of vmm_data is
sure to need its own implementation of the constructor new.
17
vmm_xactor Base class
All transactors are derived from this base class, including bus-functional
models, monitors and generators. It provides a standard set of methods that
all transactors need.
class vmm_xactor;
18
Command-level transactors
At the lowest level of the testbench structure, a command level transactor
provides the bridge between the object-oriented, class-based world of the
testbench and the module-based world of the DUT together with its
supporting test harness including clock generators, module-to-module
interconnections and so on. There is a standard implementation pattern for
this bridge, exploiting SystemVerilog’s interface, clocking and
virtual interface constructs. In summary:
19
vmm_channel Macro and base class
Base class vmm_channel implements a generic transaction-level interface
mechanism. Properties and virtual methods of vmm_channel are
summarized on the facing page.
`vmm_channel ( class_name )
This macro creates a new channel class definition. It does not instance
anything.
20
Macro and base class vmm_channel
continued
21
vmm_notify Base class
The vmm_notify class implements an interface to the notification service,
used for synchronization between concurrent threads or transactors. It
provides more functionality than is available using event variables.
class vmm_notify;
class vmm_notification;
22
Macro vmm_atomic_gen
This macro is used to define a class named class_name_atomic_gen for
any user-specified class class_name that is derived from vmm_data. The
resulting generator class is an extension of vmm_xactor.
23
vmm_scenario_gen Macro
Macro `vmm_scenario_gen ( class_name, class_description_string )
defines the following classes:
class class_name_atomic_scenario;
Implements a scenario composed of a single unconstrained transaction.
int unsigned ATOMIC;
constraint atomic_scenario;
class class_name_scenario;
24
Macro vmm_scenario_gen
class class_name_scenario_election;
Implements a random selection process for selecting the next scenario
descriptor to be randomized, from a set of available descriptors stored in
its scenario_set queue variable.
int stream_id;
int scenario_id;
int unsigned n_scenarios;
int unsigned last_selected [ $ ];
int unsigned next_in_set;
class_name_scenario scenario_set [ $ ];
rand int select;
constraint round_robin;
class class_name_scenario_gen_callbacks;
Defines a façade for the scenario generator’s callbacks.
virtual task pre_scenario_randomize ( class_name_scenario_gen gen,
ref class_name_scenario scenario );
virtual task post_scenario_gen ( class_name_scenario_gen gen,
class_name_scenario scenario, ref bit dropped );
25
vmm_broadcast Base class
class vmm_broadcast;
vmm_log log;
typedef enum { AFAP, ALAP } bcast_mode_e;
function new ( string name, string instance, vmm_channel source,
bit use_references = 1, bcast_mode_e mode = AFAP );
virtual function void start_xactor ( );
virtual function void stop_xactor ( );
virtual function void reset_xactor ( reset_e rst_type = SOFT_RST );
broadcast_mode ( bcast_mode_e mode );
virtual function int new_output (
vmm_channel channel, logic use_references = 1'bx );
virtual function void bcast_on ( int unsigned output_id );
virtual function void bcast_off ( int unsigned output_id );
virtual protected function bit add_to_output ( int unsigned decision_id,
int unsigned output_id, vmm_channel channel, vmm_data obj );
26
Base class vmm_scheduler
This class is the reverse of the vmm_broadcast class. It handles multiple
sources feeding data into a channel with only one consumer. If a multipoint-
to-point mechanism must follow a specific scheduling algorithm, a
vmm_scheduler component can be used to control the choice of source
stream providing the next transaction to the output stream.
class vmm_scheduler;
vmm_log log;
protected vmm_channel out_chan;
function new ( string name, string instance,
vmm_channel destination, int instance_id = -1 );
virtual function void start_xactor ( );
virtual function void stop_xactor ( );
virtual function void reset_xactor ( reset_e rst_typ = SOFT_RST );
virtual function int new_source ( vmm_channel chan );
virtual function void sched_on ( int unsigned input_id );
virtual function void sched_off ( int unsigned input_id );
virtual protected task schedule ( output vmm_data obj,
input vmm_channel sources [ $ ], int unsigned input_ids [ $ ] );
virtual protected task get_object ( output vmm_data obj,
vmm_channel source, int unsigned input_id, int offset );
vmm_scheduler_election randomized_sched;
27
vmm_log Base classes
This class is used to connect to the message service, for reporting events
and interesting occurrences. Note: owing to the size of this class, this is not
an exhaustive list. More details can be found in the full description of
vmm_log in appendix A of the VMM book.
class vmm_log_format;
28
Base classes vmm_log
class vmm_log;
29
vmm_env Base class
class vmm_env;
vmm_log log;
vmm_notify notify;
function new ( string name = "Verif Env" );
task run ( );
// Test sequencing methods called by run ( ):
virtual function void gen_cfg ( );
virtual function void build ( );
virtual task reset_dut ( );
virtual task cfg_dut ( );
virtual task start ( );
virtual task wait_for_end ( );
virtual task stop ( );
virtual task cleanup ( );
virtual task report ( );
event end_test;
30
Using the VMM Standard Library with VCS
`include "vmm.sv"
% simv
% simv –gui
runs interactively.
31
Utility program rvmgen
The rvmgen utility provides an easy way to generate source code templates
for VMM-compliant verification components, based on answers to a few
simple questions.
Options:
Typical usage:
% rvmgen -l sv
The tool will give you a list of possibilities from the libraries it can see:
Make the appropriate choice and the code skeleton is generated. “Physical
interface declaration” constructs a SystemVerilog interface block needed
to connect your VMM-compliant testbench to the DUT. The transaction
descriptor is derived from vmm_data; drivers and monitors are derived from
vmm_xactor.
32