Creating a UVM agent for an existing task based BFM

I have an existing VIP library for an internal bus that includes a task based BFM that I would like to incorporate into a new UVM environment.

My initial thought was to simply wrap the existing BFM in a uvm_monitor class, but that did not seem to be the cleanest way as that class would need to know the full hierarchy of the instantiated BFM in the toplevel to be able to execute the tasks.

My second thought was to register the hierarchy name of the BFM in the UVM database and then retrieve it in the uvm_monitor, as a virtual interface can be passed, to call the tasks. Unfortunately I couldn’t find an easy way to then use that hierarchy name to call the task short of creating a new DPI function.

Has anyone found a good method of integrating task based BFMs into UVM?

How is your BFM implemented? Is it a Verilog Module, a SystemVerilog interface or is it a class?

If it’s a class, then you can put the class as a sub-component within a UVM driver or monitor and call the tasks from the driver. To use sequences, you’d have to implement a sequence item to use sequences using the driver to convert the sequence items into task calls.

If it’s a module, then you might consider changing the module to an interface and then passing that to the UVM driver/monitor as a virtual interface. Again, to integrate with sequences you’d have to implement a sequence_item and call interface tasks from the driver/monitor.

In reply to mperyer:

You may want to take a look at this old thread from OVMWorld to see how the actually connections can be made: OVM wrapper for Verilog Bfms?? | Verification Academy

I recently updated this for UVM in another DVCon2012 Paper: The Missing Link: The Testbench to DUT Connection | Technical Paper | Verification Academy

The BFMs current in our verification library are Verilog modules that expose tasks that directly drive signals on the BFM. The expectation is that the BFM is instantiated in the testbench and the directly connected to the DUT.

The issue, and one that was not cleanly solved in our VMM wrapper, is that the full hierarchy name to the BFM is required to be able to call the tasks from the driver class. It is this issue that I was looking for a better solution so that a new UVM framework would not rely on these hardcoded hierarchy names and support multiple variants.

After reviewing the previous OVM posts, Dave’s DVEcon papers and the AVM I believe the best choice may be a variant of the cross-reference class in an interface mentioned in chapter 9 of the AVM. Since our tests are currently done in 2 passes, 1 for configuration generation and the second for random stimulus generation, I believe this could fit right in.

For example, let’s say my configuration space for the DUT could be 1-4 bus interfaces based on a DUT parameter each of which would be connected to a BFM in the testbench. The instantiation of the BFMs would be done using a generate loop and the hierarchy paths would be known deterministically. In the configuration stage, one of the output files generated (that are consumed by the simulation stage) would simply write n instances of a Verilog macro which would create the cross-reference interfaces with the correct hierarchy names.

From the point of view of the testbench, the array of virtual interfaces is then just available and can be passes through the UVM database.

Comments?