Запрещено использовать иерархические ссылки Verilog или OOMR в пакете SystemVerilog.Это связано с тем, что пакеты SystemVerilog сначала компилируются, иным образом, чем остальная часть кода SystemVerilog.
Как правило, вы будете помещать свои классы в пакет.Поэтому вам следует избегать использования Verilog Hierarchical References или OOMR в классах.
Очевидно, что вы захотите подключить код в классе к портам DUT (например, к драйверам и мониторам), и вы можете также исследовать внутренние сигналы DUT.Решение этих проблем различно для каждого случая.
Для подключения к портам DUT большинство людей используют интерфейс SystemVerilog .Вы создаете экземпляр интерфейса на том же уровне иерархии, что и DUT, и каким-либо образом подключаете элементы интерфейса к DUT, например, используя Verilog Hierarchical References или OOMR), например:
interface TB_hook (input bit clk);
logic Stim, Resp;
...
endinterface
module harness;
bit clk;
TB_hook DUT_intf (.clk);
Sys_Top DUT (
.clk (clk),
.Stim (DUT_intf.Stim),
.Resp (DUT_intf.Resp),
...
Затем в некотором классе (драйвер,монитор или агент) вы можете использовать виртуальный интерфейс SystemVerilog для подключения к экземпляру интерфейса.Виртуальный интерфейс - это особая переменная SystemVerilog, которая может хранить иерархическую ссылку Verilog или OOMR в экземпляре интерфейса или модпорте.Поскольку вы должны назначить это значение во время выполнения, виртуальный интерфейс может быть скомпилирован в пакет (но код, который назначает значение, не может быть в пакете), например:
class driver;
virtual TB_hook V;
task drive (input bit data);
V.Stim <= data;
Затем в некотором Verilogmodule
(возможно, модуль верхнего уровня), вы бы присвоили значение переменной виртуального интерфейса.Вы можете сделать это напрямую, например:
module TB_top;
top_env env;
...
initial begin
...
env.agent.driver.V = harness.DUT_intf;
, но большинство людей будут использовать конфигурационную базу данных UVM:
module TB_top;
top_env env;
...
initial begin
...
uvm_config_db #(virtual TB_hook)::set(null, "*", "DUT_intf", harness.DUT_intf);
class driver;
virtual TB_hook V;
...
function void connect_phase(uvm_phase phase);
...
ok = uvm_config_db#(virtual TB_hook)::get(this, "", "DUT_intf", V);
Вы можете усовершенствовать эту технику, используя modports и / или блоки синхронизации.
Для зондирования внутренних сигналов ИУ предусмотрены средства, предоставляемые уровнем регистрации UVM.Для этого есть набор функций / задач:
uvm_hdl_check_path
- проверяет, существует ли путь HDL uvm_hdl_deposit
- вносит значение в RTL uvm_hdl_force
- форсирует значение в RTL uvm_hdl_force_time
- форсирует значение на указанную продолжительность uvm_hdl_release
- сбрасывает форсированное значение uvm_hdl_release_and_read
- освобождает принудительное значение и читает новое значение uvm_hdl_read
- читает значение RTL