Thought Leadership

Starting Your UVM Simulation

由克里斯矛

Introduction

What happens when you start your simulation with a UVM test bench? Where should you put the uvm_config_db::set() calls to send the virtual interface to the test class? Are there potential race conditions? And what happens when your test is over?

Let’s Get This Started

At the start of the simulation, you need to put虚拟接口in theuvm_config_dbfor the testbench. You could put this in an initial block in your RTL code.

module hdl_top; logic clk, rst; tx_ifc tx_if (clk, reset); // Instantiate the tx_ifc interface rx_ifc rx_if (clk, reset); // Instantiate the rx_ifc interface dut i0 (tx_if, rx_if); initial begin uvm_config_db#(virtual tx_ifc)::set(null, "uvm_test_top", "tx_if", tx_if); uvm_config_db#(virtual rx_ifc)::set(null, "uvm_test_top", "rx_if", rx_if); end endmodule

Over in the test module, you start the UVM code.

module hvl_top; import uvm_pkg::*; import tx_pkg::*; // tx definitions import rx_pkg::*; // rx definitions initial run_test(); // Start UVM endmodule

You can also put the uvm_config_db::set() calls in the testbench module. Just make sure they are before the call to run_test(), or in a separate initial block. The final argument to set() is the value of the virtual interface, which is a hierarchical name.

initial begin uvm_config_db#(virtual tx_ifc)::set(null, "uvm_test_top", "tx_if", hdl_top.tx_if); uvm_config_db#(virtual rx_ifc)::set(null, "uvm_test_top", "rx_if", hdl_top.rx_if); run_test(); // Start UVM end

Going the Distance

If there are two initial blocks, is there a race condition? Could your test class call uvm_config_db::get() before the set() call? Good news – the UVM developers anticipated this problem and added a #0 delay before your test code starts. As a result, all the initial and always blocks across the simulation set the uvm_config_db entries before the test class tries to get them.

Here is a little more detail. The UVM global method run_test() constructs a uvm_root object and calls its run_test() method. That gets the test name from the +UVM_TESTNAME command line switch and constructs the test object. It then starts the UVM phases, which includes a #0 delay, ensuring all your initial blocks have woken up.

The run_test() method never returns, so any code after it will never execute.

initial begin
run_phase();
$display("This will never print");
end

Extra, Extra, Extra

在我看来,the run_test() method should have been called uvm_run_test(), but I’m a few decades late for that battle.

The method has an argument for the test name – don’t use it. UVM has the great concept of including all tests in one simulation image, so you don’t need to recompile between tests. The only time you might want to give a default test name is for a trivial example with a single test.

After UVM ends your test, it calls $finish(). If you need to run some code at the end of the test, put it in a final_phase() function. That way, your code runs with other testbench OOP code.

Conclusion

在UVM,叫uvm_config_db::设置()发送virtual interface to the test class. Put these calls in an initial block. This are typically in the RTL module. If they are in the testbench module, put them before the call to run_test(), or in a separate initial block.

Learn More

You can learn more about these topics, including Oriented Programming with the Siemens SystemVerilog for Verification course. It is offered in instructor-led format by our industry expert instructors, or in a self-paced,on-demandformat. It can also be tailored to address your specific design goals and show you how to set up an environment for reuse for additional designs. Also, you can now earn a digital badge/level 1 certificate by taking ourAdvanced Topics Badging Exam. This will enable you to showcase your knowledge of this topic by displaying the badge on your social media and email signature.

Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at //www.8920666.com/verificationhorizons/2023/10/10/starting-your-uvm-simulation/
Baidu
map