Error when use set_inst_override_by_type

Hi,

When I use set_inst_override_by_type to override an old driver,but the simulation stop by because compile Error:

** Error: …/test/sv/tc_axi.sv(142): (vlog-2164) Class or package ‘axi_wr_driver’ not found.
** Error: …/test/sv/tc_axi.sv(142): near “::” syntax error, unexpected ::, expecting ’)’
** Error: …/test/sv/tc_axi.sv(142): (vlog-2164) Class or package ‘axi_wr_new_driver’ not found.

The code is as follows,


//old driver
class axi_wr_driver extends uvm_driver #(axi_wr_transfer);
  ... ...
endclass

//new driver
class axi_wr_new_driver extends axi_wr_driver #(axi_wr_transfer);
  ... ...
  `uvm_component_utils_begin(axi_wr_new_driver)
   ... ...
  `uvm_component_tuils_end

   ...

endclass

//axi_wr_agent
class axi_wr_agent extends uvm_agent;
  ... ...
  axi_wr_driver u_wr_driver;
  ... ...

function void build_phase(uvm_phase phase);
  ... ...
  u_wr_driver = axi_wr_driver::type_id::create(“u_wr_driver”, this);
endfunction

endclass

//tc_axi.sv
class tc_axi_write extends uvm_test;
  ... ...

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);

    uvm_config_db#(uvm_object_wrapper)::set(this, "u_axi_top.virtual_sequencer.run_phase", "default_sequence",
              axi_write::type_id::get());
    u_axi_top = axi_top::type_id::create("u_axi_top", this);
 
    set_type_override_by_type(axi_wr_driver::get_type(), axi_wr_new_driver::get_type()); //Line142
    
  endfunction : build_phase
endclass


Hi,

When you are getting compilation error it doesn’t mean that your set_type_override is not working.

From the log file error messages, it seems like you haven’t compile it properly OR maybe you didn’t import the package that you have the definition of axi_wr_driver and axi_wr_new_driver on the same code that you have your test’s class definition.

And additionally, from your code snippet it seems like your axi_wr_driver doesn’t use the uvm_component_utils to register the class into UVM factory. I hope that you may just have missed it when you add this query.

When you want to use UVM factory override, both of the original class and override class has to be registered in UVM Factory.

-Baser

Both of axi_wr_driver and axi_wr_new_driver has been registered in UVM Factory,here no problem.

I added axi_wr_driver.sv & axi_wr_new_driver.sv in aix_pkg.sv.

From the compile Error, it seems that tc_axi_write cann’t recognized the two class: axi_wr_driver & axi_wr_new_driver, I don’t know where is the issue. If it need to add full path of axi_wr_driver
or u_wr_driver?

Okay. Will please check there is no typo or anything missing on the code snippet that you shared? It will be helpful if you share the code if possible.

Showing the exact code of line ./test/sv/tc_axi.sv(142) will be helpful as well.

I can see one issue on your code (based on the snippet above).
I can see that the axi_wr_driver is not parameterized with with any sequence item. And I suspect that following code is the one that has problem, because you are passing paramater to the axi_wr_driver.


class axi_wr_new_driver extends axi_wr_driver #(axi_wr_transfer);

-Baser

Hi, I added some code,please see it as follows,thanks,


//sequence item
calss axi_wr_transfer extends uvm_sequence_item;
  rand bit ...
  ... ...

  `uvm_object_utils_begin(axi_wr_transfer)
    ... ...
  `uvm_object_utils_end

//contraint
   contraint awaddr_c {
    ... ...
   }
   ... ...
class : axi_wr_transfer

//old driver
class axi_wr_driver extends uvm_driver #(axi_wr_transfer);
   virtual axi_master_if vif;
   ... ...
   axi_wr_transfer write_item;
   ... ...

  `uvm_component_utils_begin(axi_wr_driver)
     ... ...
  `uvm_component_tuils_end
  
   ... ...
  
   function void axi_wr_driver::build_phse(uvm_phase phase);
     super.build_phase(phase);
     ... ...
   endfunction : build_phase
endclass
 
//new driver
class axi_wr_new_driver extends axi_wr_driver #(axi_wr_transfer);
   virtual axi_master_if vif;
   ... ...
   axi_wr_transfer write_item;
   ... ...


  `uvm_component_utils_begin(axi_wr_new_driver)
   ... ...
  `uvm_component_tuils_end

   ... ...

   function void axi_wr_driver::build_phse(uvm_phase phase);
     super.build_phase(phase);
     ... ...
   endfunction : build_phase
 
endclass

//axi_wr_agent
class axi_wr_agent extends uvm_agent;
  ... ...
  axi_wr_driver u_wr_driver;
  ... ...
 
function void build_phase(uvm_phase phase);
  ... ...
  u_wr_driver = axi_wr_driver::type_id::create(“u_wr_driver”, this);
endfunction
 
endclass
 
//tc_axi.sv
class tc_axi_write extends uvm_test;
  ... ...
 
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
 
    uvm_config_db#(uvm_object_wrapper)::set(this, "u_axi_top.virtual_sequencer.run_phase", "default_sequence",axi_write::type_id::get());
    u_axi_top = axi_top::type_id::create("u_axi_top", this); //Line141
 
 set_type_override_by_type(axi_wr_driver::get_type(), axi_wr_new_driver::get_type());//Line142
 
  endfunction : build_phase //Line144
endclass


Hi,All,

By my try, if I modify the Line142 as following,the compile can pass,


//tc_axi.sv
class tc_axi_write extends uvm_test;
  ... ...
 
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
 
    uvm_config_db#(uvm_object_wrapper)::set(this, "u_axi_top.virtual_sequencer.run_phase", "default_sequence",axi_write::type_id::get());
    u_axi_top = axi_top::type_id::create("u_axi_top", this); //Line141
 
 set_type_override_by_type(axi_pkg::axi_wr_driver::get_type(), axi_pkg::axi_wr_new_driver::get_type());//Line142
 
  endfunction : build_phase //Line144
endclass

Hi,

I seems like you haven’t import axi_pkg::* under the module/package that you have tc_axi_write class. That is what I mentioned in my first response to your question.

Anyway, it is good to know that you managed to figure it out yourself.

Good luck!

-Baser

Hi,Baser,

Thanks very much for your kindly response!

But the problem is that, I have import axi_pkg::* in my top module;


module axi_test_top;
  import uvm_pkg::*;
  
  import apb_pkg::*;
  import axi_pkg::*;
  import axi_test_pkg::*;

  ... ... 

  //instance of DUT
  ... ...
  ... ...
endmodule

Hi,

No problem:D.
I see, you may not have it imported under your package axi_test_pkg; then.

The point is you should import package where you defined the class that you want to use in other SystemVerilog’s scope (package/module/interface/program). You can choose either to import the entire package


module/program/package/interface <my scope name> ...
   ...
   import [package_name]::*;
   ...

OR doing scoped referencing as

[package_name]::[type_name]..

.

This is pretty much precisely described in chapter “26.3 Referencing data in packages” under SystemVerilog LRM.

Regards,
Baser

Hi, Baser,

Yes, I haven’t imported axi_pkg under package axi_test_pkg. But I have a question,

I imported axi_pkg under my top module, it couldn’t pass down to it’s sub hierarchical?

Best Regards,
Jevon

In reply to dfx9230:

Hi Jevon,

Unlike module/interface/program, package is a standalone scope and it will not be instantiated under your testbench or any module/interface/program instances hierarchy. Calling the import is actually means something like that you are just getting the visibility of a package’s content from your current scope (module/interface/program/package). When you import a package into a package, it doesn’t mean that the package being imported will be included into the parent package and everything inside it will become a content of parent package. See description below on how it is described in SystemVerilog LRM page 739.

26.2 Package declarations
SystemVerilog packages provide an additional mechanism for sharing parameters, data, type, task, function,
sequence, property, and checker declarations among multiple SystemVerilog modules, interfaces, programs,
and checkers.
Packages are explicitly named scopes appearing at the outermost level of the source text (at the same level as
top-level modules and primitives). Types, nets, variables, tasks, functions, sequences, properties, and
checkers may be declared within a package. Such declarations may be referenced within modules,
interfaces, programs, checkers, and other packages by either import or fully resolved name.
Packages may contain processes inside checkers only. Therefore, net declarations with implicit continuous
assignments are not allowed.

I recommend you to go through the SystemVerilog LRM to understand better on this, as I may be able to ONLY answer your direct question.

Regards,
Baser

Okay. Thank you very much, Baser!

In reply to dfx9230:

Hi Jevon,

Your are welcome :D

-Baser