В среднем половина времени разработки для ПЛИС тратится на верификацию. Мы знаем, что разработка архитектуры важна и для качества проекта, и для времени разработки. Таким образом очевидно, что то же применимо и к тестбенчу. Кроме того интересен факт того, что половина времени верификации тратится на отладку. Это значит, что потенциально можно улучшить верификацию в общем и отладку в частности, и уменьшить временные затраты. Методология UVVM (the open source Universal VHDL Verification Methodology) была разработана чтобы решить эту проблему и значительно уменьшить время верификации, тем самым улучшая качество продукта. UVVM предоставляет очень простую и мощную архитектуру, которая позволяет разработчкам строить их собственные тестбенчи и тестовые сценарии намного быстрее. Полезные ссылки:
Далее рассмотрим на сколько просто понять и начать исползовать предложенную методологию. Также рассмотрим как UVVM поможет нам сделать лучше тестбенчи и в то же время уменьшить рабочую нагрузку.
Основные поставщики САПР говорят о пробеле в верификации и предоставляют решения чтобы решить эту проблему. К сожалению, они предпочитают решение, которое является сложной методологией, называемой UVM (Universal Verification Meyhofology). Эта методолгоия требует изучения дополнительного языка SystemVerilog и покупкт очень дорогих инструментов. Подовляющее большенство FPGA разработчиков в Европе используют VHDL для разработки и верификации (60% и 50% соответвенно во всём мире) и нет причин менять это.
UVVM на самом деле копирует некоторые принципы из UVM и таким образом можно рассматривать UVVM как упрощённую VHDL версию UVM. VHDL является достаточно мощным языком для большенства FPGA проектов и позволяет разработчикам продолжать использовать известный им язык, а затем шаг за шагом просто добавлять функциональность по мере необходимости. Другими словами, ваш тесбенч и язык мягко и эффективно эволюционирует, но возможностей и функциональности самих по себе не достаточно: структура и архитектура яывляются ключевыми для абсолютно всех аспектов хорошей FPGA разработки.
Люди часто говорят об эффективном написании кода, но это не правильный фокус. Написание кода - это маленький фрагмент сложного модуля, либо FPGA разработки, отличие одного подхода от другого имеет относительно небольшой эффект на общую эффективность разработки. Что на самом деле важно:
Если мы углубимся в деталли шаг за шагом, то мы увидим что некоторая функциональность всегда требуется для любого хорошего тестбенча:
Это всё и многое другое поддерживается в библиотеке "UVVM Utility", которая входит в 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 с различными примерами, документацией и дополнительной информацией можно скачать из репозитория github https://github.com/UVVM/UVVM . Ниже приведём список шагов, которые необходимо выполнить чтобы начать работу с UVVM Utility library:
Замечание:
Библиотеки UVVM были проверены на Modelsim, Rivera-PRO и GHDL, также должны работать на Questa и Active-HDL и на любых других симуляторах совместимых с VHDL-2008.
Упомянутые скрипты были проверены на Modelsim.
GHDL предоставляет свои скрипты для UVVM.
Стоит отметить, что САПР Xilinx ISE не поддерживает VHDL-2008. VHDL-2008 поддерживается более новой САПР Xilinx Vivado.
Во время проектирования цифрогового устройства инженеры очень сильно заботятся о наиболее критичных факторах для структуры и архитектуры проекта перечисленных ранее:
По этим причинам проекты разбиваются на более-менее автономные модули в независимой функциональность, такие как, например, 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.
В UVVM существует два пути для доступа к интерфейсу DUT (Device Under Test). Наиболее простой это использование базовых процедур BFM (Bus Functional Model - функциональная модель шины), как показано в строке кода ниже, где последний параметр служит как комментарий к строке кода, и при необходимости записывается в лог.
-- UART transmission command — as a BFM uart_transmit(x"4C", "Apply byte on UART RX"); |
Эта процедура будет выполнена напрямую из процесса, где она была запущена, и применит данные x4C на шину UART RX, используя UART протокол. Это значит, что если тестовый секвенсер вызывается данной процедурой, то он применит UART протокол бит за битом. Это займёт некоторое время, в течение которого тестовый секвенсер юудет занят и не сможет делать ничего другого.
Более продвинутый вариант называется CDM (Command Distribution Method – метод распределённых комманд). В этом случае, когда секвенсер вызывает данную процедуру, команда немедленно отправляется в VVC, который задан целевым адресом (помечен красным цветом), который определяется именем и номером экземпляра VVC, который должен выполнить эту команду.
-- UART transmission command — using VVCs uart_transmit(UART_TX_VVCT,1,x"4C", "Apply byte on UART RX");
Передача команды от тестового секвенсера в VVC не занимает времени, это значит что секвенсер освобождается немедленно и может делать что-то другое, например инициировать доступ по другому интерфейсу. VVC позаботится о занимающем время протоколе UART.
Код ниже показывает как можно написать очень маленький тест чтобы проверить одновременный доступ по всем интерфейсам. Этот пример из немного другого тестбенча, здесь VVC для UART TX и RX объединены в общий VVC для более удобного использования. Для этого случая было решено использовать дополнительный параметр для обозначения канала (RX или TX).
sbi_write(SBI_VVCT,1, C_ADDR_TX_DATA, x"A0", "Send byte UART TX"); uart_expect(UART_VVCT,1,RX, x"A0", "Check byte from UART TX"); uart_transmit(UART_VVCT,1,TX, x"A1", "Apply byte on UART RX"); wait for C_FRAME_PERIOD; sbi_check(SBI_VVCT,1, C_ADDR_RX_DATA, x"A1", "Check UART RX byte"); |
Во любом FPGA проекте важно иметь хорошую архитектуру верхнего уровня, однако этого недостаточно. Не менее важно иметь хорошую микроархитектуру на всех уровнях. Это применимо и для тестбенчей, и это значит, что архитектура VVC должна быть так же проста для понимания, модификации и переиспользования. И опять же – стандартизация была бы замечательна. Базовый компонент VVC состоит из блоков в желтом прямоугольнике, и это применимо абсолютно ко всем VVC.
VVC будет смотреть на CDM выше и принимать только команды, которые являются целевыми для конкретно этого VVC. Затем он поместит команду uart_transmit() в очередь и отпустит тестовый секвенсер. Executor будет выбирать команды из очереди, увидит что это команда uart_transmit(), и затем выполнит эту команду с помощью BFM используя переданные параметры.
Очень структурированная архитектура VVC даёт дополнительное преимущество. Это преимущество в том, что легко добавлять более структурированную функциональность: неважно, либо для более сложных интерфейсов, либо чтобы просто включить более удобную функциональность (как, например, различные проверки). Протокол с раздельными транзакциями, такой как Avalon MM, часто приводит к хаотичным тестбенчам, поскольку там может быть несколько запросов на чтение до получения первого ответа на чтение. Используя же VVC архитектуру рассмотренную ранее и это можно сделать достаточно просто и очень структурировано. Базовый 'executor' выбирает команды из очереди и знает, что это доступ с разделёнными транзакциями. Таким образом он вызывает процедуру запроса BFM, и в то же время передаёт команду чтения в следующую очередь. Ответный 'executor' заберёт эту команду и затем просто вызовет BFM проедуру для получения ответа на чтение и будет ждать ответа. Таким образом, может быть любое число запросов на чтение между любыми ответами на чтение, и пр иэтом всё достаточно просто и наглядно.
UVVM предоставляет скрипт для того чтобы сгенерировать VVC для новых интерфейсов. Сгенерированный код – это шаблон, в котором ясно отмечено, где пользователю необходимо добавить его собственные BFM и различные адаптации. Учитывая процедуры BFM, которые в любом случае пользователь должен описать для любого тестбенча, создание VVC с нуля должно занять около 30 минут. Если верить Doulis, то немного дольше в первый раз, но возможно 30 минут хватит в следующий раз.
Подводя итог, наиболее важные части тестбенча следующие:
Первый пункт лежит на библиотеке UVVM Utility. Довольно структурированная архитектура (на верхнем уровне и внутри VVC) заботится о следующих двух пунктах. В то время, как последний и вероятно самый важный пункт (поскольку здесь надо будет потратить большую часть времени) выполняется, позволяя высокоуровневым и легко понимаемым командам контролировать весь тестбенч, включая одновременную активность на многих интерфейсах.
Для FPGA дизайна, сандартизация в течение нескольких десятилетий, используя хорошую концепцию архитектуры с регистрами управления и состояния, системой шин, автономными модулями и высокоуровневыми программными командами, привела к эффективной методолгии проектирования устройст на FPGA, а также к эффективной разработке программного обеспечения, поскольку программистам не нужно разбираться в деталях модулей, которыми они управляют. Это может казаться очевидным, что для тестбенчей проектов на FPGA мы имеем похожий сценарий, где секвенсер контроллирует множество интерфейсов. Однако VHDL тестбенчи не были стандартизированы до UVVM. Нже список того, что предоставляет UVVM , и даже стандартизирует наиболее важные аспекты:
Ранее мы рассмотрели как начать работу с UVVM Utility library, рассмотрели общую концепцию работы с VVC и общую структуру тестбенча. В UVVM входит следующий набор библиотек.
Library | Description | Location |
---|---|---|
UVVM Utility Library | UVVM Utility Library is an open source VHDL test bench (TB) infrastructure library for verification of FPGA and ASIC.
Used by VVC FRAMEWORK as a common testbench infrastructure.
For more information on UVVM Utility Library and latest release please visit http://www.bitvis.no/products/uvvm-utility-library/ For UVVM v0.2.0 the UVVM Utility Library is compatible with Bitvis Utility Library (for VHDL 2008), and hence the current documentation for Bitvis Utility Library still applies. New features of UVVM Utility Library will be described soon. |
<install_dir>/uvvm_util |
UVVM VVC Framework | The library for the VVC Framework with the functionality described in this document. | <install_dir>/uvvm_vvc_framework |
bitvis_vip_sbi | VIP including a BFM and VVC for a simple bus interface (SBI). This VVC is intended as a template for writing new VVCs and for understanding the VVC functionality.
This library is also used in the provided testbench example. |
<install_dir>/bitvis_vip_sbi |
bitvis_vip_uart | VIP including a BFM and VVC for a simple UART interface. This VVC may be used as a template for writing new VVCs for multi-channel interfaces.
This library is also used in the provided testbench example. |
<install_dir>/bitvis_vip_uart |
bitvis_uart | This is a simple UART design that is being used as a DUT for the provided example testbench | <install_dir>/bitvis_uart |
bitvis_vip_axilite | VIP including BFM and VVC. This simple AXI4-Lite BFM and VVC is provided as a kick start for users to make their own testbenches using VVC FRAMEWORK, as many designs today have an AXI4-lite interface. | <install_dir>/bitvis_vip_axilite |
bitvis_vip_avalon_mm | VIP including a BFM and VVC for an Avalon-MM interface. | <install_dir>/bitvis_vip_avalon_mm |
bitvis_vip_axistream | VIP including a BFM and VVC for a simple AXI-Stream interface. | <install_dir>/bitvis_vip_axistream |
bitvis_vip_i2c | VIP including a BFM and VVC for a simple I2C interface. | <install_dir>/bitvis_vip_i2c |
bitvis_vip_spi | VIP including a BFM and VVC for a simple SPI interface. | <install_dir>/bitvis_vip_spi |
bitvis_vip_gpio | VIP including a BFM and a VVC for a simple GPIO interface. | <install_dir>/bitvis_vip_gpio |
uvvm_osvvm | A UVVM compatible version of OSVVM | <install_dir>/uvvm_osvvm |
Для работы с VVC нам понадобится UVVM VVC Framework, который является частью UVVM. Установка и компиляция VVC Framework
Если вы хотите запустить пример тестбенча, который идёт в комплекте с UVVM, то вам следует выполнить несколько дополнительных действий
Международные игроки с сильным интересом в VHDL и верификации сейчас принимают UVVM. Два основных симулятора VHDL, Aldec и Mentor Graphics, оба показывают большой интерес, Aldec уже провёл несколько вебинаров по UVVM (https://www.aldec.com/en/downloads/private/920 и https://www.aldec.com/en/downloads/private/1158). И Mentor включил презентации UVVM в их "FPGA verification day" (https://trias-mikro.de/en/dates/fpga-verification-day/). Doulos, лучший международный постовщик тренингов для FPGA и ASIC методологий, рекомендует UVVM для FPGA тестбенчей. Последним свидетельством того, что UVVM на самом деле набирает обороты, является то, что ESA (European Space Agency – Европейское космическое агенство) теперь UVVM спомощью контракта на более чем 250 000 евро на расширение UVVM, и может рекомендовать своим постовщикам использовать UVVM для верификации FPGA проектов (https://indico.esa.int/event/232/contributions/2159/). То, что UVVM набирает обороты – это сильное преуменьшение. Со второго квартала 2016 по второй квартал 2018 года (между двумя исследованиями Wilson Research Group https://www.mentor.com/products/fv/events/the-2018-wilson-research-group-asic-and-fpga-functional-verification-study) количество пользователей UVVM во всём мире резко вырасло – с долей процента в 2016 году до 10% от всех FPGA разработчиков во втором квартале 2018 года и продолжает расти.
UVVM поддерживается любыми совместимыми с VHDL-2008 симуляторами. Для опенсорс сообщество будет хорошей новостью то, что GHDL был обновлён для работы с UVVM (https://github.com/ghdl/ghdl).
Дополнительно был создан новый репозиторий для внешнего вклада в UVVM(https://github.com/UVVM/UVVM_Community_VIPs) и обмена верификационными компонентами.
Проект европейского космического агенства предоставит несколько новых и важных функций для UVVM. Некоторые уже были предоставлены, например, легко используемый, гибкий и конфигурируемый Scoreboard, и некоторые всё ещё разрабатываются, такие как watchdogs, механизм инжекции ошибок, улучшенный контроль рандомизации и функционального покрытия, и более удобная система подключения DUT моделей к harness тестбенча.
Наиболее важная функциональность, которая скоро появится – иерархические верификационные компоненты. Это позволит решить проблему использования scoreboards для проверки данных, которые проходят через DUT, когда слой коммуникации различный с двух сторон, например, когда ввод с одной стороны ориентирован на слова или байты, как в AXI4-lite или Avalon, а выход с другой стороны ориентирован на пакеты, как например Ethernet. Ирерархические верификационные компоненты позволят легко обрабатывать такие сценарии.
Кроме того, UVVM постоянно обновляется, добовляя незначительную функциональность за пределами проекта ESA, и в настоящее время разрабатываются планы для дальнейших небольших и крупных расширений.
Структурированная верификация является очень важной для эффективности, качества и повторного использования. UVVM – открытый проект, который предоставляет очень струкртурированную методологию и библиотеку. UVVM даже предоставляет открытые VVC и BFM для UART, I2C, SPI, SBI, AXI4-Lite, AXI4-steam, GPIO и Avalon MM. Это даёт возможность для отличного старта любого проекта, который использует эти (либо аналогичные) периферийные устройства.