1 Introduction The Universal Verification Methodology (UVM) is a standardized hybrid methodology for verifying complex design in the semiconductor industry. It has superseded the Open Verification Methodology which was an Open Source verification methodology was supported by both Cadence and Mentor. UVM has full industry wide support and standardised under the Accellera Systems Initiative. In this paper TVS describes in detail the differences between the Open Verification Methodology (version2.1.2) and the Universal Verification Methodology (version 1.b). It is intended to help engineers to understand the implications of moving from OVM to UVM. The paper starts with a short history of OVM and UVM to set the context. A detailed comparison then follows looking at phases, managing the end of test, component configuration and finally register modeling. About the Authors: Suresh Babu has been involved in hardware verification for 10 years. Currently he is a project lead @ TVS with responsibility for OVM, UVM and erm Based test bench and VIP development, customer support and metric driven based verification signoff using asuresign. Dr. Mike Bartley founded TVS in 2008 after spending over 20 years working in both hardware verification and software testing. About Test and Verification Solutions TVS delivers tailored solutions for hardware verification and software testing. TVS is an independent company providing both services and products (VIP & asuresign ) from offices around the world. TVS prides itself on having the flexibility to meet diverse client requirements. To learn more about our offerings, visit www.testandverification.com or write to us at info@testandverification.com
2 Overview of UVM History UVM is built on System Verilog and the history of that language is shown in Figure 1: History of System Verilog below. 1980 1990 2000 2005 HiLo Verilog SuperLog VHDL C e Vera System Verilog Figure 1: History of System Verilog Verification methodologies came into existence soon after the first dedicated HVLs (Hardware Verification Languages) appeared (see. The main advantages of adopting a methodology (such as UVM) are Reusability through test bench re use and verification IP allowing plug and play A proven methodology with industry wide support and availability of engineers with existing knowledge/experience Simulator and vendor independence
Vera RVM VMM VMM 1.2 System Verilog AVM OVM UVM URM Open Source e erm Figure 2: History of Verification Methodologies 2.1 OVM and UVM Availability The following releases are available in http://verificationacademy.com/verification methodology UVM 1.1b (tar.gz) Accellera UVM 1.1b User Guide Accellera UVM 1.1a (tar.gz) Accellera UVM 1.0 (tar.gz) Accellera OVM 2.1.2 (.zip) OVM 2.1.2 (tar.gz) UVM Register Kit for OVM 2.1.2 (tar.gz) OVM< >VMM reference library, examples and documentation
3 OVM Phases vs. UVM Phases In this section we look at the main changes in the way phases are handled in UVM. There are 2 changes in the methods (see section 3.1) and changes in the actual numbers of phases (see section 3.2). Note that as these changes are significant and not backwards compatible then there is a way to invoke OVM style semantics. If you add +UVM_USE_OVM_RUN_SEMANTIC in the command line it will cause the run phase to use old OVM style run semantics. 3.1 Changes in phase methods There are 2 changes in the interface to the phase methods. These are summarised below with the detail in Table 1: Summary of the changes in phase methods. 1. Method name changed into <phase_name>_phase. 2. Argument added in all the phase methods. OVM class xbus_env extends ovm_env; // Virtual Interface variable protected virtual interface xbus_if xi0; function void build(); string inst_name; super.build(); if(has_bus_monitor == 1) begin bus_monitor = xbus_bus_monitor::type_id::create("bus_monitor", this); end Endfunction : build UVM class ubus_env extends uvm_env; // Virtual Interface variable protected virtual interface ubus_if vif; function void build_phase(uvm_phase phase); string inst_name; super.build_phase(phase); if(!uvm_config_db#(virtual ubus_if)::get(this, "", "vif", vif)) `uvm_fatal("novif",{"virtual interface must be set for: ",get_full_name(),".vif"}); Endfunction : build_phase
// implement run task task run; fork update_vif_enables(); join endtask : run function void end_of_elaboration(); $display("%0t: %0s: end_of_elaboration", $time, get_full_name()); function void start_of_simulation(); $display("%0t: %0s: start_of_simulation", $time, get_full_name()); function void extract(); $display("%0t: %0s: extract", $time, get_full_name()); function void check(); $display("%0t: %0s: check", $time, get_full_name()); function void report(); $display("%0t: %0s: report", $time, get_full_name()); Endfunction Table 1: Summary of the changes in phase methods // implement run task task run_phase(uvm_phase phase); fork update_vif_enables(); join endtask : run_phase function void end_of_elaboration_phase(uvm_phase phase); $display("%0t: %0s: end_of_elaboration", $time, get_full_name()); function void start_of_simulation_phase(uvm_phase phase); $display("%0t: %0s: start_of_simulation", $time, get_full_name()); function void extract_phase(uvm_phase phase); $display("%0t: %0s: extract", $time, get_full_name()); function void check_phase(uvm_phase phase); $display("%0t: %0s: check", $time, get_full_name()); 3.2 Additional phases in UVM UVM saw the introduction of a large number of new phases to give finer control over the simulation. These are summarised in Error! Reference source not found. below.
OVM UVM Table 2: Additional phases in UVM
4 Managing the End of Test Modern test benches provide a way for components and objects to synchronize their testing activity and indicate it is safe to end the phase and the simulation. UVM (and OVM) provides a built in objection for each phase which allows a component to object to the phase ending. This objection mechanism gives a structured way for hierarchical test bench components status to communicate their status. For example, a component may raise an objection when it starts a transaction with the DUT ( Design Under Test ) and not drop that objection under the transaction is complete. Or a component expecting a response from the DUT will keep an objection raised until the response is received. Note that the uvm_test_done objection also works in UVM, but it is not the recommended way of managing the end of test. In UVM it is recommended to use the available time consuming phases, so using a global variable is no longer a robust mechanism. In OVM, calling global_stop_request was not recommended but it was not deprecated. OVM task run(); seq.start( m_virtual_sequencer ); global_stop_request(); endtask UVM task run_phase( uvm_phase phase ); phase.raise_objection( this ); seq.start( m_virtual_sequencer ); phase.lower_objection( this ); endtask task run(); ovm_test_done.raise_objection(); seq.start( m_virtual_sequencer ); ovm_test_done.drop_objection(); endtask task run_phase( uvm_phase phase ); phase.raise_objection( this, "started sequence" ); seq.start( m_virtual_sequencer ); phase.drop_objection( this, "finished sequence"); endtask Table 3: Comparing end of test in OVM and UVM
5 Configuring Component In UVM it is recommended to use uvm_config_db method for configuring components. OVM used the [set,get]_config_[int,string,object] methods for configuring components. The UVM equivalents of these methods are available, but not recommended. The uvm_config_db is parameterized by the type of object that is being configured. OVM class my_env extends ovm_env; function void build(); ahb_cfg = ahb_config::type_id::create("ahb_cfg"); ahb_cfg.width = 16; // set additional fields set_config_object("*","ahb_cfg",ahb_cfg); endclass class my_ahb_agent extends ovm_component; function void build(); ovm_object cfg; ahb_config my_cfg; assert(get_config_object("ahb_cfg",cfg,0); if (!$cast(my_cfg, cfg)) ovm_report_error(); endclass Table 4: Configuring components in OVM and UVM UVM class my_env extends uvm_env; function void build(); ahb_cfg = ahb_config::type_id::create("ahb_cfg"); ahb_cfg.width = 16; // set additional fields uvm_config_db#(ahb_config)::set( this,"ahb_agent","ahb_cfg",ahb_cfg); endclass class my_ahb_agent extends uvm_component; function void build(); ahb_config my_cfg; if (!uvm_config_db::ahb_config::get( this,"","ahb_cfg",my_cfg); `uvm_error() endclass
It is recommended to avoid using assign_vi function that takes a virtual interface handle as an argument and calls an equivalent function on one or more child component. This is repeated down until the last component reached. Following approach is not recommended XBUS ENV function void assign_vi(virtual interface xbus_if xi); xi0 = xi; if( bus_monitor!= null) begin bus_monitor.assign_vi(xi); end for(int i = 0; i < num_masters; i++) begin masters[i].assign_vi(xi); end for(int i = 0; i < num_slaves; i++) begin slaves[i].assign_vi(xi); end : assign_vi AGENT function void assign_vi(virtual interface xbus_if xmi); monitor.assign_vi(xmi); if (is_active == UVM_ACTIVE) begin sequencer.assign_vi(xmi); driver.assign_vi(xmi); end : assign_vi Table 5: Avoid using assign_vi
6 UVM Register layer Constrained random test benches are required to model the DUT behaviour to predict expected behaviours. This includes models of the registers and/or memories within the DUT. The UVM provides register layer classes to create a high level, object oriented model for memorymapped registers and memories in a design under verification. The following methodology features are key to building and using such a model. Create an abstract model of the registers and memories in DUT o To maintain a mirror of the DUT registers. Create a hierarchy that is analogous to the DUT hierarchy o Register Block o Register File o Memory o Register o Field Provide access to the register through a defined API o Address independent instance/string names Model the address map o Model access via specific interface Figure 3 opposite shows the steps involved in using the register model. Figure 3: The steps involved in using the register model
6.1 Access API Table 6: Register access API below gives an overview of the register access API and how it should be used. Command Read()/Write() Description Peek()/poke() Generate Physical Read from the DUT Generate physical Write to the DUT Get()/set() Peek() or poke() methods Read/write directly to the register Get() or set() methods read/write directly to the desired value
Update() Mirror() Update() the DUT with desired value in the model Read the DUT register and check/update the model value Table 6: Register access API 7 Summary Over the years various verification methodologies have been introduced in order to optimise use of scarce verification resources. The methodologies have followed an evolution that has brought us naturally to UVM an industry wide methodology built on an open source language and library. In this paper we have shown what is required in order to transition from OVM to UVM.