Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> VHDL

Интеграция библиотек IP Quartus Prime в VUnit: пошаговое руководство

Хотели ли вы когда-нибудь запустить VHDL-симуляцию, включающую IP-ядро Quartus через фреймворк верификации VUnit?

Именно это имел в виду FPGA-инженер Константинос Параскевопулос, но он не смог найти подходящий туториал. К счастью, он использовал свой талант, чтобы разобраться, как это сделать, и был достаточно добр, чтобы поделиться этим с VHDLwhiz через эту гостевую статью.

Дадим слово Константиносу!

Часто желательно включить предопределенные IP из каталога Quartus IP в свой дизайн при симуляции вашей системы с VUnit. Этот туториал поставляет знания, необходимые для генерации, включения и связывания внешних библиотек IP Quartus с средой VUnit.

Новичок в VUnit? Посмотрите этот туториал: Getting started with VUnit

Обзор

Этот туториал состоит из трех основных частей:

  1. Краткое описание выбранного IP
  2. Шаги, необходимые для генерации и связывания соответствующих библиотек
  3. Верификация с использованием VUnit и Modelsim

Требования

Также предполагается наличие базовых знаний VHDL и навыков ModelSim.

Проектируемое устройство (DUT)

Для нашего сценария мы используем IP Параллельного Складывателя из списка Integer Arithmetic IP Quartus.

Интеграция библиотек IP Quartus Prime в VUnit: пошаговое руководство

Наш дизайн принимает три 16-битных входных вектора и выдает суммированный результат в 17-битном векторе.

Шаг 1: Генерация IP

Мы генерируем наш складыватель в окне каталога IP двойным кликом на компоненте параллельного складывателя под Library/Basic functions/Arithmetic.

После того как мы даем имя и кастомизируем наш компонент под наши нужды, мы нажимаем кнопку Generate HDL в правом нижнем углу.

Интеграция библиотек IP Quartus Prime в VUnit: пошаговое руководство

В этот момент появится окно, как показано на следующем рисунке.

Примечание: Мы должны установить Create simulation model под разделом Simulation либо в VHDL, либо в Verilog для генерации симуляционных файлов, так как опция по умолчанию — none. Если мы не выберем один, файл given_ip_name.spd не будет сгенерирован, вызывая провал следующего шага.

Интеграция библиотек IP Quartus Prime в VUnit: пошаговое руководство

Вышеуказанный процесс генерирует файл и папку под нашей директорией quartus:

  1. Файл: given_ip_name.ip
  2. Папка: given_ip_name

Папка содержит .vhd и .v файлы, которые нужно добавить позже в наш скрипт run.py.

Шаг 2: Генерация симуляционных файлов IP

  1. GUI: Выберите Tools ➤ Generate Simulator Setup Script for IP и укажите выходную директорию в окне запроса,
  2. CMD: Используя команды Qsys, мы можем сгенерировать те же файлы, введя в терминале следующую команду:
ip-setup-simulation --quartus-project= <project's_QPF_filepath> \ --output-directory= <my_dir>

Используя один из двух методов выше, мы инструктируем Quartus сгенерировать директорию для каждого поддерживаемого симулятора, содержащую скрипт для создания и компиляции библиотек IP.

Шаг 3: Генерация и компиляция библиотек IP для Modelsim

Следующий шаг — найти скрипт msim_setup.tcl в папке mentor, созданной предыдущим шагом, и продублировать его с именем setup.tcl. Затем, в файле setup.tcl, раскомментируйте проиллюстрированные команды и установите переменную $QSYS_SIMDIR.

# # QSYS_SIMDIR используется в Quartus-генерированном IP симуляционном скрипте для # # построения путей к файлам, необходимым для симуляции IP в вашем Quartus # # проекте. По умолчанию IP скрипт предполагает, что вы запускаете # # симулятор из локации IP скрипта. Если запускаете из другой # # локации, установите QSYS_SIMDIR в выходную директорию, которую вы указали, когда # # генерировали IP скрипт, относительно директории, из которой вы запускаете # # симулятор. # set QSYS_SIMDIR <script generation output directory> # # # Source the generated IP simulation script. source $QSYS_SIMDIR/mentor/msim_setup.tcl # # # Установите любые опции компиляции, которые вам требуются (это необычно). # set USER_DEFINED_COMPILE_OPTIONS <compilation options> # set USER_DEFINED_VHDL_COMPILE_OPTIONS <compilation options for VHDL> # set USER_DEFINED_VERILOG_COMPILE_OPTIONS <compilation options for Verilog> # # # Вызовите команду для компиляции библиотеки симуляции Quartus EDA. dev_com # # # Вызовите команду для компиляции Quartus-генерированных IP симуляционных файлов. com # 

После изменения и сохранения setup.tcl, мы можем безопасно выполнить Tcl-файл с помощью команды vsim.

vsim -c -do "do setup.tcl; quit"

Это генерирует скомпилированные библиотеки в папке mentor.

Шаг 4: Связывание с VUnit

Теперь, когда IP-библиотеки сгенерированы, мы должны связать их, используя Python-скрипт run.py.

Посмотрите на рисунок ниже, чтобы лучше понять структуру директорий нашего примера. Исходная топология состояла из корневой папки demo, папок tb, vunit и quartus. Все подпапки и файлы под папкой quartus сгенерированы через фреймворк Quartus после создания проекта и завершения шагов 1–3.

Примечание: Quartus генерирует больше файлов и папок, но изображение ниже показывает те, что интересны для нас.

Интеграция библиотек IP Quartus Prime в VUnit: пошаговое руководство

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

Обратите внимание, что sim_files — это директория, которую мы указали в шаге 2, где папка mentor была сохранена.

from vunit import VUnit from os.path import join, dirname, abspath # ROOT root = join(dirname(__file__), '../') # Path to generated libraries path_2_lib = '/quartus/sim_files/mentor/libraries/' # ROOT

После создания экземпляра VUnit под названием vu, мы можем указать библиотеку дизайна для нашего VHDL-кода и связать любые необходимые внешние библиотеки:

# Create VUnit instance by parsing command line arguments vu = VUnit.from_argv() # create design's library my_lib = vu.add_library('my_lib') # Link external library vu.add_external_library("parallel_adder", root + path_2_lib + "parallel_adder")

И наконец, добавим наши исходные файлы. Они находятся в трех подпапках под директорией given_ip_name:

  1. parallel_add_191
  2. synth
  3. sim

Директории synth и sim содержат одну и ту же информацию, а именно топ-уровневый дизайн нашего IP. Однако форматирование этих файлов в нашем случае на VHDL. Они могли быть на Verilog, и это зависит от выбранного языка на шаге 1.

В случае, если наш топ-уровневый дизайн включает подкомпоненты, мы также должны включить их исходные файлы. Они находятся под подпапками в директории given_ip_name, такие как компонент parallel_add_191 в нашем случае.

my_lib.add_source_files(join(root,'quartus','parallel_adder','sim','parallel_adder.vhd')) my_lib.add_source_files(join(root,'quartus','parallel_adder','parallel_add_191','sim','parallel_adder_parallel_add_191_oh4guxa.vhd')) my_lib.add_source_files(join(root,'tb','tb_demo.vhd')) testbench = my_lib.entity("tb_demo") vu.main()

Тестбенч

Для начала вы можете проверить эту ссылку, чтобы узнать о основах формирования тестбенча VUnit.

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

Примечание: Выполнение процесса в нашем примере последовательное. Таким образом, контрольные сигналы (называемые флагами) используются для уведомления процесса, должен ли он начаться или завершиться.

library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; library vunit_lib; context vunit_lib.vunit_context; entity tb_demo is generic ( runner_cfg : string:= runner_cfg_default); end tb_demo; architecture sim of tb_demo is constant clk_period : time := 10 ns; signal clk : std_logic := '0'; signal rst : std_logic := '0'; -- INPUTS signal data_a : std_logic_vector(0 to 15):= (others => '0'); signal data_b : std_logic_vector(0 to 15):= (others => '0'); signal data_c : std_logic_vector(0 to 15):= (others => '0'); -- OUTPUTS signal result : std_logic_vector(0 to 16); -- CONTROL FLAGS signal reset_done :boolean := false; signal sim_done :boolean := false; signal start_sim :boolean := false; 

Далее, мы инстанцируем наш UUT. Quartus поставляет примеры инстанциации компонентов для VHDL и Verilog под именами файлов ip_name_inst.vhd и ip_name_inst.v.

begin -- Unit Under Test UUT : entity work.parallel_adder port map ( data0x => data_a, -- parallel_add_input.data0x data1x => data_b, -- .data1x data2x => data_c, -- .data2x result => result -- parallel_add_output.result );

Первые два процесса, которые начинаются — clk_process и reset_rel. Пока последний приостанавливается после сброса и установки флага reset_done в true, clk_process работает на протяжении всего симуляционного времени.

clk_process : process begin clk <= '1'; wait for clk_period/2; clk <= '0'; wait for clk_period/2; end process clk_process; reset_rel : process begin rst <= '1'; wait for clk_period*2; wait until rising_edge(clk); rst <= not rst; reset_done <= true; wait; end process reset_rel;

Теперь, когда сброс сделан, мы можем вызвать процесс test_runner для выполнения наших тестов. Кроме того, test runner остается активным до тех пор, пока флаг sim_done не будет установлен в true, что происходит в последнем процессе.

test_runner : process begin test_runner_setup(runner, runner_cfg); wait until reset_done and rising_edge(clk); iterate : while test_suite loop start_sim <= true; if run("test_case_1") then info ("Start"); info (running_test_case); wait until sim_done; end if; end loop; test_runner_cleanup(runner); end process test_runner; 

Наконец, процесс data_generator выполняет несколько сложений, присваивая значения трем входам нашего параллельного складывателя, используя цикл for.

Примечание: Этот процесс запускается, когда процесс test_runner инструктирует это, устанавливая флаг start_sim. В конце этого процесса он поднимает флаг sim_done, приказывая test runner приостановить симуляцию.

data_generator : process constant tag2 : log_level_t := new_log_level("INFO", fg => blue, bg => black, style => bright); variable a,b,c,d : integer; begin wait until start_sim; wait until rising_edge(clk); show(display_handler, tag2); if running_test_case = "test_case_1" then for i in 0 to 10 loop data_a <= std_logic_vector(to_unsigned(i+10,data_a'length)); data_b <= std_logic_vector(to_unsigned(i+20,data_a'length)); data_c <= std_logic_vector(to_unsigned(i+30,data_a'length)); wait until rising_edge(clk); a := to_integer(unsigned(data_a)); b := to_integer(unsigned(data_b)); c := to_integer(unsigned(data_c)); d := to_integer(unsigned(result)); log( integer'image(a) &" + & integer'image(b) &" + & integer'image(c) &" = & integer'image(d), tag2); end loop; end if; sim_done <= true; end process data_generator; 

Верификация

Для запуска тест-кейса и верификации, что все работает как ожидается, мы можем выполнить скрипт run.py из директории, где он находится, просто введя в терминале следующую команду.

python ./run.py -v

Примечание: Кастомизированный логгер использован для лучшей иллюстрации в нашем выводе, видимом при предоставлении verbose опции -v. Кроме того, поскольку определен только один тест-кейс, нам не нужно предоставлять опцию для его указания.

Интеграция библиотек IP Quartus Prime в VUnit: пошаговое руководство

Наконец, для верификации наших результатов в ModelSim, мы могли бы ввести следующую команду:

python ./run.py --gui

Интеграция библиотек IP Quartus Prime в VUnit: пошаговое руководство

(Нажмите на изображение, чтобы увеличить)

Заключение

Подводя итог, мы узнали, как включить и тестировать IP Quartus, которые находятся в каталоге IP, в среде VUnit. Хотя этот туториал использовал предопределенный IP, тот же процесс применяется к кастомным упакованным IP.

Посмотрите этот туториал VUnit, если вы еще не сделали этого:
Getting started with VUnit

VHDL

  1. SigFox разъяснен: технология, рыночное влияние и сравнение с Link Labs
  2. VUnit 101: Практическое руководство по автоматизированной VHDL-верификации
  3. Создание списков строк в VHDL: лучшие практики и пример
  4. Корректное завершение симуляции VHDL-тестбенча
  5. Реализация PWM-контроллера в VHDL: проектирование, симуляция и FPGA-демо
  6. Как создать самопроверяющийся тестбенч в VHDL — практическое руководство
  7. Технологии: ключ к прозрачным, этичным цепочкам поставок
  8. Станок для производства рабицы: принцип работы и преимущества
  9. Как пропраймить (запустить) шестеренчатый гидравлический насос для оптимальной работы
  10. Пошаговое руководство: пропрайминг гидравлического насоса трактора Ford