UVM testbench - What is the "UVM" way to connect two different drivers to same interface?
system-verilog, uvm
Solution
I would also suggest, like Tudor, to use only one agent. But then I would use inheritance, declaring a base_driver and a base_sequencer (that may have common functionalities from both ModeA or ModeB drivers and/or sequencers), and ModeA and ModeB units would extend those base ones. Then, in the agent, and using a flag in the uvm_config_db set in each test, you would select between instantiating one or the other:
Base driver:
class my_proj_base_driver extends uvm_driver#(my_proj_tr);
[...]
ModeA driver:
class my_proj_ModeA_driver extends my_proj_base_driver;
[...]
ModeB driver:
class my_proj_ModeB_driver extends my_proj_base_driver;
[...]
In the agent:
[...]
my_proj_base_driver driver;
bit modeAorB // 0 for A, 1 for B
[...]
if (!uvm_config_db#(bit)::get(this,"","modeAorB", modeAorB))
`uvm_fatal("NOMODE","No mode set for this agent")
if(!modeAorB)
driver = my_proj_ModeA_driver::type_id::create(.name("driver"), .parent(this));
else
driver = my_proj_ModeB_driver::type_id::create(.name("driver"), .parent(this));
And the same for the sequencer.
Problem
In my Testbench, I have an interface that I need to drive. The interface can be driven in 2 different modes, with each mode having its own driver protocol and transaction type. So far, I have designed both uvm_agents separately. Now, I need a way to swap one or the other in, depending on the testcase I am running. I also want to do this in the way that best fits with UVM philosophy. My best method that I could come up with is: in my uvm_env, getting a uvm_db_config parameter from the test that says either "ModeA" or "ModeB", and based on that, setting is_active for the agents to "UVM_ACTIVE" and "UVM_PASSIVE" appropriately. I would like an opinion on this method. A way suggested to me was to keep a common uvm_agent, and instantiate the uvm_driver/uvm_sequencer based on the configuration. Not too sure about this method as it looks messy.