В очередной раз, начав изучать что-то новое для себя, я столкнулся с типичной для меня проблемой: нет нигде быстро гуглящегося how-to и step-by-step руководства по быстрому созданию какой-либо простой конструкции на Verilog и описания способа эту конструкцию быстро симулировать без необходимости запуска кода в железе для проверки конечного результата. Я надеялся очень быстро найти готовый материал о том, как под Altera Quartus 20.1 и ModelSim 2020.1 под Linux всё по-быстрому сделать и идти дальше. В итоге не найдя ничего системно и последовательно описанного в одном месте я традиционно разобрался самостоятельно и решил это исправить своей очередной статьей на Хабре.
Возможно, этот материал поможет таким же как я новичкам на самом старте и позволит не растерять энтузиазм во время танцев по граблям. Всем, кто заинтересовался — добро пожаловать под кат.

Дисклеймер. Перед началом повествования, хотелось бы заранее оговориться, что основная цель, которую я преследую при написании этой статьи — рассказать о своем опыте. Я не являюсь профессиональным разработчиком под ПЛИС на языке SystemVerilog и могу допускать какие-либо ошибки в использовании терминологии, использовать не самые оптимальные пути решения задач, etc. Но отмечу, что любая конструктивная и аргументированная критика только приветствуется. Что ж, поехали…
Итак. Представим, что вы абсолютный новичок в области ПЛИС aka FPGA и вот однажды вы услышали, интересные рассказы о том, что с помощью одного из языков описания аппаратуры (HDL) можно решать разнообразные задачи с очень высокой скоростью и при этом параллельно, т.е. одновременно. Первым вопросом, которым задался я как новичок когда услышал про ПЛИС — а с чего начать? На тот момент мне казалось, что все начинается с отладок с нужным чипом и примеров. Я без особого понимания критериев отбора, чем отличаются Altera от Xilinx — быстренько заказал себе отладку на Cyclone IV и после того как получил — научился создавать и запускать простейшие проекты. Каждая правка исходного проекта и проверка сопровождалась ожиданием синтеза, роутинга, заливкой прошивки в ПЛИС для проверки и отладки с помощью светодиодов и кнопок и SignalTap. И чем сложнее были примеры — тем больше времени я тратил на ожидание синтеза, рассовывания пробников отладчика по сигналам и тут я начал задумываться о том, что возможно что-то тут я делаю не так. А если вспомнить, что SignalTap занимает в ПЛИС тоже некоторое количество логических блоков и в сложных проектах он уже не умещался в ПЛИС — ситуация точно требовала изменения подхода.
И тут я начал вникать в то, как организуют процесс разработки в среде профессионалов — я понял, что я упустил тут один очень важный шаг — симуляцию и тестирование с помощью т.н. testbench-ей.
Вникнув и разобравшись — я захотел поделиться своим опытом в этом материале и при написании этой статьи я поставил для себя несколько задач: разобрать вопрос создания простого проекта в Altera Quartus под Linux и как запустить его симуляцию в ModelSim, с попутным объяснением как решить возникающие проблемы, коих по ходу дела возникает немало (вполне возможно, что только у меня).
Задачи для меня и моего уровня вполне достижимые, давайте расскажу и покажу как я их решал.
Вообще, отдельно стоит рассказать о том, как работают с ПЛИС профессионалы и что следует взять себе за ориентир. Ниже, я попытался обобщить в виде схемы свое представление о алгоритме разработки под ПЛИС. Коротко опишу каждый из этих этапов. Оговорюсь сразу, что в рамках этой статьи я рассмотрю только первые три интересующих нас этапа.

Идея и техническое задание. Пункт с вполне понятным смысловым наполнением. На этом этапе формируется идея будущего устройства, что он должен уметь делать, чего делать не должен. На основании идеи формируется уже техническое задание которое отражает в форме измеримых величин требования для конечного устройства.
Реализация HDL-кода. На этом этапе происходит основная часть работы — в HDL-коде реализуется конечный автомат или группа из таковых, вместе со всеми багами, корявостями и синтаксическими ошибками ?.
Функциональное и поведенческое моделирование (например, в ModelSim). А вот на этом этапе происходит, на мой взгляд самое интересное. Здесь как раз и происходит первая проверка полученного результата, а не напрямую в ПЛИС, как я делал до этого.
В ходе реализации проекта, на каждом этапе когда находятся те или иные ошибки — происходят доработки и исправления — и все начинается по новому циклу. В целом все достаточно просто. Вот реализацию этого флоу я хочу отразить на конкретном примере с картинками и разбором всех граблей.
Итак, казалось бы, что может быть проще: создаем проект и запускаем ModelSim, пишем тестбенч и проверяем, что всё работает как нужно. Я так думал, когда первый раз хотел, что-нибудь прогнать через симуляцию. Но не тут-то было. Но обо всё по порядку.
Открываем Quartus и создадим новый проект:

Жмем New Project Wizard, откроется мастер и можно идти по шагам.
Жмём Next и указываем каталог, в котором будет жить наш проект, заполняем его имя.

Тыкаем кнопку Next и указываем, что мы создаем пустой проект, выбрав пункт Empty project.

Файлы никакие добавлять не будем, поэтому жмякаем Next.

В следующем меню выбираем модель чипа с которым вы работаете, в моем случае это EP4CE6F17C8.

А вот в последнем меню в пункте Simulation нужно выбрать ModelSim-Altera и SystemVerilog HDL (если конечно именно он используется, а не VHDL или Verilog HDL например).

Просматриваем Summary, проверяем нет ли ошибок и жмем Finish:

Откроется окно пустого проекта и можно приступать к его наполнению и настройке.
Реализуем первый этап из флоу — т.е. составим техническое задание: необходимо реализовать на языке SystemVerilog модуль, который на входе будет иметь два логических сигнала A и B, и один на выходе Y, который будет результатом логической операции & (AND) от A и B. Идея достаточно простая и эту, казалось бы простую задачу, можно реализовать аж тремя путями.
Рассмотрим каждый из вариантов:
Какой из вариантов вам больше нравится — такой и выбирайте. Мне нравится больше подход Data Flow.
Создаем новый файл в меню File — New — System Verilog HDL File. Откроется редактор, и запишем интересующий вариант модуля:

Далее сохраняем файл и даем ему соответствующее его роли название:

Теперь нужно добавить файл Top-Level entity, в котором будет находиться модуль, который мы будем пропускать через симуляцию. Для этого в Project Navigator с включенным видом Files кликаем правой кнопкой и выбираем пункт Set as Top-Level Entity:

В меню сообщений будет следующая строка: Info (125061): Changed top-level design entity name to «Top».
Теперь можно запустить анализ и синтез:

Но Quartus выдаст нам ошибку, что якобы Error (12007): Top-level design entity «Top» is undefined.
Что ж, придется снова указать, кто в проекте Top-level Entity. Выбираем в Project Navigator вид отображения Hierarchy, кликаем правой по Top и Settings:

Выбираем первый пункт в меню настроек General, далее кликаем по многоточию и выбираем AND_DATA_FLOW и нажимаем ОК и еще раз ОК чтобы закрыть это меню и перезапускаем анализ и синтез:

Дожидаемся окончания операции и видим что все окончилось успешно и без ошибок, только предупреждения:

Смотрим в отчет и видим, что израсходован один логический элемент и задействовано три пина. Эта информация может в будущем оказаться весьма полезной:

Идём дальше. Теперь, раз всё компилируется, стоит произвести моделирование полученного дизайна и убедиться что все будет работать как нужно.
Итак, общий флоу по интеграции ModelSim в процесс разработки под ПЛИС из нескольких этапов:
Если не осуществить эту настройку — можно собрать много разнообразных ошибок и ничего не получится. Например, если попробовать просто запустить RTL Simulation:

То само собой получим ошибку, что EDA Simulation Software настроен:

Что ж, перейдем к настройке Native Link. Для этого необходимо перейти в общие настройки Quartus и указать каталог, в котором находится ModelSim. Это делается путем перехода в главном меню Tools — Options…

Откроется меню настроек и нужно перейти в пункт меню EDA Tools Options и в поле ModelSim и\или ModelSim-Altera указать путь до каталога modelsim_ase/linux так, как это сделано у меня:

Далее в настройках проекта тоже необходимо какой тип симулятора используется. Для этого возвращаемся в настройки проекта в Project Navigator (в котором мы устанавливали Top-Level Entity) и переходим в пункт меню EDA Tools Settings и в пункте Simulation выбираем ModelSim-Altera / SystemVerilog HDL:

После переходим в пункт Simulation и видим что в пункте настроек NativeLink ничего не настроено и всё нужно сделать своими ручками:

На этом этапе необходимо указать файл testbench, которые у нас еще отсутствуют. Перейдем к созданию этих файлов.
В многих источниках рекомендуют воспользоваться пунктом меню Processing — Start — Start Test Bench Template Writer:

Но на этом этапе я столкнулся с ошибкой, что якобы данная опция для SystemVerilog не поддерживается:

Окей, попробуем создать файл Testbench самостоятельно в проект и прикрепить его в настройках симуляции руками самостоятельно. Для этого берем создаем новый файл через File — New — SystemVerilog HDL File.
После создания файла откроется редактор и в него запишем заготовку:
После сохраним файл c именем and_gate_test_bench.sv и возвращаемся в меню NativeLink settings. Выбираем пункт меню Compile test bench и кликаем по кнопке Test Benches…
В открывшемся меню Test Benches нажимаем кнопку New… и заполняем настройки следующим образом:

Главное указать Top level module in test bench в четком соответствии как это было заполнено в файле в предыдущих шагах. Везде нажимаем OK и выходим.
Теперь запускаем компиляцию:

И видим в сообщениях, что все завершено удачно:

Теперь запуск RTL Simulation из главного меню должен открыть ModelSim, но этого не достаточно т.к. при запуске симуляции будет выданы ошибки о том, что нет необходимых библиотек для симуляции. Поэтому сделаем компиляцию необходимых библиотек.
Для это необходимо перейти в главное меню и нажать Tools — Launch Simulation Library Compiler:

Откроется меню, в котором нужно указать ModelSim, проверить что в поле Selected families указан Cyclone IV E и что указана директория для сохранения результатов компиляции:

Жмём кнопку Start Compilation и ожидаем результатов компиляции. Ожидаем, что компиляция пройдет успешно:

После закрываем окно и попробуем совершить акт симуляции. =)
Теперь можно перейти ко второму этапу — моделирование и проверка правильности работы полученного кода через Testbench. Как вы уже поняли — Testbench является по сути отдельным модулем написанный на языке HDL, который объявляется в отдельном файле. Поэтому перейдем в наш файл and_gate_test_bench.sv, который мы создали в предыдущих шагах.
Напомню, что в этой статье я не ставил себе целью подробный разбор как писать testbench-файлы и не планировал рассматривать синтаксис, поэтому приведу код testbench-файла как есть, лишь сопроводив его некоторым количеством комментариев:
В начале мы объявляем два регистра A и B, чтобы они сохраняли свое значение до тех пор пока не будут назначено новое. Они будут означать входные сигналы. И зададим сигнальный проводник Y, который будет выводить результат.
После инициализируем экземпляр модуля, созданного в главном файле проекта, с именем DUT, указав сигналы в порядке объявления.
В модуле initial указываются действия которые исполняются после старта модуля в симуляторе. Соответственно при старте задаются значения сигналов A и B равными нулю и через каждый условную единицу времени изменяем сигналы на новые значения (в соответствии с таблицей истинности модуля).
Плюсом к этому добавляем отладочный вывод в лог симулятора, чтобы помимо временной диаграммы видеть текущие значения входных сигналов и того, что имеем на выходе. Сохраняем полученный testbench-файл и нажимаем Compilation.
Дождавшись результатов компиляции — можно запустить ModelSim и увидеть результаты моделирования. Для этого нужно перейти в главное меню и нажать Tools — RTL Simulation:

Если в предыдущих шагах все сделали правильно — то будет запущен ModelSim и выведен лог:

И если увеличить масштаб в Waveform-меню — можно увидеть результат на временной шкале:

Соответственно, зная наперёд как работает логический элемент AND — мы можем сказать что всё сработало верно, результаты соответствуют ожидаемым, как в логе, так и во временной диаграмме. Ну и покуда всё работает верно — нет необходимости переходить к пути коррекции ошибок и можем считать, что задача решена.
Вот путём таких не хитрых манипуляций можно достаточно быстро, без реальной железки, проверить свой HDL-дизайн и получить быстрый ответ на вопрос “работает\не работает”. Если вы застряли, на каком-либо из этапов — не стесняйтесь обращаться за помощью в комментариях, возможно я или более опытные коллеги смогут вам помочь.
Как пользоваться средой моделирования и как раскрыть весь потенциал ModelSim — тема на большое количество статей или даже книгу, тут мы с вами скорее попробовали просто настроить проект перед тем как приступать к более сложным вещам. Но думаю, что много из того, что я буду рассматривать в своих следующих статьях, в той или иной степени, позволит расширить представление о ModelSim и его возможностях.
Если статья вам понравилась — ставьте “подписывайтесь и ставьте стрелочку вверх”. Этим самым вы поддерживаете меня как автора и стимулируете на написание новых материалов для вас. До встречи в следующих статьях!
Возможно, захочется почитать и это:
Возможно, этот материал поможет таким же как я новичкам на самом старте и позволит не растерять энтузиазм во время танцев по граблям. Всем, кто заинтересовался — добро пожаловать под кат.

Дисклеймер. Перед началом повествования, хотелось бы заранее оговориться, что основная цель, которую я преследую при написании этой статьи — рассказать о своем опыте. Я не являюсь профессиональным разработчиком под ПЛИС на языке SystemVerilog и могу допускать какие-либо ошибки в использовании терминологии, использовать не самые оптимальные пути решения задач, etc. Но отмечу, что любая конструктивная и аргументированная критика только приветствуется. Что ж, поехали…
❯ Постановка задачи
Итак. Представим, что вы абсолютный новичок в области ПЛИС aka FPGA и вот однажды вы услышали, интересные рассказы о том, что с помощью одного из языков описания аппаратуры (HDL) можно решать разнообразные задачи с очень высокой скоростью и при этом параллельно, т.е. одновременно. Первым вопросом, которым задался я как новичок когда услышал про ПЛИС — а с чего начать? На тот момент мне казалось, что все начинается с отладок с нужным чипом и примеров. Я без особого понимания критериев отбора, чем отличаются Altera от Xilinx — быстренько заказал себе отладку на Cyclone IV и после того как получил — научился создавать и запускать простейшие проекты. Каждая правка исходного проекта и проверка сопровождалась ожиданием синтеза, роутинга, заливкой прошивки в ПЛИС для проверки и отладки с помощью светодиодов и кнопок и SignalTap. И чем сложнее были примеры — тем больше времени я тратил на ожидание синтеза, рассовывания пробников отладчика по сигналам и тут я начал задумываться о том, что возможно что-то тут я делаю не так. А если вспомнить, что SignalTap занимает в ПЛИС тоже некоторое количество логических блоков и в сложных проектах он уже не умещался в ПЛИС — ситуация точно требовала изменения подхода.
И тут я начал вникать в то, как организуют процесс разработки в среде профессионалов — я понял, что я упустил тут один очень важный шаг — симуляцию и тестирование с помощью т.н. testbench-ей.
Вникнув и разобравшись — я захотел поделиться своим опытом в этом материале и при написании этой статьи я поставил для себя несколько задач: разобрать вопрос создания простого проекта в Altera Quartus под Linux и как запустить его симуляцию в ModelSim, с попутным объяснением как решить возникающие проблемы, коих по ходу дела возникает немало (вполне возможно, что только у меня).
Задачи для меня и моего уровня вполне достижимые, давайте расскажу и покажу как я их решал.
❯ Общий flow разработки под ПЛИС
Вообще, отдельно стоит рассказать о том, как работают с ПЛИС профессионалы и что следует взять себе за ориентир. Ниже, я попытался обобщить в виде схемы свое представление о алгоритме разработки под ПЛИС. Коротко опишу каждый из этих этапов. Оговорюсь сразу, что в рамках этой статьи я рассмотрю только первые три интересующих нас этапа.

Идея и техническое задание. Пункт с вполне понятным смысловым наполнением. На этом этапе формируется идея будущего устройства, что он должен уметь делать, чего делать не должен. На основании идеи формируется уже техническое задание которое отражает в форме измеримых величин требования для конечного устройства.
Реализация HDL-кода. На этом этапе происходит основная часть работы — в HDL-коде реализуется конечный автомат или группа из таковых, вместе со всеми багами, корявостями и синтаксическими ошибками ?.
Функциональное и поведенческое моделирование (например, в ModelSim). А вот на этом этапе происходит, на мой взгляд самое интересное. Здесь как раз и происходит первая проверка полученного результата, а не напрямую в ПЛИС, как я делал до этого.
В ходе реализации проекта, на каждом этапе когда находятся те или иные ошибки — происходят доработки и исправления — и все начинается по новому циклу. В целом все достаточно просто. Вот реализацию этого флоу я хочу отразить на конкретном примере с картинками и разбором всех граблей.
❯ Создаем проект в Quartus
Итак, казалось бы, что может быть проще: создаем проект и запускаем ModelSim, пишем тестбенч и проверяем, что всё работает как нужно. Я так думал, когда первый раз хотел, что-нибудь прогнать через симуляцию. Но не тут-то было. Но обо всё по порядку.
Открываем Quartus и создадим новый проект:

Жмем New Project Wizard, откроется мастер и можно идти по шагам.

Жмём Next и указываем каталог, в котором будет жить наш проект, заполняем его имя.

Тыкаем кнопку Next и указываем, что мы создаем пустой проект, выбрав пункт Empty project.

Файлы никакие добавлять не будем, поэтому жмякаем Next.

В следующем меню выбираем модель чипа с которым вы работаете, в моем случае это EP4CE6F17C8.

А вот в последнем меню в пункте Simulation нужно выбрать ModelSim-Altera и SystemVerilog HDL (если конечно именно он используется, а не VHDL или Verilog HDL например).

Просматриваем Summary, проверяем нет ли ошибок и жмем Finish:

Откроется окно пустого проекта и можно приступать к его наполнению и настройке.
❯ Наполняем проект смыслом
Реализуем первый этап из флоу — т.е. составим техническое задание: необходимо реализовать на языке SystemVerilog модуль, который на входе будет иметь два логических сигнала A и B, и один на выходе Y, который будет результатом логической операции & (AND) от A и B. Идея достаточно простая и эту, казалось бы простую задачу, можно реализовать аж тремя путями.
Рассмотрим каждый из вариантов:
- Gate Level, то есть через представление в виде логических элементов:
module AND_GATE(output Y, input A, B);
and(Y, A, B);
endmodule
- Data flow, то есть через обозначение направления потока данных:
module AND_DATA_FLOW(output Y, input A, B);
assign Y = A & B;
endmodule
- Behavioral, то есть поведенческий подход, в котором происходит работа с изменениями состояний сигналов:
module AND_BEHAVIORAL(output reg Y, input A, B);
always @ (A or B) begin
if (A == 1'b1 & B == 1'b1) begin
Y = 1'b1;
end
else
Y = 1'b0;
end
endmodule
Какой из вариантов вам больше нравится — такой и выбирайте. Мне нравится больше подход Data Flow.
Создаем новый файл в меню File — New — System Verilog HDL File. Откроется редактор, и запишем интересующий вариант модуля:

Далее сохраняем файл и даем ему соответствующее его роли название:

Теперь нужно добавить файл Top-Level entity, в котором будет находиться модуль, который мы будем пропускать через симуляцию. Для этого в Project Navigator с включенным видом Files кликаем правой кнопкой и выбираем пункт Set as Top-Level Entity:

В меню сообщений будет следующая строка: Info (125061): Changed top-level design entity name to «Top».
Теперь можно запустить анализ и синтез:

Но Quartus выдаст нам ошибку, что якобы Error (12007): Top-level design entity «Top» is undefined.

Что ж, придется снова указать, кто в проекте Top-level Entity. Выбираем в Project Navigator вид отображения Hierarchy, кликаем правой по Top и Settings:

Выбираем первый пункт в меню настроек General, далее кликаем по многоточию и выбираем AND_DATA_FLOW и нажимаем ОК и еще раз ОК чтобы закрыть это меню и перезапускаем анализ и синтез:

Дожидаемся окончания операции и видим что все окончилось успешно и без ошибок, только предупреждения:

Смотрим в отчет и видим, что израсходован один логический элемент и задействовано три пина. Эта информация может в будущем оказаться весьма полезной:

Идём дальше. Теперь, раз всё компилируется, стоит произвести моделирование полученного дизайна и убедиться что все будет работать как нужно.
❯ Интеграция Quartus с ModelSim и запуск симуляции
Итак, общий флоу по интеграции ModelSim в процесс разработки под ПЛИС из нескольких этапов:
- Конфигурирование NativeLink, благодаря которому происходит обмен информацией между Quartus и внешними инструментами, например ModelSim;
- Компиляция необходимых библиотек Quartus, которыми будет оперировать ModelSim;
- Написание Testbench (тестового скрипта) и интеграция его в проект;
- Запуск симуляции, анализ результатов и внесение изменений в проект (при необходимости).
Если не осуществить эту настройку — можно собрать много разнообразных ошибок и ничего не получится. Например, если попробовать просто запустить RTL Simulation:

То само собой получим ошибку, что EDA Simulation Software настроен:

Что ж, перейдем к настройке Native Link. Для этого необходимо перейти в общие настройки Quartus и указать каталог, в котором находится ModelSim. Это делается путем перехода в главном меню Tools — Options…

Откроется меню настроек и нужно перейти в пункт меню EDA Tools Options и в поле ModelSim и\или ModelSim-Altera указать путь до каталога modelsim_ase/linux так, как это сделано у меня:

Далее в настройках проекта тоже необходимо какой тип симулятора используется. Для этого возвращаемся в настройки проекта в Project Navigator (в котором мы устанавливали Top-Level Entity) и переходим в пункт меню EDA Tools Settings и в пункте Simulation выбираем ModelSim-Altera / SystemVerilog HDL:

После переходим в пункт Simulation и видим что в пункте настроек NativeLink ничего не настроено и всё нужно сделать своими ручками:

На этом этапе необходимо указать файл testbench, которые у нас еще отсутствуют. Перейдем к созданию этих файлов.
В многих источниках рекомендуют воспользоваться пунктом меню Processing — Start — Start Test Bench Template Writer:

Но на этом этапе я столкнулся с ошибкой, что якобы данная опция для SystemVerilog не поддерживается:

Окей, попробуем создать файл Testbench самостоятельно в проект и прикрепить его в настройках симуляции руками самостоятельно. Для этого берем создаем новый файл через File — New — SystemVerilog HDL File.
После создания файла откроется редактор и в него запишем заготовку:
module and_gate_test_bench;
endmodule
После сохраним файл c именем and_gate_test_bench.sv и возвращаемся в меню NativeLink settings. Выбираем пункт меню Compile test bench и кликаем по кнопке Test Benches…
В открывшемся меню Test Benches нажимаем кнопку New… и заполняем настройки следующим образом:

Главное указать Top level module in test bench в четком соответствии как это было заполнено в файле в предыдущих шагах. Везде нажимаем OK и выходим.
Теперь запускаем компиляцию:

И видим в сообщениях, что все завершено удачно:

Теперь запуск RTL Simulation из главного меню должен открыть ModelSim, но этого не достаточно т.к. при запуске симуляции будет выданы ошибки о том, что нет необходимых библиотек для симуляции. Поэтому сделаем компиляцию необходимых библиотек.
Для это необходимо перейти в главное меню и нажать Tools — Launch Simulation Library Compiler:

Откроется меню, в котором нужно указать ModelSim, проверить что в поле Selected families указан Cyclone IV E и что указана директория для сохранения результатов компиляции:

Жмём кнопку Start Compilation и ожидаем результатов компиляции. Ожидаем, что компиляция пройдет успешно:

После закрываем окно и попробуем совершить акт симуляции. =)
❯ Пишем Testbench для проекта
Теперь можно перейти ко второму этапу — моделирование и проверка правильности работы полученного кода через Testbench. Как вы уже поняли — Testbench является по сути отдельным модулем написанный на языке HDL, который объявляется в отдельном файле. Поэтому перейдем в наш файл and_gate_test_bench.sv, который мы создали в предыдущих шагах.
Напомню, что в этой статье я не ставил себе целью подробный разбор как писать testbench-файлы и не планировал рассматривать синтаксис, поэтому приведу код testbench-файла как есть, лишь сопроводив его некоторым количеством комментариев:
module and_gate_test_bench;
reg A, B;
wire Y;
AND_DATA_FLOW DUT(Y, A, B);
initial begin
A = 0; B = 0;
#1 A = 0; B = 1;
#1 A = 1; B = 0;
#1 A = 1; B = 1;
end
initial begin
$monitor ("%t | A = %d| B = %d| Y = %d", $time, A, B, Y);
end
endmodule
В начале мы объявляем два регистра A и B, чтобы они сохраняли свое значение до тех пор пока не будут назначено новое. Они будут означать входные сигналы. И зададим сигнальный проводник Y, который будет выводить результат.
После инициализируем экземпляр модуля, созданного в главном файле проекта, с именем DUT, указав сигналы в порядке объявления.
В модуле initial указываются действия которые исполняются после старта модуля в симуляторе. Соответственно при старте задаются значения сигналов A и B равными нулю и через каждый условную единицу времени изменяем сигналы на новые значения (в соответствии с таблицей истинности модуля).
Плюсом к этому добавляем отладочный вывод в лог симулятора, чтобы помимо временной диаграммы видеть текущие значения входных сигналов и того, что имеем на выходе. Сохраняем полученный testbench-файл и нажимаем Compilation.
❯ Запускаем Testbench
Дождавшись результатов компиляции — можно запустить ModelSim и увидеть результаты моделирования. Для этого нужно перейти в главное меню и нажать Tools — RTL Simulation:

Если в предыдущих шагах все сделали правильно — то будет запущен ModelSim и выведен лог:

И если увеличить масштаб в Waveform-меню — можно увидеть результат на временной шкале:

Соответственно, зная наперёд как работает логический элемент AND — мы можем сказать что всё сработало верно, результаты соответствуют ожидаемым, как в логе, так и во временной диаграмме. Ну и покуда всё работает верно — нет необходимости переходить к пути коррекции ошибок и можем считать, что задача решена.
❯ Заключение
Вот путём таких не хитрых манипуляций можно достаточно быстро, без реальной железки, проверить свой HDL-дизайн и получить быстрый ответ на вопрос “работает\не работает”. Если вы застряли, на каком-либо из этапов — не стесняйтесь обращаться за помощью в комментариях, возможно я или более опытные коллеги смогут вам помочь.
Как пользоваться средой моделирования и как раскрыть весь потенциал ModelSim — тема на большое количество статей или даже книгу, тут мы с вами скорее попробовали просто настроить проект перед тем как приступать к более сложным вещам. Но думаю, что много из того, что я буду рассматривать в своих следующих статьях, в той или иной степени, позволит расширить представление о ModelSim и его возможностях.
Если статья вам понравилась — ставьте “подписывайтесь и ставьте стрелочку вверх”. Этим самым вы поддерживаете меня как автора и стимулируете на написание новых материалов для вас. До встречи в следующих статьях!