Небольшой мануал по настройке симулятора ModelSim для новичков в освоении ПЛИС, симулятор очень поможет как в ожидании заказанной ПЛИСы\отладочной платы (т. к. можно тренироваться и наращивать свой скилл без реального железа), так и в отладке уже реального проекта под конкретное железо (т. к. процесс компиляции, синтеза, размещения и прошивки крайне не быстр), а также далеко не всё можно посмотреть логическим анализатором или осциллографом, поэтому освоение симулятора HDL крайне важно и необходимо.
Статья разбита на три части, первая — настройка запуска ModelSim напрямую из Quartus Prime c минимальными усилиями, вторая — самостоятельная настройка ModelSim для симулирования проекта\модуля без использования Quartus Prime и третья — общая, о работе в ModelSim.
В статье рассматривается ModelSim-Intel FPGA Starter Edition 10.5b, идущая в комплекте Quartus Prime 18.0 Lite, — она бесплатная и ограничений серьёзных нет, кроме одного — максимального числа строк исходников для проведения симуляции — 10000 линий на проект. Также стоит отметить, что все написанное ниже применимо и к другим версиям ModelSim.
Запуск из Quartus Prime
Допустим, у вас уже есть какой-либо проект и вы хотите провести симуляцию работы какого-либо модуля в нём. Test bench (и дальше по тексту буду так писать, ибо как перевести корректно и красиво звучаще, не придумал, а перевод а-ля «испытательный стенд» как-то режет глаз, подскажете лучше варианты — переделаю) у вас уже написан (не буду углубляться в этой статье в его написание, ниже будут даны примеры простого модуля и test bench для него) и вы хотите, собственно, их просимулировать.
Идём в настройки проекта:
И переходим в раздел EDA Tool Settings -> Simulation:
Для запуска простой симуляции нас интересуют здесь следующие вещи, отмеченные на скриншоте выше:
- Tool Name — выбираем ModelSim-Altera;
- Run gate-level simulation automaticlly afther compilation — убираем галочку, это для проведения симуляции не на идеальных логических элементах, а на библиотеках логических элементов того семейства ПЛИС, под которое вы разрабатываете проект (для начала лучше разобраться на идеальных);
- Format for output netlist — выбираем тип HDL, на котором написан модуль и test bench;
- Compile test bench — выбираем этот пункт в NativeLink Settings и нажимаем на кнопку Test Benches… для, собственно, настройки test bench-ей.
После нажатия кнопки Test Benches… будет показано следующее окно:
У вас оно будет пустое. :) Нажимаем на New… :
И опять у вас в нём всё будет пусто, на скриншоте выше же показан пример заполнения, сначала внизу в File Name добавляем файл test bench-а (кнопкой Add после выбора файла), для которого будет проведено симулирование, далее в Test Bench Name вводим любое имя, а в Top Level Module in Test Bench точно вводим имя модуля test bench (ну обычно это имя файла без расширения должно получиться). Еще можно задать Simulation Period — это период времени, в течение которого будет проводиться симуляция, но обычно этот период задаётся в файле самого test bench.
Вот вроде бы и всё, можно жмакать на старт:
Но скорее всего у вас отобразится сообщение типа этого:
Странно, ставил я полный пакет Quartus Prime 18.0 Lite, а пути к ModelSim не прописываются автоматом. Поправить это легко, открываем Options…:
Переходим во вкладку General -> EDA Tool Options:
И в самом низу, собственно, прописываем путь к ModelSim.
Примечание: важно прописать путь не к корню, а к вложенной папке win32aloem и в конце поставить бэкслэш.
Вот и всё, теперь можно запускать симуляцию! Нажимаем опять RTL Simulation и с некоторым запозданием появляется окно ModelSim:
Автоматически запустится процесс симуляции и все (или почти все) сигналы test bench будут добавлены в Wave окно (на скрине выше сигналов особо и нету, да, модуль самописно-кривой и ещё не готов).
Более подробно об интерфейсе и окнах ниже в разделе с общими сведениями.
Самостоятельная работа в ModelSim
Запускаем ModelSim — Intel FPGA Starter Edition с ярлыка. Перед нами открывается основное окно и единственное окно Library:
Создаём новый проект:
Перед нами открывается окно создания проекта:
Здесь задаём имя проекта и корневую папку (где лежат Verilog файлы), название библиотеки и копирование настроек можно не трогать. Клацаем ОК, далее открывается диалог создания\добавления существующих файлов HDL, создания папок и, собственно, файла настроек симуляции.
Я выбрал добавление в проект существующих файлов:
Выбрал сразу оба и не менял настройку копирования файлов, т. к. они и так лежат в корне папки проекта. На этом можно закрыть диалог. Должно получиться следующее:
Появились оба выбранных файла и у обоих статус в виде вопросительных знаков — это значит, что они не скомпилированны. Компилируем:
Если ошибок в них нет и всё прошло успешно, то статус изменится на зеленые галочки, в противном случае смотрим в консоли возникшие ошибки и исправляем причину их возникновения:
Теперь можно добавить файл настроек симуляции:
В появившемся диалоге выбираем из библиотеки work (ранее задавали такое имя при создании проекта) необходимые файлы и test bench для проведения симуляции (у меня их всего 2, выбираю оба):
Настройки пока не трогаю, для общего понимания процесса все можно оставить по умолчанию. Нажимаем Save, файл настроек должен появится в проекте:
Практически всё. Кликаем двойным ЛКМ на файле Simulation 1:
Подгрузились дополнительные окна с файлами проекта, цепями, окном осциллограммы работы, процессами и консолью (на скриншоте выше я уже выбрал все цепи и перетащил на окно Wave для отображения их работы после симуляции).
Вот и всё, нажимаем на кнопку Countine Run для запуска симуляции до стоп-команды в test bench или Run для запуска симуляции кратно выбранному временному отрезку (у меня указан 100 нс) и можно видеть результаты работы:
Всё не так уж и сложно было. ;)
Общие сведения о работе в ModelSim
Тестовые файлы
Полный код тестовых файлов, над которыми можно провести эксперименты и обучиться работе в ModelSim. Файл с модулем, который надо тестировать — counter.v :
`timescale 1ns/1ns module counter ( input wire reset, input wire clk, input wire [7:0]wdata, input wire wr, output reg [7:0]data ); always @ (posedge clk or posedge reset) if (reset) data <= 8'h00; else if(wr) data <= wdata; else data <= data + 8'h01; endmodule
Файл с test bench для модуля counter, который проверит корректность его работы — counter_tb.v :
`timescale 1ns/1ns module counter_tb(); reg reset, clk, wr; reg [7:0]wdata; wire [7:0] data_cnt; counter DUT(reset, clk, wdata, wr, data_cnt); always #10 clk = ~clk; initial begin clk = 0; reset = 0; wdata = 8'h00; wr = 1'b0; #10 reset = 1; #5 reset = 0; #50; // расскоментировать по необходимости /*@(posedge clk) #0 begin wdata = 8'h55; wr = 1'b1; end @(posedge clk) #0 begin wdata = 8'h00; wr = 1'b0; end*/ end initial begin #400 $stop; end initial begin $dumpfile("out.vcd"); $dumpvars(0,DUT); end initial $monitor($stime,, reset,, clk,,, wdata,, wr,, data_cnt); endmodule
Обратите внимание — файл test bench и, соответственно, модуль test bench без портов называются как «проверяемый модуль» + «_tb» = counter_tb — это для наглядности и быстрого разделения по категориям рабочий модуль \ test bench для него.
Сигналы и формат состояния сигнала
Во вкладке Sim находятся все модули, а также их процессы. При выделении любого из модулей или процесса, к нему относящегося, все сигналы модуля появятся во вкладке Objects. Активные процессы также отображаются в отдельной вкладке Processes (Active), и выделение любого из них меняет отображаемые сигналы из вкладки Objects. К примеру, выбираем экземпляр DUT из test bench:
Далее выделяем все сигналы из вкладки Objects и переносим их, зажимая ЛКМ, на вкладку Wave (для наглядности на скриншоте ниже уже проведено несколько шагов симуляции, чтобы отобразились формы сигналов):
На вкладке Wave есть 3 столбца, первый по умолчанию отображает сигнал с подробным именем формата «/ файл / экземпляр_модуля / имя_сигнала», второй столбец отображает текущее значение сигнала в зависимости от конкретного положения выделенного курсора с выбираемым форматом отображения, а третий столбец — окно, отображающее формы сигналов по времени с возможностью установки курсоров и выбора временного отрезка для отображения.
Пример установки формата отображения для всей шины сигналов data как беззнаковый тип числа:
Пример установки формата отображения для битов шины сигналов data как бинарный тип числа:
После применения формата отображения для шины сигналов можно видеть, как для продолжительных состояний отображается их значение, что довольно удобно и наглядно:
Также на скриншоте можно увидеть, что состояние шины wdata в бинарном виде занимает много места («00000000»), а состояние шины data в беззнаковом виде значительно сокращает используемое место и умещается в период тактового сигнала clk без зумирования.
Управление симуляцией, отладка
Основная панель управлением симуляции так и называется — Simulate, и вот основные элементы управления в ней:
Последовательно по названиям элементы управления на скриншоте выше:
- Restart — полный сброс состояния симуляции и графика сигналов.
- Run Lenght — элемент ввода отрезка времени, который необходимо просимулировать одинарно.
- Run — одинарная симуляция с отрезком времени, указываемым в Run Lenght.
- Continue Run — продолжительная симуляция до команды остановки.
- Run -All — бесконечная симуляция.
- Break — пауза симуляции с отображением текущего шага.
- Stop — полная остановка симуляции.
Далее панель для пошаговой отладки — Step:
Последовательно по названиям элементы управления на скриншоте выше:
- Step Into — выполнение HDL кода по шагам.
- Step Over — при нажатии происходит выполнение блока кода и остановка на его последнем действии.
- Step Out — при нажатии происходит остановка на первом действии следующего блока кода и выполнение текущего блока кода.
- Следующие 3 кнопки аналогичны первым, но их выполнение только в пределах одного потока\процесса (потому у них в названии и приписка в конце — «Current Thread«).
Вот так выглядит выполнение по шагам:
Появляется синяя стрелочка (слева, около номеров строк), отображающая текущий шаг выполнения HDL кода. При нажатии на любой номер кода можно ставить Break Point, как в обычном IDE при написании обычных программ или прошивок для микроконтроллеров.
Курсоры
За добавление\удаление курсоров, их привязку отвечает следующая панель:
Последовательно по названиям элементы управления на скриншоте выше:
- Insert Cursor — добавление курсора.
- Delete Cursor — удаление курсора.
- Find Previous Transition — для выделенного сигнала, перейти к предыдущему изменению уровня.
- Find Next Transition — для выделенного сигнала, перейти к следующему изменению уровня.
- Find Previous Falling Edge — для выделенного сигнала, перейти к предыдущему спадающему уровню.
- Find Next Falling Edge — для выделенного сигнала, перейти к следующему спадающему уровню.
- Find Previous Rising Edge — для выделенного сигнала, перейти к предыдущему нарастающему уровню.
- Find Next Rising Edge — для выделенного сигнала, перейти к следующему нарастающему уровню.
Также, добавив несколько курсоров, можно увидеть дельту времени между их значениями:
Управляется каждый курсор по выделению необходимого, а также внизу слева есть дополнительные колонки со всеми курсорами, в которых можно назначить имя, время, цвет, заблокировать курсор, удалить его или добавить новый.
Также рядом находится маленькая кнопка Grid, Timeline & Cursor Control… (выделена красным на скриншоте выше), отображающая окно Wave Windows Preferences, — настройки отображения графика и его сетки (кликабельно):
И отчасти относящаяся к курсорам панель с кнопками приближения\отдаления, приведу её уже как дополнение:
Последовательно по названиям элементы управления на скриншоте выше (в скобках указаны хоткеи):
- Zoom In (I) — приближение относительно центра текущего положения.
- Zoom Out (O) — отдаление относительно центра текущего положения.
- Zoom Full (F) — полное отдаление до вмещения всего графика.
- Zoom In on Active Cursor (C) — приближение относительно положения активного курсора.
- Zoom between Cursors — приближение относительно центра двух активных курсоров.
- Zoom Other Windows (M) — приближение в другом окне (для многооконного использования).
Изменение и перекомпиляция файлов в ModelSim
Это не совсем очевидный путь в этой программе, и я решил описать его. Хотя, возможно, есть путь и легче, рад буду, если подскажете в комментариях…
Итак, для редактирования файлов, как тестируемого модуля, так и файла test bench, необходимо вначале завершить симуляцию:
Станут открыты только две вкладки — Library и редактор файла (может и не быть открытым, если не использовали отладку, тогда нажимаем на нужном файле ПКМ и в контекстном меню выбираем пункт Edit):
Но при попытке что-либо изменить или добавить ничего не происходит… что за дела? Всё просто — надо снять галочку, что файл только для чтения:
Для проверки внесённых изменений я раскомментировал блок, который выставляет данные на шину wdata и устанавливает сигнал wr. Нажимаем Ctrl + S и видим, что статус изменённого файла изменился (опять появился вопрос):
Просто компилируем его (ну или всё сразу):
И опять нажимаем двойным ЛКМ на файл симуляции, проверяем изменения:
Всё заработало! И теперь установка данных на шине wdata и сигнала wr влияет на выходную шину data. Всё это можете самостоятельно проверить, скопировав код файлов выше. ;)
Примечание: изменения файлов вносятся в оригинальные файлы только при закрытии ModelSim! Для симуляции создаётся их копия, а во время работы в ModelSim вы работаете с копией, и только при выходе из программы изменения вносятся в оригинальные файлы.
Ссылки
- ModelSim-Intel FPGA Software Products — описание и сравнение версий;
- Download Center — здесь можно скачать как отдельно ModelSim Intel FPGA Edition Starter Edition, так и полный пакет Quartus Prime Lite Edition (Free).