Мое предпочтение состоит в том, чтобы иметь единственный модуль (или небольшое количество модулей) в Вашем испытательном стенде, который содержит все Ваши датчики, но никакую другую функциональность. Все другие модули в Вашем испытательном стенде, которые требуют датчиков затем, соединяются с тем "тестовым модулем". Используйте интерфейсы SystemVerilog в предпочтении к необработанным проводам, если это - опция для Вас. Это обходит Вашу проблему, так как никакой наблюдатель не потребует глобальных иерархий, и Ваш испытательный стенд в целом будет значительно легче поддержать. См. Закон Demeter.
Кроме того... (но это помещает иерархию в Ваши инстанцирования...),
module watcher(sig, bar);
input sig;
input bar;
...
endmodule
watcher w1(`HIER1.sig, `HIER1.foo.bar); // instantiation
watcher w2(`HIER2.sig, `HIER2.foo.bar); // second instantiation, except with a different hierarchy
Впоследствии Вы можете также:
`define WATCHER_INST(NAME, HIER) watcher NAME(HIER.sig, HIER.foo.sig)
`WATCHER_INST(w1, `HIER1);
`WATCHER_INST(w2, `HIER2);
Можно ли использовать ключевое слово SystemVerilog bind
для привязки модуля к каждой иерархии, которая требует этого? (Для этого требуется, чтобы вы использовали SystemVerilog и у вас была лицензия на симулятор.)
Использование связывания похоже на создание экземпляра модуля обычным способом, за исключением того, что вы указываете путь к иерархии, в которой модуль создается "удаленно":
bind top.my.hier my_module instance_name(.*);
bind top.my_other.hier my_module instance_name(.*);
Еще лучше: предположите, что каждая иерархия, к которой вы привязываетесь, является отдельным экземпляром одного и того же модуля. Затем:
bind remote_module my_module instance_name(.*);
Это связывает ваш модуль с каждым экземпляром цели, независимо от того, где он находится в проекте. Это очень эффективно, если ваш модуль является средством проверки.