How to connect multiple interface within dut in UVM?

Hi

I’m trying to implement multiple interface into DUT.


`include "interface.sv"
`include "test.sv"

module tbench_top;
   
  //creatinng instance of interface
  intf 		i_intf();
  i2c_intf  i_i2c_intf();
  
  //Testcase instance
  test t1(i_intf);  
  
  //DUT instance, interface signals are connected to the DUT ports
  adder DUT (
    .a(i_intf.a),
    .b(i_intf.b),
    .c(i_intf.c),
    .i_scl_in(i_i2c_intf.i_scl_in),
    .o_sda_out(i_i2c_intf.o_sda_out)
   );
  
endmodule

But I have some problem what I try to instance interface as below I got the error message.
** at environment.sv(18): Multiple constructors declared for class environment - only one allowed.

`include "environment.sv"
module test(intf i_intf);
  
  //declaring environment instance
  environment env;
  
  initial begin
    //creating environment
    env = new(i_intf);
       
    //calling run of env
    env.run();
  end
endmodule



class environment;
  
  //virtual interface
  virtual intf vif;
  virtual i2c_intf i2c_vif;
  
  //constructor
  function new(virtual intf vif);
    //get the interface from test
    this.vif = vif;
  endfunction
  
  //constructor
  function new(virtual i2c_intf i2c_vif);
    this.i2c_intf = i2c_vif;
  endfunction
  
  //run task
  task run;
    vif.a = 6;
    vif.b = 4;
    
    $display("Value of a = %0d, b = %0d",vif.a,vif.b);
    #5;
    $display("Sum of a and b, c = %0d",vif.c);
    $finish;
  endtask
endclass

[2022-02-16 08:22:55 EST] vlib work && vlog -writetoplevels questa.tops ‘-timescale’ ‘1ns/1ns’ design.sv testbench.sv && vsim -f questa.tops -batch -do “vsim -voptargs=+acc=npr; run -all; exit” -voptargs=+acc=npr
QuestaSim-64 vlog 2021.3_1 Compiler 2021.08 Aug 15 2021
Start time: 08:22:55 on Feb 16,2022
vlog -writetoplevels questa.tops -timescale 1ns/1ns design.sv testbench.sv
– Compiling module adder
– Compiling interface intf
– Compiling interface i2c_intf
** Error: ** while parsing file included at testbench.sv(6)
** while parsing file included at test.sv(1)
** at environment.sv(18): Multiple constructors declared for class environment - only one allowed.
End time: 08:22:55 on Feb 16,2022, Elapsed time: 0:00:00
Errors: 1, Warnings: 0
Exit code expected: 0, received: 1

How do I implement multiple interface into DUT?

In reply to UVM_LOVE:

You have two new() functions (constructors) in your environment class. This is why you have an error. You should have only one new() function and pass both interface handles as arguments.

In reply to cgales:

BTW, we strongly recommend using the uvm_config_db to pass information to a class instance instead of adding extra arguments to the constructor. Adding constructor arguments prevents using the UVM factory, and also leads to “argument creep” when adding inheritance or hierarchical class structures.

In reply to dave_59:

Hi Dave,

Do you mind elaborate on what is “argument creep”?

In reply to Jeff_Li_90:

It means the number of places that have to deal with the argument creeps up in number. This example only has one layer of class construction, but let’s add another layer.

class test;
  env e;
  function new(virtual i2c_intf i2c_vif);
    e = new(i2c_vif);
  endfunction
  ...
endclass

If you need to change the interface type, you have to change it in two places. Now lets and another env with a different virtual interface; you have to and another argument to the test class. In a typical UVM testbench, there are several layers of components (test->env->agent->driver). You don’t want to have to change all the intermediate level classes just because you made a change at the lowest level.

In reply to dave_59:

Oh I see what you mean. Passing variable by constructor requires that each level has the same constructor signature, while passing variable by config_db is a nice way of using global variable/hashmap.

Thanks,
Jeff

In reply to dave_59:

In reply to cgales:
BTW, we strongly recommend using the uvm_config_db to pass information to a class instance instead of adding extra arguments to the constructor. Adding constructor arguments prevents using the UVM factory, and also leads to “argument creep” when adding inheritance or hierarchical class structures.

Dear Dave_59,

Could you give some guide example code for “using the uvm_config_db to pass information” into my situation to avoid “argument creeps” for understading?

In reply to UVM_LOVE:
https://lmgtfy.app/?q=using+the+uvm_config_db

In reply to dave_59:

In reply to UVM_LOVE:
https://lmgtfy.app/?q=using+the+uvm_config_db

But uvm_config_db is only work in UVM. doesn’t it?

In reply to UVM_LOVE:

You posted this question in the UVM forum, so we assume you’re already using the UVM.

But even if you’re not, you could still
import
this one class from the UVM library into your testbench. Or worst case, reinvent similar functionality in your testbench.

In reply to dave_59:

In reply to UVM_LOVE:
You posted this question in the UVM forum, so we assume you’re already using the UVM.
But even if you’re not, you could still
import
this one class from the UVM library into your testbench. Or worst case, reinvent similar functionality in your testbench.

Thank you, I’ll look into your way.