OVM 2.0 Golden Reference Guide - 0
OVM 2.0 Golden Reference Guide - 0
OVM 2.0 Golden Reference Guide - 0
(
port_type provider);
connects the analysis export
to another analysis export,
or to an analysis imp, that
implements a subscriber's
write functionality
();
Returns type name
virtual function ovm_component
get_parent();
Returns handle to parent
component
ovm_component
26 Copyright 2008 by Doulos. All rights reserved.
function ovm_component
get_child(string name);
Returns handle to named child
component
function int get_first_child(
ref string name);
Get the name of the first child
function int get_next_child(
ref string name);
Get the name of the next child
function int
get_num_children();
Return the number of child
components
function int has_child(
string name);
True if child exists
function ovm_component lookup(
string name );
Search for named component
(no wildcards)
function void print(
ovm_printer printer=null);
Prints the component
(int size=0);
Prints footer information
for arrays and marks the
completion of array
printing
virtual function void
print_array_header
(string name,
int size,
string arraytype="array",
byte scope_separator=".");
Prints header
information for arrays
virtual function void
print_array_range
();
Prints footer information
virtual function void
print_header
();
Prints header
information
ovm_printer
Copyright 2008 by Doulos. All rights reserved. 101
virtual protected function void
print_id
(string id,
byte scope_separator=".");
Prints a fields name
virtual protected function void
print_newline
(
bit do_global_indent=1);
Prints a newline
virtual protected function void
print_size
(int size=-1);
Prints a fields size
virtual protected function void
print_type_name
(string name,
bit is_object=0);
Prints a fields type
virtual protected function void
print_value
(ovm_bitstream_t value,
int size,
radix_enum radix=OVM_NORADIX);
Prints an integral fields
value
virtual protected function void
print_value_array
(string value="",
int size=0);
Prints an arrays value
virtual protected function void
print_value_object
(
ovm_object value);
Prints a unique identifier
associated with an
object
virtual protected function void
print_value_string
(string value);
Prints a string field
(unless it is "-")
virtual protected function void
indent
(int depth,
string indent_str=" ");
Prints an indentation
(depth copies of
indent_str)
protected function void
write_stream
(string str);
Prints a string
; Handle to sequencer
executing this sequence
sequence 2
sequence 1
ovm_simple_sequence
ovm_exhaustive_sequence
ovm_random_sequence
sequence items
get_next_item(item)
item_done(item)
seq_item_port
ovm_sequencer
156 Copyright 2008 by Doulos. All rights reserved.
Declaration
class ovm_sequencer #(type REQ = ovm_sequence_item,
type RSP = REQ)
extends ovm_sequencer_param_base #(REQ, RSP);
typedef ovm_sequencer #(ovm_sequence_item)
ovm_virtual_sequencer;
typedef enum {SEQ_TYPE_REQ, SEQ_TYPE_LOCK, SEQ_TYPE_GRAB}
SEQ_REQ_TYPE;
typedef enum {SEQ_ARB_FIFO, SEQ_ARB_WEIGHTED,
SEQ_ARB_RANDOM, SEQ_ARB_STRICT_FIFO,
SEQ_ARB_STRICT_RANDOM, SEQ_ARB_USER}
SEQ_ARB_TYPE;
Methods
From ovm_sequencer_base:
function bit is_child(
ovm_sequence_base parent,
ovm_sequence_base child);
Returns 1 if child is
child of parent
task wait_for_grant(
ovm_sequence_base sequence_ptr,
integer item_priority = -1,
bit lock_request = 0);
Issues request for
sequence and waits
until granted
task wait_for_item_done(
ovm_sequence_base sequence_ptr,
integer transaction_id);
Waits until driver calls
item_done or put
function bit is_blocked(
ovm_sequence_base sequence_ptr);
Returns 1 if sequence
is blocked
function bit is_locked(
ovm_sequence_base sequence_ptr);
Returns 1 if sequence
is locked
task lock(
ovm_sequence_base sequence_ptr);
Requests a lock on
sequence
task grab(
ovm_sequence_base sequence_ptr);
Grants exclusive
access to the
sequencers action
queue, blocking all
other requests
function void unlock(
ovm_sequence_base sequence_ptr);
Removes locks from
sequence
ovm_sequencer
Copyright 2008 by Doulos. All rights reserved. 157
function void ungrab(
ovm_sequence_base sequence_ptr);
Releases exclusive
access to the
sequencers action
queue granted by
grab()
virtual function ovm_sequence_base
current_grabber();
Returns a reference to
the current grabbing
sequence, null if no
grabbing sequence
function void stop_sequences(); Kills all sequences
running on this
sequencer
virtual function bit is_grabbed(); Returns 1 if a
sequence is currently
grabbing exclusive
access, 0 if no
sequence is grabbing
function bit has_do_available(); Returns 1 if the
sequencer has an item
available for
immediate processing,
0 if no items are
available
function void set_arbitration(
SEQ_ARB_TYPE val);
Change the
arbitratrion mode
virtual function integer
user_priority_arbitration(
integer avail_sequences[$]);
Called if arbitration
mode =
SEQ_ARB_USER to
arbitrate between
sequences. Default
behavior is
SEQ_ARB_FIFO
virtual task wait_for_sequences(); User overridable task
used to introduce delta
delay cycles (default
100) , allowing
processes placing
items in the consumer
interface to complete
before the producer
interface retrieves the
items
function void add_sequence(
string type_name);
Add a sequence to the
sequence library
function void remove_sequence(
string type_name);
Remove a sequence
from the sequence
library
ovm_sequencer
158 Copyright 2008 by Doulos. All rights reserved.
function integer get_seq_kind(
string type_name);
Returns the integer
mapping of a
sequence in the
sequence library
specified by
type_name
function ovm_sequence_base
get_sequence(integer req_kind);
Creates a sequence of
the type located at the
specified integer
mapping in the
sequence library
function integer num_sequences(); Returns number of
sequences in
sequence library
virtual function void
send_request(
ovm_sequence_base sequence_ptr,
ovm_sequence_item t,
bit rerandomize = 0);
Sends a request to the
sequencer. May only
be called immediately
after
wait_for_grant
From ovm_sequencer_param_base:
function REQ get_current_item(); Returns the sequence
item being executed
function void put_response(RSP t); Put item in response
queue
task start_default_sequence(); Called by sequencer's
run task to start
default sequence
function int get_num_reqs_sent(); Returns number of
requests sent by
sequencer
function int get_num_rsps_received(); Returns number of
responses received by
sequencer
function void set_num_last_reqs(
int unsigned max);
Sets size of last
request buffer
(default=1,max=1024)
function int unsigned
get_num_last_reqs();
Gets size of last
requests buffer
function REQ last_req(
int unsigned n = 0);
Gets the last request
from the buffer (or
possition within buffer)
ovm_sequencer
Copyright 2008 by Doulos. All rights reserved. 159
function void set_num_last_rsps(
int unsigned max);
Sets size of last
response buffer
(default=1,max=1024)
function int unsigned
get_num_last_rsps();
Gets size of last
response buffer
function RSP last_rsp(
int unsigned n = 0);
Gets the last response
from the buffer (or
possition within buffer)
virtual task
execute_item(ovm_sequence_item item);
Execute a sequence
without adding it to the
library and ignoring
the response
From ovm_sequencer:
function new( string name,
ovm_component parent);
Constructor
virtual function string
get_type_name();
Returns
"ovm_sequencer"
virtual function void
send_request(
ovm_sequence_base sequence_ptr,
ovm_sequence_item t,
bit rerandomize = 0);
Sends a request to the
sequencer. May only
be called immediately
after
wait_for_grant
Members
From ovm_sequencer_base:
protected rand int seq_kind; Sequence id
string sequences[$]; Queue storing the
names of the available
sequences
protected string default_sequence
= "ovm_random_sequence";
Name of the sequence
the sequencer starts
automatically if the
count != 0
int count = -1; Integer value used by
the
ovm_random_sequen
ce to determine the
number of random
sequences to execute
if count = -1, then a
random number of
ovm_sequencer
160 Copyright 2008 by Doulos. All rights reserved.
sequences between 1
and
max_random_count
are selected
if count = 0, then the
default_sequence is
not started by
sequencer
if count > 0, then the
specified count of
random sequences
are selected
integer unsigned max_random_count=10; Max number of
selected sequences if
count = -1
int unsigned max_random_depth = 4; Depth of random
sequence
From ovm_sequencer_param_base:
ovm_analysis_export #(RSP)
rsp_export;
Analysis export that
may be used to send
responses to
sequencer
From ovm_sequencer:
ovm_seq_item_pull_imp #(REQ, RSP,
this_type) seq_item_export;
Sequence item export
(connects to driver)
Macros
Utility macros create the sequence library and/or register the sequencer with the
OVM factory.
(1)`ovm_sequencer_utils(SEQUENCER)
This macro provides the infrastructure required to build the sequencers
sequence library and utilize the random sequence selection interfaces. It adds
ovm_random_sequence, ovm_exhaustive_sequence, and
ovm_simple_sequence to the sequencers sequence library. It also calls
`ovm_component_utils(SEQUENCER).
(2)`ovm_sequencer_utils_begin(SEQUENCER)
`ovm_sequencer_utils_end
This is similar to`ovm_sequencer_utils, but
calls`ovm_component_utils_begin(SEQUENCER), and
ovm_sequencer
Copyright 2008 by Doulos. All rights reserved. 161
`ovm_component_utils_end. This allows the `ovm_field_* macros to be
called. For example,
`ovm_sequencer_utils_begin(my_sequencer, my_sequencer)
`ovm_field_int(status, OVM_ALL_ON)
...
`ovm_sequencer_utils_end
(3)`ovm_sequencer_param_utils(SEQUENCER)
`ovm_sequencer_param_utils_begin(SEQUENCER)
`ovm_sequencer_utils_end
These macros are provided for parameterized sequencers. They have the same
behavior as (1) and (2) except that they do not add a type name when they
register the sequencer with the factory.
(4) `ovm_update_sequence_lib_and_item(USER_ITEM_TYPE)
This macro populates the sequences[$] queue and builds the sequence
library with the ovm_random_sequence, ovm_exhaustive_sequence, and
ovm_simple_sequence. The USER_ITEM_TYPE defines the sequence item
type to be used with the ovm_simple_sequence.
This macro should only be used with a non-virtual sequencer and placed in its
constructor as follows:
function my_sequencer::new( string name = "",
ovm_component parent = null );
super.new( name, parent );
`ovm_update_sequence_lib_and_item( my_seq_item )
endfunction : new
(5) `ovm_update_sequence_lib
This macro populates the sequences[$] queue and builds the sequence
library with the ovm_random_sequence,
ovm_exhaustive_sequence. Unlike (4), it does not add
ovm_simple_sequence to the sequence library. It is used for virtual
sequencers that do not create sequence item directly (only by invoking
sequences on other sequencers). See Virtual Sequences
Example
// Define an ovm_sequence_item
typedef enum { read, write } dir_t;
class my_seq_item extends ovm_sequence_item;
bit [31:0] data;
bit [9:0] addr;
dir_t dir;
ovm_sequencer
162 Copyright 2008 by Doulos. All rights reserved.
// Register sequence item with the factory and add the
// field automation macros
`ovm_object_utils_begin( my_seq_item )
`ovm_field_int( data, OVM_ALL_ON )
`ovm_field_int( addr, OVM_ALL_ON )
`ovm_field_enum( dir_t, dir, OVM_ALL_ON )
`ovm_object_utils_end
endclass : my_seq_item
// Create the sequencer
class my_sequencer extends ovm_sequencer #(my_seq_item);
// Register the sequencer with the factory
`ovm_sequencer_utils ( my_sequencer )
function new ( string name = "my_sequencer",
ovm_component parent = null );
super.new ( name, parent );
// Create the sequence library
`ovm_update_sequence_lib_and_item ( my_seq_item )
endfunction : new
endclass : my_sequencer
// Connect the sequencer to the driver
class my_env extends ovm_env;
...
my_sequencer m_seqr;
my_driver m_drv;
function void connect;
// Hook up the sequencer to the driver
m_drv.seq_item_port.connect(m_seqr.seq_item_export);
endfunction : connect
...
endclass : my_env
Tips
Use set_config_string to set the default sequence that the sequencer
should execute. For example,
set_config_string( "*.intf_sequencer", //Sequencer name
ovm_sequencer
Copyright 2008 by Doulos. All rights reserved. 163
"default_sequence",
"my_seq" ); // New sequence
When in random mode, sequencers begin executing sequences
automatically based on the setting of default_sequence. Using
set_config_string simplifies a test case so that only the
default_sequence needs to be specified:
class read_write_test extends ovm_test;
... // register with factory, define constructor
// Only need build to define starting sequence
virtual function void build();
super.build();
// Specify the test sequence
set_config_string( "*.intf_sequencer",
"default_sequence",
"read_write_seq" );
// Create the environment for the test
m_env = my_env::type_id::create(...);
endfunction : build
endclass : read_write_test
Set the count to 0 using set_config_int if the test case only needs to
execute one specific sequence. For example,
// Execute only the "my_seq" sequence
set_config_string( "*", "default_sequence", "my_seq" );
set_config_int( "*.sequencer", "count", 0);
Gotchas
As of OVM 2.0, the ovm_sequencer implements only PULL mode,
meaning that the ovm_driver controls or pulls the sequence items from
the sequencer. For the sequencer to control the interaction (i.e., PUSH
mode), user modifications are required.
By default, a sequencer will execute the ovm_random_sequence, which is
a random selection of sequences from the sequencers sequence library.
The number of sequences executed will be between 1 and
max_random_count (default 10). These sequences will execute in
addition to the test case sequence unless count is set to 0 and the
default_sequence is set to a sequence test sequence (see examples
above in Tips section).
ovm_sequencer
164 Copyright 2008 by Doulos. All rights reserved.
See also
Sequence, Virtual Sequences, ovm_sequence, ovm_sequence_item, Special
Sequences, ovm_driver, Sequence Action Macros, Sequencer Interface and
Ports
Sequencer Interface and Ports
Copyright 2008 by Doulos. All rights reserved. 165
In OVM, the passing of transactions between sequencers and drivers happens
through a sequencer interface export/port pair. A sequencer producing items or
sequences contains a sequence item export and a driver consuming items or
sequences contains a sequence item port.
The OVM library provides an interface class and an associated export and port
to handle the communication between sequencers and drivers. The interface is
defined by class sqr_if_base.
An instance of class ovm_seq_item_pull_port named
ovm_seq_item_port is a member of ovm_driver. It enables the driver to
call interface methods such as get_next_item and item_done, which pull
sequence items from the sequencers item queue.
An instance of class ovm_seq_item_pull_imp named
ovm_seq_item_export is a member of ovm_sequencer. It provides the
implementation of the sequencer interface methods which manage the queuing
of sequence items and sequencer synchronization.
Declarations
virtual class sqr_if_base #(type T1=ovm_object, T2=T1);
class ovm_seq_item_pull_port #(type REQ=int, type RSP=REQ)
extends ovm_port_base #(sqr_if_base #(REQ, RSP));
class ovm_seq_item_pull_export #(type REQ=int,
type RSP=REQ)
extends ovm_port_base #(sqr_if_base #(REQ, RSP));
class ovm_seq_item_pull_imp #(type REQ=int,
type RSP=REQ, type IMP=int)
extends ovm_port_base #(sqr_if_base #(REQ, RSP));
Methods
sqr_if_base
virtual task get_next_item(
output T1 t);
Blocks until an item is
returned from the
sequencer
virtual task try_next_item(
output T1 t);
Returns immediately an
item if available,
otherwise, null
virtual function void item_done(
input T2 t = null);
Indicates to the
sequencer that the
driver is done
processing the item
Sequencer Interface and Ports
166 Copyright 2008 by Doulos. All rights reserved.
virtual task wait_for_sequences(); Calls the
wait_for_sequences
task of the connected
sequencer (see
ovm_sequencer)
virtual function bit
has_do_available();
Returns 1 if item is
available, 0 if no item
available
virtual function void
put_response(input T2 t);
Puts a response into the
sequencer queue
virtual task get(output T1 t); Blocks until item is
returned from
sequencer. Call
item_done before
returning.
virtual task peek(output T1 t); Blocks until item is
returned from
sequencer. Does not
remove item from
sequencer fifo
virtual task put(input T2 t); Sends response back to
sequencer
ovm_seq_item_pull_port
function new (string name,
ovm_component parent,
int min_size=0, int max_size=1);
Constructor
Plus implementation of sqr_if_base methods
ovm_seq_item_pull_export
function new (string name,
ovm_component parent,
int min_size=0, int max_size=1);
Constructor
Plus implementation of sqr_if_base methods
ovm_seq_item_pull_imp
function new (string name,
ovm_component parent,
int min_size=0, int max_size=1);
Constructor
Plus implementation of sqr_if_base methods
Sequencer Interface and Ports
Copyright 2008 by Doulos. All rights reserved. 167
Example
//
// Demonstrate the use of ovm_seq_item_pull_port and
// ovm_seq_item_pull_imp between a driver and sequencer
//
class my_driver extends ovm_driver #(my_trans);
...
task run();
forever begin
// Pull a sequence item from the interface
seq_item_port.get_next_item( req );
... // Apply transaction to DUT interface
// Indicate that item is done
seq_item_port.item_done( rsp );
end
endtask : run
endclass : my_driver
// Connect the sequencer and driver together
class my_env extend ovm_env;
...
function void connect;
my_drv.seq_item_port.connect(
my_seqr.seq_item_export );
endfunction : connect
endclass : my_env
Tips
A driver can call get_next_item multiple times before indicating item_done
to the sequencer (in other words, there is no one-to-one correspondence of
function calls).
See also
ovm_driver, ovm_sequencer, Virtual Sequences, ovm_sequence
Special Sequences
168 Copyright 2008 by Doulos. All rights reserved.
OVM defines several special sequences that are created automatically using the
sequencer macros. When `ovm_update_sequence_lib or
`ovm_update_sequence_lib_and_item(USER_ITEM) are declared in a
sequencer, the sequence library is populated with ovm_random_sequence and
ovm_exhaustive_sequence. Both special sequences operate on all the
other sequences in the sequencers sequence library (excluding each other).
For example, ovm_random_sequence randomly selects a number of
sequences between count and max_random_count (see ovm_sequencer).
The ovm_exhaustive_sequence randomly executes all of the sequences in
the sequencers sequence library.
A third special sequence is available that executes a single randomized
sequence item called ovm_simple_sequence. The ovm_simple_sequence
is not used by virtual sequencers since virtual sequencers do not operate on
sequence items. The `ovm_update_sequence_lib_and_item(
USER_ITEM) macro adds this special sequence to a regular sequencers library
and registers the USER_ITEM as its default sequence item type.
Each sequencers or virtual sequencers default_sequence variable is set by
default to ovm_random_sequence. On startup, each sequencer executes the
sequence assigned to default_sequence, provided its count variable is not
set to 0. Therefore, by default, a sequencer will automatically start executing
the ovm_random_sequence sequence even if nothing else is specified.
Declaration
class ovm_random_sequence
extends ovm_sequence #(ovm_sequence_item);;
class ovm_exhaustive_sequence
extends ovm_sequence #(ovm_sequence_item);;
class ovm_simple_sequence
extends ovm_sequence #(ovm_sequence_item);;
Methods
ovm_random_sequence
function new(
string name ="ovm_random_sequence");
Constructor
ovm_exhaustive_sequence
function new(
string name="ovm_exhaustive_sequence");
Constructor
Special Sequences
Copyright 2008 by Doulos. All rights reserved. 169
ovm_simple_sequence
function new(
string name="ovm_simple_sequence");
Constructor
Example
// Use the ovm_exhaustive_sequence in an exhaustive test
class exhaustive_test extends ovm_test;
...
task run();
// Set all sequencers to exhaustively execute all
// sequences in every sequencers library
set_config_string( "*",
"default_sequence",
"ovm_exhaustive_sequence");
endtask : run
endclass : exhaustive_test
Tips
Use set_config_string to override the default_sequence of a
sequencer in order to the specify a specific test sequence.
Use set_config_int to override count and max_random_count to
control the behavior of the ovm_random_sequence sequence..
Gotchas
By default, the ovm_random_sequence will execute even if a test case
executes another set of sequences. In cases where this is not desired, set
the sequencers count to 0 and default_sequence to the test
sequence.
Take care not to use `ovm_update_sequence_lib_and_item(
USER_TYPE) in a virtual sequencer since it adds ovm_simple_sequence
to the virtual sequencers sequence library. No ovm_simple_sequence
should be defined for a virtual sequencer since virtual sequencers do not
operate on sequence items.
See also
Sequences, ovm_sequence, ovm_sequencer, Virtual Sequences
ovm_subscriber
170 Copyright 2008 by Doulos. All rights reserved.
ovm_subscriber is a convenient base class for a user-defined subscriber (an
analysis component that will receive transaction data from another component's
analysis port).
A subscriber that is derived from ovm_subscriber must override its inherited
write method, which will be called automatically whenever a transaction data
item is written to a connected analysis port. The analysis_export member of
a subscriber instance should be connected to the analysis port that produces the
data (typically on a monitor or other verification component).
Declaration
virtual class ovm_subscriber #(type T = int)
extends ovm_component;
Methods
function new( string name,
ovm_component parent);
Constructor
pure virtual function void write(
transaction_type t);
Override this method to
implement your subscriber's
behavior when it receives a
transaction data item
Members
ovm_analysis_imp
#(transaction_type, this_type)
analysis_export;
Implementation of an
analysis export, ready for
connection to an analysis
port
ovm_subscriber
Copyright 2008 by Doulos. All rights reserved. 171
Example
// Define a specialized subscriber class. This class does nothing except to
// report all transactions it receives.
class example_subscriber extends
ovm_subscriber #(example_transaction);
int transaction_count;
function new(string name, ovm_component parent);
super.new(name, parent);
endfunction
function void write (example_transaction t);
ovm_report_info("WRITE", $psprintf(
"Received transaction number %0d:\n%s",
transaction_count++, t.sprint() ) );
endfunction
endclass
// In the enclosing environment class:
class subscriber_test_env extends ovm_env;
example_subscriber m_subscriber;
example_monitor m_monitor; // see article ovm_monitor
...
function void build();
...
$cast ( m_monitor,
create_component("example_monitor",
"m_monitor") );
$cast ( m_subscriber,
create_component("example_subscriber",
"m_subscriber") );
...
endfunction
function void connect();
// Connect monitor's analysis port (requires)
// to subscriber's export (provides)
m_monitor.monitor_ap.connect (
m_subscriber.analysis_export );
endfunction
...
endclass
ovm_subscriber
172 Copyright 2008 by Doulos. All rights reserved.
Tips
Use ovm_subscriber as the base for any custom class that needs to
monitor a single stream of transactions. Typical uses include coverage
collection, protocol checking, or data logging to a file. It is not appropriate
for end-to-end checkers, since these typically need to monitor transaction
streams from more than one analysis port (see Gotchas below). For such
applications, one of the built-in comparator components such as
ovm_in_order_class_comparator or
ovm_algorithmic_comparator may be appropriate.
Gotchas
Unless one of the built-in comparator components meets your need, a
component that needs to subscribe to more than one analysis port must be
created as a specialized extension of ovm_component, with a separate
ovm_analysis_export for connection to each analysis port that will
provide data. Classes derived from ovm_subscriber are applicable only
for monitoring the output from a single analysis port (but note that a custom
comparator could contain multiple subscriber members that implement the
write function for each of its analysis_exports).
The argument for the overridden write function MUST be named "t".
See also
ovm_in_order_*_comparator, ovm_analysis_export
ovm_test
Copyright 2008 by Doulos. All rights reserved. 173
A class derived from ovm_test should be used to represent each test case. A
test will create and configure the environment(s) required to verify particular
features of the device under test (DUT). There will typically be multiple test
classes associated with a testbench: a single test object is created from one of
these at the start of each simulation run. This approach separates the testbench
from individual test cases and improves its reusability. ovm_test is itself
derived from ovm_component so a test may include a run task. A test class is
sometimes defined, but never explicitly instantiated, in the top-level testbench
module (a test class cannot be defined in a package if it needs to include
hierarchical references).
The ovm_top.run_test task or the global run_test task is called from an
initial block in the top-level testbench module to instantiate a test (using the
factory) and then run it (run_test is a wrapper that calls
ovm_top.run_test.)
The tests build method creates the top-level environment(s).
The simulators command-line plusarg +OVM_TESTNAME=testname specifies
the name of the test to run (a name is associated with a test by registering the
test class with the factory). If this plusarg is not used, then the test_name
argument of run_test may be used to specify the test name instead. If no test
name is given, a default test that does nothing will be run and no environment
will be created.
Configuration and/or factory overrides may be used within the test to customize
a reusable test environment (or any of its components) without having to modify
the environment code.
Declaration
virtual class ovm_test extends ovm_component
Methods
function new ( string name,
ovm_component parent);
Constructor
Also, inherited methods, including build, configure, connect, run
ovm_test
174 Copyright 2008 by Doulos. All rights reserved.
Example
This example shows a test being defined and run from a top-level module.
module top;
class test1 extends ovm_test;
...
function void build();
// Create environment
endfunction: build
function void connect();
// Connect test environments virtual interface to the DUTs interface
m_env.m_mon.m_bus_if = tf.cpu_if.mon;
endfunction: connect
task run();
// Call methods in environment to control test (optional)
endtask: run
// Register test with factory
`ovm_component_utils(test1)
endclass: test1
initial begin
run_test("test1"); // Use test1 by default
// Can override using +OVM_TESTNAME
end
// Contains DUT, DUT interface, clock/reset, ancillary modules etc.
test_harness tf ();
endmodule
Tips
Write a new test class for each test case in your verification plan.
Keep the test classes simple: functionality that is required for every test
should be part of the testbench and not repeated in every test class.
It is a good idea to start with a "default" test that provides random stimulus
before spending time developing more directed tests.
ovm_test
Copyright 2008 by Doulos. All rights reserved. 175
Use the connect method to connect the virtual interface in the driver to the
DUTs interface.
If you want to declare a test in a package, you will need to wrap the DUTs
interface in a class (as described in the Virtual Interface Wrapper article).
By doing this, you will avoid using hierarchical names in the test.
The name of the test instance is ovm_test_top.
Gotchas
Do not forget to register the test with the factory, using
`ovm_component_utils.
Do not call the set_inst_override member function (inherited from
ovm_component) for a top-level test.
See also
ovm_env, Configuration, Virtual Interface Wrapper, ovm_factory
tlm_analysis_fifo
176 Copyright 2008 by Doulos. All rights reserved.
Class tlm_analysis_fifo is provided for use as part of an analysis
component that expects to receive its data from an analysis port. It is derived
from tlm_fifo and adds a write member function. Only the methods directly
relevant to analysis FIFOs are described here; for full details, consult the article
on tlm_fifo.
The "put" end of an analysis FIFO is intended to be written-to by an analysis
port. Consequently, an analysis FIFO is invariably set up to have unbounded
depth so that it can never block on write. The FIFO's try_put method is
re-packaged as a write function, which is then exposed through an
analysis_export that can in its turn be connected to an analysis_port on
a producer component. The get_export (or similar) at the other end of the
FIFO is typically connected to an analysis component, such as a scoreboard,
that may need to wait for other data before it is able to process the FIFO's
output.
The type of data carried by the analysis FIFO is set by a type parameter.
Declaration
class tlm_analysis_fifo #(type T=int)extends tlm_fifo #(T);
Methods
function new(string name,
ovm_component parent = null);
Constructor
function void write(input T t); Puts transaction on to the
FIFO; cannot block (FIFO
is unbounded)
function void flush() ; Clears FIFO contents
task get(output T t); Blocks if the FIFO is
empty
function bit try_get(output T t); Returns 0 if FIFO empty
function bit try_peek(output T t); Returns 0 if FIFO empty
function bit try_put(input T t); Returns 0 if FIFO full
function int used(); number of items in FIFO
function bit is_empty(); returns 1 if FIFO empty
Members
ovm_analysis_imp
#(T, tlm_analysis_fifo #(T))
analysis_export;
For connection to an
analysis port on another
component.
tlm_analysis_fifo
Copyright 2008 by Doulos. All rights reserved. 177
blocking_get_export
;
nonblocking_get_export
;
get_export
;
Exports blocking/non-
blocking/combined get
interface
blocking_peek_export
;
nonblocking_peek_export
;
peek_export
;
Exports blocking/non-
blocking/combined peek
interface
blocking_get_peek_export
;
nonblocking_get_peek_export
;
get_peek_export
;
Exports blocking/non-
blocking/combined
get_peek interface
ovm_analysis_port #( T ) put_ap;
ovm_analysis_port #( T ) get_ap;
Analysis ports
;
nonblocking_put_export
;
put_export
;
Exports blocking/non-
blocking/combined put
interface
blocking_get_export
;
nonblocking_get_export
;
get_export
;
Exports blocking/non-
blocking/combined get
interface
blocking_peek_export
;
nonblocking_peek_export
;
peek_export
;
Exports blocking/non-
blocking/combined peek
interface
blocking_get_peek_export
;
nonblocking_get_peek_export
;
get_peek_export
;
Exports blocking/non-
blocking/combined get_peek
interface
ovm_analysis_port #( T )
put_ap;
ovm_analysis_port #( T )
get_ap;
Analysis ports