Factory Over-ride and Parameterization

Hello everyone,
I have been trying out factory override and have hit a dead-end I can not escape.
I have two sequence items as below,


class seq_item extends uvm_sequence_item;

  rand logic                        rst_n;
  rand logic [7:0]                  count;


  `uvm_object_utils_begin(seq_item)
  `uvm_field_int(rst_n,UVM_ALL_ON)
  `uvm_field_int(count,UVM_ALL_ON)
  `uvm_object_utils_end


  function new(string name = "seq_item");
    super.new(name);
  endfunction: new

endclass

class seq_item_2 extends seq_item;

  rand logic                        enb;

  `uvm_object_utils_begin(seq_item_2)
  `uvm_field_int(enb,UVM_ALL_ON)
  `uvm_object_utils_end


  function new(string name = "seq_item_2");
    super.new(name);
  endfunction: new

endclass

And two drivers as below,


class c_driver #(type T = seq_item) extends uvm_driver #(T);
  `uvm_component_utils(c_driver #(T))

  T item;
  virtual c_interface vif;

  function new(string name = "c_driver", uvm_component parent = null);
    super.new(name, parent);
    `uvm_info(get_full_name(),"DRIVER INITIATED\n", UVM_MEDIUM)  
  endfunction

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    `uvm_info(get_full_name(), "DRIVER BUILD PHASE\n", UVM_MEDIUM)

    if (!(uvm_config_db #(virtual c_interface)::get(this, "", "c_interface", vif)) ) begin
      `uvm_fatal(get_full_name(),"SIMULATION STOPPED || DRIVER COULD NOT FIND INTERFACE\n") 
    end

  endfunction

  task run_phase(uvm_phase phase);
    `uvm_info(get_full_name(),"DRIVER RUN PHASE \n", UVM_MEDIUM) 

    forever begin
      seq_item_port.get_next_item(item);

      vif.rst_n <= item.rst_n;
      @(negedge vif.clk)

      seq_item_port.item_done();
    end

  endtask

endclass

class c_driver_2 #(type T = seq_item_2) extends c_driver #(T);
  `uvm_component_utils(c_driver_2 #(T))

  function new(string name = "c_driver_2", uvm_component parent = null);
    super.new(name, parent);
    `uvm_info(get_full_name(),"DRIVER_v2 INITIATED\n", UVM_MEDIUM)  
  endfunction


  task run_phase(uvm_phase phase);
    `uvm_info(get_full_name(),"DRIVER_v2 RUN PHASE \n", UVM_MEDIUM) 

    forever begin
      seq_item_port.get_next_item(item);

      vif.rst_n <= item.rst_n;
      vif.enb <= item.enb;
      @(negedge vif.clk)

      seq_item_port.item_done();
    end

  endtask

endclass

The agent build phase is,


  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    `uvm_info(get_full_name(), "AGENT BUILD PHASE \n", UVM_MEDIUM)

    sqncr = c_sqncr::type_id::create("sqncr", this);   // created sqncr
    drvr = c_driver::type_id::create("drvr", this);  // created driver
  endfunction

And the Test build phase,


  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    `uvm_info(get_full_name(),"TEST BUILD PHASE \n", UVM_MEDIUM)
    
    set_type_override_by_type (seq_item::get_type(), seq_item_2::get_type());
    set_type_override_by_type (c_driver::get_type(), c_driver_2::get_type());

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

  endfunction

I am hitting an UVM_FATAL as,

UVM_FATAL @ 0: reporter [FCTTYP] Factory did not return a component of type ‘c_driver #(T)’. A component of type ‘c_driver_2 #(T)’ was returned instead. Name=drvr Parent=c_agent contxt=uvm_test_top.env.agent

How can I resolve this issue??

In reply to Husni Mahdi:

This does not work because the base class of the type your are trying to override does not match the the type you are trying to create. I suggest you do not parameterize your c_driver base class.

class c_driver extends uvm_driver #(seq_item);

uvm_driver already contains the variable ‘req’ which has the type ‘seq_item’ there is no need to declare a seperate ‘item’.

That means in c_driver_2, you will need to downcast 'req` to a ‘seq_item_2’ variable

task run_phase(uvm_phase phase);
     seq_item_2 item;
    `uvm_info(get_full_name(),"DRIVER_v2 RUN PHASE \n", UVM_MEDIUM) 
 
    forever begin
      seq_item_port.get_next_item(req);
      if (!$cast(item,req))
          // fatal or do something else
      vif.rst_n <= item.rst_n;
      vif.enb <= item.enb;
      @(negedge vif.clk)
 
      seq_item_port.item_done();
    end
 
  endtask