Verification in the trenches: Implementing Complex Synchronization Between Components Using VMM1.2
Posted by Ambar Sarkar on February 5th, 2010
Dr. Ambar Sarkar, Chief Verification Technologist, Paradigm Works Inc.
Why is it tricky to get transactors and other verification components to work in sync with each other, especially if they come from different projects? It is likely that they worked well within their source projects, but their phases (build, configure, reset, start, shutdown etc) were implemented quite differently compared to other components. These differences are usually driven by the inherent protocol requirements or team preferences. For example, consider the verification of an SOC with an AXI host interface and a PCIe Root Complex. You will likely get your host interface transactor out of reset and execute a configuration sequence before you let your PCIe end point transactor send in requests. So you would not want to run the phases of these two transactors in lock step.
While there are countless ways to implement the phases and their sequencing, one can broadly classify a component as being either explicitly or implicitly driven, depending on how its phases are invoked.
Implicit phasing: In my earlier post, we discussed how one can often easily coordinate the execution of various verification components. Simply put, as long as one is able to distribute the execution of the component between predetermined methods (called phases), the components can execute in lock-step with one another without requiring any additional coding by the verification engineer. This is called implicit phasing. Implicit phasing may suffice in many cases, but the challenge is to agree on the same set of phases and their sequencing. You basically will need a way to define additional phases and potentially even rearrange their implicit calling sequence.
Explicit phasing: In contrast, explicit phasing requires the environment writer to explicitly call and synchronize the phases of the components. Typically, it takes some work to get such components to play well with one another. This happens more often for legacy or externally developed components. In such cases, the developers may not have known about the predetermined phases so they could not have broken down the implementation quite the way the target environment expects. Explicit phasing is often unavoidable in environments with components from multiple sources, since you may need to carefully control and coordinate the phases by hand to accommodate their differing implementation assumptions.
So the challenge we are discussing today is really about making these explicit and implicit phased components get their phases to match and cooperate during their phase transitions.
This is where vmm_timeline helps. Simply put, vmm_timeline object encapsulates your implicitly phased object and allows it to be called as an explicitly phased object. It lets you define your own phases and the sequence in which you want to execute them. The ability to customize phases is critical, as you may need to define additional phases to fit in with the way the explicitly phased target environment expects its phases to execute.
Here is an example that shows how an implicitly-phased component(my_implicit_comp) is being executed within an explicitly-phased my_env. Notice how the my_tl(derived from vmm_timeline) is used.
Step a. Create a vmm_timeline object and instantiate the components
| // Implicitly phased comp class my_implicit_comp extends vmm_group; `vmm_typename(my_implicit_comp) … function new(string name = “”, vmm_object parent = null); super.new(“my_implicit_comp”, name, null); super.set_parent_object(parent); endfunctionvirtual function void build_ph(); super.build_ph(); … endfunction endclass // Create a vmm_timeline class to wrap this implicitly phased component class my_tl extends vmm_timeline; function new(string name = “”, virtual function void build_ph(); // Create an instance endclass |
Step b. Instantiate in top-level vmm_env and call out the implicit methods
| // Instantiate the vmm_timeline object in the top environment and call its phases explicitly.class my_env extends vmm_env; `vmm_typename(my_env) my_tl tl; function new(); virtual function void build(); virtual task start(); virtual task wait_for_end(); virtual task stop(); // shutdown phase corresponds best here |
Note that the converse is also true. Explicitly phased components can be incorporated into implicitly driven environments. You need to encapsulate them in a parent class derived from the vmm_subenv class and define how each implicit phase of the parent class can be mapped to the proper explicit phase(s) of the original component. Then you can simply instantiate this parent class in the target environment. For further details, search the string “Mixed Phasing” in the VMM 1.2 User Guide.
In summary, vmm_timeline helps you manage different phasing and sequencing needs of verification components by making it easier for explicitly and implicitly phased components to interact. No wonder that under the hood of VMM1.2, vmm_timeline is used to implement advanced features such as multi-test concatenation.
This article is the 4th in the Verification in the trenches series. Hope you found this article useful. If you would like to hear about any other related topic, please comment or drop me a line at ambar.sarkar@paradigm-works.com. Also, if you are starting out fresh, please check out the free VMM1.2 environment generator at http://resourceworks.paradigm-works.com/svftg/vmm .








