UVM Interview Questions
UVM Interview Questions
A UVM RAL (Register Abstraction Layer) model is a fundamental component of the Universal
Verification Methodology (UVM). It consists of a set of base classes used to create register models
that emulate the register contents within a hardware design. The necessity for a UVM RAL model
arises from the need to simplify interactions with the design's registers. Instead of sending
individual bus transactions for every read and write operation, a register model provides a higher-
level abstraction, making it easier to read from and write to the registers. Additionally, the register
model maintains a mirrored value, representing the current state of the design, which enhances
efficiency and convenience.
p_sequencer is a term used in UVM, referring to a handle that identifies the sequencer on which
the current sequence should execute. It is typically accessed within sequences using the
uvm_declare_p_sequencer macro. The primary use of p_sequencer is to initiate and execute
other sequences, allowing for complex test scenarios and sequencing control within the UVM
verification environment.
In UVM, new() and create() serve different purposes for object instantiation. The new() method
is the traditional SystemVerilog way of creating an object instance. In contrast, the create()
method is a UVM addition that leverages the factory mechanism. It allows the factory to return
an object of the desired type, providing greater configurability within the UVM framework.
5. Is UVM independent of SystemVerilog?
No, UVM is not independent of SystemVerilog. UVM is built on top of the SystemVerilog language,
meaning that it cannot be used with tools or environments that do not support SystemVerilog.
Registering a class with a factory in UVM is not mandatory but highly beneficial. It enhances the
reusability of components within the testbench and allows for the potential override of a
registered class with a derivative component when necessary. This registration process provides
flexibility and configurability in testbench construction.
In UVM, an agent typically comprises a driver, sequencer, and a monitor. Active and Passive modes
define the behavior of the agent:
A Passive agent only monitors signals on the interface without driving data to the Design Under
Test (DUT). In this mode, sequencer and driver components are not instantiated.
An Active agent can run sequences on its sequencer, drive signals to the DUT, and monitor the
interface, enabling comprehensive testing capabilities.
A TLM FIFO (Transaction-Level Modeling FIFO) is a critical component in UVM used when two
components with different clock domains need to operate independently and communicate. It
acts as a buffer, allowing one component to send data at a faster rate while the other component
receives data at a slower rate. TLM FIFOs ensure proper synchronization and data flow between
components.
Both uvm_component_utils and uvm_object_utils are macros used to register classes with the
factory in UVM. The choice between them depends on whether the class is derived from
uvm_component or uvm_object. There are no inherent advantages of one over the other; they
offer separate ways to register classes with the factory, enhancing configurability and reuse.
10. How does a sequence start in UVM?
By using the uvm_do macro. This allows sequences to be executed within the testbench,
providing control over the verification environment's sequencing and flow.
The main phases in UVM, used for testbench development and synchronization, are as follows:
build_phase
connect_phase
end_of_elaboration_phase
start_of_simulation_phase
run_phase
extract_phase
check_phase
report_phase
final_phase
A virtual sequence in UVM is a container designed to hold and execute multiple smaller
sequences. It provides a means to manage and execute a group of sequences as a single entity.
The uvm_do macro automatically creates a new object, randomizes it, and sends it to the
specified sequencer in UVM.
On the other hand, uvm_send is used when the object is already created and randomized but
needs to be executed on a sequencer. It is employed to send a pre-existing item to the sequencer
for execution.
uvm_transaction is the root base class for UVM transactions, featuring a timing and recording
interface. It is deprecated for user-defined transactions, and its intended use is to record events
to a vendor-specific transaction database using methods like accept_tr, begin_tr, and end_tr.
uvm_sequence_item is primarily used to define data objects and related methods, making it the
preferred base class for user-defined transactions in UVM.
Faster testbench prototyping due to provided base classes for drivers, monitors, sequencers, and
more.
A: Yes, it is possible to define custom phases in UVM. To achieve this, you need to create a new
phase class inherited from uvm_task_phase, implement the exec_task or exec_func method, and
then insert the custom phase into the existing schedule or domain object.
17. What is the difference between RAL backdoor and frontdoor accesses?
Backdoor access allows direct dumping of values onto DUT registers via a hard-coded RTL signal
path. It does not consume simulation time.
Frontdoor access involves sending data as a transaction through an associated peripheral bus
interface, consuming simulation time.
A phase objection is a mechanism in UVM used for component synchronization during different
phases. It allows a component to stall other components from proceeding to the next phase until
it completes its own tasks. This is achieved using raise_objection() and drop_objection() methods
from the uvm_phase class.
To access signals within a Design Under Test (DUT) in a UVM component or sequence:
Interface signals can be accessed via a virtual interface handle that points to the actual physical
interface.
Signals within the DUT can be accessed directly by providing a hierarchical RTL path to uvm_hdl_*
functions like uvm_hdl_force, uvm_hdl_deposit, and uvm_hdl_read.
For example:
uvm_hdl_force("top.eatable.fruits.apple.slice", 2);
uvm_hdl_deposit("top.eatable.fruits.apple.slice", 3);
uvm_hdl_read("top.eatable.fruits.apple.slice", rdata);
RALGEN is a tool by Synopsys used to generate Register Abstraction Layer (RAL) models from an
IPXACT specification file. To use RALGEN:
Specify the required options and select the block for which you need to generate class structures.
RALGEN will generate the RAL model classes based on the IPXACT specification.
Desired values are the values that are intended to be written to the design registers and can be
updated later.
Mirrored values are the latest known values that reflect the actual values in the Design Under
Test (DUT).
24. What are reg2bus and bus2reg functions used for in RAL?
reg2bus and bus2reg are RAL functions designed for converting between generic register contents
and actual bus transactions:
25. How would you debug a config database name or path mismatch problem in UVM?
Use the command-line define +UVM_CONFIG_DB_TRACE to enable tracing for SET and GET calls
made to the configuration database.
This trace will provide information related to the path, instance, and other details of the
configuration database calls, helping identify any mismatches.
Driver
Monitor
Scoreboard
Sequencer
Agent
Environment
Test
Sequences
27. Which UVM phase typically takes more time and why?
Run-time phases in UVM typically consume more time as they are the major phases that consume
simulation time. The duration of these phases can vary depending on the specific tests being
executed, as they may test different aspects of the design.
28. How do you connect a monitor with a scoreboard in UVM?
In the environment's connect method, connect the monitor's analysis port with the analysis port
declared in the scoreboard.
In an agent's connect method, you can connect the driver's seq_item_port with the sequencer's
seq_item_export.
Both uvm_config_db and uvm_resource_db are mechanisms in UVM used for placing an object
in a central lookup table under a specified name and path. This allows another component to
retrieve the object using the same name and path.
31. Can you provide pseudo-code for implementing an AHB-Lite driver in UVM?
Certainly! Below is pseudo-code for implementing an AHB-Lite driver in UVM. It's important to
note that AHB-Lite is a pipelined protocol, so the address phase of the next transaction should be
active while the data phase of the current transaction is ongoing. This is achieved by starting the
same task twice in a fork-join.
A: In UVM, a sequence typically contains a task called body() within which you can write the actual
stimulus to test the design for a particular feature. The body() task defines the sequence of actions
and transactions to be executed during the sequence's execution.
▶ The sequence will be waiting for a request (get_next_item) from the driver.
▶ After receiving the request, the sequence will call "start_item(req)" and generate the
sequence_item or transactions using "req.randomize()".
▶The generated transactions will be sent to the driver with the help of a sequencer.
▶The driver will receive the transactions and drive (req) them to DUT.
▶Once all the data is driven, the driver will send an acknowledgment as item_done.
▶The sequence will wait for the acknowledgment from the driver and then call finish_item(req).
📝 Here's an example of how to write a UVM sequence:
`uvm_object_utils(mem_sequence)
// Constructor
super.new(name);
endfunction
// Body method
endtask
endclass
34. Is the build_phase() method executed top-down in the UVM component hierarchy?
Yes, in UVM, the build_phase() method is executed top-down in the testbench component
hierarchy. This means that a parent component constructs its child components, which can
further construct their own child components using the build_phase() method.