2
votes

I'm trying to figure out how to connect multiple UVCs (UVM Verification Components) to the same DUT where the UVC's do not share an interface but do connect to the same signals on the DUT.

The DUT that can operate on different protocols on common signals and can switch between protocols after a receiving a specific sequence. Each protocol was developed independently into is its own UVC; lets call them low-speed and high-speed. Assume the interfaces and DUT are the follows:

interface lowspeed_if( input bit clock, reset );
  logic       a;
  logic       b;
  logic       c;
  logic [7:0] io_drv;  wire  [7:0] io = io_drv;
                       wire        ready;
  initial {a,b,c,io_drv} = 'z;
endinterface : lowspeed_if

interface highspeed_if( input bit clock, clk2, reset );
  logic       a;
  logic       b_drv;   wire        b = b_drv;
  logic [7:0] io_drv;  wire  [7:0] io = io_drv;
                       wire        ready;
  initial {a,b_drv,io_drv} = 'z;
endinterface : highspeed_if

module device_to_test(input a, inout b, input c, inout [7:0] io, output ready);
  /* RTL */
endmodule : device

Because the UVC's were not designed considering the other protocols, the low-speed driver/monitor can only connect with lowspeed_if and the high-speed driver/monitor can only connect with highspeed_if. This means there are two interfaces that need to connect to the same a, b, io, and ready signals.

Is there a way connect these UVCs to the same DUT without changing the original UVCs?

2

2 Answers

1
votes

At the top level define the connecting signals as wires. Use assign statements for signals that only drive the DUT. Use tran for bi-directional. For signals only monitoring the DUT, use assign statements

bit clock,clk2,reset;
wire a,b,c;
wire ready;
wire [7:0] io;

lowspeed_if  ls_if(.*);
highspeed_if hs_if(.*);
device dut( .* );

assign {a,b,c} = {ls_if.a, ls_if.b, ls_if.c};
tran link_io_ls[7:0](io, ls_if.io);
assign ls_if.ready = ready;

assign a = hs_if.a;
tran link_b_hs(b,hs_if.b);
tran link_io_hs[7:0](io, hs_if.io);
assign hs_if.ready = ready;

ready could have been connected with a tran since it is defined as a wire in the interfaces. Using the assign statement makes the direction explicit and is flexible if a future interface defines the outputs as something other then wire.


I discovered assign {a,a} = {ls_if.a,hs_if.a}; also works for assigning drivers.

0
votes

It's a good thing your interfaces have wires to work with - that makes it easy to tie them together and have multiple drivers. You can create a tie module that collapses three wires together into one.

module tie(inout .a(w), .b(w), .c(w));
   wire w;
endmodule

Then your testbench would look like:

module top;

  wire a,b;
  wire [7:0] io;
  wire clk, clk2, reset, ready

  lowspeed_if  ls_if(clk, reset);
  highspeed_if hs_if(clk,clk2,reset);

  tie tie_a(ls_if.a, hs_if.a, a);
  tie tie_b(ls_if.b, hs_if.b, b);
  tie tie_rdy(ls_if.ready, hs_if.ready, ready);
  tie tie_a[7:0](ls_if.io, hs_if.io, io);

  device_to_test DUT(a, b, ls_if.c, io, ready);

endmodule