SystemVerilog и виртуальный интерфейс. Связь статического и динамического мира симуляции.
Сергей Чусов, НИУ МИЭТВместе с большим количеством нововведений несинтезируемого подмножества (class, fork-join, randomize(), queue, ...) SystemVerilog "порадовал" инженеров новыми синтезируемыми конструкциями. Одной из них являлся интерфейс (interface).
Задумка здесь очень простая. Интерфейс по своей сути является сгруппированным набором сигналов. Например, для простейшего AXI-Stream этот набор может быть объявлен следующим образом:

Интерфейс обладает статической природой (как, например, и модуль). Его экземпляр создается в нулевой момент времени симуляции и не может быть удален до ее завершения.

Как правило, экземпляры интерфейсов объявляются в главном модуле симуляции и подключаются к интерфейсам или портам тестируемого устройства.
Заметим, что не все провода интерфейса обязательно должны быть использованы при его подключении. Например, в примере выше провод tlast для интерфейса intf_1не подключается.
Структурно и в системной памяти имеем следующую картину:

Статические элементы в начале симуляции занимают место в памяти и существуют до завершения симуляции.
Так как в SystemVerilog появились динамические объекты (class), то возникла также необходимость в получении доступа из динамических объектов к статическим элементам верификационного окружения. Для этих целей и существует виртуальный интерфейс.
Виртуальный интерфейс - указатель на статический экземпляр интерфейса. В ходе симуляции виртуальный интерфейс может указывать на различные экземпляры.

Результатом запуска симуляции в таком случае будет:
# null # /testbench/intf_1
В начале виртуальный интерфейс не указывает ни на какой из статических интерфейсов, то есть проинициализирован null(нулевым указателем). Строка vif = intf_1 определяет для виртуального интерфейса статический экземпляр интерфейса, на который он будет указывать.

При помощи виртуального интерфейса пользователь может взаимодействовать с сигналами статического интерфейса. В ходе симуляции виртуальный интерфейс может использоваться для изменения сигналов различных статических интерфейсов.

Результаты симуляции:
# /testbench/intf_1 # /testbench/intf_2

Заметим, что в промежутке между присвоениями указателей на статические интерфейсы виртуальный "успел побывать" и в нулевом (null) значении. В ходе симуляции указатель, содержащийся в виртуальном интерфейсе, может динамически создаваться и уничтожаться.
Изображение ниже демонстрирует процесс создания и удаления указателя на статические интерфейсы (пример кода выше). Изначально виртуальный интерфейс указывал на intf_1 (отмечено -->), после чего был проинициализирован null, а после стал указывать на intf_2 (отмечено ->).

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

Результат симуляции кода:

В данном примере в конструктор класса my_design_driver передается статический интерфейс. Однако в аргументе конструктора тип аргумента объявлен как virtual axi_s_intf, то есть происходит присвоение virtual axi_s_intf vif = axi_s_intf intf_1, что является абсолютно легальным в SystemVerilog (было разобрано в примерах выше).

Как видите, ничего сложного!
Больше заметок вы можете найти в Telegram-канале автора Verification For All.
Хорошего тебе дня, читатель, и до новых встреч!