Поддерживает ли UVM вложенные / внутренние классы?

Рекомендации по коду для нашей среды проверки - по одному классу на файл.

Иногда uvm_object требуется только 1 другому uvm_component, поэтому, следуя объектно-ориентированной теории, мы должны использовать вложенные / внутренние классы.

Вложенные классы полностью поддерживаются SystemVerilog. Однако поддерживаются ли они UVM?

Можно ли скомпилировать что-то вроде следующего:

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

В настоящее время приведенный выше код дает ошибку компиляции:

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

Пример полного кода здесь: http://www.edaplayground.com/x/3r8


person Victor Lyuboslavsky    schedule 03.02.2014    source источник


Ответы (3)


В SystemVerilog есть пакеты, которые являются предпочтительным механизмом для «скрытия» объявлений классов от других пакетов.

У вас возникнут проблемы с использованием макросов полей или чего-либо еще, что пытается ссылаться на идентификаторы из внутреннего класса, которые определены с тем же именем как в глобальном uvm_pkg, так и во внешнем классе. Все методы uvm_report_... определены в обоих, потому что uvm_component расширен от uvm_report_object, а uvm_report_... находится в глобальном uvm_pkg.

У вас также будут проблемы с использованием фабрики с вложенными классами. Только внешний класс сможет предоставлять переопределения по типу, но строковые переопределения по имени являются глобальными. Таким образом, даже если вы вложили внутренний класс, области, отличные от внешнего класса, смогут предоставить его как переопределение по имени строки.

person dave_59    schedule 04.02.2014

Я изменил код, чтобы удалить макросы поля, и это работает. Таким образом, похоже, что это поддерживается, если вы можете отказаться от макросов автоматизации поля: 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
person nguthrie    schedule 04.02.2014
comment
В моем случае автоматизация поля нужна только для print и sprint методов. Полагаю, я мог бы вручную реализовать do_print обратный вызов. - person Victor Lyuboslavsky; 04.02.2014
comment
Как указывает Дейв выше, вам будет лучше, если вы поместите эти два класса в пакет. Это также имеет то преимущество, что его легче поддерживать, поскольку это стандартный способ сделать это. - person nguthrie; 04.02.2014

в общем работает. однако бывают ситуации, когда UVM использует ярлыки, которые противоречат сценарию класса в классе. примеры

  • фабрика на основе строк (inception_level_2 может быть зарегистрирован только один раз, несмотря на то, что foo: inception_level_2 и bla :: inception_level_2 будут разными классами)
  • конфликт поиска имени (здесь для uvm_report_warning, который должен перейти к uvm_pkg :: uvm_report_warning, а не к включающему классу uvm_component :: uvm_report_warning) ... и т. д.
person uwes    schedule 09.12.2015