Passing a parameterized virtual interface (or any class/object) through a config object

I would like to pass a virtual interface from the base test down to the env level through the use of a config object. The interface is parameterized and I would like to override it with a new value in the base test. Also, I would like the same parameter value to be passed to lower level components (agent down to driver/monitor/etc.). Sample code:

my_common.svh


`define MY_N  `PROJ_N // get the project-specific param

my_config.svh


class my_config extends uvm_object;
    virtual my_intf  vif;
    int unsigned     my_n;

    function new(string name = "my_config")
        super.new(name);
        my_n = 32;
    endfunction
endclass

my_interface.sv


interface my_intf #(parameter N = 32)
  (input clk, rstn)
    logic[N-1:0] bus;
    ...
endinterface

my_tb_top.sv


`define PROJ_N  64 // pretend this has been defined in a different file somewhere else
...
`include my_common.svh
`include my_config.sv
`include my_interface.sv
`include my_env.sv
`include my_agent.sv
...
`include my_base_test.sv
...
module my_tb_top
    logic  clk, rstn;
    my_intf #(.N(`MY_N)) my_vif (clk, rstn);

    initial begin
        uvm_config_db #(virtual my_intf #(`MY_N))::set(null, "*", "my_vif", my_vif);
        uvm_config_db #(int)::set(null, "", "my_n", `MY_N);
    end
endmodule

my_base_test.sv


class my_base_test extends uvm_test;
    my_config  cfg;
    my_env     env;
    ...
    virtual function void build_phase(uvm_phase phase);
        cfg = new();
        if (!uvm_config_db #(virtual my_intf #(`MY_N))::get(this, "", "my_vif", cfg.vif))
          `uvm_fatal(get_type_name(), "Didn't get a handle to the virtual interface!")
        uvm_config_db #(int)::get(this, "", "my_n", cfg.my_n);
        uvm_config_db #(apb_config)::set(this, "env*", "cfg", cfg); // for agent/s all the way down
    endfunction
    ...
endclass

I’m now getting this error:

xmelab: *E,TYCMPAT (./my_base_test.sv,15|112): formal and actual do not have assignment compatible data types on instance '$unit_0x074ee474' (expecting datatype compatible with 'virtual interface my_intf#(.N(32))' but found an incompatible 'virtual interface my_intf#(.N(64))' instead).

If I remove the #(`MY_N) in the build phase of the base test, I’m able to get past the compile phase but I will run into the “Didn’t get a handle to the virtual interface!” fatal error.

How do I resolve this? Or is there a better way of getting project-specific parameters such that it can be easily passed on to the interface instantiation and to the UVM environment (all the way down to driver/monitor modules)?

In reply to renvillph:

This error comes from my_config.svh


class my_config extends uvm_object;
    virtual my_intf  vif;  // <- here!!
    int unsigned     my_n;
 
    function new(string name = "my_config")
        super.new(name);
        my_n = 32;
    endfunction
endclass

To solve the error, please read a presentation below.
https://www.verilab.com/files/verilab_dvcon_eu2015_6_params.pdf