Проектирование цифровых систем на языках описания аппаратуры/Лекция 14
- Заголовок
- Верификация с использованием библиотеки UVVM.
- Автор
- Ланкевич Ю.Ю.
- Нижний колонтитул
- Проектирование цифровых систем на языках описания аппаратуры/Лекция 14
- Дополнительный нижний колонтитул
- Ланкевич Ю.Ю., 18:40, 23 ноября 2020
Слайд:Введение в UVVM
В среднем половина времени разработки для ПЛИС тратится на верификацию. Мы знаем, что разработка архитектуры важна и для качества проекта, и для времени разработки. Таким образом очевидно, что то же применимо и к тестбенчу. Кроме того интересен факт того, что половина времени верификации тратится на отладку. Это значит, что потенциально можно улучшить верификацию в общем и отладку в частности, и уменьшить временные затраты. Методология UVVM (the open source Universal VHDL Verification Methodology) была разработана чтобы решить эту проблему и значительно уменьшить время верификации, тем самым улучшая качество продукта. UVVM предоставляет очень простую и мощную архитектуру, которая позволяет разработчкам строить их собственные тестбенчи и тестовые сценарии намного быстрее. Полезные ссылки:
- https://uvvm.org/ - сайт разработчиков UVVM
- https://github.com/UVVM/UVVM - репозиторий с исходным кодом UVVM
Далее рассмотрим на сколько просто понять и начать исползовать предложенную методологию. Также рассмотрим как UVVM поможет нам сделать лучше тестбенчи и в то же время уменьшить рабочую нагрузку.
Слайд:Разработка эффективных тестбенчей на VHDL
Основные поставщики САПР говорят о пробеле в верификации и предоставляют решения чтобы решить эту проблему. К сожалению, они предпочитают решение, которое является сложной методологией, называемой UVM (Universal Verification Meyhofology). Эта методолгоия требует изучения дополнительного языка SystemVerilog и покупкт очень дорогих инструментов. Подовляющее большенство FPGA разработчиков в Европе используют VHDL для разработки и верификации (60% и 50% соответвенно во всём мире) и нет причин менять это.
UVVM на самом деле копирует некоторые принципы из UVM и таким образом можно рассматривать UVVM как упрощённую VHDL версию UVM. VHDL является достаточно мощным языком для большенства FPGA проектов и позволяет разработчикам продолжать использовать известный им язык, а затем шаг за шагом просто добавлять функциональность по мере необходимости. Другими словами, ваш тесбенч и язык мягко и эффективно эволюционирует, но возможностей и функциональности самих по себе не достаточно: структура и архитектура яывляются ключевыми для абсолютно всех аспектов хорошей FPGA разработки.
Люди часто говорят об эффективном написании кода, но это не правильный фокус. Написание кода - это маленький фрагмент сложного модуля, либо FPGA разработки, отличие одного подхода от другого имеет относительно небольшой эффект на общую эффективность разработки. Что на самом деле важно:
- Обзорность, читаемость: простое понимание тест harness и того, как работает тестбенч.
- Модифицируемость, поддерживаемость и расширяемость: простота модификации или расширения функциональности.
- Отлаживаемость: хорошая поддержка для поиска корневой причины проблемы.
- Переиспользуемость: эффективное переиспользование между различными модулями тестбенчей, из block level тестбенчей в top level тестбенче, из одного проекта в другом, и между различными модулями верификации (Verification Components).
Если мы углубимся в деталли шаг за шагом, то мы увидим что некоторая функциональность всегда требуется для любого хорошего тестбенча:
- Обработка предупреждений: чтобы гарантировать, что любая потенциальная проблема помечается и выдаётся соответствующее предупреждение. Эти проблемы также должны быть посчитаны, суммированы и обработаны раличными спосабами.
- Логирование:чтобы позволить выдавать простые сообщения о конкретных действиях, а также и детализированные сообщения о прогрессе. Может уменьшить время отладки в разы, когда перед предупреждением выдаётся детальная информация о транзакции в структурированном виде.
- Проверка значений сигналов: наиболее общая часть во всех тестбенчах – проверка реакций проаеряемой системы.
- Проверка сигналов во времени: важно, например, для обеспечения того, чтобы не было неожиданных импульсов, либо чтобы сигнал был стабильным в течение некоторого периода времени.
- Ожидание значений, либо изменений: необходимо, например, чтобы ожидать прерывания, либо определенного значения. Необходимо иметь таймаут, чтобы избежать вечного ожидания (зависания).
Это всё и многое другое поддерживается в библиотеке "UVVM Utility", которая входит в UVVM и это является базисом для более продвинутых возможностей.
Слайд:Пример использования UVVM
Ниже продемонстрированы примеры некоторых комманд. Логирование и проверка значений выбраны как пример, поскольку это две из наиболее важных функций.
-- In test sequencer as a noraml progress msg log("Checking Registers in UART");
BV: 160ns uart_tb Checking Registers in UART
Префикс "BV" может быть изменён пользователем.
Доступны также и более продвинутые варианты процедуры логирования, например контроль количества выводимых сообщений.
-- In test sequencer as a section header log(ID_LOG_HDR, "Checking Registers in UART");
BV: 60ns uart_tb Check defaults for all registers BV:----------------------------------------------------
Предоставляются многочисленные варианты комманды check_value() для различных типов сигналов, с возвращаемым значением, либо без него, и некоторые более продвинутые опции.
-- E.g. inside the test sequencer check_value(dout, x"00", ERROR, "dout must be default inactive");
BV: 60ns irqc_tb check_value(slv x00)=> OK. dout must be default incative
Сообщение об ошибке:
BV:==================================================== BV: ERROR: BV: 192 ns. irqc_tb BV: value was: 'xFF'. expected 'x00'. BV: dout must be default inactive BV:====================================================
Библиотека UVVM Utility предоставляет также множество других полезных комманд, которые можно найти в PDF документе "Quick Reference" (util_quick_ref.pdf), который постовляется вместе с UVVM. В этом документе можно найти обзор всех доступных комманд и типов, а также каждую команду с подробным описанием для всех возможными перегрузок, примерами и комментариями.
Пример использования комманды await_value():
await_value(irq, '1', 0 ns, 2* C_CLK_PERIOD, ERROR, "Interrupt expected immediately");
Пример описания из документа "Quick Reference" для комманды await_value():
Name | Parameters and examples | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
await_value() |
target(sl), exp(sl), [match_strictness], min_time, max_time, [alert_level], msg, [scope, (etc.)] target(slv), exp(slv), [match_strictness], min_time, max_time, [alert_level], msg, [scope, (etc.)] target(bool), exp(bool), min_time, max_time, [alert_level], msg, [scope, (etc.)]] target(u), exp(u), min_time, max_time, [alert_level], msg, [scope, (etc.)] target(s), exp(s), min_time, max_time, [alert_level], msg, [scope, (etc.)] target(int), exp(int), min_time, max_time, [alert_level], msg, [scope, (etc.)] target(real), exp(real), min_time, max_time, [alert_level], msg, [scope, (etc.)] Examples await_value(bol, true, 10 ns, 20 ns, “Waiting for bol to become true”); await_value(slv8, “10101010”, MATCH_STD, 3 ns, 7 ns, WARNING, “Waiting for slv8 value”); |
Waits until the target signal equals the exp signal, or times out after max_time. An alert is asserted if the signal does not equal the expected value between min_time and max_time. Note that if the value changes to the expected value at exactly max_time, the timeout gets precedence. - match_strictness: Specifies if match needs to be exact or std_match , e.g. ‘H’ = ‘1’. (MATCH_EXACT, MATCH_STD)
|
В левой колонке (Parameters and examples) показаны параметры процедуры, каждая строка соответсует одной перегрузке. И затем слудует два примера использования. В крайней правой колонке даны комментарии и объяснения.
Важно то, что тесбенч будет всегда сообщать как минимум о падении или успешном прохождении, но также предпочтительно выводить итоговый отчёт обо всех предупреждениях:
============================================================ BV: *** SUMMARY OF ALL ALERTS *** BV: ======================================================= BV: REGARDED EXPECTED IGNORED Comment? BV: NOTE : 0 0 0 ok BV: TB_NOTE : 0 0 0 ok BV: WARNING : 0 0 0 ok BV: TB_WARNING : 0 0 0 ok BV: MANUAL_CHECK: 0 0 0 ok BV: ERROR : 0 0 0 ok BV: TB_ERROR : 0 0 0 ok BV: FAILURE : 0 0 0 ok BV: TB_FAILURE : 0 0 0 ok BV: ======================================================= BV: No mismatch between counted and expected serious alerts BV: =======================================================
Слайд:Начало работы с UVVM Utility Library
Библиотеку UVVM с различными примерами, документацией и дополнительной информацией можно скачать из репозитория github https://github.com/UVVM/UVVM . Ниже приведём список шагов, которые необходимо выполнить чтобы начать работу с UVVM Utility library:
- Скачать репозиторий https://github.com/UVVM/UVVM
- Скомпилировать UVVM Utility library
a) В консоли вашего симулятора перейти в 'uvvm_util/script';
b) Выполнить: 'do ../script/compile_src.do' - Добавить библиотеку в ваш тестбенч, добавив следующие строки до декларации entity тестбенча
library uvvm_util;
context uvvm_util.uvvm_util_context; - Теперь вы можете включить любую команду из данной библиотеки в ваш тестбенч (процесс, либо подпрограмму); например:
log("Hello world");
Замечание:
Библиотеки UVVM были проверены на Modelsim, Rivera-PRO и GHDL, также должны работать на Questa и Active-HDL и на любых других симуляторах совместимых с VHDL-2008.
Упомянутые скрипты были проверены на Modelsim.
GHDL предоставляет свои скрипты для UVVM.
Стоит отметить, что САПР Xilinx ISE не поддерживает VHDL-2008. VHDL-2008 поддерживается более новой САПР Xilinx Vivado.
Слайд:Структура и архитектура VHDL дизайна
Во время проектирования цифрогового устройства инженеры очень сильно заботятся о наиболее критичных факторах для структуры и архитектуры проекта перечисленных ранее:
- обзорность, читаемость;
- модифицируемость, поддерживаемость и расширяемость;
- отлаживаемость;
- переиспользуемость.
По этим причинам проекты разбиваются на более-менее автономные модули в независимой функциональность, такие как, например, UART, SPI, DMA контроллер, ADC и т.д.
Эти модули (или VHDL enities/components) получают комманды от программы (software) и затем выполняют требуемые задачи, пока программа продолжает выполнение и делает что-то параллельно и совершенно независимо. Если что-то идёт не так, либо модуль нуждается во внимании, то он говорит об этом (обычно с помощью прерывания (interrupt)). В этом подходе хорошо то, что верхний уровень FPGA проекта в таком случае легко понять. Мы видим модули и знаем, что они делают, интерфейсы модуля стандартизированы (например AXI4-lite или Avalon) и запущенная программа контролирует это всё с помощью команд высокого уровня.
Слайд:Структура и архитектура верификации
Очевидно, что структура проекта рассмотренная ранее является чрезвычайно эффективной и способствует хорошему качеству проекта. Однако для VHDL тестбенчей не было такой системы, либо методологии. Это основная причина того, что большинство тесбенчей довольно неструктурированы, и основная причина разработки UVVM.
UVVM отражает структуру дизайна ЦС. В результате мы имеем архитектуру тестбенча, которую легко понять, при этом сохраняются преимущества хорошей можульной стркутуры:
- Верификационные модули с хорошо понимаемой функциональностью интерфейсом;
- Стандартизированная система шин от секвенсера к верификационному модулю;
- Стандартизированный интерфейс шин на для всех верификационных модулей.
Верификационные модули в UVVM называются VVC (VHDL Verification Components). На рисунке ниже 'SBI_VVC' – Simple Bus Interface, но также это мог бы быть интерфейс 'AXI4-lite' или 'Avalon'.

Архитектура UVVM очень похожа на архитектуру FPGA дизайна с внешним программным секвенсером упомянутом ранее. Тестовый секвсенсер раздаёт команды различным VVC, так же, как и программа раздаёт команды FPGA модулям. Затем VVC делают то, что им говорят – так же, как и модули в FPGA. Обычно это означает обработку доступа к их физическому интерфейсу. Например, FPGA модуль может передавать некоторые данные, и на самом деле VVC может делать то же самое. Для нашего примера UART тестбенча, сиквенсер может послать команду на UART TX чтобы передать байт на вход UART RX.