Introduction:
We know that UVM is a fairly complex Verification Environment since many things happens inside of the Environment on the fly and signal level details involved are limited to the Interface/Virtual Interface level. Component hierarchy is created, Virtual Interface and Configuration Objects are passed from the Test to the Driver, Monitor & other components as needed using uvm_config_db set/get methods. Many a times regular expressions are used to match up the strings. Transactions are generated by the Sequences and are passed from the Sequencers to the Driver. Sequencer deals with the Arbitration process and so on. All that are part of UVM Verification Environment which makes things highly complex and debugging complicated.
UVM provides many built-in Debug features which can be used to ease out our debugging process to save lots of time and energy.
Lets analyze these features one-by-one. Before that, lets list these features by categories:
- Configuration Debug Features
- Factory Debug Features
- Phasing Debug Features
- Objection Debug Features
- TLM Port Debug Features
- General Debug Features
1. Configuration Debug Features
UVM Configuration Database is used to pass the configuration information from the Test down into the Testbench. This mechanism is very powerful but it largely depends on string matching to perform correctly. To support that, UVM provides few capabilities to ensure what is intended took place or not?
A) UVM Command Line Processor
UVM Command Line Plusarg i.e. +UVM_CONFIG_DB_TRACE can be used to debug the status about when information is placed (set) into the resource database and pulled out (get) of the resource database.
Once used, messages similar to the shown below can be seen in log file:
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration 'uvm_test_top.ADPCM_vif' (type virtual interface adpcm_if.mon_mp) set by = (virtual interface adpcm_if.mon_mp) '{} UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration 'uvm_test_top.ADPCM_vif' (type virtual interface adpcm_if.mon_mp) read by uvm_test_top = (virtual interface adpcm_if.mon_mp) '{}
B) UVM Environment Components
UVM facilitate to print all the Configuration information for the classes which are extended from uvm_test, uvm_env & uvm_component e.g. Test, Env, Agent, Driver, Monitor etc.
Prototype of this function is shown below:
function void print_config( bit recurse = 0, bit audit = 0 )
This function contain two setting parameters, recurse and audit.
If recurse is set, then configuration information for all children and below are printed as well.
if audit is set then the audit trail for each resource is printed along with the resource name and value.
This function can be called from build_phase(), connect_phase() or most likely from the end_of_elaboration_phase().
C) Resource Database Dump:
Another option to explore what is there currently in the Resource Database is a function called dump(). When it is used, it will print what is currently in the Resource Database along with the type and paths of the each item that is stored in the database.
To use this facilty, uvm_config_db #(<type>)::dump() needs to be added to your source code. “<type>” can be anything including int, bit, or some user defined type.
This function can be called from build_phase(), connect_phase() or most likely from the end_of_elaboration_phase().
uvm_config_db #(int)::dump();
=== resource pool === ADPCM_vif [/^uvm_test_top$/] : (virtual interface adpcm_if.mon_mp) ? - === end of resource pool ===
2. Factory Debug Features:
The UVM Factory is used to create objects in UVM. By the use of Factory Override, it also allows to test the conditions by replacing existing components and objects with the desired type.
Factory Debug feature of UVM helps to understand who is registered with Factory and which overrides the Factory is currently using.
The function to be used is print(). It prints the state of the uvm_factory, including registered types, instance overrides, and type overrides. It means it tells which classes are registered with the Factory and any overrides that is registered with the Factory.
This function can be called from build_phase(), connect_phase() or most likely from the end_of_elaboration_phase().
uvm_factory::get().print();
It shows output something like this:
#### Factory Configuration (*) No instance or type overrides are registered with this factory All types registered with the factory: 44 total (types without type names will not be printed) Type Name --------- adpcm_driver adpcm_seq_item adpcm_sequencer adpcm_test adpcm_tx_seq snps_uvm_reg_bank_group snps_uvm_reg_map (*) Types with no associated type name will be printed as <unknown> ####
3. Phasing Debug Features:
UVM Phasing can be complicated with multiple phases running in parallel. To help understand when a phase starts and ends, the UVM Command Line Processor can be used to enable a trace with the +UVM_PHASE_TRACE plusarg.
When this plusarg is added to the simulator command line, it results in output similiar to this:
UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_phase.svh(1124) @ 0: reporter [PH/TRC/STRT] Phase 'common' (id=173) Starting phase UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_phase.svh(1381) @ 0: reporter [PH/TRC/DONE] Phase 'common' (id=173) Completed phase UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_phase.svh(1403) @ 0: reporter [PH/TRC/SCHEDULED] Phase 'common.build' (id=191) Scheduled from phase common UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_phase.svh(1124) @ 0: reporter [PH/TRC/STRT] Phase 'common.build' (id=191) Starting phase UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_phase.svh(1381) @ 0: reporter [PH/TRC/DONE] Phase 'common.build' (id=191) Completed phase UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_phase.svh(1403) @ 0: reporter [PH/TRC/SCHEDULED] Phase 'common.connect' (id=203) Scheduled from phase common.build UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_phase.svh(1124) @ 0: reporter [PH/TRC/STRT] Phase 'common.connect' (id=203) Starting phase UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_phase.svh(1381) @ 0: reporter [PH/TRC/DONE] Phase 'common.connect' (id=203) Completed phase
4. Objection Debug Features:
UVM Objections are used to control when a time consuming phase is going to end. Understanding when an objection is raised and dropped can be difficult specifically since all the raised objection call must be matched with the number of dropped objections. The UVM Command Line Processor can be enabled to trace with the +UVM_OBJECTION_TRACE plusarg.
When this plusarg is added to the simulator command line, it results in output similar to this:
UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top raised 1 objection(s) (starting test_seq): count=1 total=1 UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_top added 1 objection(s) to its total (raised from source object uvm_test_top, starting test_seq): count=0 total=1 UVM_INFO @ 3570: run [OBJTN_TRC] Object uvm_test_top dropped 1 objection(s) (finished test_seq): count=0 total=0 UVM_INFO @ 3570: run [OBJTN_TRC] Object uvm_test_top all_dropped 1 objection(s) (finished test_seq): count=0 total=0 UVM_INFO @ 3570: run [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (dropped from source object uvm_test_top, finished test_seq): count=0 total=0 UVM_INFO @ 3570: run [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total(all_dropped from source object uvm_test_top, finished test_seq):count=0 total=0
5. TLM Port Debug Features
Components in UVM are connected together via TLM ports, exports and imps UVM provides two functions which can be called on a port, export or imp to understand which objects are connected together.
Those two functions are debug_connected_to() (usually used with ports) and debug_provided_to() (usually used with imps or exports).
debug_connected_to() – It tells about the port’s fanout i.e. the port/export/imp network to which this port connects
debug_provided_to() – It tell about the port’s fanin i.e. the port/export network that ultimately connect to this port.
These functions should be called from the end_of_elaboration_phase as that is when all connections will have been completed by then.
m_driver.seq_item_port.debug_connected_to();
Output shows something like this:
UVM_INFO @ 0: uvm_test_top.m_driver.seq_item_port [debug_connected_to] This port's fanout network: uvm_test_top.m_driver.seq_item_port (uvm_seq_item_pull_port) | |_uvm_test_top.m_sequencer.seq_item_export (uvm_seq_item_pull_imp) Resolved implementation list: 0: uvm_test_top.m_sequencer.seq_item_export (uvm_seq_item_pull_imp)
m_sequencer.seq_item_export.debug_provided_to();
Output shows something like this:
UVM_INFO @ 0: uvm_test_top.m_sequencer.seq_item_export [debug_provided_to] This port's fanin network: uvm_test_top.m_sequencer.seq_item_export (uvm_seq_item_pull_imp) | |_uvm_test_top.m_driver.seq_item_port (uvm_seq_item_pull_port)
6. General Debug Features:
UVM provides some general debug features, lets have a look on these too.
A) Environment’s Component Hierarchy
UVM provides a function called print_topology() to show the current component hierarchy of an UVM Testbench. This function is advised to call from end_of_elaboration_phase.
uvm_top.print_topology();
Output shows something like this:
UVM_INFO @ 0: reporter [UVMTOP] UVM testbench topology: ---------------------------------------------------------- Name Type Size Value ---------------------------------------------------------- uvm_test_top adpcm_test - @460 m_driver adpcm_driver - @468 rsp_port uvm_analysis_port - @485 seq_item_port uvm_seq_item_pull_port - @476 m_sequencer adpcm_sequencer - @494 rsp_export uvm_analysis_export - @502 seq_item_export uvm_seq_item_pull_imp - @608 arbitration_queue array 0 - lock_queue array 0 - num_last_reqs integral 32 'd1 num_last_rsps integral 32 'd1 ----------------------------------------------------------
B) Controlling Verbosity:
UVM messaging system provides very good flexibility regarding the information/messages which are to be displayed to the user using the verbosity control.
Useful messages can be embedded into the whole UVM Testbench with given Verbosity Level e.g. UVM_MEDIUM, UVM_HIGH and UVM_DEBUG. The messages with UVM_HIGH or UVM_DEBUG level will not be visible in default mode. UVM provides Command Line Processor plusarg called +UVM_VERBOSITY to globally impact the Verbosity level depending on the debug details required. In case of modifying the Verbosity level of any individual component, +uvm_set_verbosity plusarg can be utilized.
If you want to have more information on UVM Verbosity, you may check out my post here.
Few things I want to highlight here about UVM Debug features and the UVM version you’re using. The above shown debug features in this post are supported by UVM 1.2. There might be some changes required in the upcoming UVM version or UVM 1.1x, please refer the corresponding resources. Also please refer other extensive resources available online as well as offline to get further more details on each of the Debug feature.
I’m hopeful that this work should help you to understand the UVM built-in Debug features in an easy & concise way. If yes, please do share your inputs, thoughts via comments section below. I’d be glad to hear from you. I’m happy here to contribute with another post which can be beneficial for you.
Until next time with another post, take care, enjoy life .. bye! Thank you! 🙂