Documente Academic
Documente Profesional
Documente Cultură
Product Incisive® Plan-to-Closure Methodology contains technology licensed from, and copyrighted by: Open SystemC
Initiative, Inc. and is © 1996-2006 by all contributors, all rights reserved; (c) 2007-2008 Cadence Design Systems, Inc., and
(c) 2007-2008 Mentor Graphics, Inc., all rights reserved. Associated Apache license terms may be found at
$SOCV_KIT_HOME/.
Trademarks: Trademarks and service marks of Cadence Design Systems, Inc. contained in this document are attributed to
Cadence with the appropriate symbol. For queries regarding Cadence’s trademarks, contact the corporate legal department at
the address shown above or call 800.862.4522. All other trademarks are the property of their respective holders.
Restricted Permission: This publication is protected by copyright law and international treaties and contains trade secrets and
proprietary information owned by Cadence. Unauthorized reproduction or distribution of this publication, or any portion of it,
may result in civil and criminal penalties. Except as specified in this permission statement, this publication may not be copied,
reproduced, modified, published, uploaded, posted, transmitted, or distributed in any way, without prior written permission
from Cadence. Unless otherwise agreed to by Cadence in writing, this statement grants Cadence customers permission to print
one (1) hard copy of this publication subject to the following conditions:
1. The publication may be used only in accordance with a written agreement between Cadence and its customer;
2. The publication may not be modified in any way;
3. Any authorized copy of the publication or portion thereof must include all original copyright, trademark, and other
proprietary notices and this permission statement;
4. The information contained in this document cannot be used in the development of like products or software, whether
for internal or external use, and shall not be used for the benefit of any other party, whether or not for consideration
Disclaimer: Information in this publication is subject to change without notice and does not represent a commitment on the
part of Cadence. Except as may be explicitly set forth in such agreement, Cadence does not make, and expressly disclaims, any
representations or warranties as to the completeness, accuracy or usefulness of the information contained in this document.
Cadence does not warrant that use of such information will not infringe any third party rights, nor does Cadence assume any
liability for damages or costs of any kind that may result from use of such information.
Restricted Rights: Use, duplication, or disclosure by the Government is subject to restrictions as set forth in FAR52.227-14
and DFAR252.227-7013 et seq. or its successor.
Terms of Use: Permission to internally use, modify, or distribute these source code files is hereby granted, provided that the
following conditions are met:
Customers may only modify or use this material for internal purposes related to integrated circuit design within Cadence's
design and verification environment. Customer shall not (1) copy this material except to the extent necessary to fulfill the
purpose stated above; (2) distribute this material to any third party without express written permission from Cadence; (3) allow
this material to be accessed or used by third parties or anyone other than customer's employees whose duties require such access
or use; or (4) distribute these materials for profit or commercial advantage.
Subject to compliance with the terms and conditions herein and the agreement under which this material is provided (the
“Agreement”), Cadence agrees to provide, or have provided, Maintenance Service as defined in the Agreement for the Term of
Use specified in the Agreement.
THIS SOFTWARE IS PROVIDED “AS IS” COMPLETELY WITHOUT ANY WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS ARE DISCLAIMED.
IN NO EVENT SHALL CADENCE BE LIABLE FOR ANY CLAIMS OR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, PROFITS, OR BUSINESS INTERRUPTION)
HOWEVER CAUSED, OR ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Contents
The utilities for building multi-language verification Chapter 2 “Multi-Language UVM (ML-UVM)
environments, where some Universal Verification Features for e and SystemVerilog”
Components (UVCs) are implemented in e and others
in SystemVerilog
About the API that lets you send sequences from a Chapter 3 “Using SystemVerilog Sequences
top-level e test to be run by a SystemVerilog in an e Testbench”
component
irun invocation commands and utilities for Chapter 4 “Multi-Language UVM (ML-UVM)
Multi-Langue UVM Reference”
How to build a UVM-compliant interface for a UVC Chapter 5 “UVM Interface Generator (UIG)
Reference”
How to generate data types between different Chapter 6 “mltypemap Utility: Automatic
languages Generation of Data Types”
About the interface between e and SystemC using Chapter 7 “Multi-Language TLM 2.0”
TLM 2.0
Typeface Represents
courier font Indicates code. For example:
do burst_response keeping {
courier bold Used to highlight important sections of code, like actions. For example:
do burst_response keeping {
Also used to identify user input. The following example indicates that the
user enters the command “demo.sh -h”, in response to which the system
displays the command options for demo.sh:
% demo.sh –h
Usage: demo.sh -h[elp] [-test_case <test_name>]
[-seed <seed number>]
[-run_mode batch]
bold The bold font indicates keywords in descriptive text. For example, the
following sentence contains keywords for the show ini command and the
get_symbol() routine:
You can display these settings with the show ini setting command or
retrieve them within e code with the get_symbol() routine.
italic The italic font represents user-defined variables that you must provide.
For example, the following line defining the syntax for the command
option “-seed” instructs you to type “-seed” as it appears, and then the
actual seed number:
-seed seed_number
[ ] square brackets Square brackets indicate optional parameters. For example, in the
following construct the keywords “list of” are optional:
[ ] bold brackets Bold square brackets are required. For example, in the following construct
you must type the bold square brackets as they appear:
Typeface Represents
cmd-prompt> Denotes the prompt for the Cadence tool you are running, for example,
Incisive® Design Team Simulator or Incisive® Enterprise Specman
Simulator.
Each UVC must be instantiated and configured appropriately according to its part within the overall
verification environment. The UVCs together form a logical multi-language hierarchy, which in
turn must be mapped to several disjoint trees of UVCs, each tree being in its own language domain.
● Synchronized elaboration
Each of the supported verification languages defines its own elaboration phases. These phases must
be synchronized to let the various parts of the verification environment be constructed and
connected in a coordinated fashion. For example, binding communication ports between e and
SystemVerilog UVCs can only occur once the SystemVerilog hierarchy has been created, which
happens only after simulation begins.
● Passing of data across language boundaries
The UVCs comprising the verification environment must be able to exchange information, usually
in the form of transactions. Transaction Level Modeling (TLM) interfaces provide a standard and
common approach for such communication schemes. However, when the UVCs are implemented in
different languages, it must be possible to connect TLM interfaces across language boundaries.
Notes
● The Multi-Language UVM (ML-UVM) features support SystemC. However, this chapter focuses
on e and SystemVerilog UVCs. For more information on using SystemC models in a multi-language
environment, see Chapter 8 “SystemC in Mixed-Language UVM”.
● The ML-UVM features are supported only with the UVM SystemVerilog class library included with
IES and IES-XL. The open-source version of the class library (available from
http://www.uvmworld.org) cannot be used with the ML-UVM features, as it does not include the
necessary hooks.
Taking an existing SystemVerilog environment built on top of the open source class library and
running it with the class library in IES is trivial, as the later is a fully compatible superset of the
open-source library.
● This chapter does not cover approaches where an API layer is created for a given UVC in a different
language than the UVC’s core implementation. Unlike the true multi-language approach described
in this document, creating an API layer hides to some extent the core implementation of the UVC.
The API layer makes the UVC look-and-feel as if natively written in the API layer’s language. For
example, a UVC implemented in e can have a SystemVerilog API layer, allowing it to be used just
as a native SystemVerilog UVC. For more information on this alternative approach, see
“SystemVerilog Class Based over e” in the UVM Multi-Language Methodology.
See Also
● The irun Command chapter of the irun User Guide, available with IES-L and IES-XL.
The current release of ML-UVM supports only the parallel trees approach. In absence of support for the
single multi-language tree, parallel trees can be used as a workaround for the logical hierarchy by
ordering the independent trees. The parallel trees have separate topmost components, but they may
communicate via TLM ports.
Figure 2-1 on page 2-4 shows a simple multi-language verification environment consisting of e and
SystemVerilog UVCs. The logical tree on the left represents the logical hierarchy of the UVCs, as we
would like to think about it. The very top is an e test that configures and controls an e module UVC. A
module UVC verifies a module-level or cluster-level DUT and would typically control several interface
UVCs. Each interface UVC connects to one interface of the DUT, like an Ethernet port, AHB, USB or
any other standard or proprietary protocol. In the diagram, the e module UVC controls two
SystemVerilog interface UVCs to actually drive the DUT signals.
e test Language
Boundary
e top SV tops
Module e test
UVC (e) Interface
UVC (SV)
Interface
UVC (SV) DUT
TLM Communication
Signal-level
Communication Legend
e
DUT SV
Unlike the logical tree, from an implementation perspective this environment must actually be
represented by two single-language trees each operating in its own language domain. The right side of
the figure shows the e domain containing the e test and the module UVC with the e test as a top entity.
Similarly, the SystemVerilog interface UVC instances are top entities in the SystemVerilog domain. The
data communication between the UVCs in both cases is shown as TLM-based communication.
1. The test is instantiated first, and goes through each of the elaboration phases first, before any other
top entities.
2. In SystemVerilog, the test instance will always have a fixed name – uvm_test_top – as in pure
SystemVerilog UVM environments. This consistent naming ensures that other parts in the
verification environment can access components in SystemVerilog with a full path that is fixed for
all the tests associated with a specific configuration. In addition, consistent test instance name
enables merging coverage results from simulations with different tests.
The other top entities declared on the irun command line using -uvmtop switches are built according to
the order in which they are specified. The exact same order applies to the other elaboration phases (e.g.
connect).
For details on the elaboration flow with multiple top entities, see “Synchronized Elaboration Phases” on
page 2-7.
module top_module;
import uvm_pkg::*;
import ml_uvm::*; // Required for ML-UVM
...
The e test file itself is identical to a test file in a pure-e environment. It does not require any additional
logic to support ML-UVM.
Note Make sure to import the ml_uvm package from within a module, or another package, and
not in the compilation unit scope.
● Do not specify the UVM package file on the irun command line.
With the use of -uvmtop, irun will automatically compile the UVM and ml_uvm SystemVerilog
packages in a separate compilation step.
● pre_generate()
● post_generate()
● connect_pointers()
● connect_ports()
● check_generation()
● run()
● build_phase()
● connect_phase()
● end_of_elaboration_phase()
● start_of_simulation_phase()
The SystemC LRM defines the following initial phases of the static components:
● end_of_construction()
● end_of_elaboration()
● start_of_simulation()
Note All of the phases, except the run phase in UVM SystemVerilog, are non-blocking (cannot
consume simulation time).
See Also
● “Test Phase Flow” in the Specman e Language Reference
● “Simulation Phase Methods” in the UVM User Guide
● “Callback Phases” in the SystemC Language Reference, and “Methodology for Hierarchy
Construction” in the SystemC Library Reference
This is not sufficient to support multi-language environments. For example, consider an environment
with both e and SystemVerilog components. If a top test entity in e is used, the e portions must be
elaborated first, followed by the SystemVerilog portions. However, with a similar environment using a
SystemVerilog top test entity, the opposite order is used: SystemVerilog portions elaborated first,
followed by the e portions.
Despite the terminology and naming differences, the language-specific phases have much in common.
ML-UVM establishes the correspondence between the phases and provides a mechanism that
synchronizes them at run time. The synchronization is achieved by interleaving the invocation of the
existing phases in all languages. Each logical phase is executed for all quasi-static components of the
testbench, regardless of the component’s language of implementation. Figure 2-2 on page 2-9 shows the
synchronization of phases across the different languages supported by ML-UVM.
SystemC e UVM SV
end_of_construction()
end_of_construction pre_generate(), build_phase()
post_generate()
connect_pointers(), connect_phase()
connect_ports()
The order of execution of the phases at the same level (for example, end_of_construction in SystemC, e
generation, and build in UVM SystemVerilog) is controlled by users according to the order of -uvmtop
command line switches. This does not depend on the language itself.
● Explicit top entities are those defined using the -uvmtop command line switch.
● Implicit top entities are those that exist by default (for example sys in e) or are created procedurally
in the testbench, with no parent in their language domain. For example, in SystemVerilog you might
have a uvm_component instance with a null parent that was created using a static initializer.
ML-UVM invokes the phases in explicit top entities and their children in the order in which their
respective -uvmtop switches were specified. Once all explicit top entities have gone through a certain
phase, ML-UVM invokes the same phase in all implicit top entities.
The order of phase invocation in implicit top entities matches their instantiation order within each
language domain. The order between language domains is arbitrary.
● As a single top entity, the entire e testbench goes through each of the elaboration phases at once.
● If you specify an e test file as a top entity using -uvmtop, its order relative to other -uvmtop switches
determines when the e testbench goes through its phases.
● If you do not have an e test file, like other implicit top entities the e testbench will go through its
phases last, after all other explicit top entities.
Example
Consider an environment that specifies three explicit top entities:
% irun -uvmtest SV:sv_test \
-uvmtop e:test.e \
-uvmtop SV:sv_env ...
Based on the order of explicit top entities, ML-UVM invokes the elaboration phases in the following
order:
1. Build:
2. Connect:
3. Check:
ML-UVM obsoletes both of the above by implementing an automated mechanism to trigger the phases
in all supported languages. The appropriate time to execute the quasi-static testbench phases is at the
beginning of simulation, before any concurrent design processes. Such timing enables execution of the
procedural code for phases in all languages (construction of testbench components, connection of ports,
initialization of stimuli, and so on). It avoids race conditions between testbench elaboration and the
DUT.
ML-UVM takes care of instantiating and starting the quasi-static elaboration phases. This occurs at the
following point in simulation time zero:
● After the TCL run command has been entered at the ncsim prompt (or after the run command in
batch mode)
● After static initialization of the DUT and the testbench, including initialization of HDL variable
declarations and initialization of static SystemVerilog class members
● Before execution of any DUT processes, including SystemVerilog initial blocks
Execution of the testbench threads in the other languages (e and SystemC) happens as before, because
they are not synchronized with any phase.
initial begin
// configure the virtual interface in the testbench class
uvm_config_db#(virtual my_interface)::set(null, "*_tb", "vif", intf_0);
run_test();
end
endmodule
Note The above code will not work with ML-UVM. With ML-UVM, all the SV top
components—including the test, if used—are constructed before any initial blocks are executed. As a
result, the configuration call will occur too late, and thus will not have the desired effect. Furthermore,
it's likely that checks inside the testbench, which ensure that a virtual interface was properly configured,
will fire during one of the elaboration phases before the initial block even executes. In addition, the code
invokes run_test(), which is redundant (a warning message will be printed) because ML-UVM takes
care of it already.
To accommodate ML-UVM, you need to change your testbench by eliminating any configuration done
inside initial blocks. The same logic should be moved into a function of the module, which should be
called during initialization of a new auxiliary variable in the same module.
The following code shows the above example modified to work properly with ML-UVM:
// Modified example for ML-UVM
// This code will work with ML-UVM
module top;
...
// interface instance
my_interface intf_0();
return 1;
endfunction
set_config* and Move into build() Do not use set_config* or uvm_config_db calls
uvm_config_db# calls functions of top inside initial blocks. They will not have any effect
inside initial blocks component(s), or a since with ML-UVM elaboration phases are
function called invoked (and the SV component hierarchy fully
during initialization built) before any initial blocks are executed.
Instead, move the set_config* calls to the build()
hook of one of your top SV components. If you
are trying to configure virtual interfaces from
within the an initial block, see the section “Using
the UVM-SV Configuration Database” on page
2-11.
Tip If you mistakenly use the +UVM_TESTNAME command line option along with ML-UVM, the
following error is issued at run-time:
UVM_FATAL @ 0: uvm_test_top [ILLCRT] It is illegal to create a component
once phasing reaches end_of_elaboration. The current phase is
start_of_simulation.
‘include "uvm_macros.svh"
module top;
import uvm_pkg::*;
import ml_uvm::*;
endmodule
The main purpose of the above code is to print a message when the component goes through its main
elaboration phases (build and connect).
pre_generate() is also {
message(LOW, "In pre_generate!");
};
connect_ports() is also {
message(LOW, "In connect_ports!");
};
};
extend sys {
my_e_top: my_e_top_u is instance;
};
’>
You can now use both the e test file and the SystemVerilog component that were defined as top entities
to be instantiated by ML-UVM.
The order of top entities on the command line determines the order in which entities are instantiated and
elaborated by ML-UVM. Therefore, the e testbench should be first in each elaboration phase, followed
by the SystemVerilog components. The simulation log file shows:
ncsim> run
Loading test.e ...
read...parse...update...patch...h code...code...clean...
[0] hier=my_sv_env: SV env created!
Doing setup ...
Generating the test using seed 1...
[0] E_ENV: In pre_generate!
[0] hier=my_sv_env: SV env in build phase!
[0] E_ENV: In connect_ports!
[0] hier=my_sv_env: SV env in connect phase!
As you can see in the last four lines in the log, elaboration is performed in the expected order:
1. The e environment goes through pre-run generation (shown by the E_ENV printout in the
pre_generate() phase).
2. The SystemVerilog portion is built next (shown by the printout from the SystemVerilog env going
through build_phase() ).
3. Port connection in e takes place (shown by the E_ENV printout in the connect_ports() phase).
4. Port connection in SystemVerilog follows (shown by the printout from the SystemVerilog env going
through connect_phase() ).
This time, the SystemVerilog entity should be built first, followed by the e environment. The simulation
log file now shows:
ncsim> run
[0] hier=my_sv_env: SV env created!
Loading test.e ...
read...parse...update...patch...h code...code...clean...
[0] hier=my_sv_env: SV env in build phase!
As seen in the last six lines in the log, the elaboration is performed in the expected order:
1. The SystemVerilog portion is built first (shown by the printout from the SystemVerilog env going
through build_phase()).
2. The e environment goes through pre-run generation next (shown by the E_ENV printout in the
pre_generate() phase).
3. Port connection in SystemVerilog takes place (shown by the printout from the SystemVerilog env
going through connect_phase()).
4. Port connection in e follows (shown by the E_ENV printout in the connect_ports() phase).
#!/bin/sh
UVM_HOME=`ncroot`/tools/uvm
ML_UVM_SRC=`ncroot`/tools/uvm/ml
ncvlog \
-messages \
-sv \
-incdir ${UVM_HOME}/src \
${UVM_HOME}/src/uvm_macros.svh \
${UVM_HOME}/src/uvm_pkg.sv \
${ML_UVM_SRC}/ml_uvm_pkg.sv \
top.sv \
specman.sv \
-nowarn PMBDVX \
-nowarn ENUMERR
ncelab \
-messages \
worklib.top \
worklib.specman \
-access +rw
ncsim \
-messages \
-uvmtest sv:my_sv_env \
-uvmtop e:test.e \
-input sn_cmds.tcl \
worklib.top:module
● Method ports allow binding a single e method to a SV/SC function or task. A TLM interface
encapsulates a number of related functions and tasks.
● Method ports are e-specific. They support binding on the e side only. Multi-language TLM ports can
be instantiated and bound in any supported language.
● External method ports require generation of glue SystemVerilog or SystemC code (known as the
stubs file). Implementation of multi-language TLM ports is generic. It does not require additional
code generation.
● An input e method port is associated with a global SystemVerilog or SystemC function/task, which
requires a special unit mapping logic to support multiple instances. The connection of multi-language
TLM ports is natively done by instance.
● The mltypemap utility can be used to generate data types in a target language based on data types in
a source language. These data types can then be used as data types in ML UVM transactions using
ML UVM TLM ports.
● Sequence items — Generated by one component and needing to be driven to the DUT by another
● Monitor transactions — Collected by a monitor and broadcast to other components for checking
and coverage collection
Passing an object across a language boundary requires the ability to map an object of a given type
in one language domain to a completely different class type in the other language domain. Past
attempts to enable such communication required adding significant amounts of manually-created
code. The extra code managed the packing and unpacking of objects to a binary form that would
then be passed across the language boundary. The same functionality is better handled by the
underlying engines in each language, reducing dramatically the potential for user error and
maintenance effort over time.
The ML-UVM features added to the underlying tools in IES-XL address the above requirements as
described in the following sections.
Note In SystemVerilog and SystemC, the ML-UVM utilities should be used instead of the built-in
utilities in the respective language or UVM library implementation.
See Also
● “Executing Specman Code Asynchronously” in the Specman Integrators Guide contains information
about working in mixed verification environments and using timeless models where Specman is often
called asynchronously.
For more information on the e utilities, see “Using e TLM Interface Ports” in the Specman Testbench
Integrators Guide. The SystemVerilog utilities are described in this document. For more information on
the SystemC utilities, see Chapter 8 “SystemC in Mixed-Language UVM”.
2. Make sure that the SystemVerilog ports/implementations to which you are connecting have been
registered with ML-UVM using a call to the ml_uvm::external_if() SystemVerilog function. If
needed, you may add calls to ml_uvm::external_if() in your SystemVerilog testbench layer to
register any existing TLM ports/implementations in the SystemVerilog UVCs.
2. Make sure that any e ports to which you refer have been bound externally using a bind(port,
external) constraints in the e code. If needed, you can easily add bind(port, external) constraints in
the e testbench layer by extending any unit of the underlying e UVCs.
For a complete example, see “Example: e to SystemVerilog TLM Port Connection” on page 2-24.
Note If using one of the procedural connection approaches above, make sure to invoke it in the correct
phase: connect_ports() in e, connect() in SystemVerilog. These phases are executed after all testbench
components are created and before the correctness of connections is checked.
The strings passed to connect_names() can be dynamically calculated during the elaboration phases,
based on configuration from the top testbench layer. This lets you create reusable connection logic that
can be applied as is regardless of the language domain where the actual UVCs and their
ports/implementations are instantiated.
The fact that the external path in all languages is specified as a string expression, lets UVCs and
connection logic be independent of the implementation language of other parts of the testbench.
The external path does not need to contain any indication of the implementation language. The
underlying ML-UVM implementation finds the corresponding port (or implementation) according to the
name and path of the topmost component for that language. For example, sys is a predefined topmost
component for all e units and ports, the names of the topmost UVM SystemVerilog components are
registered in the UVM library, and so on.
Note All topmost components must have unique names, resulting in unique ML-UVM paths.
● any_struct in e
● uvm_object in SystemVerilog and SystemC
To be passed across a language boundary, an object is first packed into a bitstream using the packing
utilities defined by the language itself (in e), the UVM library (in SystemVerilog), or by users (in
SystemC). The bitstream is then passed to the other language, and unpacked there into an instance of the
target object type.
Passing transactions across languages is always done by value and not by reference. A consumer
component that received a transaction can modify any of its attributes, but none of the modifications are
visible on the producer side. Similarly, if the producer modifies the transaction while it is being handled
by the consumer, none of the modifications are visible to the consumer.
Note Native TLM implementations vary by the approach chosen for passing transactions within the
same language. Pure SystemC TLM passes transactions by value in the TLM 1.0 standard, and by
reference in the TLM 2.0 standard. TLM implementations in pure SystemVerilog or e pass transactions
by reference.
Using mltypemap lets you avoid manually coding type definitions, which can be complex, tedious, and
error prone.
mltypemap is a TCL-based tool that is invoked from irun. When you invoke mltypemap, you must
enter the appropriate mltypemap-related flags plus all the compilation flags necessary for irun to
compile the files and elaborate the snapshot (in the case of SystemVerilog inputs).
For information on invoking mltypemap and its commands, see Chapter 6 “mltypemap Utility: Automatic
Generation of Data Types”.
Without using the mltypemap utility, transaction types in different languages are compatible if they
match at the binary representation level. This requires that all attributes (fields) in the two transactions
match in type and declaration order. Only compatible transaction types can be packed into a bitstream in
one language and then successfully unpacked to a valid object in another language.
For e structs which make use of when-subtypes, mltypemap must be used to create the corresponding
SystemVerilog/SC types.
The only legal type mappings are those provided in Table 6-1 on page 6-17 and Table 8-2 on page 8-21.
If you use a mapping outside these tables, the mapping may or may not work, depending on the
implementation. Even if it does work in a particular release, there are no guarantees it will continue to
work in future releases, because the implementation may change from one release to another. Where
possible, use the mltypemap utility which will ensure only legal mappings are used.
Refer to “Mapping Types with mltypemap” on page 6-11 for more information on type mapping across
languages.
Consider first the SystemVerilog code. A driver class defines a put implementation and registers it with
ML-UVM using the external_if() function.
File: top.sv
class burst extends uvm_transaction;
...
endclass
The sv_tb class shown above is instantiated by ML-UVM as a top entity by naming it with a -uvmtop
command line switch.
Next, consider the e code that defines a TLM put port with a matching transaction type.
File: top.e
struct burst like any_sequence_item {
... // Burst attributes here
};
unit e_generator_u {
burst_op : out interface_port of tlm_put of burst is instance;
...
drive_burst( b: burst) @clock is {
burst_op$.put(b); // Put burst on port
};
};
extend e_tb {
generator: e_generator_u is instance;
};
Connection In e
To connect the ports in e, place the following logic in a separate e file that configures the testbench.
extend e_tb {
keep bind(generator.burst_op, external);
connect_ports() is also {
ml_uvm.connect_names("sys.generator.burst_op",
"sv_tb.driver.burst_ip");
};
Note The order of arguments to connect_names matters. The first argument must be the port or out
interface_port in e. The second argument must be the export - implementation in SystemVerilog, or in
interface_port in e.
The connection from e would apply only if the SystemVerilog port has been registered with ML-UVM
through a call to ml_uvm::external_if(). You can add the call from the SystemVerilog testbench layer:
class sv_tb extends uvm_env;
driver_c driver;
...
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
ml_uvm::external_if(driver.burst_ip, "burst");
endfunction
endclass
Connection in SystemVerilog
Similarly, the port connection can be done in SystemVerilog instead of e.
ml_uvm::connect_names("sys.generator.burst_op",
"sv_tb.driver.burst_ip");
endfunction
endclass
Note The order of arguments to connect_names matters. The first argument must be the port or out
interface_port in e. The second argument must be the export - implementation in SystemVerilog, or in
interface_port in e.
For the above connection to work, the e port should be bound externally. This can easily be added in the
e testbench level.
extend e_tb {
keep bind(generator.burst_op, external);
};
First, consider the ❅ code. It defines the embedded object type (header) and the compound transaction
(burst).
File: top.e
type color_t :[ RED = 0,
BLUE = 1,
GREEN = 4 ] (bits: 3);
struct header {
%data: byte;
};
File: top.sv
typedef enum bit [2:0] { SV_RED=’d0,
SV_BLUE=’d1,
SV_GREEN=’d4 } color_t;
‘uvm_object_utils_begin(header)
‘uvm_field_int(data, UVM_ALL_ON)
‘uvm_object_utils_end
endclass
‘uvm_object_utils_begin(burst)
‘uvm_field_int(address, UVM_ALL_ON)
‘uvm_field_enum(color_t, color, UVM_ALL_ON)
‘uvm_field_object(header, UVM_ALL_ON)
‘uvm_field_array_int(data_bits, UVM_ALL_ON)
‘uvm_object_utils_end
endclass
In our example, both enumerated types are defined with a bit size of three. In addition, the numeric
values are assigned explicitly and are made to match. For example, GREEN in e and SV_GREEN
in SystemVerilog have the same numeric value of four.
Pay special attention to the order of ‘uvm_field_* macros, which determine the packing and
unpacking order. They must match the order of field declarations in the counterpart e struct.
The table shows only the port types. Each port type has an associated implementation types, with the
name derived as follows:
SystemC SystemVerilog e
Table 2-4 TLM Port Type Mapping in the ML-UVM Supported Languages (continued)
SystemC SystemVerilog e
● Multi-language TLM is supported with IES-XL only, and not with any third-party simulators.
● Passing of transactions by reference through TLM ports is not supported.
● Only transactions of a SystemVerilog class (derived from uvm_object) and e struct types are supported
in TLM communication.
● There is no automated checking of type conformance for multi-language TLM ports.
● A SystemC port/export can be bound across a language domain only to its counterpart
implementation/port. So, for example, connecting a SystemC port to an e/SystemVerilog port, or a
SystemC export to an e/SystemVerilog implementation/export is not supported.
● Multiple binding (multiport) for multi-language connections is supported only for analysis ports
between e and SystemVerilog.
● Blocking calls between Specman/e threads and SystemVerilog/SystemC threads are preemptive. This
means that control does not pass from one language to another immediately, but rather involves the
simulation scheduler. This consumes an additional Specman tick and one cycle of simulation time,
in contrast to communication between SystemVerilog and SystemC threads.
● The default length (in bits) of a transaction passed in a multi-language TLM port is the value of
UVM_STREAMBITS SystemVerilog constant - 4096. To increase this limit you can use the
documented define UVM_PACK_MAX_SIZE. For example:
% irun -defineall UVM_PACK_MAX_SIZE=<value-in-bits>
● The functions ok_to_put(), ok_to_get(), ok_to_peek() in the relevant TLM ports are not supported
by ML-UVM. Some of these are also not supported by UVM SystemVerilog.
● The TLM master and slave interfaces are not supported by ML-UVM.
● The e testbench must be explicitly configured to work with SystemVerilog using one of the following
options:
● -snsv command line switch in irun (for the SystemVerilog/e only mode)
● agent() attribute in any one of the instantiated e units
● The TCL command uvm_phase -stop_at does not stop simulation at the build, connect,
end_of_elaboration, and start_of_simulation phases when in ML-UVM mode.
● Process control features (for example, disable in SystemVerilog or quit() in e) in the various
supported languages should not be used on threads that perform cross-language communication. The
result of using process control features on such threads is unpredictable.
e top-level test
Virtual
sequencer
Data item Proxy
struct sequencer
ML
UART SV-OCV sequencer APB e-OCV
stub UART
Rx agent DUT Slave
Tx agent Master
APB
Sequencer Sequencer
Monitor Monitor
UART
Driver Driver
3.2.1 ml_proxy_seq_driver
A proxy sequence driver forwards sequences to the SystemVerilog UVM sequencer through the
sequencer stub with which it is associated. The ml_proxy_seq_driver unit, which is derived from
any_sequence_driver, is the base unit type for e proxy sequence drivers.
Any do-item requests on a proxy sequencer are delegated to the SystemVerilog sequencer, while the e
side generates the items. You can execute items in the SystemVerilog sequencer from the e side by using
the do action, or the wait_for_grant(), deliver_item(), and wait_for_item_done() methods inherited
from any_sequence_driver. Grab requests are delegated to the SystemVerilog sequencer in the same
way.
Any do-sequence requests for sequence kinds that do not have a body() TCM are delegated to the
SystemVerilog sequencer after generation. However, do requests for sequence kinds that have a body()
are executed locally.
Note Both item and sequence types in e must be mapped to the corresponding SystemVerilog item
and sequence types.
When declaring a sequence for a mapped data item, you must use ml_proxy_seq_driver, or a unit type
derived from it, as a base for the sequence driver. Use the standard sequence statement with the
sequence_driver_type option. You must bind each instance of the proxy sequencer in e to the
corresponding sequencer stub in SystemVerilog by using the external_uvm_path() unit attribute. This
attribute specifies the SV-UVM component path for method port communication relative to the
containing unit.
For example:
sequence packet_seq using item=packet,
sequence_driver_type=ml_proxy_seq_driver;
3.2.1.1 update_item_after_done()
Purpose
User hook method to update the original item after its handling is done
Syntax
update_item_after_done(original: any_sequence_item, foreign: any_sequence_item)
Parameters
original The original e item that was delivered by the current do request.
foreign The actual item that was sent to the SystemVerilog sequencer by the current
do request in its current state.
Description
This method is called automatically on a proxy sequence driver after an item is signaled as done in the
SystemVerilog sequencer, just before the do action unblocks. You can override or extend this method to
update field values from the current SystemVerilog item to the original item generated in e so, for
example, the BFM response data can be read from the item in the sequence right after the do action.
Example
extend packet_seq_driver {
update_item_after_done(original: any_sequence_item,
foreign: any_sequence_item) is also {
original.as_a(packet).data = foreign.as_a(packet).data;
};
};
3.2.2 ml_uvm_sequencer_stub
Purpose
Serve as a mediator between an e proxy sequence driver and a SystemVerilog sequencer
Description
A sequencer stub receives requests from an e proxy sequencer and delegates them to its assigned
sequencer. Its purpose is to encapsulate communications and data conversions. You must instantiate a
sequencer stub in SystemVerilog for each sequencer instance that will serve e sequences. You associate
the sequencer stub with an e proxy sequence driver by using the external_uvm_path() unit attribute in
e.
Use the SV package ml_uvm_seq that ships with the Specman installation to declare a sequencer
stub. To use it, you must add the following command-line options to your compilation flow, as
additional command-line arguments to irun or ncvlog:
setenv ML_SEQ_DIR `sn_root -home`/src
irun \
... \
${ML_SEQ_DIR}/ml_uvm_seq.sv \
-incdir ${ML_SEQ_DIR}
To introduce your own item preparation code, derive a new component class from
ml_uvm_sequencer_stub by overriding the prepare_item_to_send() hook method.
irun \
... \
${ML_SEQ_DIR}/ml_uvm_seq.sv \
-incdir ${ML_SEQ_DIR}
3.2.2.2 assign_sequencer()
Purpose
Assign a sequencer to a sequencer stub
Syntax
void assign_sequencer(uvm_sequencer_base seqer);
Description
This method associates a sequencer, seqer, with a sequencer stub. It must be called before
end_of_elaboration, preferably during the build phase, otherwise an error is issued.
Example
The following example instantiates a sequencer and a user-defined sequencer stub side-by-side under an
env component.
‘uvm_component_utils(my_uvc_env)
3.2.2.3 prepare_item_to_send()
Purpose
User hook method to locally randomize the item and prepare it to be sent
Syntax
void prepare_item_to_send(inout uvm_sequence_item item);
Description
This virtual function is called automatically before an item is sent to the SystemVerilog sequencer. You
can override it in a subclass of ml_uvm_sequencer_stub to modify the item that was received from the
e proxy sequence driver. In particular, the item can be fully or partially randomized.
The parameter is declared inout to enable sending a different object than the one received from the e
side. In these cases, the new item must be created using the ‘uvm_create_on macro.
Example
class my_uvc_seqer_stub extends ml_uvm_seq::ml_uvm_sequencer_stub;
‘uvm_component_utils(my_uvc_seqer_stub)
assert($cast(p,item));
if (p.use_data == 1)
p.data.rand_mode(0); // Field randomization determined by flag
assert(p.randomize());
endfunction
endclass
3.2.3 Limitations
Features that are not supported in SystemVerilog cannot be supported by an e proxy sequence driver,
because it delegates all requests to the SystemVerilog sequencer. Features that are not supported by
SystemVerilog include the following:
Features that are not supported in e cannot be supported for multi-language sequences, because they are
not part of the e interface that programmers expect. These features include the following:
● Response routing
● Some arbitration schemes that are unique to SystemVerilog UVM
Some advanced features in e have analogous functionality in SystemVerilog, but are not supported for
multi-language sequences in the current release. These include the following:
● Sequence priorities
● Sequence-level is_relevant() callbacks
● Sequence stop() method
User-defined sequences on the e side are not registered in the SystemVerilog sequence library by the
sequencer. Therefore, they cannot be chosen randomly and invoked by SystemVerilog sequences.
See Also
● Chapter 6 “mltypemap Utility: Automatic Generation of Data Types”
4.1.1 -uvmtest
Purpose
Enable ML-UVM and declare a top test entity in a multi-language verification environment. Use this
option for the single topmost entity, which is the logical root of the entire multi-language hierarchy.
Category
Command line switch for irun and ncsim
Syntax
% irun -uvmtest [language:]entity-name ...
% ncsim -uvmtest [language:]entity-name ...
Description
Use this switch to declare the test, which is the logical root of the multi-language testbench hierarchy.
You can only specify one entity with the -uvmtest option, and it can be in any one of the supported
languages.
Use this option to specify either your e test file name, or SystemVerilog/SystemC test class. If your root
is a SystemVerilog test class, an instance of it is created with the name uvm_test_top, as in a pure
SystemVerilog testbench.
The command line switch takes an entity name consisting of a language identifier and an entity name.
The language identifier marks the language domain of the top entity. It can be one of the following:
● You cannot specify an e unit type name with -uvmtest. Only e test files are supported as top entities
in e.
● If you specify -uvmtest, the command line switches -uvm and -ml_uvm are turned on and need not
be specified explicitly.
Examples
● Naming an e test file as a top entity:
% irun -uvmtest e:my_test.e ...
● Naming an UVM SystemVerilog test class (similar to the pure UVM SystemVerilog
+UVM_TESTNAME switch) as a top entity:
% irun -uvmtest SV:my_test_class ...
● Naming two top entities — an e test and an UVM SystemVerilog env class:
% irun -uvmtest e:my_test.e \
-uvmtop SV:my_ethernet_env ...
4.1.2 -uvmtop
Purpose
Enable ML-UVM and declare a top entity in a multi-language verification environment. Use this option
to name entities which are top entities in their language domain, because their parent entity is in another
language domain.
Cadence recommends that you use the -uvmtest option and not -uvmtop to name the test - the root of the
logical testbench hierarchy. For more information see Section 4.1.1, “-uvmtest,” on page 4-1.
Category
Command line switch for irun and ncsim
Syntax
% irun -uvmtop [language:]entity-name ...
% ncsim -uvmtop [language:]entity-name ...
Description
Use this switch to declare a top entity in one of the language domains. To specify several top entities, use
this switch multiple times, each naming one of the entities. Each of the entities you name has a parent
entity in another language domain, and therefore is a top entity (no parent) in its own language domain.
This option should not be used for the root entity of the logical testbench hierarchy, where -uvmtest
should be used instead. For more information, see Section 4.1.1, “-uvmtest,” on page 4-1.
This command line switch takes an entity name consisting of a language identifier and an entity name,
as described in Section 4.1.1, “-uvmtest,” on page 4-1.
● The order of top entities as declared on the command line determines the order in which they are
created and built. Therefore, make sure to name the test as the very first top entity.
● You can omit the “e:” language identifier if you specify an e test file name with a .e suffix. If you
omit the language identifier and the name has no .e suffix, it is assumed to be a SystemVerilog class
name. You cannot omit the SC language identifier.
Cadence recommends that you always include a language identifier, for clarity and readability.
● You cannot specify an e unit type name with -uvmtop. Only e test files are supported as top entities
in e.
● If you specify -uvmtop, the command line switches -uvm and -ml_uvm are turned on and need not
be specified explicitly.
Examples
● Naming two top entities — an e test root and an UVM SystemVerilog env class:
% irun -uvmtest e:my_test.e \
-uvmtop SV:my_ethernet_env ...
4.1.3 -ml_uvm
Purpose
Enable the ML-UVM features.
Category
Command line switch for irun and ncsim
Syntax
% irun -ml_uvm ...
% ncsim -ml_uvm ...
Description
Use this switch to enable ML-UVM when no -uvmtop switch is used. This is useful in cases when you
have a top e layer where the e test file is being loaded by other means (for example through a TCL
command) and a SystemVerilog OVC that is instantiated by other means than an -uvmtop switch.
● If you are using SystemVerilog components, you must have at least one import statement to import
the ml_uvm package in your SystemVerilog source:
import ml_uvm::*; // Required for ML-UVM
● When you specify the -ml_uvm command line switch, the -uvm switch is implicitly added, causing
irun to compile the UVM package that is included with your IES release.
4.2.1 ml_uvm.connect_names()
Purpose
Language-neutral connection of TLM ports in a multi-language environment.
Category
e method
Syntax
ml_uvm.connect_names(port_path: string,
export_path: string);
Parameters
Description
Call this method in your e code during the connect_ports phase. It lets your e code connect any two
ports/implementations by their UVM path, regardless of the language domain where they are
implemented.
Note This function can connect only ports/implementations that were registered with ML-UVM. This
includes:
For more details on TLM ports in e, see “Using TLM Interface Ports” in the Specman Integrators Guide.
Example
extend my_env_unit {
connect_ports() is also {
ml_uvm.connect_names("tb.env0.monitor.packet_done_port",
"tb.scoreboard0.packet_done_export");
};
};
Note ML-UVM cannot be used with any of the open-source UVM SystemVerilog class library
versions.
4.3.1 ml_uvm::connect()
Purpose
Connect a SystemVerilog TLM port/implementation to another port/implementation named by its
ML-UVM path. The target port/implementation may be defined in any supported language.
Category
SystemVerilog function in the ml_uvm package
Syntax
package ml_uvm;
function void connect(uvm_if_base_abstract port_or_export,
string external_path,
string T1_name,
string T2_name = "");
Parameters
external_path ML-UVM path of the target port/implementation. Use a full ML-UVM path, as
defined in “ML-UVM External Path Strings” on page 2-22.
T1_name Type name of the transaction class passed by the port. This name must match
the transaction type in the port/implementation definition.
T2_name Type name of the second transaction type, when applicable (for example, in
uvm_transport_port). This name must match the second transaction type in the
port/implementation definition.
Description
Use this function to connect a SystemVerilog TLM port/implementation to a matching
port/implementation named through its full ML-UVM path. The external_path argument can reference
any TLM port/implementation in any language supported by ML-UVM.
Note This external_path parameter can name only a port/implementation that was registered with
ML-UVM. This includes:
Example
import ml_uvm::*;
4.3.2 ml_uvm::connect_names()
Purpose
Language-neutral connection of multi-language TLM ports/implementations.
Category
SystemVerilog function in the ml_uvm package
Syntax
package ml_uvm;
function void connect_names(string port_path,
string export_path);
Parameters
Description
Use this function to connect any two ports by their UVM path, regardless of the language in which they
are implemented. This function is equivalent to the ml_uvm.connect_names() method in e, described in
“ml_uvm.connect_names()” on page 4-5.
Note This function can connect only ports/implementations that were registered with ML-UVM. This
includes:
Example
import ml_uvm::*;
4.3.3 ml_uvm::external_if()
Purpose
Register a SystemVerilog port or implementation with ML-UVM prior to connecting it. The
port/implementation can then be connected by logic in the same or another language domain.
Category
SystemVerilog function in the ml_uvm package
Syntax
package ml_uvm;
function void external_if (uvm_if_base_abstract port_or_export,
string T1_name,
string T2_name = "");
Parameters
T1_name Type name of the transaction class passed by the port. This name must match
the transaction type in the port/implementation definition
T2_name Type name of the second transaction type, when applicable (for example, in
uvm_transport_port). This name must match the second transaction type in
the port/implementation definition.
Description
Call this function before or during the SystemVerilog connect phase to register ports and
implementations with ML-UVM. Once registered, connection logic in other language domains can
connect the port/implementation.
Example
import ml_uvm::*;
Test
Scoreboard Module System Multi Channel Stimuli
UVM UVM
Monitor Stimuli Interface Interface Monitor Stimuli Monitor Stimuli
Monitor Stimuli
TLM TLM TLM TLM TLM
BFM BFM BFM TLM TLM
TBA TLM
Collector Driver Collector Driver Collector Driver Collector Driver
DUT
BUS HW
CPU USB
You can use UIG to develop a class-based SystemVerilog (SV) interface to a UVC defined in e. Cadence
provides another utility – UIC (UVM Interface Customizer) to help you configure and tailor UIG to your
specific e UVC. For a step-by-step description of how to do this, see Chapter 4, “SystemVerilog Class
Based over e”, in the UVM Mixed-Language Methodology.
The default behavior of UIG in 10.2 is to create a UVM-SV interface, and not OVM-SV. To generate
OVM-SV code, add -lang OVM-SV to the run_uig.sh command line.
Please use the following email alias to provide feedback and get additional support:
uig_support@cadence.com
See Also
● Chapter 4, “SystemVerilog Class Based over e”, in the UVM Mixed-Language Methodology.
developer-created files
adaptor
DUT
config
interface
file
dynamic
config svh
file files
internal
eVC +
e files
e glue
logic
UIG is delivered as part of IES and consumes an IES license. It resides under
/specman-install-dir/specman/packages/uig.
The e export file identifies the components in the UVC that you want to make available to the SV
integrator and to end users to enable configuration of the UVC, the generation and driving of
stimuli, and connecting to the UVC monitors.
For every exported e component (env, agent, sequencer, monitor, and so on), UIG creates a proxy
UVM-compliant SV component (class). The proxy component contains tasks and functions that end
users can invoke to activate different capabilities in the UVC.
In the export file, you can also associate one or more DUT interfaces with a proxy component. For
each DUT interface, UIG creates a virtual interface handle of the exported interface type in the
proxy component class. The end users use the virtual interface handle to map ports in the UVC to
DUT signals.
You must create e glue logic to enable interaction between the UVC components and the SV proxy
components.
For more information, see the SystemVerilog Class Based over e chapter of the UVM for
Multi-Language Environments document. This chapter provides a methodology overview of the
whole process, and points to a workshop in the following location with all the low-level details:
$SOCV_KIT_HOME/doc/kit_topics/uvm_mixed/sv_over_e/workshop
Specman’s SystemVerilog adapter provides mappings between e and all SystemVerilog integer data
types. UIG creates baseline mappings between e user-defined types and the corresponding SV
types. However, you can refine those mappings to specify, for example, that the names of the
enumerated values are the same in SV as they are in e.
This e file is compiled by the end user and queries the UVM proxy environment at run time to
construct, connect and configure the topology of the UVC to reflect the UVM proxy environment.
An SV sequence library provides the end user with a UVM way of doing sequences. These
sequences also show users how to write their own SV UVM sequences.
To test the UVM interface, you have to create a simple SV environment, including an SVE
configuration file, a testbench, and a test.
The final tasks include moving the UVM-related files into the appropriate subdirectories, if they are
not already there, and writing the user documentation.
Note Cadence recommends that you follow a gradual, iterative process, starting by exporting a small,
simple feature of the eVC and testing that feature in simulation. Then you gradually add other features
to the SV interface, testing each feature as it is developed. This iterative process is described in Chapter
5, “SystemVerilog Class Based over e”, in the UVM Mixed-Language Methodology manual in the
KITSOCV release.
SV
UVM
tests IES
SV
UVM
SVE
UVM
UVC
5.2.1 run_uig.sh
Syntax
`sn_which.sh uig/bin/run_uig.sh`
e-UVC-top-files
adapter-config-file
-eexp export-file
[-lang UVM-SV | UVM11-SV | OVM-SV]
[-out base-prefix]
[-import export-file]
[-debug NONE | MEDIUM | FULL]
Syntax Example
`sn_which.sh uig/bin/run_uig.sh`
vr_axi_top.e
vr_axi_adapter_config.e
-eexp vr_axi.eexp
Parameters
e-UVC-top-files You must provide to UIG all the top-level file(s) of the e UVC
extensions you made for ML UVM as well as the original
top-level file(s) of the eVC.
-eexp export-file The name of a Nested Text Format (NTF) file that controls and
configures the export of entities in an eVC to SV. The default file
extension is eexp.
[-out base-prefix] The prefix for all generated files. The default is the UVC’s
package name. Use this flag only when you want the prefix of
the files to be different from the UVC’s package name.
[-import export-file] Specifies the name of a Nested Text Format (NTF) file that
controls and configures the export to SV of entities in a
previously exported eVC. The default file extension is eexp. You
can use this option to reuse the components of a previously
exported eVC.
Note You must also provide the eVC’s source files to UIG
when using this option.
[-debug NONE|MEDIUM|FULL] Controls UIG’s verbosity. Starting in the 9.2 release, MEDIUM
and FULL have the same effect. The default is NONE.
Description
Table 5-1shows the files generated by run_uig.sh. By default, the base_prefix is the UVC’s package
name, but you can modify the prefix with -out.
Table 5-1 Generated Files
File Description
File Description
base_prefix_query.svh This file contains the SV coded needed for querying the UVM
component configuration from Specman.
base_prefix_types.svh This UVM stubs file contains the exported data type
definitions.
base_prefix_extensions.svh This file contains `defines that allow extending the interface
of the generated components.
The e export file defines the exported entities in terms of attributes and elements. Attributes are defined
either at the top-level or inside an element. Elements can also contain other elements. Attributes and
elements are defined using the following syntax:
attribute-name : attribute-value;...
element-type element-name {
attribute-name : attribute-value;...
This section covers the following topics related to the export file:
<uvm_component_type> <unit-name> {
external_name : <uvm-component-type-name>;
comment : <description-of-component>;
extends : <unit-name>;
class_code : <class-code-string>;
build_code : <build-code-string>;
new_function_code : <new-function-code-string>;
connect_code : <connect-code-string>;
post_build_code : <post-build-code-string>;
control_active_passive : [FALSE, TRUE];
constrain_count : [TRUE, FALSE];
create_assign_vi : [TRUE, FALSE];
create_pointer_to_parent_config: [TRUE, FALSE];
use_ml_sequencer : [FALSE, TRUE];
external_package_name : <package-name>;
start_of_build_code : <start-of-build-code-string>;
end_of_build_code : <end-of-build-code-string>;
use_layering : [FALSE, TRUE];
sequence <sequence-name> {
comment : <description-of-sequence>;
in : <field-name[,field_name]*>;
inout : <field-name[,field_name]*>;
out : <field-name[,field_name]*>;
external_name : <foreign-language-method-name>;
class_code : <class-code-string>;
create_sequence_class : [FALSE, TRUE];
use_ml_sequence : [FALSE, TRUE];
new_function_code : <new-function-code-string>;
external_class_name : <foreign-language-class-name>;
in|out|inout <field-name> {
comment : <description-of-field>;
external_name : <external-name-of-field>;
is_rand : [TRUE, FALSE];
};
};
item <item-name> {
comment : <description-of-item>;
external_name : <foreign-language-method-name>;
gen_method : <method-name>;
update_method : <method-name>;
sv_item : <item-type-name>;
interaction_mode : [PULL_MODE, PUSH_MODE];
send_method : <method-name>;
class_code : <class-code-string>;
new_function_code : <new-function-code-string>;
convert_e_item_method : <method-name>;
convert_external_item_method : <method-name>;
update_e_item_method : <method-name>;
update_external_item_method : <method-name>;
e_response_method : <method-name>;
external_response_method : <method-name>;
response_method : <method-name>;
external_type : <external-e-type-name>;
response_type : <e-response-type-name>;
use_response : [FALSE, TRUE];
update_after_gen : [TRUE, FALSE];
};
to_e_method <method-name> {
comment : <description-of-method>;
external_name : <foreign-language-method-name>;
};
from_e_method <method-name> {
comment : <description-of-method>;
external_name : <foreign-language-method-name>;
method_code : <method-code-string>;
create_analysis_port: [FALSE, TRUE];
analysis_port_name : <port-name>;
optimization_mode : [USER_DEFINED, NONE];
};
to_e_event <event-name> {
comment : <description-of-event>;
external_name : <foreign-language-event-name>;
data_method : <method_name>;
external_class_name: <event-class-name>;
};
from_e_event <event-name> {
comment : <description-of-event>;
external_name : <foreign-language-event-name>;
data_method : <method_name>;
external_class_name : <event-class-name>;
create_analysis_port: [FALSE, TRUE];
analysis_port_name : <port-name>;
optimization_mode : [USER_DEFINED, NONE];
data_transfer_mode : [USER_DEFINED, NONE];
};
subcomponent <field-name> {
comment : <description-of-subcomponent>;
external_name : <foreign-language-field-name>;
component_type : <exported-component-type-name>;
control_build : [FALSE, TRUE];
control_field : <foreign_field_name>;
control_value : <foreign_field_value>;
build_by_default: [FALSE, TRUE];
is_list : [FALSE, TRUE];
};
dut_interface <field-name> {
comment : <description-of-dut-interface>;
external_name : <foreign-language-field-name>;
interface_type : <exported-interface-type-name>;
use_in_assign_vi : [TRUE, FALSE];
propagate_to_subcomponents: [TRUE, FALSE];
};
config <foreign-language-field-name> {
comment : <description dut interface>;
use_config_object : [FALSE, TRUE];
external_name : <foreign-language-field-name>;
external_class_name : <uvm-class-type-name>;
class_code : <class-code-string>;
new_function_code : <new-function-code-string>;
include_fields : <struct-type_name.field_name>;
exclude_fields : <struct-type_name.field_name>;
default : [FALSE, TRUE];
create_default_object : [FALSE, TRUE];
field_name_in_parent_config: <field_name>;
field <field-name> {
comment : <description-of-field>;
external_name: <foreign-language-field-name>;
e_type : <e-type>;
external_type: <external-type>;
external_kind: <external-kind>;
default_value: <value>;
is_rand : [FALSE, TRUE];
is_static : [FALSE, TRUE];
is_listL : [FALSE, TRUE];
};
};
};
interface <unit-name> {
comment : <description-of-interface>;
external_name : <foreign-language-interface-name>;
interface_code : <interface-code-string>;
include_signals : <port-name>;
deep_include_signals : <port-name>;
exclude_signals : <port-name>;
external_package_name : <foreign-language-package-name>;
pre_declaration_code : <pre-declaration-code-string>;
post_declaration_code : <post-declaration-code-string>;
signal_code : <signal-code-string>;
implementation_code : <implementation-code-string>;
signal <port-name> {
comment : <description-of-signal>;
external_name : <foreign-language-signal-name>;
net_type : <net-type-name>;
data_type : <data-type-name>;
signal_size : <signal-size-string>;
list_size : <list-size>;
create_as_port : [FALSE, TRUE];
signal_kind : [DRIVER, VERILOG_WIRE];
port_direction : [INOUT,INPUT,OUTPUT];
initial_value : <initial-value>;
create_as_packed_array: [FALSE, TRUE];
create_array : [TRUE, FALSE];
list_delimiter : <delimiter>;
};
clocking_block <clocking-block-name> {
comment : <description of clocking block>;
external_name : <foreign-language-clocking-block-name>;
default : [FALSE, TRUE];
clocking_event : <clocking-event>;
default_sampling_skew: <skew>;
default_driving_skew : <skew>;
clocking_code : <clocking-block-code-string>;
include_signals : <unit-name>.<port-name>;
exclude_signals : <unit-name>.<port-name>;
clocking_signal <port-name> {
comment : <description-of-signal>;
external_name: <foreign-language-signal-name>;
sampling_skew: <skew>;
driving_skew : <skew>;
direction : [INOUT, INPUT, OUTPUT];
};
};
};
5.3.2 #include
An e export file can include other e export files using an #include statement:
#include <file-name>
Notes
● There is no semi-colon in the end of the #include statement.
● This directive can be used on any line in the file.
● UIG uses $SPECMAN_PATH when searching for the file.
create_file_per_class: If FALSE (the default), one file is created for all generated component class
bool definitions. If TRUE, each component class is generated in its own file.
top_e_file: filename-list | Specifies one or more e files that the end user must compile or load for
top_e_files: filename-list simulation, typically:
Notes
● You must use this attribute to specify the base_prefix_uvm.e file that is
generated by UIG.
● You can use the import attribute to import all the required files from
base_prefix_uvm.e and then specify only base_prefix_uvm.e in
top_e_files.
● Do not use this attribute for the dynamic configuration file if it has any
define-as-computed macros that rely on information from
SystemVerilog. Instead, use the load_after_build attribute.
import: e-filename The name of an e file to be imported by the base_prefix_uvm.e file generated
by UIG.
load_after_build: The name of an e file to be loaded after the SV build phase is done. You can
e-filename use this attribute to load e files with define-as-computed macros that rely on
information from the SV side.
external_package_name: The name of the SV package to contain the exported entities. The default is
package-name the UVC’s package name.
uig_e_file: filename | A list of all the e pathnames needed by UIG to generate the UVC, in other
uig_e_files: filename-list words, a list of the pathnames of all the e files that must be passed to the UIG
run script. The path of the files must be relative to the root of the UVC, for
example:
my_uvc/e/api/sv/my_uvc_uvm_top.e
my_uvc/e/api/sv/my_uvc_adapter_config.e
Note This attribute is required.
export_file: filename The pathname of the e export file. The pathname must be relative to the root
of the UVC, for example:
my_uvc/misc/my_uvc_uvm_sv.eexp
Note This attribute is required.
export_type: type-name If you are extending a type that has previously been exported and that type is
not explicitly mentioned in the .eexp file or in the imported eexp file, you
must specify its typename here.
typedef_code: code Specifies code to be added to the typedef area of the UVC package.
post_declaration_code: Specifies code to be added after all other declarations in the generated UVC
code package.
pre_declaration_code: Specifies code to be added before any other declarations in the generated
code UVC package.
Purpose
Define a exported component
Context
Top-level (not within any other element)
Syntax
uvm-component-type e-unit-name {
attribute | element;...
};
Syntax Example
monitor vr_axi_agent_monitor {
//The name of class type in SV
external_name : vr_axi_agent_monitor;
...
};
Parameters
uvm-component-type Determines what kind of UVM component is generated from the e unit. It must be
one of the following:
agent Is the base type for UVM agents. Agents usually contain
three subcomponents:
● sequencer
● driver
● monitor
sequencer Is the base type for UVM sequencers and can be used to
export an e unit derived from any_sequence_driver.
virtual_sequencer Is the base type for UVM virtual sequencers and can be
used to export an e unit derived from
any_sequence_driver.
e-unit-name The name of the exported e unit or when subtype. If the name includes special
characters, it must be enclosed in quotes. For example:
env "SV_IC'sv_type vr_axi_env" {...};
element An UVM component element can contain the following kinds of elements:
● method elements
● event elements
● subcomponent elements
● dut_interface elements
● config elements
Note sequence elements and item elements can only be contained in
sequencer elements
Description
UIG creates a proxy UVM class for every exported component. This class contains tasks and functions
that end users can invoke to activate different capabilities in the eVC.
You can export a component as any one of the following uvm_component types:
● uvm_env
● uvm_agent
● uvm_sequencer
● uvm_driver
● uvm_monitor
Note Different export file attributes and elements are associated with each uvm_component type.
See “Example 1” on page 5-21 and following for examples of exporting various types of UVM
components.
Element Attributes
Table 5-3 UVM Component Element Attributes
external_name: Specifies the name of the exported component in SV. For example:
uvm-component-type-name
external_name : vr_axi_agent_monitor;
comment: component-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines. For example:
comment: <text>Collects the transfers/bursts,
then emits events on the status of traffic to
and from the DUT</text>;
extends: unit-name Specifies that this exported component inherits from the specified
unit in the foreign language. The specified unit must be a supertype
of the exported component in e. Inheriting components cannot
override/extend any constructs already exported in the supertype,
except for from_e_method. The supertype can be declared in an
imported eexp file.
class_code: string Inserts additional code into the exported class. Use the <text>
</text> tags to insert multiple lines of code.
build_code: string Inserts additional code at the end of the component’s build
function. Use the <text> </text> tags to insert multiple lines of
code.
new_function_code: string Inserts additional code at the end of the component’s new function.
Use the <text> </text> tags to insert multiple lines of code.
connect_code: string Inserts additional code at the end of the component’s connect
function. Use the <text> </text> tags to insert multiple lines of
code.
post_build_code: string Inserts additional code at the end of the component’s post_build
function. Use the <text> </text> tags to insert multiple lines of
code.
control_active_passive: bool When TRUE (the default for agents), a field called is_active is
automatically created in the component. You can use the value
assigned to the field by users to control the active/passive attribute
of the e agent unit. When FALSE, this field is not created.
constrain_count: bool If TRUE (the default), UIG adds the constraint “keep soft count
==0”, and no sequences are generated unless the end user
over-rides this constraint. If FALSE, no constraint is added, and the
default sequence is generated.
external_package_name: The name of the SV package to contain the exported entities. The
package-name default is the UVC’s package name.
use_ml_sequencer: bool Specifies whether this sequencer uses the 9.2 multi-language
sequence API or the 8.2 sequence model. For further information,
see “9.2 Multi-Language Sequence Use Model” on page 5-31 or see
the migration guide available here:
$SOCV_KIT_HOME/doc/kit_topics/uvm_mixed/sv_over_e/new_s
equence_model_92ml.pdf.
start_of_build_code: string Inserts additional code at the start or end of the component’s build
end_of_build_code: string function.
use_layering: bool Specifies whether this sequencer uses the layering facilities
enabled by the 9.2 multi-language sequence API. Setting this to
TRUE might require the implementation of additional conversion
methods.
create_assign_vi: bool When TRUE (the default), a function called “assign_vi” is created
in the component. This function handles the DUT interface
connections for all DUT interfaces declared in the component.
When FALSE, no function is created. You might want to set this
attribute to FALSE if, for example, you have several DUT
interfaces in a component and want to have a different function for
setting each one. In this case, you can add your own function using
class_code.
external_name: vr_axi_if_env;
subcomponent master {
component_type: vr_axi_master;
is_list: FALSE;
};
subcomponent slave {
component_type: vr_axi_slave;
is_list: FALSE;
};
};
config cfg {
include_fields : vr_axi_interconnect_config.*;
use_config_object : TRUE;
};
subcomponent slave_input_ports {
component_type: vr_axi_slave;
is_list: TRUE;
};
subcomponent master_output_ports {
component_type: vr_axi_master;
is_list: TRUE;
};
from_e_method convert_id_tag{};
};
//////////////////////////////////////////////////////////
// Events to be exported to SV //
//////////////////////////////////////////////////////////
from_e_event sv_burst_ended {
comment : "Emitted when a burst ends on the sequencer";
data_method: get_ended_sv_burst;
external_name: master_burst_ended;
};
//////////////////////////////////////////////////////////
// Exported methods to be used in SV is_relevant //
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// Exported sequences (mapped sequence) //
//////////////////////////////////////////////////////////
sequence API_READ {
in : address;
in : burst_kind;
in : length;
in : size;
out : read_memory;
external_name : read;
comment: <text>This task sends read burst with default parameters.
The task returns once the read burst has ended and updates
the read data. Only normal access is supported</text>;
};
...
//////////////////////////////////////////////////////////
// dut interface of master driver (pointer to signals) //
//////////////////////////////////////////////////////////
dut_interface vr_axi_signal_interface {
interface_type:vr_axi_master_signal_map ;
};
};
//////////////////////////////////////////////////////////
// Events to be exported to SV //
//////////////////////////////////////////////////////////
from_e_event read_burst_started {
comment : "Emitted on read burst start";
data_method: get_started_read_burst_info;
};
from_e_event write_burst_started {
comment : "Emitted on write burst start";
data_method: get_started_write_burst_info;
};
...
//////////////////////////////////////////////////////////
// Methods exported to SV //
//////////////////////////////////////////////////////////
to_e_method write_memory{};
//////////////////////////////////////////////////////////
// dut interface in the monitor (pointer to signals) //
//////////////////////////////////////////////////////////
dut_interface vr_axi_signal_interface {
interface_type:vr_axi_master_signal_map ;
};
};
Purpose
Defines the sequence types for which the UVM interface is built
Context
Only allowed within a sequencer element
Syntax
sequence sequence-name {
attribute;...
};
Syntax Example
sequence API_READ {
in : address;
in : burst_kind;
in : length;
in : size {
external_name: real_size;
};
out : read_memory;
external_name : read;
comment: <text>This task sends a read burst with default parameters;
The task returns once the read burst has ended,
and updates the read data;
Only normal access is supported;</text>;
};
Parameters
sequence-name The name of the sequence, in other words, the when subtype that defines the
exported sequence. For example:
sequence RANDOM {...};
Description
For every exported sequence, a task is created in the sequencer component class.
● The task name is the external_name, if defined. Otherwise, it is the sequence name.
● The parameters of the tasks reflect the fields in the e export file. For an input field, there is an input
parameter. For an output field, there is an output parameter.
● The names of the parameters reflect the names of the fields.
● The types of the parameters are the SystemVerilog equivalent types of the corresponding e types.
● The order of the parameters reflects the order of the field declarations in the e export file.
● A maximum of 14 fields is currently allowed per exported sequence.
● When this task is called, it causes a do action for the sequence that is constrained using the given
parameters. When returning from the task, the output parameters have the value of the fields in the
sequence struct, as they were when the do action was terminated.
If the create_sequence_class attribute is TRUE, a class deriving from uvm_sequence is also created.
● The class name is the external_name, if defined. Otherwise, it is the sequence name.
● The fields of the class reflect the fields in the export file.
● The names of the class fields reflect the names of the fields in the eexp file.
● The types of the fields are the SystemVerilog equivalent types of the corresponding e types.
● The sequence is registered automatically with the sequencer.
● The body() task of the sequence calls the sequencer task that is created in the sequencer component
class (as explained above).
In 9.2, UIG enables the use of the multi-language sequence API. If you used the use_ml_sequencer
attribute, a sequence class is created by default for this sequence, since this is mandatory for multi
language sequences.
For more information and examples on multi-language sequences, see “9.2 Multi-Language Sequence
Use Model” on page 5-31 or New Sequence Model.
Element Attributes
Table 5-4 Sequence Element Attributes
comment: sequence-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
in: field-name-list A comma-separated list of the names of the fields that are used to
constrain the entity. These fields must be generatable.
out: field-name-list A comma-separated list of the names of the fields that are to be
returned after the do action is executed. For example:
out : read_memory;
inout: field-name-list A comma-separated list of the names of the fields that are used to
constrain the entity and that are to be returned after the do action
is executed.
class_code: string Inserts additional code into the class of the exported entity. Use the
<text> </text> tags to insert multiple lines of code.
use_ml_sequence: bool If TRUE, specifies that this sequence must be used with the 9.2
multi-language sequence API. Valid only if use_ml_sequencer is
set to TRUE in the containing sequencer component.
create_sequence_class: bool If FALSE (the default), a task in the sequencer component class is
created for each exported sequence. If TRUE, UIG generates a
SystemVerilog class that represents the sequence, similar to pure
UVM SystemVerilog sequences.
Notes
● If use_ml_sequence is set to TRUE, create_sequence_class
is also TRUE by default.
● Cadence recommends specifying a TRUE value for the
create_sequence_class attribute. If you do not enable this
attribute, UIG only places a task in the sequencer that
represents the sequence. Tasks can be easily called by end
users, but they cannot be invoked with the ‘uvm_do or
‘uvm_do_with macro.
Purpose
Define a field that constrains or is returned by a sequence
Context
Within a sequence element
Syntax
in|inout|out : field-name {
attribute;...
};
Syntax Example
in : size {
external_name: real_size;
is_rand: TRUE;
};
Parameters
field-name The name of the field that constrains or is to be returned by the sequence element.
Description
You can use this element to specify the names of the fields that are used to constrain the entity and/or
that are to be returned after the do action is executed.
Element Attributes
Table 5-5 Field Element Attributes
comment: field-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
is_rand: bool If TRUE, the field is created as a generatable field. The default is
FALSE.
Purpose
Defines the data type that is constrained and sent by the sequencer
Context
Only allowed within a sequencer element
Syntax
item type-name{
attribute;...
};
Syntax Example
item vr_axi_slave_driven_burst_response {
sv_item: vr_axi_slave_burst_response;
};
Parameters
Description
You can declare only one item element for an exported sequencer component.
When an item element is declared, UIG creates infrastructure for synchronizing the UVM sequencer
with the e sequencer. The e sequencer runs a special sequence that listens for do actions on the UVM
side, and pulls these items.
If you are using the PULL_MODE interaction mode, you must provide a method for checking and
generating an e item according to a UVM item, as well as a method for updating the UVM item
according the e item. These methods must be defined in the sequence struct. UIG looks for these
methods with the names specified by the gen_method and update_method attributes.
If you are using the PUSH_MODE interaction mode, you must provide a method that gets an SV item as
a parameter, checks it for validity, generates a corresponding e item and sends it to the e driver. UIG
looks for this method with the name specified by the send_method attribute.
The item exported into SV and the e item most likely have to be two different e types. In this case the
exported item has to be the actual e item, and the SV item has to be specified in the e export file using
the attribute sv_item.
The exported item is automatically generated as deriving from uvm_sequence_item, with all the
relevant field macros and the correct new function.
You can control how the item is exported using the adapter unit configuration.
In 9.2, UIG enables the usage of the multi-language sequence API. It enables true SystemVerilog
sequencer proxy because the generated proxy does not maintain its own do queue. Instead, the proxy
delegates all calls to e sequence drivers. It removes multiple current limitations, including the layering
of sequencers, grab/ungrab across-languages, and delicate timing issues in pipelined protocols.
Using the multi-language sequence API requires you to define and implement several conversion
methods in the exported sequence driver. These methods are used to pass data (request and response
items) between the languages. The following attributes control the names of the conversion methods:
● convert_e_item_method specifies the method used to convert the e representation of the external
item to the e item type. The default signature of this method is:
gen_e_from_sv_item(sv_item: <sv-item-type>) : <e-item-type>;
● convert_external_item_method specifies the method used to convert the e item to the e
representation of the external item type. The default signature of this method is:
gen_sv_from_e_item(sv_item: <e-item-type>) : <sv-item-type>;
● update_e_item_method is used in layered protocols and specifies the method used to update the e
item according to the changes made in the foreign language. The default signature of this method is:
update_e_from_sv_item(e_item: <e-item-type>, sv_item: <sv-item-type>);
● update_external_item_method specifies the method used to update the e representation of the
external item according to the generation made in Specman. The default signature of this method is:
update_sv_from_e_item(sv_item: <sv-item-type>, e_item: <e-item-type>);
● external_response_method specifies the method used to convert the e response to the external
response type. Only needed if the use_response attribute is specified. The default signature of this
method is:
gen_sv_from_e_response(e_response: <e-response-type>) :
<sv-response-type>);
Element Attributes
Table 5-6 Item Element Attributes (8.2 Use Model)
comment: item-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
class_code: class-code-string Inserts additional code into the class of the exported entity. Use the
<text> </text> tags to insert multiple lines of code.
interaction_mode: mode The mode of interaction between the e sequencer and driver.
Possible values are PULL_MODE and PUSH_MODE. The
default is PULL_MODE.
external_name: name Specifies the name of the exported item type in SV.
sv_item: type-name The name of an e struct that represents the SV data item. For
example:
sv_item: vr_axi_slave_burst_response;
send_method: name The name of a method defined in the e sequencer unit that gets an
SV item as a parameter, checks it for validity, generates a
corresponding e item and sends it to the e driver. Valid only for
PUSH_MODE. The default is send_item().
gen_method: name The name of a method defined in the e sequence struct that gets an
SV item as a parameter, checks it for validity and returns a
generated e item. Valid only for PULL_MODE. The default is
gen_e_from_sv_item().
update_method: name The name of a method defined in the e sequence struct that gets an
e item as a parameter, and returns an SV item. Valid only for
PULL_MODE. The default is update_sv_from_e_item().
comment: item-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
class_code: class-code-string Inserts additional code into the class of the exported entity. Use the
<text> </text> tags to insert multiple lines of code.
interaction_mode: mode The mode of interaction between the e sequencer and driver.
Possible values are PULL_MODE and PUSH_MODE. The
default is PULL_MODE.
external_name: name Specifies the name of the exported item type in SV.
sv_item: type-name The name of an e struct that represents the SV data item. For
example:
sv_item: vr_axi_slave_burst_response;
send_method: name The name of a method defined in the e sequencer unit that gets an
SV item as a parameter, checks it for validity, generates a
corresponding e item and sends it to the e driver. Valid only for
PUSH_MODE. The default is send_item().
convert_e_item_method: The name of a sequencer method that converts the e item type to
method-name the e representation of the external item.
update_e_item_method: The name of a sequencer method that updates the e item according
method-name to the e representation of the external item.
update_after_gen: bool Indicates whether to update the foreign language item after
generation is done on the e side.
use_response: bool Specifies whether to return a response when the item is done.
response_type: e-type Specifies the type of the response, if it differs from the item type.
external_type: type The name of an e struct that represents the SV data item. For
example:
external_type: vr_axi_slave_burst_response;
For further information on migrating to the 9.2 use model, see the migration guide available here:
$SOCV_KIT_HOME/doc/kit_topics/uvm_mixed/sv_over_e/new_sequence_model_92ml.pdf.
See Also
● “Executing Specman Code Asynchronously” in the Specman Integrators Guide contains information
about working in mixed verification environments and using timeless models where Specman is often
called asynchronously.
5.3.8.1 to_e_method
Purpose
Define a regular e method or TCM to be called from SV
Context
Within any UVM component element
Syntax
to_e_method method-name {
attribute;...
};
Syntax Example
to_e_method *_write_* {
external_name : xbus_$1_write_to_$2;
};
Parameters
method-name The name of the e method as defined in e. Wildcards are allowed. The
external_name can use $1 ($2, $3, …) to refer to the wildcards.
Description
For every to_e_method element, a task or a function is created:
Element Attributes
Table 5-8 To e Method Element Attributes
external_name: method-name Specifies the name of the exported method in SV. If not specified,
the e name is used.
comment: method-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
5.3.8.2 from_e_method
Purpose
Define an empty hookup method in SV that is called after the specified e method executes
Context
Within any UVM component element
Syntax
from_e_method method-name {
attribute;...
};
Syntax Example
from_e_method *_read_* {
external_name : xbus_$1_read_from_$2;
};
Parameters
method-name The name of the e method as defined in e. Wildcards are allowed. The
external_name can use $1 ($2, $3, …) to refer to the wildcards.
Description
When the e export file defines a from_e_method element, a callback is created. A callback is
function/task that is called at the end of execution of the e method.
Element Attributes
Table 5-9 From e Method Element Attributes
external_name: method-name Specifies the name of the exported method in SV. If not specified,
the e name is used.
comment: method-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
method_code: string Defines SV code to be added to the SV method. Use the <text>
</text> tags to insert multiple lines of code.
analysis_port_name: name The name of the created analysis port, implying that the
create_analysis_port attribute is set to TRUE.
Example 1
To add code to the empty hookup method created for the from_e_method, enter the code between
<text></text> markers in a method_code attribute. At the end of the execution of my_from_e_method,
the SV code defined in the method_code attribute is executed. For example:
agent my_agent {
...
from_e_method my_from_e_method {
external_name: my_from_e_method;
method_code:
<text>`message(UVM_LOW, "[%m] in my_from_e_method... ");
</text>;
};
};
See Also
● “Executing Specman Code Asynchronously” in the Specman Integrators Guide contains information
about working in mixed verification environments and using timeless models where Specman is often
called asynchronously.
5.3.9.1 to_e_event
Purpose
Create an e event that is triggered by an SV event
Context
Within any UVM component element
Syntax
to_e_event event-name {
attribute;...
};
Syntax Example
to_e_event reset_done {
external_name : report_reset_to_e_uvc;
};
Parameters
event-name The name of the e event to be defined. Wildcards are allowed. The external_name
can use $1 ($2, $3, …) to refer to the wildcards.
Description
For every event in the e export file, a corresponding UVM event class (uvm_event) is created, and an
object of this event type is created in the exported component. The event object name is the
external_name, if it is defined. Otherwise, it is the e event name. The event class name is the
external_class_name, if it is defined, or the name of the object with _event appended.
For to_e_event element, an e event is emitted each time the SystemVerilog event is triggered.
For each event, a task emit_event_name is created in the exported component. These tasks are used by
Specman and by the UVM event class, and should not be used directly by the user. The UVM library
documentation defines the API that users can use to interact with the event.
Element Attributes
Table 5-10 To e Event Element Attributes
external_name: event-name Specifies the name of the triggering event in SV. If not specified,
the e event-name is used.
comment: event-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
5.3.9.2 from_e_event
Purpose
Create an SV event that is triggered by an e event
Context
Within any UVM component element
Syntax
from_e_event event-name {
attribute;...
};
Syntax Example
from_e_event read_burst_started {
comment : "Emitted on read burst start";
data_method: get_started_read_burst_info;
};
Parameters
event-name The name of the e event as defined in e. Wildcards are allowed. The
external_name can use $1 ($2, $3, …) to refer to the wildcards.
Description
For every event in the e export file, a corresponding UVM event class (uvm_event) is created, and an
object of this event type is created in the exported component. The event object name is the
external_name, if it is defined. Otherwise, it is the e event name. The event class name is the
external_class_name, if it is defined, or the name of the object with _event appended.
For a from_e_event element, the SystemVerilog event is triggered every time the e event is emitted.
A from_e_event can declare a data_method, which must be the name of a method that has no
parameters and returns an object configured to derive from uvm_object using the adapter unit
configuration. If this method is declared, the result of this method is sent with the e event, and the user
can retrieve it from the uvm event.
If data_method is used, you can use the create_analysis_port attribute to create an analysis port based
on the exported event. In this case, every time the event is triggered, the analysis port calls its write
function using the object passed with event as parameter.
By default, UIG creates configuration fields that allow the UVC user to disable the event and data
transfer. You can remove these fields by setting the optimization_mode and data_transfer_mode
attributes to NONE.
Note The data in the event is stored as an uvm_object, so casting its attributes is required in order to
use it.
For each event, a task emit_event_name is created in the exported component. These tasks are used by
Specman and by the UVM event class, and should not be used directly by the user. The UVM library
documentation defines the API that users can use to interact with the event.
Element Attributes
Table 5-11 From e Event Element Attributes
external_name: event-name Specifies the name of the event to be created in SV. If not specified,
the e event-name is used.
comment: method-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
data_method: method-name The name of a method in the exported unit that returns data to be
sent with the event.
analysis_port_name: name The name of the created analysis port, implying that the
create_analysis_port attribute is set to TRUE.
Purpose
Export a subcomponent of the exported component
Context
Within a UVM component element
Syntax
subcomponent subcomponent-name {
attribute | element;...
};
Syntax Example
env "SV_IC'sv_type vr_axi_env" {
external_name: vr_axi_ic_env;
subcomponent masters {
external_name: masters;
};
subcomponent slaves {
external_name: slaves;
};
subcomponent passive_interconnect {
component_type: "PASSIVE'active_passive vr_axi_interconnect";
is_list: FALSE;
};
};
Parameters
subcomponent-name The name of the exported e subcomponent. If the exported subcomponent is not a
field of the exported component, the attribute component_type is required. The
value specified by component_type must correspond to a UVM component
exported elsewhere in the e export file. For example:
agent "PASSIVE'active_passive vr_axi_interconnect" {
external_name: vr_axi_interconnect_agent;
...
};
env "SV_IC'sv_type vr_axi_env" {
...
subcomponent passive_interconnect {
component_type:
"PASSIVE'active_passive vr_axi_interconnect";
....
};
};
Description
For every subcomponent element in the export file, a field of the appropriate subcomponent type is
created in the parent component. If the subcomponent element is the name of a field in the enclosing e
unit, the type of the subcomponent object is the exported type of the field. Otherwise, the user must
specify the component type. In any case, that type must be an exported component in the export file.
The name of the field is the external_name if one is defined. Otherwise, it is the name of the
subcomponent in the export file.
If the exported e field is a list, or the is_list attribute is set to TRUE, a dynamic array is created. The size
of the dynamic array is controlled by a generatable configuration attribute UIG creates under the name
num_subcomponent-name. For example, if the “slaves: subcomponent in the Syntax example above is a
list, UIG defines an unsigned integer configuration field named “num_slaves”. Your e code for dynamic
configuration can query the value of this configuration field to obtain the number of instances in the list.
Note The num_* field is placed in the container component or within the default configuration object
if use_config_object is TRUE.
Element Attributes
Table 5-12 Subcomponent Element Attributes
comment: Free text within double quotes that defines text to be added as a
subcomponent-description comment to the generated code. You can use the <text></text>
tags for multiple lines.
component_type: string The actual name as defined in e of the unit type to be exported. This
name must be provided if subcomponent-name does not match an
actual field name in the exported environment.
control_value: string Specifies the value of the control field for which the subcomponent
is built. See Example 2 below.
Example 1
In this example, a new bit field with the default name “build_mon” is created in the env’s config class.
Its default value is 0 because build_by_default is FALSE. So by default, this monitor is not built.
env my_env {
...
subcomponent mon {
control_build : TRUE;
build_by_default: FALSE;
};
...
};
Example 2
In this example, a new bit field “do_not_create_agents” is created in the env’s config class. If
“do_not_create_agents” is 0 (the value specified by control_value), the array of agents is created. The
default value for “do_not_create_agents” is 0 because build_by_default is FALSE. So by default, the
array of agents is built.
env my_env {
...
external_name: env;
subcomponent agents {
control_build: TRUE;
control_field: do_not_create_agents;
control_value: 0;
build_by_default: FALSE;
};
...
};
Purpose
Specify the DUT interface to be exported for a UVM component
Context
Within a UVM component element
Syntax
dut_interface e-unit-name {
attribute;...
};
Syntax Example
sequencer vr_axi_slave_driver {
...
dut_interface vr_axi_signal_interface {
interface_type:vr_axi_master_signal_map ;
};
};
Parameters
e-unit-name If the exported DUT interface is not a field of the exported component, the attribute
interface_type is required. The value specified by interface_type must
correspond to an interface element defined elsewhere in the e export file. For
example:
sequencer vr_axi_slave_driver {
...
dut_interface vr_axi_signal_interface {
interface_type:vr_axi_master_signal_map ;
};
};
interface vr_axi_master_signal_map {
...
;
Description
Multiple dut_interface elements are allowed in a single component.
This element defines a DUT interface for the exported component. For every dut_interface element in
a component, a virtual interface handle of the exported interface type is created in the exported
component class. If the DUT interface element is a name of a field in the exported unit, the type of the
virtual interface handle is the exported type of the field. Otherwise, the user must specify the interface
type. In any case, that type must be exported in the export file as an interface element.
The name of the virtual interface handle is the external_name if it is defined. Otherwise, it is the name
of the DUT interface element.
If a component has one or more DUT interfaces, by default a function called assign_vi() is created in the
component in order to set the virtual interface handles. (See create_assign_vi in Table 5-3 on page
5-19.) The function’s parameters are all the DUT interfaces defined for the component. If the component
is an agent, and it has subcomponents that themselves have DUT interface elements of the same type, by
default the agent’s assign_vi() function propagates the relevant interfaces to the subcomponents.
According to the UVM flow, this function should be called by the user in connect_phase().
Element Attributes
Table 5-13 DUT Interface Element Attributes
comment: Free text within double quotes that defines text to be added as a
DUT-interface-description comment to the generated code. You can use the <text></text>
tags for multiple lines.
interface_type: string The name of an exported interface type, defined elsewhere in the
export file. Must be provided if DUT interface is not based on an
actual e field of the exported component.
external_package_name: The name of the SV package to contain the exported entities. The
package-name default is the UVC’s package name.
Purpose
Export configuration properties for a UVM component
Context
Within a UVM component element
Syntax
config sv-field-name {
attribute | element;...
};
Syntax Example
config cfg {
include_fields: vr_axi_component.*;
include_fields: vr_axi_interface.*;
include_fields : vr_axi_master_config.*;
field is_default {
e_type: bool;
default_value: TRUE;
}:
};
Parameters
sv-field-name The name of the exported e unit that contains ports to be connected to the DUT.
Description
UIG allows the definition of properties in the SystemVerilog proxy classes to be used for configuration.
The exported attribute can originate from a field in the associated e unit but this is not a requirement.
You can use this feature to reflect any e UVC attribute that the SystemVerilog user should assign to
control the configuration and behavior of the e UVC.
To take a configuration property from the associated e unit (or any other e struct), specify the fields
using the include_fields and exclude_fields attributes. To create properties not based on any e field, use
the field element. (See “Field Element” on page 5-52 for more information.)
You can use the use_config_object attribute to encapsulate several configuration properties in a class. If
set to TRUE, a configuration class is created for the component and a field of this class type is created in
the component.
The name of the configuration object’s field is the external_name, if one is defined. Otherwise, it is the
name of the configuration element in the export file. The name of the configuration class is the
external_class_name if one is defined. Otherwise it is component_type_name_config.
If a parent component has a configuration object, UIG automatically adds to the parent’s configuration
class a configuration object for each of the subcomponents that also has a configuration object. Values
for these objects are automatically propagated to the subcomponents during the parent’s build function.
In sequencer, driver and monitor elements, an uvm_object field is automatically created to hold the
parent’s configuration. This field is set during the parent’s build function if the parent has a
configuration object.
Element Attributes
Table 5-14 Configuration Element Attributes
comment: Free text within double quotes that defines text to be added as a
config-struct-description comment to the generated code. You can use the <text></text>
tags for multiple lines.
use_config_object: bool If TRUE, creates a configuration class for use with the component.
If FALSE (the default), all configuration properties of this
component are placed directly in the component class itself. For
example:
use_config_object : TRUE;
class_code: string Defines SV code to be added to the class. Use the <text> </text>
tags to insert multiple lines of code.
new_function_code: string Specifies code to be added to the class constructor (the new
function). Use the <text> </text> tags to insert multiple lines of
code.
include_fields: Specifies the names of specific fields that are used as configuration
struct-name.field-name properties of the exported component. Wildcards are allowed for
the field name.
exclude_fields: Specifies the names of specific fields that are not used as
struct-name.field-name configuration properties of the exported component. Used to refine
the choice of fields made with include_fields. Wildcards are
allowed for the field name.
field_name_in_parent_config: Use this attribute to specify the name of the field that is created in
name this component’s parent configuration class.
default: bool Indicates that this is the default config element. If no config
element has this attribute, the first element defined is the default.
All the properties that UIG creates automatically, including the
configuration objects of the subcomponents, are created in the
default configuration object.
Purpose
Define a configuration field not based on an e field
Context
Within a config element
Syntax
field field-name {
attribute;...
};
Syntax Example
field has_checks {
e_type: bool;
default_value: TRUE;
is_rand: TRUE;
};
Parameters
Description
You can use this element to create configuration fields not based on any e field.
● Specifying the e_type attribute creates a field of an SV type that is equivalent to the specified e type.
● Specifying the external_type attribute creates a field of the specified SV type. It must be a valid
SystemVerilog type.
Notes
● UIG does not check whether the external_type specified is valid. If it is not valid, a compilation
error occurs when you try to compile the UVC.
● When specifying an external_type, use the external_kind attribute to tell UIG what kind of type it
is. Currently, UIG supports only scalar, enumeration or string types.
Element Attributes
Table 5-15 Field Element Attributes
comment: field-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
e_type: e-type-name A valid e type name. UIG checks that the specified type is valid
and then sets the generated field’s type to the equivalent
SystemVerilog type.
is_rand: bool If TRUE, the field is created as a generatable field. The default is
FALSE.
is_static: bool If TRUE, the field is created as a static field. The default is FALSE.
is_list: bool If TRUE, the field is created as an array. The default is FALSE.
Purpose
Define an exported DUT interface
Context
Top-level, not within any other element
Syntax
interface e-unit-name {
attribute | element;...
};
Syntax Example
interface vr_axi_master_signal_map {
// The name of class type in SV
external_name: vr_axi_signals;
...
signal awaddr {
...
};
clocking_block clk_blk {
...
};
};
Parameters
e-unit-name The name of the exported e unit that contains ports to be connected to the DUT.
element The interface element can contain signal and clocking_block elements. These
elements define the contents of the generated interface.
Description
All communication between the generated UVM components and the DUT as well as between Specman
and the DUT must be done using a SystemVerilog interface (a SV signal map):
generated-UVM-components => SV-interface => DUT
Specman => SV-interface => DUT
When you define an interface element, UIG creates the SV-interface for you. You can define more than
one interface element in an export file. For each interface declaration in the export file, UIG creates a
SystemVerilog interface that includes by default signals matching all the simple ports and all the input
event ports declared in the base type of the exported unit.
See “Example Selectively Including/Excluding Ports” on page 5-58 for more information.
You can define signal and clocking_block elements within the interface element to control in more detail
how the ports are exported.
By default, the ports are exported as signals. You can configure each signal to be created as a port
instead of as a signal using the create_as_port attribute.
If you already have SV module that defines a signal map, you can use this instead of or in addition to
defining an interface element. See “Example HDL Wrapper” on page 5-58 for more information.
Element Attributes
Table 5-16 Interface Element Attributes
comment: Free text within double quotes that defines text to be added as a
interface-description comment to the generated code. You can use the <text></text>
tags for multiple lines.
exclude_signals: port-name The names of simple ports that are not to be exported as signals of
the interface. Simple ports not matched by exclude_signals are
exported.
include_signals: port-name The names of simple ports that are exported as signals of the
interface. include_signals looks for ports in the exported unit only,
not in its when subtypes. Simple ports not matched by
include_signals are not exported.
interface_code: string Inserts additional code into the exported entity. Use the <text>
</text> tags to insert multiple lines of code.
post_declaration_code: code Specifies code to be added after all other declarations in the
generated interface.
pre_declaration_code: code Specifies code to be added before any other declarations in the
generated interface.
implementation_code: string Inserts additional code into the implementation section of the
interface. Use the <text> </text> tags to insert multiple lines of
code.
signal_code: string Inserts additional code into the signal section of the interface. Use
the <text> </text> tags to insert multiple lines of code.
interface signal_map {
include_signals: p*; // matches p1 and p2
deep_include_signals: /p3/; // matches p3
deep_include_signals: "MASTER signal_map.p3"; //matches p3
exclude_signals: "/write_enable/"
};
Note You can export multiple HDL wrappers or use an HDL wrapper in combination with a
UIG-generated interface.
};
UIG generates implementation code for the ports you specified. If you defined multiple
hdl_wrapper containers, each exported HDL wrapper is stored in a different file. The name of the
exported wrapper file is wrapper-name_imp.svh, where wrapper-name is the name of the
hdl_wrapper container that you defined in Step 1.
4. Open the SV file that defines the signal map and add a ‘include line with the name of the
UIG-generated svh file.
e Code
unit vr_axi_signal_map {
data: out simple_port of int;
keep data.verilog_wire() == TRUE;
address: out simple_port of int;
keep data.driver() == TRUE;
};
eexp file
hdl_wrapper vr_axi_signal_map {
include_signals: address;
include_signals: data;
signal address {
signal_kind: verilog_wire;
net_type: wire;
...
};
signal data {
signal_kind: driver;
net_type: wire;
...
};
...
};
bit reset;
bit clock;
endmodule : vr_axi_hdl_wrapper
...
Purpose
Controls the export of specific ports
Context
Within an interface element
Syntax
signal e-port-name {
attribute;...
};
Syntax Example
signal wstrb {
signal_size: "[(`VR_AXI_MAX_DATA_WIDTH/8)-1:0]";
};
Parameters
e-port-name The name of the e port to be exported. By default, for all simple port fields of the
exported unit, matching signals are created in the interface.
Description
This element configures the exported interface signals:
● The name of the signal is the external_name if specified, or else the port’s field name.
● The net type of the signal is the net_type if specified, or else the signal is a variable.
● The data type of the signal is the data_type if specified, or logic by default. This is also the default
data type for nets.
● If the exported field is a list of simple ports, you must specify the list size using the list_size attribute.
By default, an unpacked array is created. If the size of the port’s element type is 1 bit (bit, bool, mvl)
and the create_packed_array attribute is set to TRUE, a packed array is created instead. To create
separate signals for each port in the list instead of an array, set the create_array attribute to FALSE.
● The signal’s packed dimensions are signal_size if specified, or the size of the exported port element
type.
● By default, each port is not exported as an interface port. If the create_as_port attribute is TRUE,
the signal is exported as an interface port with the direction specified by the port_direction attribute.
The default direction is inout.
Notes
● To define a signal with a variable width, you can use `defines. For example:
signal p {
signal_size: "[`MAX_WIDTH-1:0]";
};
● When defining external names for the exported signals, you can use wildcards and $ variables in the
expression. The number of $ variables is equal to the number of wildcards in the expression and the
variable index starts at 1. Both AWK-style and Specman-style expressions are supported. For
example:
interface my_signal_map {
external_name: signal_map;
signal p*ma* {
external_name: s$1ma$2;
};
};
Element Attributes
Table 5-17 Signal Element Attributes
external_name: signal-name Specifies the name of the exported signal in SV. The default is the
e port field name.
comment: signal-description Free text within double quotes that defines text to be added as a
comment to the generated code. You can use the <text></text>
tags for multiple lines.
net_type: string Specifies the net type of the signal. If not defined, the signal is a
variable.
data_type: string Specifies the data type of the signal. If not defined, the default is
logic. This is also the default data type for nets.
initial_value: value A string specifying the initial value to be driven to the signal.
signal_size: string Specifies the packed dimensions of the signal. The default is the
size of the exported port element type.
list_size: string If the exported signal is a list of simple ports, this attribute is
required to specify the size of the generated array.
create_as_port: bool If TRUE, the signal is created as a port of the interface. The default
is FALSE.
create_array: bool If TRUE (the default), a list of simple ports is exported as an array.
If FALSE, separate signals are created for every port in the list.
Each signal’s name is appended with its index in the list.
list_delimiter: string If create_array is used, this string is used to separate the created
signal’s name and its index.
Purpose
Define a clocking block for the created interface
Context
Within an interface element
Syntax
clocking_block clocking-block-name {
attribute;...
};
Syntax Example
clocking_block clk_blk {
clocking_event: "clk";
default_driving_skew: "#0";
clocking_code: <text>always @clk $display("[%m] clk = ",clk);</text>;
};
Parameters
Description
This element is not based on a field of the exported unit.
SystemVerilog clocking blocks specify timing and synchronization requirements on signals in the DUT.
You can sample or drive signals with optional skews relative to a certain clock. This allows you to
sample the value a signal had some time in the past, as well as to drive a signal with a certain delay, all
relative to some clock.
You can define one or more clocking blocks in an interface but only one of them can be the default
clocking block, as defined in the SystemVerilog LRM.
Within a clocking block, you can declare default driving and sampling skews. Using the
include_signals and exclude_signals keywords you can select which signals are present in the clocking
block. Using a clocking_signal element, you can define signals (declared within this given interface) to
be sampled and/or driven within the clocking block.
Element Attributes
Table 5-18 Clocking Block Element Attributes
comment: Free text within double quotes that defines text to be added as a
clocking-block-description comment to the generated code. You can use the <text></text>
tags for multiple lines.
clocking_event: event An event with which the driving and sampling of the clocking
signals is to be synchronized. Any legal event for SV clocking
blocks is valid here.
clocking_code: string Inserts additional code into the clocking block. Use the <text>
</text> tags to insert multiple lines of code.
default: bool If TRUE, the clocking block is created as the default clocking
block. The default is FALSE
default_driving_skew: string A string specifying a default time skew for driving inout and
output signals. For example: “#2”. There is no default driving
skew.
default_sampling_skew: A string specifying a default time skew for sampling input and
string inout signals. The default is “#0”.
exclude_signals: port-name The names of simple ports that are not to be included in the
clocking block. Simple ports not matched by exclude_signals are
included.
include_signals: port-name The names of simple ports that are included in the clocking block.
include_signals looks for ports in the exported unit only, not in its
when subtypes. Simple ports not matched by include_signals are
not included.
Example 1
In the following example, all exported signals (specified by the wildcard “*”) are DUT inputs (specified
by “direction: output”) and will be driven with the default skew of #2 when an event occurs on “aclk”.
clocking_block clk_blk {
clocking_event: aclk;
default_driving_skew: "#2";
clocking_signal: * {
direction: output;
};
};
Purpose
Define one or more signals to be sampled and/or driven within the clocking block
Context
Within an clocking_block element
Syntax
clocking_signal port-name {
attribute;...
};
Syntax Example
clocking_signal clk_sig {
direction: INPUT;
driving_skew: "#2";
};
Parameters
port-name The name of the exported port in the interface, as specified by include_signals or
deep_include_signals. The syntax for port-name is [struct_name.]port_name.
Regular expressions using Specman style or AWK style are allowed. See
“Interface Element” on page 5-54 for examples.
Description
This element is not based on fields of the exported unit, but on signals already exported in the interface.
You can declare an optional input and/or output skews for the signals.
Element Attributes
Table 5-19 Clocking Signal Element Attributes
comment: Free text within double quotes that defines text to be added as a
clocking-signal-description comment to the generated code. You can use the <text></text>
tags for multiple lines.
direction: direction INPUT clocking signals (DUT outputs) can be sampled but not
driven. OUTPUT clocking signals (DUT inputs) can be driven but
not sampled. INOUT clocking signals can be sampled and driven.
The default is INPUT.
driving_skew: string A string specifying a time skew for driving the clock signal. For
example: “#2”. The default is the default_driving_skew specified
for the clocking block.
sampling_skew: string A string specifying a time skew for sampling the clock signal. For
example: “#2”. The default is the default_sampling_skew
specified for the clocking block.
When the SV interfaces are created in this way, users of the UVC can:
See Also
● “Creating an SV UVC Proxy Based on an Existing Proxy” on page 5-68
● “Reusing Data Types and Components from an Existing SV UVC Proxy” on page 5-68
● “Extending the Hierarchy of Class Data Types” on page 5-70
● “Known Limitations” on page 5-71
cdn_i2c_cb.eexp:
sequencer cdn_i2c_master_sequence_driver {
external_name: cdn_i2c_master_sequencer;
...
};
cdn_smbus_cb.eexp
agent cdn_smbus_master_agent {
external_name: cdn_smbus_master_agent;
subcomponent sequencer {
component_type: cdn_i2c_master_sequence_driver;
};
...
};
If this method returns TRUE for any given type, this type's declaration will not be created in the relevant
package. The “relevant package” means any package for which this code is loaded during UIG
invocation.
For example, assume you exported cdn_i2c_master_transaction in the I2C package, and you want to
reuse it in the SMBUS package. The following method must be added to the I2C adapter unit
configuration to prevent this type from being created again in the SMBUS package:
extend cdn_i2c_config_unit {
remove_type_declaration(cur_type: rf_type) : bool is also {
if (cur_type.get_name() == "cdn_i2c_master_transaction") {
result = TRUE;
};
};
};
Notes
● The adapter unit's package_name field must be set to the type's package. Otherwise this code does
not have any impact. Since probably an adapter unit for this package (reference package) already
exists, it is best to extend this unit and add the method to it. This extension should only be loaded
when generating the reusing package.
● Make sure to use the get_package_name() method to explicitly specify the destination package of a
type. This also must be done in an adapter unit whose package_name field is the same as the package
in which the type is declared in. This method should be loaded when generating the reference package
and the reusing package.
For example, assume you exported cdn_i2c_master_transaction in the I2C package, and you want to
create a class inheriting from it in the SMBUS package:
Type Definitions:
package cdn_i2c;
struct cdn_i2c_master_transaction {
...
};
package cdn_smbus;
struct cdn_smbus_master_transaction like cdn_i2c_master_transaction {
...
};
result = "cdn_smbus";
};
};
};
extend sys {
cdn_smbus_config_unit is instance;
keep cdn_smbus_config_unit.package_name == "cdn_smbus";
};
● Extending the hierarchy using when subtypes must be done using the when hierarchy adapter unit
configuration. The reference package does not have to use when hierarchy, but in order to export a
when subtype of a type exported in the reference package, the reusing package must configure the
when hierarchy.
● When subtypes are always defined in the context of the package of the when base, even if the subtype
is explicitly defined in another package. This means that all when hierarchy configuration must be
done in the adapter unit of the when base's package.
● If the reusing package does not explicitly export a construct that uses the extended types, the
extend_type top level export file attribute must be used to tell UIG that a type needs extending.
Without this attribute UIG will not create the extension.
The file uses the UIG configuration API to query the UVM user environment and build the e
environment accordingly. This file must be loaded at simulation time and might also be needed during
UIG invocation and stub generation, depending on the UVC.
You can enable dynamic configuration in one or more of the following ways:
Note Although configuration properties might be comprised of complex objects, only integer and
string values can be queried.
Table 5-20 UIG Dynamic Config API: Quick Reference
Method Description
uig_get_uvm_path_by_id on Returns the full UVM path of an instance using the component’s id
page 5-76
uig_get_array_size on page Returns the size of an array field under the component or inside a
5-79 configuration object of the component
Each exported unit needs to have two UVM unit attributes defined, as described in Table 5-21. For the
top-level e entities (one or more units of type any_env), you first set the uvm_unit_id arbitrarily and
then retrieve the uvm_path. For each subcomponent, because its place in the unit hierarchy is
important, you calculate the uvm_path based on the parent’s path and then set the uvm_unit_id.
Table 5-21 UIG Unit Attributes: Quick Reference
Attribute Description
uvm_path() This attribute specifies the full UVM path of the SystemVerilog
proxy class instance associated with an e unit. The UVM path
attribute must hold the same string value that would be returned by
calling the proxy class instance’s get_full_name() function. This
function is defined in the UVM SystemVerilog uvm_component
class. For top level instances, you know the ID of the instance and
can use the uig_get_uvm_path_by_id() utility function to obtain
the path.
See Also
● “Dynamic e Configuration API” on page 5-71
Note If you use define as computed macros to dynamically configure the UVC, you must specify
those with the load_after_build attribute in the e export file. These macros are compiled only after the
SV environment is built.
The following example shows the use of a define as computed macro to extend an enumerated type and
add values defined in SV. This is typically part of the dynamic configuration logic.
Usage Example:
acme_uvc_soft_extend acme_uvc acme_uvc_env_name_t uvc_name acme_uvc_env_u;
This example:
● Assumes the SV code has proxy classes of type “acme_uvc_env_u” in a package called “acme_uvc”
● Assumes each of those classes has an exported string config field called “uvc_name”
● Creates e code that extends the “acme_uvc_env_name_t” enumerated type with all the values
assigned to the uvc_name field in all SV instances of acme_uvc_env_u
For example, if the SV has two instances of acme_uvc_env_u, with their uvc_name field equal to
“ENV0” and “ENV1”, the macro invocation above generates the following code:
extend acme_uvc_env_name_t: [ENV0, ENV1]
Macro Code:
define <acme_uvc_soft_extend'statement>
"acme_uvc_soft_extend <sv_pkg'name> <e_type'name> <sv_field'string>
<sv_type'name>,..." as computed {
var list_size: uint;
var uvm_path: string;
var names: list of string;
var idx:uint;
var name: string;
for each (sv_t) in <sv_type'names> {
list_size = uig_get_num_instances(<sv_pkg'name>, // SV package name
sv_t); // SV type
for {idx=0; idx<list_size; idx+=1} do {
uvm_path = uig_get_uvm_path_by_id(<sv_pkg'name>, // SV package name
sv_t, // SV type name
idx); // serial ID
name = uig_get_field_value_string(<sv_pkg'name>, // SV package name
sv_t, // SV type name
uvm_path, // SV path
<sv_field'string>); // SV field name
names.add(name);
};
};
names = names.sort(it).unique(it);
var rfe:rf_enum = rf_manager.get_type_by_name(<e_type'name>).as_a(rf_enum);
var cur_names : list of string = rfe.get_items().apply(it.get_name());
var new_names : list of string = names.all(it not in cur_names);
return appendf("extend %s: [%s]", <e_type'name>, str_join(new_names, ","));
};
1. Specify the default value for this define both in e and in SV.
For example, in e:
#ifdnef MAX_WIDTH
#define MAX_WIDTH 100
#endif
And in SV:
`ifdnef MAX_WIDTH
`define MAX_WIDTH
`endif
You can store the defines file in e_uvc-dir/sv.
3. Instruct the user to over-ride the value in one of the following ways:
For example:
irun .... -defineall "MAX_WIDTH 32"
Or
irun .... -defineall MAX_WIDTH=32
b. Put the define in SV header file and give its name as a parameter to irun.
5.5.4 uig_get_num_instances
Purpose
Return the total number of instances of a specific exported type
Syntax
uig_get_num_instances(package_name: string, type_name: string, default_value: int =0):int
Syntax Example
extend sys {
//number of AXI envs with interconnect from SV world
vr_axi_sv_ic_axi_envs : list of vr_axi_env is instance;
keep vr_axi_sv_ic_axi_envs.size() ==
uig_get_num_instances("vr_axi","vr_axi_ic_env",1);
...
};
Parameters
default_value The value to be used during interface generation and stubs generation, when the
actual user environment is not available. The default is 0.
5.5.5 uig_get_uvm_path_by_id
Purpose
Returns the full UVM path of an instance using the component’s id.
Syntax
uig_get_uvm_path_by_id(package_name: string, type_name: string, uvm_unit_id: int):string
Syntax Example
env.uvm_path() ==
uig_get_uvm_path_by_id("vr_axi","vr_axi_ic_env",env.uvm_unit_id())
Parameters
Note No default value is needed for this method. An empty string is returned during interface and
stub generation.
5.5.6 uig_get_field_value_<type>
Purpose
These methods retrieve a field value from a specific UVM exported component
Syntax
uig_get_field_value_int (package_name: string, type_name: string, path: string, field_name: string,
default_value: int = 0):int
Syntax Example
slave.uvm_unit_id() ==
uig_get_field_value_int("vr_axi","vr_axi_slave_agent",
slave.uvm_path(),"id", 0);
slave.config.interface.bus_endiannes ==
uig_get_field_value_string("vr_axi",
"vr_axi_slave_agent", slave.uvm_path(),"cfg.bus_endiannes",
"LITTLE").as_a(vr_axi_endianness_t);
Parameters
path The uvm path of an exported component that is defined with the type type_name
in a package package_name.
field_name Can be a path under the component, if the required field is inside a configuration
object.
default_value The value to be used during interface generation and stubs generation, when the
actual user environment is not available.
Description
uig_get_field_value_int() returns a 32-bit signed integer. uig_get_field_value_long() returns a
1024-bit signed integer. You can retrieve numerated types using the int and string methods.
5.5.7 uig_get_dut_interface_path
Purpose
Return the full hierarchical path of a DUT interface instance
Syntax
uig_get_dut_interface_path(package_name: string, type_name: string, path: string, field_name: string,
default_value: string = “”):string
Syntax Example
slave.hdl_path() == uig_get_dut_interface_path("vr_axi",
"vr_axi_slave_agent",slave.uvm_path(),"vr_axi_signal_interface","");
Parameters
path The uvm path of an exported component that is defined with the type type_name
in a package package_name.
field_name The name of the virtual interface field under the exported component.
default_value The value to be used during interface generation and stubs generation, when the
actual user environment is not available.
5.5.8 uig_get_dut_interface_id
Purpose
Return the id of a DUT interface instance
Syntax
uig_get_dut_interface_int(package_name: string, type_name: string, path: string, field_name: string,
default_value: int = 0):int
Syntax Example
slave.id() == uig_get_dut_interface_id("vr_axi",
"vr_axi_slave_agent",slave.uvm_path(),"vr_axi_signal_interface","");
Parameters
path The uvm path of an exported component that is defined with the type type_name
in a package package_name.
field_name The name of the virtual interface field under the exported component.
default_value The value to be used during interface generation and stubs generation, when the
actual user environment is not available.
5.5.9 uig_get_array_size
Purpose
Returns the size of an array field under the component or inside a configuration object of the component
Syntax
uig_get_array_size(package_name: string, type_name: string, path: string, field_name: string,
default_value: int = 0)
Syntax Example
slave.array.size() == uig_get_array_size("vr_axi",
"vr_axi_slave_agent",slave.uvm_path(),"vr_axi_slave_array","");
Parameters
path The uvm path of an exported component that is defined with the type type_name
in a package package_name.
default_value The value to be used during interface generation and stubs generation, when the
actual user environment is not available.
Using mltypemap lets you avoid manually coding type definitions, which can be complex, tedious, and
error prone.
The supported source languages are SystemVerilog, e, and SystemC. The supported target languages are
SystemVerilog, e, and SystemC.
6.1 Examples
The following sections contain simple, runnable examples for mltypemap. The examples are divided
into sections based on the three source languages (e, SystemVerilog, or SystemC) and show how to
convert to each of the other two.
● run_mltypemap.sh— Invokes irun with the mltypemap option, and specifies a Tcl run file and e
input file
● test.e — The e source file. Its types will be mapped to either SystemVerilog or SystemC.
● do.tcl — The configuration file, specific for each output language.
● Configures mltypemap using the configuration commands described in “Configuring mltypemap”
on page 6-19
● Invokes the mapping process using the maptypes command described in “Invoking mltypemap”
on page 6-10
The mapped type is msg. It is mapped along with its two subtypes big_msg and small_msg.
File: run_mltypemap.sh
irun \
-mltypemap_input do.tcl \
test.e
File: test.e
<'
package dt;
struct msg {
kind : kind_t;
!top_unit : any_unit; // pointer to unit - do not map
};
'>
File: do.tcl
# This will generate UVM code
# to generate OVM code add the configuration command
# configure_code -ovm
Output Files
The output of the irun command for the SystemVerilog target language is three files, with base name
sv_dt:
File: do.tcl
# This will generate UVM code
# to generate OVM code add the configuration command
# configure_code -ovm
Output Files
The output of the irun command for the SystemC target language is three files, with base name sc_dt:
● run_mltypemap.sh — Invokes irun with the mltypemap option, and specifies a Tcl run file and
SV input file
● test.svh — The SystemVerilog source file
● do.tcl — The configuration file, specific for each output language.
● Configures mltypemap using the configuration commands described in “Configuring mltypemap”
on page 6-19
● Invokes the mapping process using the maptypes command described in “Invoking mltypemap”
on page 6-10
The mapped type is msg. It is mapped a long with the type data, which is used for one of its fields.
File: run_mltypemap.sh
irun \
-uvm \
-mltypemap_input do.tcl \
test.svh
File: test.svh
`ifndef TEST_SVH
`define TEST_SVH
`include "uvm_macros.svh"
package dt;
import uvm_pkg::*;
endpackage : dt
`endif
File: do.tcl
# map the scope dt to sn_dt
configure_scope -scope sv:dt -to_scope sn_dt
Output Files
The output of the irun command for the e target language is four files, with base name sn_dt:
File: do.tcl
# map the scope dt to sc_dt
configure_scope -scope sv:dt -to_scope sc_dt
Output Files
The output of the irun command for the SystemC target language is three files, with base name sc_dt:
● run_mltypemap.sh — Invokes irun with the mltypemap option, and specifies a Tcl run file and
SV input file
● test.cpp and test.h — The SystemC source files
● do.tcl — The configuration file, specific for each output language.
● Configures mltypemap using the configuration commands described in “Configuring mltypemap”
on page 6-19
● Invokes the mapping process using the maptypes command described in “Invoking mltypemap”
on page 6-10
The mapped type is msg. It is mapped along with the type data, which is used for one of its fields.
In these examples, mltypemap will map the type packet defined in the two source files: test.cpp and
test.h.
File: run_mltypemap.sh
irun \
-uvm \
-mltypemap_input do.tcl \
test.cpp \
-sysc \
-compile
File: test.cpp
#include "test.h"
namespace dt {
packet::packet() {}
packet::~packet() {}
File: test.h
#ifndef PACKET_H
#define PACKET_H
#include "ml_uvm.h"
using namespace uvm;
namespace dt {
packet();
virtual ~packet();
public:
sc_int<64> addr;
std::string name;
std::vector<sc_int<8> > data;
};
}; // namespace dt
#endif
File: do.tcl
# configure the scope
configure_scope -scope sc:dt -to_scope sn_dt
File: do.tcl
# configure the scope
configure_scope -scope sc:dt -to_scope sv_dt
Note When working with SystemC input, the input file must be a single CPP file and the
argument –sysc has to be given. More than one input file is currently not supported for SystemC.
4. Abort.
irun Arguments
Argument Description
-mltypemap_input input-file Identifies the name of an input file that contains TCL commands for
mltypemap. Typically this file contains mltypemap configuration
commands and one or more mltypemap map commands.
Examples
Syntax
maptypes –to_lang lang -from_type type-name -base_name base-name
Syntax example
maptypes –to_lang sv –from_type e:ahb::ahb_packet –base_name ahb_datatypes
Parameters
Parameter Description
–to_lang lang The name of the target language. The accepted language names are:
● e (or sn)
● sv
● sc
-from_type type-name The name of the source type. The type-name must be the full name
(including package/namespace qualifiers) and must contain the
language prefix (e, SV, SC).
-base_name base-name The base name for the output files. This parameter is mandatory.
The base name can contain a directory path to a folder. For example:
-base_name my_types
-base_name my_dir/my_dt
Description
As described above, you use the mltypemap TCL command maptypes to invoke the mapping process.
Note that the input to mltypemap must be a type defined inside a package, and, therefore, its name must
be qualified with the package name:
● In e, all types that are not defined explicitly inside a package, are defined inside the package “main”.
To map such a type, the “main” qualifier has to be used (for example, -from_type e:main::packet).
● In SystemVerilog, only types defined inside a package are supported. Types defined inside a module,
or types defined inside the compilation scope are not supported.
● In SystemC, types should be defined in namespace, or in the global namespace. Types defined inside
classes are currently not supported.
Example
The following command generates type definitions in SystemVerilog for the e type ahb_packet:
mltypemap> maptypes –from_type e:ahb::ahb_packet \
-to_lang sv \
-base_name ahb_datatypes
In addition, a serialization code is generated if SystemVerilog is the source or target language. The
serialization file name is base-name_ser.sv.
In addition, serialization code is generated if e is the source or target language. The serialization file
name is base-name_ser.e.
Limitation: No serialization code is generated to SystemC, because SystemC uses the default UVM
packing for ML serialization.
When a class is mapped, all its subtypes are mapped as well. Also, the parent classes of this class are
mapped. By default, the name of the mapped class is as the name of the source class.
You can change the default settings with the configure_type command (see configure_type Command
on page 6-21).
By default, only public, non static fields are passed. The mapping of a field can be configured using the
configure_field command. (see configure_field Command on page 6-23).
When a non-public field is passed, you can specify the setter/getter methods for the source field, as well
as for the target field.
Static Fields
By default, static fields are not mapped. Mapping of static fields is not supported, and a run-time error is
given if a static field is configured to be passed.
Randomization Modifier
“rand” or “randc” fields in SystemVerilog are mapped to a generated field in e. Generated fields in e are
mapped to “rand” field in SV.
For example:
type packet_kind : [BIG,SMALL];
struct packet {
kind : packet_kind;
when BIG packet {
data: byte;
};
when SMALL packet {
data : int(bits:100);
};
};
In this case, the struct packet has two when subtypes, BIG packet and SMALL packet. By default, all
fields defined under when will be flattened into the type packet, and their default names will be
BIG__data and SMALL__data.
If a struct in e contains a field whose type is a when subtype, this field is mapped to a field whose type
is the base type of the when subtype. For example:
struct data {
rp : RED packet;
};
In this case, the mapped type of “data” will have a field whose type is the mapped type of “packet”, not
of “RED packet”. For example, if the target language is SV, then:
class data {
packet rp;
};
struct packet {
kind : packet_kind;
when BIG packet {
data: byte;
};
when SMALL packet {
data : int(bits:100);
};
};
Suppose further that you would like to skip the field SMALL'packet.data. The proper command
would be:
configure_type -type "e:SMALL user_pkg::packet" -skip_field data
e SystemVerilog SystemC
e SystemVerilog SystemC
sc_bv<n>
Note Four-value scalars are not supported, and an error is given if a field on such a type is passed.
When the input language is SystemVerilog, mltypemap can be configured to map four-value scalars as
two-value scalars, the configuration can be done globally using configure_code -lang sv
-map_all_as_2value, or per field using configure_field option -map_as_2value. See also
“configure_field Command” on page 6-23 and “configure_code Command” on page 6-26.
Note When mapping scalars of size 8,16,32 or 64 bits to SystemC, the mapping can be controlled
using configuration option -use_cpp_type or -use_sc_type. See also “configure_field Command” on
page 6-23.
You can use the command configure_type to configure the mapping of the enum type and the command
configure_enum_item to configure the mapping of the enum items themselves. (See configure_type
Command on page 6-21 and configure_enum_item Command on page 6-25.)
6.3.8.1 Example
Given the following enum in e:
type color : [RED = 10; GREEN = 20 ; BLUE = 30];
Notes
● Specman only supports numeric typedefs. If the output language is e, all non-numeric typedefs (to
classes, or aliases for other types), will not be created, and the underlying types will be used instead.
● Typedefs defined inside a class scope will be created in the target language inside a namespace with
the class’s name, and not inside a class scope.
6.3.9.1 Example
Given the following typedef in SystemVerilog:
typedef bit signed[17:0] int18;
There are four configuration commands used to configure type-related entities: configure_scope,
configure_type, configure_field and configure_enum. The configure_code command used for global
configuration regarding the generated code. In addition, there is a print_type command that can be used
to get information about types and the configuration commands applied to them.
For example, to apply configuration type command to all types of package vr_ahb, that start with the
prefix my_, the following command has to be written:
configure_type -type e:/vr_ahb::my_/ …
For some configuration properties, sub matches can be used to set the new value of the configuration.
This is done by using $0,..,$9 in the appropriate property, and by adding () to group the sub matches in
the regular expression (where $0 refer to the full match). For example, to map all fields of type packet
starting with sv_ to start with sn_, the following command can be given:
configure_field -type sv:sv_ahb::packet -field {/^sv_(.*)/} -to_name {sn_$1} …
For simple regular expressions containing only the expression for any number of characters (.*), the
regular expression can be written as a wildcard (*), and without slashes. That is, the following are equal:
-type e:/vr_ahb::my.*bus/
-type e:vr_ahb::my*bus
If a certain property was re-configured, then the last configuration command wins and no warning is
given.
To get more information about the configuration, the print_type command can be used, which prints for
a given type the configuration commands that were applied to this type. See print_type Command on
page 6-26 for more details.
Syntax
configure_scope -scope scope-name-or-regex -to_name field-name
Syntax Example
configure_scope –scope e:vr_ahb –to_name cdn_ahb
Parameters
Argument Description
-scope scope-name-or-regex Name of source scope. This name should include the language prefix.
For example: -scope e:vr_ahb
-to_name field-name The name of the target scope. This name can contain $0..$9 refer to
the sub-matches of the scope-name-or-regex.
Description
This command should be used to configure properties of a scope (only its target name).
Note that a scope of a type can be defined using configure_scope or configure_type. If both commands
are relevant for a specific type, then the configure_type takes effect, because it is more specific.
Syntax
configure_type
-type source-type-name-or-regex
-skip_field field-name-or-regex
-pass_field field-name-or-regex
-to_name name
-to_scope scope-name
-use_existing
-skip_type
Syntax Example
configure_type –type e:vr_ahb::ahb_burst -skip_field driver \
-skip_field parent_unit -to_name AhbBusrt
Parameters
Parameter Description
-type source-type-name-or-regex Name of the source type. This name should be qualified and should
include the language prefix. For example:
-type sv:cdn_ahb::ahb_burst
-skip_field field-name-or-regex Name of a field to be skipped. This parameter can be repeated for
several fields and a regular expression can be used. This should be
used to tell mltypemap to skip fields which by default are passed.
-pass_field field-name-or-regex Name of field to be passed. The parameter can be repeated for several
fields and a regular expression can be used. This should be used to
tell mltypemap to pass field which by default is skipped.
-to_name name Target name of the type. The target name should be the simple, non
qualified name. For example, “-to_name packet”. Note that this name
can contain $0..$9; refer to sub matches in the
source-type-name-or-regex.
-to_scope scope-name Name of the scope where the type has to be defined. By default, the
target scope is the same as the scope of the source type. Note that the
scope can be set also using the configure_scope command; in this
case, the configure_type command wins since it is more specific.
-use_existing Tells mltypemap to not generate a type definition for this type, but
rather to use the existing definition. mltypemap assumes that this type
already exists with the name as given with -to_name. This
configuration should typically be used to support consecutive
invocations of mltypemap, for example, if part of the hierarchy was
already generated by previous invocation.
-skip_type Tells mltypemap to skip this type. Relevant only if this type has to be
generated as a subtype of a parent type. In this case, the type and all
its subtypes will be skipped. This configuration should be used if a
sub-hierarchy of a mapped class is not relevant for ML
communication.
Description
Use this command to configure properties of an exported type. The -type argument should be used to
describe the source type. The other parameters are used for the configuration itself.
See Also
● “Referencing when Subtypes in Configuration Commands” on page 6-16
Syntax
configure_field
-type source-type-name-or-regex
-field field-name-or-regex
-to_name field-name
-norand | -rand | -randc
-public | -protected | -private
-pack | -nopack
-print | -noprint
-compare | -nocompare
-copy | -nocopy
-dec|-hex|-bin
-to_cpp_pointer
-use_cpp_type | -use_sc_type
-map_as2value
Syntax Example
configure_field –type sv:vr_axi::axi_packet
-field data
-to_name AxiData
-nopack
-hex
Parameters
Parameter Description
-type source-type-name-or-regex Name of source type. This name should be qualified and should
include the language prefix. The name can contain regular
expressions. For example:
-type sv:cdn_axi::axi_packet
Parameter Description
-to_name field-name The target name of the field. This name can contain $0..$9 to refer to
sub-matches in field-name-or-regex.
-norand | -rand | -randc Controls the randomization type of the target field. Relevant only if
target is e or SystemVerilog. The default is the same as the source
field.
-public | -protected | -private Controls on the target access level of the field. (The default is the
same access level as the source field.)
-pack | -nopack Controls whether this field should be part of the packing. Default is
pack.
-print | -noprint Controls whether this field is printed. Has no affect if the target
language is e. Default is print.
-compare | -nocompare Controls whether this field should be part of the comparing. Has no
affect if the target language is e. Default is compare.
-copy | -nocopy Controls whether this field should be part of the copying. Has no
affect if the target language is e. Default is copy.
-dec | -hex | -bin Sets the radix for this field. Has no effect if the target language is e.
-to_cpp_pointer Relevant when the target language is SystemC, indicate that the field
should be mapped into pointer in C++.
-use_cpp_type | -use_sc_type Integers of 8,16, and 64 bits are mapped by default to SC types:
sc_(u)int<8>, sc_(u)int<16> and sc_(u)int<64> respectively. Integers
of size 32 bits are mapped by default to C++ type int or unsigned int.
This option can be used to change the default of such mapping. The
mapping is done per field, and the field can be of the integer type of
dynamic or static array of this type.
Description
Use this command to configure properties of an exported field. The -type and -field parameters should
be used to describe the source field. The other parameters are used for the configuration itself.
See Also
● “Referencing when Subtypes in Configuration Commands” on page 6-16
Syntax
configure_enum_item
-type source-type-name-or-regex
-item enum-item-name-or-regex
-to_name enum-item-name
Syntax Example
configure_enum_item –type sv:vr_ahb::color –item RED –to_name AHB_RED
Parameters
Parameter Description
-type source-type-name-or-regex Name of source enumerated type. This name should be qualified and
should include the language prefix. The name can contain regular
expressions.
-item enum-item-name-or-regex Name of the source enum item. This name can contain regular
expressions.
-to_name enum-item-name The target name of the enum item. The default is the same name as
the source enum item. The target name can contain $0..$9 refer to
sub-matches in the enum-item-name-or-regex.
Description
Use this command to configure the target name of an enumerated type item. The -type and -item
parameters should be used in order to describe the source item.
Syntax
print_type
-type source-type-name-or-regex
Syntax Example
print_type -type sv:vr_ahb::burst
Parameters
Parameter Description
-type source-type-name-or-regex Name of type to be printed. The name can contain regular
expressions. This argument can be repeated.
Description
Print information about a specific type or types. The command will print basic information on the type.
And, if any configuration was applied to it, on the relevant configuration properties.
See Also
● “Referencing when Subtypes in Configuration Commands” on page 6-16
Syntax
configure_code
-lang SV | SC | SN | e
-header_code code
-gen_adapter_config
-adapter_config_name adapter-config-unit-name
-ovm|-uvm
-map_all_as_2value
Syntax Example
configure_code –lang sv -header code {`include "my_kind_pkg.svh"}
Parameters
Parameter Description
-lang SV | SC | SN | e Name of target language for which the configuration will be applied.
This is mandatory argument.
-header_code code Instructs mltypemap to add the code in the top of the generated
header code.
Description
Use this command for general configuration of the generated code.
The option -header_code can be used to insert code into the generated header code. This is useful, for
example, when existing types are used and their header file has to be imported/included.
The third and fourth options are used to instruct mltypemap to generate adapter unit code for the e over
SV flow. Refer to e over Class-Based SystemVerilog chapter of the UVM Multi-Language Methodology
for more reference on this. The generated adapter config code implements the necessary logic to allow
the mapped types to be passed between the source and target languages through method ports. The
adapter config hooks used are described in “Mixed-Language Sequences API” on page 3-2.
Note that in this case, the adapter unit code will be generated in file called base-name_adapter_config.e.
The -ovm|-uvmoption instructs mltypemap whether to generate OVM or UVM code. The default is to
generate UVM code. Note that this option is general, and cannot be applied to a specific language.
The -map_all_as_2value option instructs mltypemap to map all four-value scalars as two-value scalars.
Note that this can be configured also per-field using the configure_field -map_as_2value option, Note
however, that when global configuration is given, the per-field configuration has no impact.
● “Multi-Language TLM 2.0 Interface” on page 7-1— describes the SystemC side of the multi-language
TLM2 interface.
● “TLM 2.0 Interface User View for e” on page 7-10 — the basic use model of the TLM 2.0 interface
for e, and includes an example that demonstrates the feature.
You can find additional information in the Incisive Specman Elite Testbench documentation that
describes the additions to Specman to support TLM 2.0 in both e-to-e and multi-language transactions.
It describes the TLM2.0 data types and related types, the TLM2.0 sockets, and socket binding. The new
information is available in these locations:
This version of the ML-TLM2 supports only an interface between e and SystemC. The interface
between SystemVerilog UVM TLM2 and other languages will be added later. The e side is described in
the Incisive Specman Elite Testbench documentation.
This version:
● Supports ML communication via combined forward and backward, blocking and non-blocking
transport interfaces
● Automates binding of SystemC and e initiator and target sockets
● Allows passing of the generic payload, phase and timing annotation arguments through the interface
methods of the sockets in different languages
● Supports extensions of the generic payload
ML_TLM2_REGISTER_INITIATOR
ML_TLM2_REGISTER_TARGET
ML_TLM2_GP_BEGIN
ML_TLM2_GP_END
ML_TLM2_GP_EXT_BEGIN
ML_TLM2_GP_EXT_END
ML_TLM2_FIELD
Argument Description
module_i A reference to a module which instantiates the target socket
tran_t Transaction type (an actual run-time argument can be a subtype derived from
the type declared here)
sckt A socket field (class member) name (not quoted) in module_i
buswidth Bus width
Return value Full hierarchical socket name which should be later supplied to
ml_tlm2_connect(). The type of the return value is STL std::string.
The macro can only be used in a class that has a name() method (for example, a module); in particular it
cannot be used in sc_main(). The supported socket types are the standard types tlm_target_socket,
tlm_initiator_socket and their subclasses (for example, simple_target_socket).
Example
#include "systemc.h"
#include "ml_tlm2.h"
When using the _WITH_PROTOCOL option, add as a fifth parameter the struct describing the protocol
types. For example:
UVM Multi-Language Reference 7-3
Multi-Language TLM 2.0
Multi-Language Socket Binding in SystemC
struct extended_burst_protocol_types {
typedef extended_burst tlm_payload_type;
typedef tlm_phase tlm_phase_type;
};
Syntax:
void ml_tlm2_connect(std::string initiator_socket_name, std::string target_socket_name, bool
map_transactions = [0|1] )
Argument Description
std::string initiator_socket_name Full hierarchical socket name. If the initiator socket is in
SystemC, the full name should be obtained with help of
ML_TLM2_REGISTER_INITIATOR[_WITH_PROT
OCOL]
std::string target_socket_name Full hierarchical socket name. If the target socket is in
SystemC, the full name should be obtained with help of
ML_TLM2_REGISTER_TARGET[_WITH_PROTOC
OL]
Argument Description
bool map_transactions Enables transaction mapping between the forward and
backward paths of a non-blocking transaction.
The e socket names must match the normal e port hierarchical names (starting from sys). The order of
the arguments is significant—the initiator socket name should always be specified before the target
socket name.
Continuing the example from the example in Section 7.1.1.1, “Registration of Sockets,” on page 7-2:
Example
top_sc_dut(sc_module_name name_) : sc_module(name_), mem_0(){
… // See above
string full_target_socket_name =
ML_TLM2_REGISTER_TARGET(mem_0,
tlm_generic_payload,tsocket,32);
ml_tlm2_connect("sys.simple_env.driver.initiator_socket",
full_target_socket_name);
}
Socket connection can be done in any supported language, not necessarily on the SystemC side; you can
currently connect from either e or SystemC.
The transaction type registration is necessary because it automates the data transformation procedures
used by the underlying implementation.
The user can specify these macros in any scope (in a .h or .cpp file) where the transaction type is
visible.
Table 7-3 ML_TLM2_GP_BEGIN and ML_TLM_2_GP_END Macros, Argument
Definition
Argument Description
T Transaction type
The list of supported data member (field) types can be found in Section 8.12, “Passing Transaction Data
by Value across SystemC Language Boundary,” on page 8-18 in the UVM Multi-Language Reference. A
transaction class data member can also be a class derived from uvm_object or std::vector<T>.
Classes that are not derived from uvm_object cannot be used as transaction members.
Each field of the user-defined transaction class, which is passed between the languages, must be
specified using one of the following macros: ML_TLM2_FIELD, ML_TLM2_FIELD_ENUM,
ML_TLM2_FIELD_ARRAY or ML_TLM2_FIELD_ARRAY_ENUM. The macro ML_TLM2_FIELD
must be used for all supported field types, except enumerated types and pointers used for declaration of
C-style arrays. A field of an enumerated type must be registered using ML_TLM2_FIELD_ENUM. An
array declared using a pointer must be registered using ML_TLM2_FIELD_ARRAY or
ML_TLM2_FIELD_ARRAY_ENUM (if the array elements are enumerated types). Note that
std::vector must also be registered using ML_TLM2_FIELD and not ML_TLM2_FIELD_ARRAY.
Argument Description
F Field (class member) name
Note The syntax uses non-quoted field names, such as ML_TLM_FIELD(name) rather than
ML_TLM_FIELD("name"). Refer to the section “Example” on page 7-7 to see code showing this syntax.
Argument Description
T Field (class member) type
f Field (class member) name
Argument Description
T Array element type
F Field (class member) name
n Number of array elements. The actual argument shall be any
expression that can be evaluated in the context of the macro. If the
size is represented by a class member it shall be specified using the
macro ML_TLM2_LOCAL (see example below)
Example
#include <vector>
#include "ml_tlm2.h"
…
using namespace std;
enum pv_burst_t {
PV_FIXED = 0,
PV_INCR,
PV_WRAP
};
class extended_burst: public tlm_generic_payload
{
public:
extended_burst() : m_cache_hint(0), m_burst(PV_FIXED) {}
unsigned char m_cache_hint;
pv_burst_t m_burst;
int m_transfer_size;
int * m_transfer;
vector<int> m_vector;
};
ML_TLM2_GP_BEGIN(extended_burst)
ML_TLM2_FIELD(m_cache_hint)
ML_TLM2_FIELD_ENUM(pv_burst_t, m_burst)
ML_TLM2_FIELD(m_transfer_size)
ML_TLM2_FIELD_ARRAY(int, m_transfer,
ML_TLM2_LOCAL(m_transfer_size))
ML_TLM2_FIELD(m_vector)
ML_TLM2_GP_END
Argument Description
T Extension type
The class members (fields) of the extension shall be registered with help of the macros
ML_TLM2_FIELD, ML_TLM2_FIELD_ENUM, ML_TLM2_FIELD_ARRAY or
ML_TLM2_FIELD_ARRAY_ENUM, described above.
Example
Let’s assume that the type extended_burst from the examples above contains a registered extension of
type ID_extension as follows:
struct ID_extension: tlm::tlm_extension<ID_extension>
{
ID_extension() : transaction_id(0) {}
…
unsigned int transaction_id;
};
The transactions are passed by copy, unlike in native SystemC TLM2. From the user perspective, it
means that the outgoing transactions can be de-allocated immediately, because the same objects will
never appear, for example, on the backward path. The user must not expect to receive the same pointers
to the incoming transactions in the sequential non-blocking interface calls.
Note that TLM 2.0 does not support a memory manager for the tlm_phase objects. Thus, the ML-TLM2
implementation reuses the objects, allocated for the incoming SystemC calls, using an internal pool. Do
not use these objects, except in the context of the functions b_transport() and nb_transport_fw().
SystemC TLM2 requires that all data in the tlm_generic_payload data array is in simulation
host-endian format. It is the UVM-e user’s responsibility to ensure that all data is in simulation
host-endian format when sending or receiving data from a SystemC TLM2 model.
● The ML interface class type arguments (the generic payload and the phase) are passed by copy.
Consequently, the changes made to argument values are not immediately visible across language
boundaries. They are updated at the end of the call.
● The following features of the SystemC TLM2 standard are not supported in the current ML-TLM2
implementation:
● User-defined transaction types other than tlm_generic_payload and its subclasses
● User-defined extension types other than derived from tlm_extension
● User-defined, non-default, phase types
● Multi-sockets
● The global quantum
● The direct memory interface (DMI)
● Payload event queues
● Callbacks registration
● Though internal implementation of ML-TLM2 is transparent to the user, be aware that the underlying
mechanism is built on top of the existing ML UVM infrastructure. Consequently, the user must use
irun in the ML UVM mode (using one of the following switches: -uvmtest, -uvmtop, or -ml_uvm,
described in “ML-UVM irun Command Line Switches” on page 4-1).
● Enabling transaction mapping using ml_tlm2_connect() results in a performance cost because more
copying between objects occurs.
See Also
● “Multi-Language TLM 2.0 Interface” on page 7-1 for the SystemC interface description.
● “e Ports” chapter of the Specman e Language Reference
● “Using e TLM 2 Sockets” chapter of the Specman Integrators Guide
The user’s SystemC code should include ml_tlm2.h. To compile the code, you must add the following
to the compiler command line:
-I`ncroot`/tools/uvm/uvm_lib/uvm_ml/sc/ml_uvm
See the “Example” on page 7-22 for an example irun command file.
The example uses two SystemC TLM modules: a memory model used as a slave having a target socket
and an initiator module used as a master driving an initiator socket. See the “Example” on page 7-22 for
detailed definition of the models.
The testbench is represented simply by a driver (BFM) connected to the SystemC module through
ML-TLM2 sockets.
The following code shows the top-level SystemC module, which instantiates the two modules (memory
and initiator) and binds their sockets to the testbench driver sockets in the constructor.
class top_sc_dut : public sc_module {
public :
simple_memory mem_0; // tlm2 slave
simple_initiator init_0; // tlm2 master
top_sc_dut(sc_module_name name_); // constructor
};
The constructor is used to create and bind the interfaces to the sockets.
Note Connecting the testbench to the DUT can be done from the e side as well. To do this, remove
the ml_tlm2_connect() in the code above and add in “simple_env”:
connect_ports() is also {
master_driver.i_socket.connect("top_sc_dut.mem_0.tsocket");
slave_driver.t_socket.connect("top_sc_dut.init_0.isocket");
};
The argument of the connect method shall be a quoted, full SystemC path, as returned by the
ML_TLM2_REGISTER_... macro.
// fields
%m_address: uint(bits:64);
%m_command: tlm_command;
%m_data: list of byte;
%m_length: uint;
%m_response_status: tlm_response_status;
%m_byte_enable: list of byte;
%m_byte_enable_length: uint;
%m_streaming_width: uint;
%m_extensions: list of tlm_extension;
// methods
// sets
it.m_response_status == TLM_INCOMPLETE_RESPONSE;
it.m_extensions.size() == 0;
};
Because tlm_generic_payload is like any_sequence_item, you can use this type directly in a do
statement in a sequence.
extend WRITE gp_burst_seq {
!burst: tlm_generic_payload;
body() @driver.clock is only {
do burst keeping { // random read
it.m_command == TLM_READ_COMMAND;
it.m_length == data_len;
it.m_data.size() == data_len;
it.m_byte_enable == {};
it.m_byte_enable_length == 0;
it.m_response_status == TLM_INCOMPLETE_RESPONSE;
it.m_streaming_width == 4;
it.m_extensions.size() == 0;
};
};
};
Then, a new extension can be generated as follows (most fields of m_ctrl are randomized):
!axi_extension: amba_pv_extension;
!amba_ctrl: amba_pv_control;
gen amba_ctrl keeping {
.m_id == 11;
.m_privileged == TRUE;
};
gen axi_extension keeping {
.m_burst_length == 16;
.m_burst == AMBA_PV_FIXED;
.m_ctrl == amba_ctrl;
.m_size == 4;
};
Note The extensions above are generated before the tlm_generic_payload, and then added
procedurally to tlm_generic_payload using:
burst.m_extensions.add(axi_extension);
See the “Example” on page 7-22 for an example of generating the tlm_generic_payload with its
extensions in a single “do”.
It is important that the order of the fields in the SystemC ML_TLM2 type registration macro be the same
as the order of the fields in e.
struct amba_pv_extension: tlm::tlm_extension<amba_pv_extension>
{
amba_pv_extension() : m_burst_length(0), m_size(0), m_ctrl(0),
m_burst(AMBA_PV_FIXED) {}
virtual ~amba_pv_extension() { };
virtual tlm_extension_base* clone() const {return t; }
virtual void copy_from(tlm_extension_base const &ext) { }
unsigned int m_burst_length;
unsigned int m_size;
amba_pv_control *m_ctrl;
amba_pv_burst_t m_burst;
}
// Declare the extension for ML_TLM2
ML_TLM2_GP_EXT_BEGIN(amba_pv_extension)
ML_TLM2_FIELD(m_burst_length)
ML_TLM2_FIELD(m_size)
ML_TLM2_FIELD(m_ctrl)
ML_TLM2_FIELD_ENUM(amba_pv_burst_t, m_burst)
ML_TLM2_GP_EXT_END(amba_pv_extension)
Simple types and vectors use the ML_TLM2_FIELD declaration. For enumeration types use
ML_TLM2_FIELD_ENUM, specifying also the type as shown above.
Note amba_pv_control in the example above is a class in SystemC. For ML_TLM2 to be able to
transfer a class across language boundary, the struct must be a uvm_object defined as follows, with the
pack and unpack methods defined as required by ML_TLM:
class amba_pv_control: public uvm_object {
public:
unsigned int m_id;
bool m_privileged;
bool m_non_secure;
bool m_instruction;
bool m_exclusive;
bool m_locked;
bool m_bufferable;
bool m_cacheable;
bool m_read_allocate;
bool m_write_allocate;
UVM_OBJECT_UTILS(amba_pv_control)
amba_pv_control() {}
virtual ~amba_pv_control() {}
virtual void do_print(ostream& os) const ;
virtual void do_pack(uvm_packer& p) const ;
virtual void do_unpack(uvm_packer& p) ;
virtual void do_copy(const uvm_object* rhs) ;
virtual bool do_compare(const uvm_object* rhs) const ;
}
A driver with an initiator socket must implement the nb_transport_bw() method. This method is called
by the socket when the backward channel returns the result. The code below shows an example that must
be extended according to the specific application.
Note The source of the figures below is the TLM 2.0 LRM. The numeric values are shown as
examples, and are different from the actual values in the code examples described below.
Phase Target
Simulation time = 100ns
Call -, BEGIN_REQ, 0ns
BEGIN_REQ
Return TLM_ACCEPTED,-,-
Simulation time = 110ns
-, END_REQ, 0ns Call
END_REQ Return
TLM_ACCEPTED,-,-
Simulation time = 120ns
-, BEGIN_RESP, 0ns Call
BEGIN_RESP Return
TLM_ACCEPTED,-,-
Simulation time = 130ns
Note that nb_transport_fw() is a method that cannot call time consuming code. This is why it starts a
TCM to manage the time consuming operations involved in getting the response and then respond
through the nb_transport_bw() interface.
The example code below assumes that there is a user method respond() that gets the transaction as a
parameter and returns the result.
extend SLAVE simple_driver {
t_socket : tlm_target_socket is instance;
};
return tr.m_length;
};
};
Note The TLM 2.0 LRM defines several use cases for a slave driver. (See sections 4.1.2.9 through
4.1.2.11, “Message sequence chart.”) The code above is similar to the first use case “Using the backward
path.” The code “Example” on page 7-22 has additional code demonstrating the other use cases.
When the driver is working in blocking mode, at the end of the “do”, the response status indicates
whether the transaction was successful. If the socket is used in non-blocking mode, the transaction might
not be completed, and a response may be received on the backward path later.
The read sequence is similar, and in the case of blocking calls, both the m_response_status and m_data
fields are updated upon completion.
The non-blocking read sequence returns as soon as the request is delivered. In this example, we generate
the item first and then execute it using driver.execute_item().
extend NB_READ gp_burst_seq {
address: uint(bits:64);
keep soft address[1:0] == 0; // address should be word-aligned by default
data_len: int;
keep soft data_len in [1..4095];
!rd_burst: tlm_generic_payload;
The response is received in the driver’s nb_transport_bw() which can be extended by the user. The
default implementation is as follows:
extend MASTER simple_driver {
nb_transport_bw(resp:tlm_generic_payload, p:*tlm_phase, t:*time):
tlm_sync_e is only {
if(resp.m_command == TLM_READ_COMMAND &&
resp.m_response_status == TLM_OK_RESPONSE && p == BEGIN_RESP) {
print resp.m_data;
};
return TLM_ACCEPTED;
};
};
In ML-TLM however, common methods of memory management might not work well because the
response transaction returned by e is not the same as the original request generated in SystemC.
Whenever possible, use an ad-hoc memory manager that takes into consideration the fact that
transactions passed through language boundaries are copied rather than passed by reference.
The TLM 2 interface further enhances the “UVM Integration with SystemC TLM2” example, provided by
Cadence to Accellera. The basic approach of using TLM1 ML as an underlying implementation
mechanism remains intact.
The new mechanism supports extensions derived from the base class tlm_extension. The user can
choose between using the extensions or subclasses of tlm_generic_payload. In any case, it’s the
user’s responsibility to take care of compatibility between the transaction class definitions in
SystemC and e.
7.2.8 Example
The example code is the implementation of the TLM 2.0 interface example described in Section 7.2.1,
“Introduction—TLM 2.0 Interface Example,” on page 7-10. It has a memory module implemented in
SystemC that accepts read and write commands from the e testbench. In addition it has an initiator
module which sends read and write instructions to a slave BFM in the testbench.
TLM_GP_ROOT is the path to the example package that can be set using:
setenv TLM_GP_ROOT `sn_which.sh ml_tlm2`
Below is an example of simple run.f file that can be used with irun.
// specify that the design is SystemC TLM 2.0
-sysc
-tlm2
// turn on tlm2 transaction recording
-sctlmrecord
// specify the SC env as a top
-sctop top_sc_dut
// specify SystemC include dirs
-I${TLM_GP_ROOT}/examples/sc
-I${ML_UVM}
-DSC_INCLUDE_DYNAMIC_PROCESSES
// enable debug and visibility
-access +rw
-g -debug
// do not compile the e code (slower to simulate, but faster to bring up)
-nosncomp
-snsc
-intelligen
// enable Specman's sequence recording in the Simvision waveform
-snprerun "trace seq trans"
-snprerun "set message MEDIUM"
// turn on NC-SystemC synchronization mechanism
-scsynceverydelta ON
// specify SystemC test files
${TLM_GP_ROOT}/examples/sc/simple_memory.cpp
${TLM_GP_ROOT}/examples/sc/top_sc_dut.cpp
${TLM_GP_ROOT}/examples/sc/simple_initiator.cpp
// specify top e testbench files
${TLM_GP_ROOT}/e/ml_tlm2_top.e
${TLM_GP_ROOT}/examples/e/simple_tb.e
The code above uses TLM sockets. To use simple sockets instead, you can declare the socket as follows:
simple_target_socket<simple_memory, 32, tlm::tlm_base_protocol_types > tsocket;
Note When using simple socket there is no need to implement get_direct_mem_ptr() and
transport_dbg(). Also, for simple sockets, you can register a callback for every interface method.
The code above uses TLM sockets. To use simple sockets instead one can declare the socket as follows:
simple_initiator_socket<simple_initiator, 32, PROTOCOL_TYPES> isocket;
&simple_initiator::nb_transport_bw);
SC_THREAD(thread_process);
}
When using derived types, you should also define the protocol types and use this struct when creating
the interface.
struct extended_burst_protocol_types {
typedef extended_burst tlm_payload_type;
typedef tlm_phase tlm_phase_type;
};
For example, if the following e struct is used as a member of an extension or a class derived from
tlm_generic_payload:
struct nested_class {
%nested_int: int;
};
!burst: tlm_generic_payload;
mid_do(burst: tlm_generic_payload) is {
var axi_extension: amba_pv_extension;
gen axi_extension keeping {
.m_burst_length == burst_length;
.m_size == trans_size;
.m_burst == burst_kind;
};
burst.m_extensions.add(axi_extension);
}; // mid_do(burst)
body() @driver.clock is only {
do burst keeping {
it.m_command == rw;
it.m_address == address;
it.m_data == data_list;
it.m_length == data_len;
it.m_byte_enable == {};
it.m_byte_enable_length == 0;
it.m_streaming_width == 4;
it.m_response_status == TLM_INCOMPLETE_RESPONSE;
it.m_extensions.size() == 0;
};
}; // body()
}; // extend AMBA_SEQ
In this case, the response sequence is simplified. Once the response is calculated it is sent using the
backward path and the transaction is terminated.
nb_transport_fw(tr: tlm_generic_payload, phase: *tlm_phase_enum, t: *time):
tlm_sync_enum is {
if(phase != BEGIN_REQ) { // acknowledge the request
dut_error("SLAVE driver nb_transport_fw received unexpected phase ", phase);
};
start nb_transport_fw_respond(tr, phase, t);
phase = END_REQ;
return TLM_UPDATED;
}; // nb_transport_fw
} else {
dut_error("SLAVE driver received unexpected phase ", phase);
};
};
Early Completion
In this use case the slave responds to the request immediately, without using the return path. The
response is done by simply modifying the fields of the request.
In this case, the response is immediate and the transaction completes immediately.
nb_transport_fw(tr:tlm_generic_payload, phase:*tlm_phase_enum, t:*time):
tlm_sync_enum is {
if(phase != BEGIN_REQ) {
dut_error("SLAVE driver nb_transport_fw received phase ", phase);
};
if(t != 0) { message(LOW, "Delay expected ", t); };
phase = BEGIN_RESP;
t = 0;
tr = respond(tr); // return response by modifying the request
return TLM_COMPLETED;
};
To participate in creation of a verification library, a SystemC module (sc_module) has to be part of the
quasi-static hierarchy created by the simulator, rather than a static hierarchy created at elaboration stage
before invocation of the simulator. To enable this functionality, you must instruct the simulator to create
such a hierarchy before simulating your test.
The simulator performs creation and elaboration of a quasi-static hierarchy as a separate step after the
static hierarchy of the design has been created by the elaborator. The quasi-static hierarchy is created and
elaborated at simulation time 0:
This particular point in time at which quasi-static elaboration occurs is referred to as the preinitial point
of the simulation. If a breakpoint triggers during execution of SystemVerilog static initializers, control
returns to the ncsim prompt, and SystemC quasi-static hierarchy creation and elaboration is not
performed yet. In this case, you must enter the run command again to finish executing all of the
SystemVerilog static initializers, and to perform creation and elaboration of the SystemC quasi-static
hierarchy. Typically, your first run command takes the simulation to the preinitial point, and triggers
SystemC quasi-static elaboration.
To determine the stage of quasi-static elaboration performed by the simulator, you can use the output of
the CFC function sc_quasi_static_elab_status() after calling the function from the ncsim
prompt with the Tcl call command. The output is one of the following lines:
● Before SystemC Quasi-Static Elaboration, if SystemC quasi-static elaboration has not started yet
● During SystemC Quasi-Static Elaboration, if SystemC quasi-static elaboration is in progress
● After SystemC Quasi-Static Elaboration, if SystemC quasi-static elaboration is over
The SystemC quasi-static hierarchy is visible in ncsim only after quasi-static elaboration; that is, after
the quasi-static end_of_simulation phase has been completed.
● “Creating Quasi-Static Top Modules with the Simulator Command” on page 8-2
● “Creating Quasi-Static Top Modules Programmatically” on page 8-3
● “Quasi-Static Elaboration” on page 8-4
● “Loading a SystemC Library into ncsim” on page 8-5
● “Mixed-Language Connection of Quasi-Static SystemC Ports and Exports” on page 8-6
● “See Also” on page 8-8
● “Mixed-Language UVM Connection Function” on page 8-9
● “SystemVerilog Mixed-Language UVM Use Model” on page 8-10
● “Using irun on Mixed-Language SystemVerilog-SystemC UVM Designs” on page 8-12
● “Compatibility with SystemVerilog UVM Use Model” on page 8-12
● “Connection of Static SystemC Ports and Exports” on page 8-15
● “Passing Transaction Data by Value across SystemC Language Boundary” on page 8-18
● “SystemC Quasi-Static Phase Alignment with SystemVerilog UVM” on page 8-23
● “Disabling a Root SystemVerilog Process Blocked in Mixed-Language UVM Call Chain” on page 8-24
● “Simulator Tcl Command Support” on page 8-24
● “SimVision Support for Quasi-Static SystemC Hierarchies” on page 8-25
● “Effect of ncelab Options on Quasi-Static Hierarchies” on page 8-25
● “Limitations” on page 8-26
● An sc_module class name, which you must register using the NCSC_MODULE_EXPORT macro
● You cannot specify the sc_main() function as an argument to -uvmtop.
● An uvm_component class that has been registered with UVM_COMPONENT_REGISTER
To create multiple SystemC tops, you can specify the option multiple times. For example:
% ncsim -uvmtop SC:sc_test1 -uvmtop SC:sc_test2 ...
However, you cannot specify the same SystemC module or the same SystemC UVM component more
than once as an argument to the -uvmtop option.
You can also use the -uvmtop option to specify SystemVerilog and e quasi-static design tops. General
syntax of the option is as follows:
-uvmtop SV_name | SC_name | e_name
SV_name::=[SV:]SV_UVM_name
SC_name::=SC:SC_module_name
e_name::=e:e_unit_name
Note If you omit the SC: or e: specification, the parameter to -uvmtop is assumed to be a
SystemVerilog UVM class.
● The simulator option -loadscsim accepts an optional bootstrap function name. Quasi-static
SystemC modules can also be directly instantiated from such bootstrap functions. For more
information about this option, refer to “Loading a SystemC Library into ncsim” on page 8-5.
Note SystemC quasi-static verification design tops cannot instantiate static HDL components like
Verilog modules. Also, a SystemC quasi-static component cannot instantiate a SystemVerilog UVM class
because the simulator supports only parallel quasi-static verification tops from different languages.
1. After static elaboration has ended and before quasi-static elaboration starts, including the time
between the first ncsim prompt and the first run command
The following steps are performed during quasi-static elaboration at preinitial time, in the given order:
2. All SystemC bootstrap functions specified as arguments to the ncsim -loadscsim option are
invoked in the order in which they were specified on the command line. The bootstrap functions can
create SystemC quasi-static tops.
3. All quasi-static tops specified through the -uvmtop option are constructed, in the order in which
they were specified on the ncsim command line.
4. The end_of_construction member methods of all SystemC quasi-static objects are invoked,
followed by the end_of_construction member methods of all SystemC
ncsc_global_quasi_static_functions objects.
5. The end_of_elaboration member methods of all SystemC quasi-static objects are invoked,
followed by the end_of_elaboration member methods of all
ncsc_global_quasi_static_functions objects.
How the SystemC quasi-static phases align with the corresponding quasi-static phases in SystemVerilog
UVM and e is described in “SystemC Quasi-Static Phase Alignment with SystemVerilog UVM” on page
8-23.
After the start of simulation, the quasi-static components are treated by the simulator similarly to static
components. For example, the end_of_simulation callback is invoked at the same point in time for
all static and quasi-static components.
In accordance with the SystemC LRM, a process created during quasi-static construction or during
quasi-static end_of_construction is a static process, and a process created after quasi-static
end_of_elaboration is a dynamic process.
However, from the simulator perspective, the processes created during quasi-static elaboration are not
dynamic, and thus are not affected by the ncsim option +scDisableDynamicHierarchy.
where:
● library_name is a shared object that contains the bootstrap function. The library must reside in
one of the directories of LD_LIBRARY_PATH. If library_name does not end in .so, then after first
checking for presence of the library name, an additional check is performed for the existence of the
library with .so added. The symbols of the library are loaded into the global namespace.
● bootstrap is a symbol within the library called at preinitial time. Its C prototype is as follows:
void bootstrap()
You can apply multiple -loadscsim options to ncsim. The simulator then loads each SystemC shared
object provided as an argument to an option. On the Tcl reset command, each such library is unloaded
and reloaded.
Note The simulator (ncsim) accepts the shortest unique prefix for options. So, you can specify
-loadsc to ncsim, while for irun and ncsc_run the full name is necessary to direct it properly to ncsim.
If you specify a -loadscsim option to ncsim, you must also provide at least one -loadsc option to
ncelab. That is, if ncsim is loading in additional SystemC libraries, then ncelab must be informed that
there is SystemC in the design through the -loadsc option.
For example, you can specify a static.cpp file and provide the name of that file as an argument to
ncsc_run or irun to build this file and the corresponding .so file, and provide it to ncelab with the
-loadsc option. If your design does not have any HDL tops, then you must also specify a SystemC top
as a static top to ncsc_run or irun:
% ncsc_run static.cpp -top static_top -loadscsim
lib_quasi_static.so:bootstrap
-uvmtop SC:quasi_static_top
You can also link a SystemC library into ncsim statically, in addition to dynamic linking. For static
linking, the syntax is as follows:
-loadscsim [library_name]:bootstrap
The library_name can be omitted; you can provide only a bootstrap function name.
Table 8-1 on page 8-7 shows the matching SystemVerilog UVM TLM exports and the e TLM exports
corresponding to SystemC TLM 1.0 ports. In this release, interfaces with blocking calls are also
supported between e and SystemC.
Note The list of TLM 1.0 sc_export types corresponding to SystemVerilog UVM TLM ports and e
TLM ports is similar to the above list.
TLM 2.0 defines a SystemC interface equivalent to the SystemVerilog UVM analysis interface
(uvm_analysis_port, and uvm_analysis_imp). If your SystemC code uses
tlm_analysis_interface, you must compile it with the -tlm2 option to irun or ncsc_run, which
allows including the TLM 2.0 headers, rather than the TLM 1.0 headers.
Cross-language port-export connections in which the export interface is derived from the port interface
qualify for matching. In other words, a simple port can be connected to a complex (having more
inheritance) export. For example, it is legal to connect an sc_port<tlm_peek_if> to an
uvm_get_peek_imp.
From the list of the SystemC TLM 1.0 interfaces listed above, this release of IES does not support those
interface functions for cross-language invocations that return a reference to an event. The following
code is an example of such an interface function:
template < typename T >
class tlm_nonblocking_get_if : public virtual sc_interface
{
public:
virtual const
sc_event &ok_to_get( tlm_tag<T> *t = 0 ) const = 0;
};
See Also
● Table 2-4 on page 2-28 in the section “Matching TLM Ports in ML-UVM” on page 2-28
ml_uvm_register(). Registration is supported only for sc_port and sc_export types that are
templated by a TLM 1.0 interface. If you attempt to register any other kind of sc_port or sc_export,
the simulator issues a run-time error message. You can perform registration at any time during static
elaboration, and up to the end_of_construction phase in quasi-static elaboration:
namespace ml_uvm {
template <typename IF>
void ml_uvm_register(sc_port<IF>& port, bool send = true);
template <typename IF>
void ml_uvm_register(sc_export<IF>& xport, bool receive = true);
}
Note The second argument to these functions is optional and can be omitted.
The first argument to the ml_uvm_connect() function is the path of a quasi-static port, and the second
argument is the path of a quasi-static export.
Other languages like SystemVerilog and e also provide a similar connection function. To connect a
SystemC port to a SystemVerilog/e export, you can specify the connection in any language: SystemC,
SystemVerilog, or e. Similarly, to connect a SystemVerilog/e port to a SystemC export, the connection
can again be specified in any language: SystemC, SystemVerilog, or e.
You can call ml_uvm_connect() during static elaboration and quasi-static elaboration, up to the
end_of_construction phase. The SystemVerilog mixed-language UVM connection function can be
called only from the SystemVerilog UVM connect phase. All ml_uvm_connect() calls made in
SystemC take effect just before the quasi-static SystemC phase end_of_elaboration, before all port
bindings have been propagated in SystemC.
Although a connection function is typically used to connect cross-language ports and exports, it is also
legal to use a connection function to connect SystemC ports to SystemC exports (for example, across
disjointed SystemC quasi-static hierarchies). Moreover, each language supports indirect port-export
connections specified through mixed-language UVM connection functions.
● Mismatched TLM 1.0 interfaces between the port and the export (for example, when an
sc_port<tlm_put_if> is connected to uvm_get_imp
● Mismatched transaction data type between the port and the export. Data type equivalence is
established only by the same class name. See Table 8-1 on page 8-7 for more details.
It is legal to register a SystemC export with an ml_uvm_register() call but to leave it unconnected.
If a SystemC port is registered, but not connected, an error is not issued when quasi-static elaboration is
over. However, if the port is accessed during simulation (that is, a port interface function is invoked), the
simulator issues a run-time error. In other words, a port can be left unconnected, as long as it is not
accessed.
Note In this release, only uvm_xxx_imp types are supported for mixed-language UVM connections;
uvm_xxx_export types are not supported.
The SystemVerilog mixed-language UVM functionality is available in the package ml_uvm. You must
import the ml_uvm package into your design to make this functionality available:
module topmodule;
import ml_uvm::*;
...
endmodule
You call the connect() function only in the connect phase of SystemVerilog UVM. For example,
to connect the SystemVerilog UVM port uvm_blocking_put_port # (T) out inside the
component producer instantiated as producer prod #(packet) prod inside the parent
component top, to a SystemC export sctop.cons.in, issue the following connect() statement
in the connect() function of top:
ml_uvm::connect(prod.out, “sctop.cons.in”, packet);
2. Registration function
function void external_if (
uvm_if_base_abstract port_or_imp,
string T1_name,
string T2_name = ““
);
The first argument is a handle to a SystemVerilog UVM parameterized port or import that will be
connected to a SystemC/e export or port using the SystemVerilog mixed-language UVM connection
function ml_uvm::connect_names(), or the SystemC mixed-language UVM connection
function ml_uvm_connect().
The second and third arguments are the string names of the actual instantiation values of the
parameter for the parameterized port or import that appears as the first argument. For parameterized
ports/imports with one parameter, the fourth argument is not filled in.
Your SystemVerilog UVM code should not call run_test(). The run phase is automatically launched
at preinitial time if an -uvmtop option has been provided to ncsim. Refer to “Compatibility with
SystemVerilog UVM Use Model” on page 8-12 for more details on run_test() usage with the present
use model.
The SystemVerilog UVM top levels specified as -uvmtop options are tracked in the variable
uvm_top_levels[], which is a queue of all top-level uvm_component objects. Depending on how
UVM is included in the design, this variable appears at different scopes:
After a simulation has past the preinitial point, the variable uvm_top_levels[] shows all of the
SystemVerilog UVM top components, specified as -uvmtop arguments.
The SimVision Design Browser shows the SystemVerilog UVM tops specified as -uvmtop arguments
under the uvm_top_levels[] variable. For easier identification, uvm_top_levels[] appears in red
on the left pane of the Design Browser.
It is also recommended that you import the ml_uvm and uvm_pkg packages in SystemVerilog source
code. As a good practice, you can also include the uvm_macros.svh file:
module topmodule;
import uvm_pkg::*;
import ml_uvm::*;
‘include “uvm_macros.svh”
...
endmodule
The existing SystemVerilog UVM use model supports instantiation of SystemVerilog quasi-static
components from a process after simulation starts running (for example, from an initial block). You can
also specify the test top name through the irun option +UVM_TESTNAME.
The SystemVerilog UVM phases are triggered by the programmatic API run_test(), called from a
SystemVerilog process.
Using -uvmtop implies a use model, in which all of the SystemVerilog UVM phases occur at preinitial
time, rather than triggered by run_test(), and are aligned with the corresponding quasi-static phases
of SystemC and e, as listed in Table 8-3 on page 8-23. Because the run phase is also launched at
preinitial time, your design should not call run_test() explicitly.
If you do not specify the -uvmtop option, the SystemVerilog UVM use model is in effect for backwards
compatibility; that is, the SystemVerilog UVM phases do not occur at preinitial time, but are triggered
by run_test().
uvm_component from an initial block, the simulator triggers an error message. The run_test()
method does not trigger an error message, but generates a warning, and is treated as no-op. It is also an
error to specify both -uvmtop and +UVM_TESTNAME at the same time.
Besides using the -uvmtop option, SystemC quasi-static tops can be created by the
ncsc_global_quasi_static_functions::startup() routines, or by the ncsim
loadscsim:bootstrap functions, which represents a SystemC-only quasi-static use model. Such a
SystemC-only use model can orthogonally co-exist with the SystemVerilog UVM use model of
programmatically instantiating SV quasi-static tops, in which case the SystemC quasi-static phases
occur at preinitial time, and are not aligned with the SystemVerilog UVM quasi-static phases; nor is
there any communication between the SystemC quasi-static hierarchy and the SystemVerilog UVM
hierarchy through the connection functions. See “Connection of Static SystemC Ports and Exports” on
page 8-15 for a description of the connection functions.
sc_test_top sv_test_top
producer consumer
sc_port<tlm_blocking_put_if> uvm_blocking_put_imp
SystemC SystemVerilog
SystemC Code:
// producer.h
#include “systemc.h”
SystemVerilog code:
// consumer.sv
class consumer # (type T = int) extends uvm_threaded_component;
uvm_blocking_put_imp #(T, consumer #(T)) exprt;
typedef consumer#(T) this_type;
‘uvm_component_utils_begin(this_type)
‘uvm_component_utils_end
virtual function put();
...
endfunction
endclass
// test_top.sv
module topmodule;
import uvm_pkg::*
Static sc_port objects templated by the TLM 1.0 interfaces can take advantage of the
ml_uvm_register(sc_port<IF>&) function, described in “Registering SystemC Ports and Exports”
on page 8-8, to register using this function. This fulfills two requirements for an sc_port object:
1. Binds the static sc_port to an object that implements the port interface, and therefore, satisfies the
requirement that all ports must be bound by the end of static elaboration
2. During ncsim quasi-static elaboration, the static sc_port can be connected to a quasi-static export
in any language, including SystemC, using a mixed-language UVM connection function like
ml_uvm_connect(). This gives you the flexibility of having the static sc_port be connected to
an export in different languages in different ncsim runs through different connection functions,
without changing the static hierarchy code. This is an important benefit, especially when the static
hierarchy represents a DUT, and the quasi-static hierarchy represents a test.
Similarly, static sc_export objects templated by the TLM 1.0 interfaces can also register using the
ml_uvm_register(sc_export<IF>&) function. Registration is not necessary for exports because
there is no binding requirement on sc_export objects. It is an optional step that provides the same
cross-language connection flexibility for sc_export described above. Namely, a static SystemC
sc_testbench_top sv_test_top
DUT
monitor
sc_port<tlm_blocking_put_if> uvm_blocking_put_imp
sc_export<tlm_blocking_put_if> uvm_blocking_put_port
driver
SystemC SystemVerilog
SystemC Code:
// dut.h
#include “systemc.h”
using namespace tlm;
template <typename T>
SC_MODULE(dut) {
public:
sc_port<tlm_blocking_put_if<T> > monitor_port;
sc_export<tlm_blocking_put_if<T> > driver_export;
SC_CTOR(producer) :
monitor_port(“monitor_port”), driver_export(“driver_export”) {
SC_THREAD(run);
}
void run() { ... } // transform the input and write it out
};
// testbench_top.cpp
#include dut.h
#include packet.h
using namespace ml_uvm;
SC_MODULE(sc_testbench_top) {
public:
dut dut_i<packet>;
SC_CTOR(sc_testbench_top) : dut_i(“dut”m) {
// register SC DUT monitoring port
ml_uvm_register(dut_i.monitor_port);
// register SC DUT driving export
ml_uvm_register(dut_i.driver_export); m
}
};
SystemVerilog code:
// test_top.sv
module topmodule;
import uvm_pkg::*;
import ml_uvm::*; // import SV unilang package
‘include “uvm_macros.svh”
‘include “monitor.sv”
‘include “driver.sv”
class sv_test_top extends uvm_test;
monitor #(packet) m;
driver #(packet) d;
‘uvm_component_utils(sv_test_top)
function new(string name, uvm_component parent=null);
super.new(name,parent);
endfunction
function void build();
m = new(“monitor”, this);
d = new(“driver”, this);
// register SV test monitor export
ml_uvm::register_imp(m.monitor_export, “packet”);
// no need to explicitly register SV test driver port
endfunction
function void connect();
// connect SV test driver port to SC DUT driver export
ml_uvm::connect_names(d.driver_port.get_full_name(),
“testbench_top.dut.driver_export”
);
This transaction data is typically a user-defined SystemC class or a basic language data type. Because
mixed-language UVM supports TLM 1.0, and TML 1.0 specifies a pass-by-value semantics, all
transaction data are passed by value. The arguments for TLM function calls that cross the language
boundary must be a class that derives from uvm_object.
The SystemC mixed-language UVM packer also supports the basic primitive types:
● bool, char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned
long, long long, unsigned long long, sc_logic, sc_bv, sc_lv, sc_int, sc_uint,
sc_bigint, sc_bigint
● string, char*
The valid argument for cross-language TLM calls is a class derived from uvm_object because the
SystemVerilog mixed-language UVM unpacker supports only objects. The member fields of such a
class can be any of the primitive data types listed above.
uvm_object, and you want this design to participate in mixed-language UVM communication, you can
define converters at the language boundary to convert to/from the legacy type from/to a corresponding
type that inherits from uvm_object. With this approach, your original design can stay unchanged and
continue using the legacy type. You can find an example of converting a legacy type at:
‘ncroot‘/tools/systemc/examples/ml_uvm/legacy_type_converter
● A create() function that takes no arguments and returns an instance of itself as an uvm_object*
● A get_type_name() function that returns the name of the class as a string
● A print function
● Pack and unpack functions
● A copy function
● A compare function
You can satisfy the first two requirements by including the macro UVM_OBJECT_UTILS inside the class
declaration. However, you should provide the constructor, pack/unpack routines, and print routines.
In addition, you must register the class with the SystemC UVM factory, so that the factory can create
instances of it. This is satisfied by including the macro UVM_OBJECT_REGISTER outside of the class
declaration.
Each argument to the << and >> operators must be either an uvm_object or one of the supported
primitive types: bool, char, unsigned char, short, unsigned short, int, unsigned int, long,
unsigned long, long long, unsigned long long, sc_logic, sc_bv, sc_lv, sc_int, sc_uint,
sc_bigint, sc_bigint. If a field is an uvm_object, you can pass it as a pointer or as an object.
Passing it as a pointer preserves the derived class information. However, when crossing the language
boundary, the object is passed by value only.
If a field is not of one of the supported types, it must be converted to one or more objects of supported
types. For example, if a field is a structure that contains subfields of supported types, you can pass the
subfields as a pointer:
(*p) << field4.i1 << field4.i2 << field5;
The pack and unpack functions preserve derived type information. For example, if you declare a class
derived from header, as follows:
class derivedheader : public header{
public:
UVM_OBJECT_UTILS(derivedheader)
derivedheader() { s = “dddd”; }
...
};
UVM_OBJECT_REGISTER(derivedheader)
and the packed class derived from uvm_object has a member field
header* head;
the pack and unpack functions for the packed class are:
virtual void do_pack(uvm_packer& p) const {
p) << head << addr;
}
virtual void do_unpack(uvm_packer& p) {
p >> head >> addr;
}
Because head is passed as a pointer, if it is pointing to a derivedheader, the head field points to
derivedheader when the packet is unpacked.
On the other hand, if the pack and unpack functions are written as follows, the head field points to a
header (base class) when the packet is unpacked:
For a packed object to be successfully unpacked, the packing and unpacking functions must agree on the
class names, the field types, and the field ordering.
Because the unpacking can occur in a different language than the packing, this generally means that the
pack routine in one language must match the unpack routine in the other language for the class of the
same name. The simplest way to ensure this is to make the class definitions in the two languages match,
and both languages pack/unpack all of the fields. However, it is possible for the class definitions to
differ, as long as the pack and unpack routines match.
The legal mapping between SystemVerilog and SystemC for the primitive data types is shown in Table
8-2 on page 8-21. For example, if your SystemC data object packet derives from uvm_object and
contains two member fields of type sc_logic and sc_int<64>, the corresponding packet object in
SystemVerilog should derive from uvm_object and contain two member fields of type logic and
bit[63:0], respectively.
logic sc_logic
logic[N-1:0] sc_lv<N>
shortint short
int int
longint int64
If the class names on both sides do not match, and one side packs an uvm_object that the other side
does not recognize, an error message is printed. The size of the two objects is also checked, and error
messages are generated for too few or too many bits. Besides this, no other error checking is performed.
For example, if one side packs a char and the other side is expecting an int, the result is a crash.
A field of type enum is passed across the language boundary as the basic non-enumeration type that it
represents (usually int). So, when packing and unpacking, you have to pack/unpack the corresponding
basic data type, and then cast it to the enum type.
If you have a class with enum members, you can declare << and >> operators when you declare the enum
inside your class. Then the pack/unpack functions can simply call << and >>, as usual. For example:
class packet : public uvm_object {
...
enum state_t { OK=1, ERROR };
state_t state;
...
virtual void do_pack(uvm_packer& p) const {
p << data;
p << state;
p << address;
}
SystemVerilog UVM
SystemC Quasi-Static Phase Phase e Phase
startup - -
-loadscsim:bootstrap - -
SystemVerilog UVM
SystemC Quasi-Static Phase Phase e Phase
uvm_component::check check check
end_of_simulation - -
It is recommended that you create all of the UVM test hierarchy in the SystemVerilog UVM phase
build. The SystemC end_of_construction phase can also create new quasi-static SystemC
modules. Also, you need to bring up to phase the newly created quasi-static components created in these
phases.
Immediately after reset, the simulation state is rolled back to time 0 before preinitial time, and
thus before quasi-static elaboration has completed. Therefore, the quasi-static hierarchy does not
exist immediately after reset. After you issue the first post-reset run command, the same
quasi-static hierarchy that existed before reset is re-constructed.
Because the quasi-static hierarchy disappears immediately after reset, any probes that were issued
on SystemC quasi-static objects before reset, are invalid after the reset, and you need to reissue
your probe commands.
In addition, the SHM database variable used for the original probe command before reset cannot
be reused for new probe commands after a reset. Instead, the reset count is stored in a new SHM
database variable. For example, if you probe the quasi-static SystemC signal sig, probing the same
signal after the first reset is recorded as the variable _1_sig in the SHM database, and as the
variable _2_sig after the second reset, and so on.
Your probe commands are not automatically reapplied after a reset, and the simulator issues a
warning message on reset, if the design contains SystemC quasi-static hierarchy in which any
quasi-static objects have been probed. You can upgrade the severity of the warning message to
error, if you do not want to see the default reset behavior.
In Post Processing Mode (ncsim -ppe), you do not have access to the quasi-static test hierarchies for
design navigation. However, you can use the saved databases and the Waveform window to view objects
in the quasi-static hierarchy.
Because the quasi-static hierarchy does not exist immediately after the reset, there is a brief period of
time, between reset and the first run command, when the SimVision windows continue to show the
SystemC quasi-static hierarchy, even though the hierarchy no longer exists. The simulator generates a
warning message when reset is issued, if the design contains SystemC quasi-static hierarchy, and
SimVision is connected to the simulator.
If this option has been specified to ncelab, the SystemC quasi-static code must also honor this
option by making all DPI import tasks return void. Similarly, if this option has not been specified to
ncelab, the quasi-static code must make all DPI import tasks return int.
● -NOASSERT
This ncelab option disables PSL assertions in the quasi-static SystemC code.
● -SCCREATEVIEWABLES
This option creates ncsc_viewable objects inserted by ncsc_wizard in the SystemC quasi-static
code.
● -SCPARAMETER arg
This option can be used to associate values with top-level quasi-static SystemC modules.
8.18 Limitations
● Because this release of IES supports only parallel quasi-static verification tops, you cannot instantiate
quasi-static components in one language within a quasi-static component in another language.
● The Tcl command reset is supported for quasi-static hierarchy in SystemC-only designs that do not
use any mixed-language UVM constructs like ml_uvm_register() or ml_uvm_connect(). For
mixed-language UVM SystemVerilog-SystemC designs, or SystemC-SystemC designs, reset is
not available.
● The simulator Tcl commands save and restart are not supported for designs containing SystemC
quasi-static hierarchies in this release of IES.
H methods
assign_sequencer() 3-5
-header_code argument for configure_code prepare_item_to_send() 3-6
command 6-27 update_item_after_done() 3-3
-hex argument for configure_field command 6-24 ML sequences API 3-2
hierarchy, extending 5-70 ml_proxy_seq_driver 3-2
ml_tlm_2_connect 7-4
I ML_TLM_2_GP_END 7-6
in|inout|out field element 5-28 ML_TLM2_FIELD 7-6
initiator 7-15 ML_TLM2_FIELD_ARRAY 7-7
interface element 5-54 ML_TLM2_FIELD_ARRAY_ENUM 7-7
irun ML_TLM2_FIELD_ENUM 7-7
arguments for mltypemap 6-10 ML_TLM2_GP_BEGIN 7-6
command line switches for ML-UVM 4-1 ML_TLM2_GP_EXT_BEGIN 7-8
is_quasi_static(), method of class sc_object to ML_TLM2_GP_EXT_END 7-8
query a SystemC object 8-4 ML_TLM2_REGISTER_INITIATOR 7-2
-item argument for configure_enum_field ML_TLM2_REGISTER_TARGET 7-2
command 6-25 -ml_uvm command-line switch for irun 4-4
item element 5-29 ml_uvm_connect(), mixed-language UVM
connection function 8-9
ml_uvm_register(), function to register SystemC
L ports and exports for UVM connections
-lang argument for configure_code command 8-9
6-27 ml_uvm_sequencer_stub 3-4
launching run phase and blocking threads 2-11 ml_uvm::connect() 4-7
legacy types, conversion of 8-18 ml_uvm.connect_names() 4-5
limitations mltypemap
for typemap 6-28 command example 6-13
in early access release 2-30 configuring 6-19
SV sequences in e testbench 3-7 example: e to SV 6-2
-loadscsim, simulator option to link a SystemC example: SC to e 6-9
quasi-static hierarchy 8-4 example: SC to SV 6-10
example: SV to e 6-4, 6-6
M invoking 6-10
irun arguments 6-10
macros, using for configuration 5-73 limitations in this release 6-28
-map_all_as_2value argument utility 6-1
for configure_code command 6-27 when subtypes support 6-16
map_as2value argument for configure_field -mltypemap_input argument for irun 6-11
command 6-24 -mltypemap_tcl argument for mltypemap 6-11
maptypes ML-UVM
command 6-12 e utilities 4-5
mapping classes 6-14 external path strings 2-22
output files 6-13 features for TLM, summary 2-20
memory management considerations 7-21
irun command line switches 4-1 -print argument for configure_field command
mixed-language SystemVerilog UVM 6-24
package 8-10 print_type command 6-26
reference 2-28, 4-1 -private argument for configure_field command
SystemVerilog utilities 4-6 6-24
multi-language -protected argument for configure_field
trees of UVCs 2-3 command 6-24
UVM (ML-UVM) 2-1 -public argument for configure_field command
features 2-2 6-24
N Q
ncsc_global_quasi_static_functions() 8-3 quasi-static
example 8-4 elaboration, steps 8-5
-NOASSERT, ncelab option, effect of quasi-static hierarchy, definition 8-1
hierarchies 8-26
-nocompare argument for configure_field R
command 6-24
-nocopy argument for configure_field command -rand argument for configure_field command
6-24 6-24
-nopack argument for configure_field command -randc argument for configure_field command
6-24 6-24
-noprint argument for configure_field command requirements
6-24 using TLM in multi-language verification
-norand argument for configure_field command environments 2-19
6-24 run_test(), API to trigger SystemVerilog UVM
phases 8-11
run_uig.sh 5-6
O
-ovm argument for configure_code command S
6-27
SC
types mapped to e, example 6-9
P types mapped to SV, example 6-10
-pack argument for configure_field command sc_quasi_static_elab_status(), function to
6-24 determine the status of SystemC
pack_fields(), SystemC UVM function 8-20 quasi-static elaboration 8-1
-pass_field argument for configure_type scalars, mapping 6-17
command 6-22 -SCCREATEVIEWABLES, ncelab option, effect
passing of quasi-static hierarchies 8-26
compound transaction 2-26 +scDisableDynamicHierarchy ncsim option,
transactions across languages 2-22 effect on quasi-static hierarchy 8-5
preinitial point, definition 8-1 -scope argument for configure_scope command
prepare_item_to_send() 3-6 6-21
U
UIG invocation 5-5
uig_get_dut_interface_id 5-78
uig_get_dut_interface_path 5-78
uig_get_field_value_<type> 5-77
uig_get_num_instances 5-75
uig_get_uvm_path_by_id 5-76
update_item_after_done() 3-3
-use_cpp_type argument for configure_field
command 6-24
-use_existing argument for configure_type
command 6-22
-use_sc_type argument for configure_field
command 6-24
using
e test as the first top entity 2-15
language-neutral connection methods 2-21
SystemVerilog component as the first top
entity 2-16
utilities
ML-UVM for e 4-5
SystemVerilog ML-UVM 4-6
-uvm argument for configure_code command
6-27
UVM component element 5-16
UVM_OBJECT_REGISTER, SystemC UVM
macro, uvm_object class 8-19
UVM_OBJECT_UTILS, System 8-19
UVM_OBJECT_UTILS, SystemC UVM macro,
uvm_object class 8-19
uvm_object, SystemC class, definition 8-19
+UVM_TESTNAME, irun option to specify
SystemVerilog test top names 8-12
uvm_top_levels, variable recording
SystemVerilog UVM top levels 8-11
-uvmtest command-line switch for irun 4-1
-uvmtop SC, ncsim or irun option to create a
SystemC quasi-static design top 8-2
-uvmtop command line switch for irun 4-3