Jump to content

Driving Internal DUT Interfaces

Recommended Posts

Hi Guys,

I was wondering if any of you have a method to drive a systemverilog interface using a uvm_driver, while the interface is already internally connected within the dut?

Either that or to replace a single internal dut module instance with an empty one? So it is not being driven by another internal module instance.

We are building up IPs that are made up of a number of modules all connected using systemverilog interfaces. My Environment has a couple of agents which I can override in the factory and point to whichever physical interface I like. So as we build up the IP we can test the blocks as add them.

To avoid managing a large number of different filelists and/test harnesses, I would like my regressions to be able use the same environment as well as whatever the current dut is. However this means I need to drive an interface which has been connected internally (i.e. when the first block level testcase was written there would be no other dut module in place, but as the dut gets developed the interface gets connected to another module).

What I need to do is to be able to disconnect an interface so I can drive it from the testbench. The monitor side is fine as monitors are passive so I can connect them to whichever interface I like.

Any ideas?

Link to comment
Share on other sites

Okay so I actually jumped the gun a bit here...

It turns out I can't use the factory to override the type of agent, So I guess this would be my first question.

Lets say I have:

class AgentA #(seq_item_type=SA, driver_type=DA, monitor_type=MA) extends uvm_agent;


`uvm_component_param_utils(AgentA #(seq_item_type, driver_type, monitor_type))



I declare Agent B:

class AgentB #(seq_item_type=SB, driver_type=DB, monitor_type=MB) extends AgentA #(seq_item_type, driver_type, monitor_type);


`uvm_component_param_utils (AgentB#(seq_item_type, driver_type, monitor_type))



in my environment I instantiate Agent A;

Now how do I override it with Agent B in a test?

I have tried:

tc extends uvm_test;


MyEnv env;


function void build phase (uvm_phase phase);



factory.set_inst_override_by_type(AgentA::get_type(), AgentB::get_type(), "/+env.agent/");

env = MyEnv::type_id::create("env", this);


end function

this seems to go through elaboration but a factory.print() yields:

Requested Type Override Path Override Type

-------------- --------------- -------------

<unknown> /+env.agent/ <unknown>

I have also tried :

factory.set_type_override_by_type(AgentA::get_type(), AgentB::get_type());

and also tried moving super.build to after the override, and also the override into the pre_build_phase;

Any pointers on how to get this to work, or if I could/should use the config_db instead?

Link to comment
Share on other sites

When you have a parameterized class, you always need to specify the parameters you want if not using the defaults. It would help if you didn't specify defaults when declaring AgentA, then you would be required to override the parameters.

class AgentB #(type seq_item_type, driver_type, monitor_type) extends  AgentA #(seq_item_type, driver_type, monitor_type);
Then when calling the static function get_type(), you need to specify the matching parameters

set_type_override_by_type(AgentA#(SI,DT,MT)::get_type (), AgentB#(SI,DT,MT)::get_type())
Note: since you are doing this from inside MyEnv which is a uvm_component, you do not use 'factory.'. Then the override is implicitly from the current place in the UVM hierarchy.
Link to comment
Share on other sites

Does that mean that my component that I will override also has to have the same parameters when it is instantiated?

I think it does (I have been experimenting today).

It seems that each specialisation of a class is actually a new class description, and is on a flat hierarchy with the original declaration.

The way I have gotten around it is to declare a base agent with no parameters, but a load of empty functions and tasks. The I can place this unparameterised class in my environment and override it with a parameterised sub-class (it's pain though, as the whole point was so that I could swap the original parameters).

Link to comment
Share on other sites

Was that your paper...

I read it today, Still not completely understanding it, but I am getting there.

Anyway I've got my factory overrides in place, the only thing I cannot do is turn the agent to passive.

in the env build_phase :

uvm_config_db#(uvm_active_passive_enum)::set(rx_agent, "", "is_active", UVM_PASSIVE);


uvm_config_db#(uvm_active_passive_enum)::set(null, "/.*rx_agent.*/", "is_active", UVM_PASSIVE);

there must be an easier way to switch this bit?

sorry the thread will eventually come around to my initial question.

Link to comment
Share on other sites


So ignoring the active/passive bit for now, I wonder if we can go back to my original question...

Is there any way to switch the tes-harness configuration on the fly?

Currently I am using `ifdefs to switch in-or-out dummy interfaces which allow me to drive different sections of the testbench, but this isn't very elegant.

I was wondering if there was a way of querying the CLI to return the UVM_TESTNAME at compile time so I can switch based on that?

The other option is to have the test harness instantiate a number of virtual interfaces, one per real interface connection and have a function that connects the correct ones together depending on the test case, but I'm not sure how succesful this will be...

Any other ideas?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...