Question

The code guideline for our verification environment is one class per file.

Sometimes a uvm_object is only needed by 1 other uvm_component, so, following object-oriented theory, we should use nested/inner classes.

Nested classes are fully supported by SystemVerilog. However, are they supported by UVM?

Is it possible to compile something like the following:

class inception_level_1 extends uvm_test;

  `uvm_component_utils(inception_level_1)

  function new(string name = "inception_level_1", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  class inception_level_2 extends uvm_object;

    int a;

    `uvm_object_utils_begin(inception_level_2)
      `uvm_field_int(a, UVM_DEFAULT)
    `uvm_object_utils_end

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

  endclass

endclass

Currently the above code gives a compile error:

** Error: testbench.sv(20): (vlog-2889) Illegal to access non-static method 'uvm_report_warning' outside its class scope.

Full code example here: http://www.edaplayground.com/x/3r8

Was it helpful?

Solution

SystemVerilog has packages, which is the preferred mechanism to "hide" class declarations from other packages.

You will have problems using the field macros, or anything else that tries to reference identifiers from inside the inner class that are defined with the same name in both the global uvm_pkg and the outer class. All the uvm_report_... methods are defined in both because uvm_component is extended from uvm_report_object, and uvm_report_... is in the global uvm_pkg.

You will also have problems using the factory with nested classes. Only the outer class will be able to provide overrides by type, but string based overrides by name are global. So even if you nested the inner class, scopes other than the outer class will be able to provide it as an override by string name.

OTHER TIPS

I changed the code to remove the field macros and this runs. So it seems like this is supported if you can give up the field automation macros: http://www.edaplayground.com/x/i5

class inception_level_1 extends uvm_test;

  `uvm_component_utils(inception_level_1)

  function new(string name = "inception_level_1", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  class inception_level_2 extends uvm_object;

    int a;

    `uvm_object_utils(inception_level_2)

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

  endclass

endclass

in general it does work. however there are situations where UVM uses shortcuts which conflict with the class-in-class scenario. examples are

  • string based factory (inception_level_2 can only be registered once despite that foo:inception_level_2 and bla::inception_level_2 would be different classes)
  • name lookup collision (here for uvm_report_warning which should goto uvm_pkg::uvm_report_warning and not to the enclosing class uvm_component::uvm_report_warning) ... etc
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top