Suppose you have two verification components, each driving its own portion of the DUT (for example, two protocols driving a DUT, one implemented in e and the other in System Verilog).
In this case, you would have two separate sequence-driven, end-of-test mechanisms - one for each framework.
An issue arises when one of the frameworks drops its last TEST_DONE objection. In this case, that framework will begin simulation finalization phase, while the other is still running. This will cause the simulation to come to its end, which will cause the other, still working, framework to stop abruptly.
The solution is to create a dependency between the objection mechanisms of both frameworks, using multi-language UVM features. A method to apply this solution is demonstrated below.
In the following method, the e verification component has two TLM put ports (one for raising the objection and the other for dropping the objection), and the SystemVerilog verification environment has two TLM put implementations. All additions made to the code were made in the topmost hierarchies of these verification components for the sake of simplicity. Also, let's call the framework that has the TLM out ports the "objection client framework," and the one that has the TLM implementation the "objection server framework."
NOTE: Ensure you have the multi-language UVM open architecture package downloaded and installed.
1. Connect the two frameworks with two TLM ports (analysis or put).
e code:
a) Extend theeenv to instantiate those two TLM ports
SV code:
a) Extend the SV env to declare two put implementation methods and make sure to register them:
b) Set the type override by type to replace instances of the old ‘env' by the new ‘extended env' in the build phase of uvm_test_top:
c) Finally connect the ports in the e framework to the implementations in the SV framework (in the System Verilog test bench top hierarchy). Note that you need to supply the UVM path as a string for the e and SV TLM ports, since the factory override takes effect only in runtime:
2. Implement the TLM write()/put() methods (for analysis/put TLM ports) to drop and raise TEST_DONE objections.
SV code: (note that this code should be where the TLM port is declared - in class counter_env from step 1):
3. At the beginning of the simulation, raise a TEST_DONE objection manually in the objection client framework.
e code: (note that this code should be in the same unit as in step 1 - counter_env_u):
4. When the objection client framework starts a sequence branch (there may be more than one), raise a TEST_DONE objection in the objection server framework by using one of the TLM ports.
When the objection client's sequence branch is done, drop the TEST_DONE objection in the objection server framework by using the second TLM port. Do this by extending the relevant sequence's pre_body() and post_body().
e code:
The objection client framework raises and drops as many objections in the objection server framework as in its independent sequence branches. Also, the objection client always has one more objection raised than objection server (the objection raised in step 3). Therefore:
- If the objection server framework dropped all of its native objections, it will still have as many objections raised as the objection client's unfinished sequence branches - and the simulation will not end until the objection client finishes its sequences.
- If the objection client finished first, it will not end until the objection server finishes its native objection count; then the simulation will end.
By applying this solution, we force the simulation to not finish even though one of the frameworks declared that it is "done." Instead, the simulation will run commensurate with the longer framework's simulation time.
Appendix 1:
Applying the UVM_ML_OA Features If Previously Unused in Your Multi-Language Environment
If you did not previously use the UVM_ML_OA features in your multi-language environment, apply them to the environment as follows:
1. Download and untar the UVM ML OA package from uvm world from here . You will need to register if you are not already registered.
2. Set the environment variables and source the setup.csh script as explained in README_INSTALLATION.txt, which is located in the ml/ folder in the untarred folder.
3. In the file that contains your top module (the module that instantiates the DUT and that includes your UVM sv VC and the uvm_pkg packages ), do the following:
a. Import the uvm_ml package:
b. In an initial block, create a string array, where each string points to the top Level entity of each framework in your environment. (In the example below, it is is only the e test file.)
c. Replace the run_test() statement with uvm_ml_run_test(). Provide uvm_ml_run_test() with the string array from the previous step and with the SV test name. (In the example below - the SV test is also the top entity in the UVM sv (SV?) framework.)
For more information on UVM ML OA constructs, syntax, and other features, go to the UVM ML OA documentation in <uvm_ml_install_dir>/ml/README.html.
Yuval Gilad
Specman Support