Key Takeaways
- The UVM framework utilizes objections for managing simulation lifecycles, ensuring proper synchronization across phases.
- Using raise_objection and drop_objection multiple times in a UVM test is inefficient; instead, use a simplified barrier approach for synchronization.
- The uvm_barrier.svh is a simpler alternative to raise/drop objections, allowing for the creation of custom barrier functions which may require fewer lines of code.
You begin writing some UVM code and there are parts of the code that aren’t done yet, so you begin to use uvm_objection, guarding that code. Rich Edelman, a product engineer at Siemens doing verification debug and analysis, wrote a paper on this topic, which I just read. This blog covers the topic of objections and provides some different approaches.
UVM is founded on processes, and processes can be synchronized automatically or by design during phases. We typically raise an objection, then later on drop the objection during a phase.
Here’s a UVM example using a raised objection to make sure that simulation doesn’t exit until a drop exception happens.
The source code of has over 1,000 lines of code, so it’s recommended to use objections once in a test. Consider a UVM test with four sequences, using raise_objection and drop_objection.
Each of the four environments (e1 – e4) call raise_objection and drop_objection, which is not so efficient.
A simpler objection in UVM is the uvm_barrier.svh, at just 240 lines, but we can define our own barrier function with even fewer lines like this:
This barrier code uses a count to pass the barrier. When the count reaches 0 after a drop, it exits.
Another approach to synchronization is using names like start, middle, and end.
This wrapper creates the barrier class if needed, and uses three names: raise, drop, and get.
The next example shows a class and a module, where there are two class instances and three Verilog modules. Three phases are synchronized across the modules and class instances: start, middle, and end. The objects simulate in each phase for some time, then drop the objection. After all objects have dropped, processing continues.
Running this example shows that each object reports after “drop” has returned, then each object moves forward.
Both Class1 and Class2 are SystemVerilog class handles, while A, B, and C are the Verilog module instances. Each of the objects in each phase waits until the next barrier completes, which is our synchronization goal.
Below are visualizations: the “middle” phase and the workload for each object. Each phase—here the middle phase—displays each object: “class1,” “B,” “A,” “class2” and “C,” in order, along with the payload for each object.
This view shows many phase begins and ends, all synchronized.
The expanded view provides details of the objects and payloads in each phase.
Objections and phasing are linked together, so use objections with phasing while limiting their usage to be more efficient. One way to create phasing is through a barrier like uvm_barrier, or using the examples presented. You can solve synchronization with your own code. Adding too many raise_objection and drop_objection pairs in your code will only slow down simulation times.
Summary
Yes, continue to use uvm_objection in your UVM code, being careful to not slow down run times by calling it too often. Alternative approaches were shared in this blog that require less code, are more intuitive, and run quicker.
Read the complete 15 page paper online.
Related Blogs
- Making UVM faster through a new configuration system
- UVM Polymorphism is Your Friend
- Happy Birthday UVM! A Very Grown-Up 10-Year-Old
- Connecting SystemC to SystemVerilog
Comments
There are no comments yet.
You must register or log in to view/post comments.