The Universal Verification Methodology (UVM) is a popular way to help verify SystemVerilog designs, and it includes a configuration system that unfortunately has some speed and usage issues. Rich Edelman from Siemens EDA wrote a detailed 20-page paper on the topic of how to avoid these issues, and I’ve gone through it to summarize the highlights for you. Verification engineers use a UVM configuration database to set values, then to get the values later in their UVM test. One example of setting and getting a value ‘T’ is:
uvm_config#(T)::set(scope, instance_path_name, field_name, value); uvm_config#(T)::get(scope, instance_path_name, field_name, value);
Connecting the UVM testbench to the device under test uses the configuration database to pass the virtual interfaces. There are three problems with using the UVM configuration:
- Big code, some 2,600 lines of code
- Requires exact type matching, so ‘int’ and ‘bit’ are not the same
- Slow code
Consider the case of slow code, because with thousands of calls to set() using names with wildcards can take up to 30 minutes to complete the ‘set’ and ‘get’ phase.
Rich proposes a new solution to UVM configurations that has much faster speeds, taking only a few seconds in comparison.
If your UVM code avoids using wildcards and has few ‘set’ commands, then your code will run faster.
Possible solutions to the UVM configuration issues are:
- Use a global variable instead
- Use UVM configuration with one set()
- Use UVM configuration with a few set()
- Use a configuration tree
- Try something different
That last approach of trying something different is the new solution, and it continues to use the set() and get() API, then simplifies by removing parameterization of the configurations, removes precedence, and removes the lookup algorithm change. The results of this new approach are fast speeds.
Your new configuration item is defined in the derived class from ‘config_item’, and the example below shows ‘int value” as the property being set. For debug purposes you add the pretty-print function.
class my_special_config_item extends config_item; function new(string name = "my_special_config_item"); super.new(name); endfunction int value; virtual function string convert2string(); return $sformatf("%s - value=%0d <%s>", get_name(), value, super.convert2string()); endfunction endclass
The ’config_item’ has a name attribute, and this name is looked up, plus the instance name. The configuration object also has a get_name() function to return the name. To find any “instance_name.field_name” the configuration database uses an associative array for fast lookup and creation speeds.
For traceability you can find out who set or who called get, because a file name and line number are fields in the set() and get() function calls.
set(null, "top.a.b.*", "SPEED", my_speed_config, `__FILE__, `__LINE__) get(null, "top.a.b.c.d.monitor1", "SPEED", speedconfig, `__FILE__, `__LINE__)
The accessor queue can be printed during debug to see who called set() and get().
To support wildcards required adding a lookup mechanism using containers. Consider the instance name ‘top.a.b.c.d.*_0’.
The wildcard part of the instance name is handled by using the container tree, instead of the associative array.
Summary
Sharing data between the module/instance and the class-based world in a UVM testbench can be done using the UVM configuration database, just be aware of the speed slowdowns. If your methodology uses lots of configurations, then consider using the new approach introduced which has a package using about 300 lines of code instead of the 2,600 lines of code in the UVM configuration database file.
Read the full 20-page paper, Avoiding Configuration Madness The Easy Way at Siemens EDA.
Related Blogs
- SystemVerilog Has Some Changes Coming Up
- The State of FPGA Functional Verification
- The State of IC and ASIC Functional Verification
- Connecting SystemC to SystemVerilog
- UVM Polymorphism is Your Friend
Comments
There are no comments yet.
You must register or log in to view/post comments.