Bind interface for internal DUT forcing

Hi,

I want to connect an interface to and internal DUT signals and connect it to a VIP driver, then force it through a task that is defined in the interface as follows:

interface vip_axi_wrapper_lbw_if (input aclk, input aresetn, 
    output wire DUT_MASTER_awvalid[0:FC_MAX_NUM_OF_LBW_MASTERS-1],
    .
    task drive_if();
	 force  DUT_MASTER_awvalid[0] = axi_if.master_if[0].awvalid;
endinterface

Then I’m binding it to the DUT internal signals as foolows:

bind top_tb vip_axi_wrapper_lbw_if pcie_rtr_vif (.aclk(top_if0.lbw_clk[0][0]), 
    .DUT_MASTER_awvalid		('{`RTR_0_0_PATH_TMP.lbw_mstr_awvalid, top_if0.dummy}));

After that I’m passing it through the set_config as follows to an agent:

initial uvm_config_db#(virtual vip_axi_wrapper_lbw_if)::set(null, "*" , "pcie_rtr_lbw_vif", top_tb.pcie_rtr_vif);

The problem is the force doesn’t apply on the RTL signal which is driven by the RTL and I see 'x’s. Is there a way of doing this?
Thanks,
Berry

In reply to berryvai:

I have two questions:
(1) why does your SV interface has ports?
(2) you are binding this Interface to tb_vip and not to the DUT. Is this what you want?

Hi,

Thanks for the response.

  1. The reason for the ports is that I’m trying to create a generic IF that I could connect RTL internal AXI interfaces in different blocks in my DUT, and force them to an AXI VIP. If I won’t use ports I’ll have to create an individual IF per RTL AXI end point.
  2. No, I’m binding the generic IF I created (vip_axi_wrapper_lbw_if) to my DUT that instantiated in the top_tb. After that I’m passing it through the factory to my agent, which will initiate the internal IF task that force the ports which was binded to the DUT.

I managed to make this work in the EDA playground with a simple example. But since I’m using the set_config_db to pass the virtual IF, I think it might cause this to fail.

Please advise.

Thanks,
Berry

In reply to berryvai:

Unfortunately I do not understand your Explanation for (1). Having ports in an SV Interface Limits the usage of this Interface.
The Syntax for the bind construct is as follows
bind <inst. name of this module>

Hi,

Sorry for being unclear, I’ll try to be more clear this time.
My main purpose is to drive internal design IFs when those are already driven by RTL drivers.

For this discussion these IFs are standard AXI4 IFs. Now, lets say I have few AXI4 IFs in the entire design, and I want to control which are driven by the VIP and overcome the RTL drivers and which are not forced by the VIP and driven by the RTL drivers as usual.

For that purpose I created only one IF that has ports which correspond to AXI4, and a task that force those ports when the task is activated - as seen above. In this way I can connected each of the AXI4 internal RTL signals to an instance of this IF wrapper, and send them to the factory for the agent to pick them up and control which is active and which is not.

The problem is that the force only apply on the ports, but the RTL signals, which are driven by the RTL, becomes ‘x’.
I there a better way of doing what I just described?

Thanks,
Berry

In reply to berryvai:

Your wording is still a Little bit confusing to me.
(1) I guess you want to drive internal nodes or signals and not complete IFs. Right?
(2) What are RTL drivers? A node/Signal is driven by a RTL signel. Right?
(3) what is the implementation language of your design?

Hi,

1)Yes. For example I have 3 RTL modules that connected one to another.
ModuleA → ModuleB → ModuleC
IF1 IF2
I would like to drive IF1 and IF2 instead of ModuleA and moduleB respectively.
But the way I want to do it is as mentioned. Encapsulate IF1 and IF2 in a virtual IF with a task that controls whether I force a VIP on them or not, send it to the UVM factory, and use the task during the simulation.
2) RTL drivers are moduleA and moduleB in my example.
3) The design is in Verilog and I do verification in SV and UVM.

Thanks.

In reply to berryvai:

OK, I understand now. You have IF1 in between ModuleA and ModuleB, IF2 in between moduleB and moduleC.
Why do you not implement in the SV Interfaces a MUX? One Input is used for the chain and the other one to drive from your testbench?

Hi Thanks.

The modules A-C are a part of the DUT. I do not have access to change them. I wish to force IF1 and IF2 from my test, depending on the configuration object defined by the user running the test.

My idea was to connect an interface to IF1 and IF2, and use the force task inside it during the simulation. The problem is that I’m getting 'X’s.

Thanks,
Berry

In reply to berryvai:

Please check this contribution:
https://verificationacademy.com/forums/uvm/how-force-dut-internal-signals-uvm-Environment

Thanks very much.
I read this contribution, but the problem with that is that they instantiate the DUT, which in my case is already instantiated and is a sub-block of the whole DUT.
They do:
dut dut_instance(.dut_pin(if_instance.dut_pin)); //connect if to DUT

In my casr I tried something similar:
dut_if if_instance(.dut_pin(`PATH_TO_SUB_BLOCK.dut_instance.dut_pin)); //connect DUT to if

But when I do get_uvm_db of the virtual vif in my testcase and drive vif.ctrl to ‘1’:
if(ctrl) begin
force dut_pin = dut_pin_desired_val;
end, the forces
the result is 'X’s on the `PATH_TO_SUB_BLOCK.dut_instance.dut_pin.

Here is another example of what I’m trying to do:
interface whitebox_if(
output wire sig
);
task drive_if();
force sig = vip.some_value;
endtask
endinterface

module top;
bind inst_dut whitebox_if wb_if( sub_1.sig ); // bind interface to DUT + connect internal signals
initial
uvm_config_db #(virtual whitebox_if)::set(null, “*”, dut.wb_if); // place (bound/buried) interface into database
endmodule

In reply to berryvai:

You are using in this example a hierarchical path (vip.some_value) and the bind. This might conflict.

This is not the problem, since I have vip class instance in the virtual interface, so you can assume this:

force sig = 'h1212;

So the problem here is much deeper That I can’t figure out. I think this is connected to the fact I’m using the factory to pass the virtual interface.

Thanks,
Berry

BTW, I can solve the whole problem by forcing to the exact RTL internal signal, and not using the ports, but this means I will have to create a unique interface per sub-block (IF1, IF2, IF3 …), and since the interfaces are pretty much the same per block, this will be very ugly.

Thanks,
Berry

In reply to berryvai:

You are using the config_db. This is a very simple and straight Forward mechanism. I do not believe it Comes from there.

Yes. But this is the only thing I have in mind here. So why does this strategy fail?

Thanks.

Anyone has more ideas, please?

In reply to berryvai:

I was working on a simple example. It is quick and dirty but it works.
Can you please respond on my email:
Christoph@christoph-suehnel.de