Использование встроенного логического анализатора (ILA) и виртуального ввода/вывода (VIO)
В этом руководстве рассматривается использование Integrated Logic Analyzer (ILA). и Виртуальный ввод/вывод (VIO) ядер для отладки и мониторинга проекта VHDL в Xilinx Vivado IDE.
Во многих случаях разработчикам необходимо выполнять проверку на кристалле. То есть получить доступ к поведению внутреннего сигнала в их конструкции FPGA для целей проверки.
Один из вариантов — подать эти сигналы на выводы FPGA и подключить их к светодиодам, чтобы визуально увидеть их поведение. Этот вариант прост, быстр и хорошо подходит для простых случаев, но он не является гибким, масштабируемым или реалистичным.
Другой вариант — использовать внешний логический анализатор с расширенными функциями, который может отображать и изображать поведение этих сигналов, но для этого требуется внешнее и относительно дорогое оборудование.
Интегрированный логический анализатор (ILA) — это альтернатива, сочетающая в себе преимущества обоих предыдущих вариантов. Это просто, быстро, гибко и имеет множество дополнительных функций, которые помогают разработчикам быстро просматривать и проверять поведение выбранных сигналов.
Обзор
Эта статья содержит несколько скриншотов из графического интерфейса Vivado. Нажимайте на изображения, чтобы увеличить их!
Используйте боковую панель для навигации по структуре для этого руководства или прокрутите вниз и нажмите всплывающую кнопку навигации в правом верхнем углу, если вы используете мобильное устройство.
ИЛА и ВИО
ILA и VIO — это бесплатные настраиваемые IP-адреса от Xilinx. ILA IP помогает легко исследовать внутренние сигналы внутри ПЛИС и выводить их в среду, подобную моделированию, для мониторинга и проверки их поведения.
В отличие от ILA, VIO IP позволяет вам виртуально управлять внутренними сигналами внутри вашей FPGA, чтобы стимулировать или контролировать вашу конструкцию, например, управлять сигналом RESET.
- Интеллектуальная собственность Xilinx:встроенный логический анализатор (ILA)
- Интеллектуальная собственность Xilinx:виртуальный ввод/вывод (VIO)
Требования
- Плата Xilinx FPGA
- Дизайнерский пакет Vivado
- Основные знания VHDL
Я использую оценочный комплект Kintex-7 FPGA KC705, но методы, показанные в этом руководстве, должны работать на любой современной плате Xilinx FPGA.
Скачать пример проекта
Вы можете загрузить пример проекта и код VHDL, используя форму ниже. Он должен работать в Vivado версии 2020.2 или новее.
Распакуйте ZIP-файл и откройте ila_tutorial.xpr. файл в Vivado, чтобы просмотреть пример дизайна, или прочитайте оставшуюся часть этой статьи, чтобы научиться создавать его с нуля.
Создать проект в Vivado
Начните с открытия Vivado. На экране приветствия Vivado нажмите Создать проект. кнопка.
Нажмите Далее. продолжить.
Измените название проекта на ila_tutorial. и нажмите Далее.
Примечание. Не используйте пробелы в имени проекта. Вместо этого используйте подчеркивание или тире.
Выберите проект RTL. и снимите флажок Не указывать источники сейчас. и нажмите Далее продолжить.
Добавьте исходные файлы; counter.vhdl и counter_top.vhdl из папки дизайна. Выберите VHDL. для целевого языка. Установите флажок Копировать исходники в проект. и нажмите Далее продолжить.
Добавьте файл ограничений top.xdc из папки дизайна. Установите флажок Копировать файлы ограничений в проект и нажмите Далее продолжить.
Примечание. этот файл ограничений специфичен для платы KC705. Вам нужно изменить пин-код и индикатор согласно вашей доске. А также -период ваших настольных часов.
Найдите свою доску и выберите ее из списка. Нажмите Далее. продолжить.
Это последний экран мастера создания нового проекта. Нажмите Готово. чтобы открыть свой проект.
Объяснение примера дизайна
В этом уроке мы будем использовать простой пример цепочки из двух счетчиков.
counter.vhdl файл содержит код RTL для тривиального 4-битного счетчика, который считает от 0 до 15, когда он включен. Он устанавливает 1-битный вывод, когда значение счетчика находится в диапазоне от 12 до 15. Для всех других значений вывод остается низким «0». .
Вот интерфейс объекта для модуля счетчика.
---------------------------------------------------------------------------- -- ENTITY DECLARATION. ---------------------------------------------------------------------------- ENTITY counter IS PORT(clk : IN STD_LOGIC; -- Main clock reset : IN STD_LOGIC; -- reset, active_high enable : IN STD_LOGIC; -- enable the next counter trigger : OUT STD_LOGIC -- trigger the next counter ); END ENTITY;
Дизайн счетчика имеет два внутренних сигнала:count . и trigger_o .
– количество используется для реализации функции подсчета.
– и trigger_o является промежуточным сигналом для подключения выходного порта триггер .
Не беспокойтесь об ATTRIBUTE. , это будет объяснено позже.
---------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION. ---------------------------------------------------------------------------- ARCHITECTURE rtl OF counter IS -- INTERNAL SIGNALS DECLARATION -- SIGNAL count : UNSIGNED(3 DOWNTO 0) := (OTHERS => '0'); SIGNAL trigger_o : STD_LOGIC := '0'; -- ATTRIBUTE DECLARATION -- ATTRIBUTE MARK_DEBUG : STRING; ATTRIBUTE MARK_DEBUG OF count : SIGNAL IS "true";
В листинге ниже мы видим реализацию счетчика. seq_proc процесс запускается по переднему фронту входного порта clk и находится в режиме сброса, когда входной порт сбрасывается имеет высокое значение «1».
количество сигнал увеличивается, когда входной порт включен имеет высокое значение «1», а trigger_o сигнал считается высоким, когда значение сигнала count составляет от 12 до 15.
seq_proc: PROCESS (reset, clk) BEGIN -- for seq_proc IF (reset = '1') THEN count <= (OTHERS => '0'); trigger_o <= '0'; ELSIF rising_edge(clk) THEN IF (enable = '1') THEN count <= count + 1; IF (count > x"B" AND count <= x"F") THEN trigger_o <= '1'; ELSE trigger_o <= '0'; END IF; END IF; END IF; END PROCESS;
Файл counter_top.vhdl содержит два последовательно соединенных момента счетчика.
– counter_1_inst всегда включен и отсчитывает counter_2_inst . То есть выходной порт триггер из counter_1_inst подключен к входному порту clk из counter_2_inst .
– В результате поведение counter_1_inst активирует counter_2_inst только 4 из 16 тактов. Таким образом, counter_2_inst будет увеличивать свой счетчик четыре раза каждые 16 отсчетов.
Создание ядра VIO для RESET
Теперь, когда вы понимаете пример дизайна, мы создадим VIO для управления входным портом reset. . Это даст нам возможность манипулировать (переключать) сбросом из Vivado IDE, чтобы мы могли вручную контролировать, когда запускать/останавливать счетчики.
Нажмите Каталог IP. , затем найдите VIO , затем дважды щелкните VIO (виртуальный ввод/вывод). .
Во-первых, мы меняем имя на vio_reset. .
Во-вторых, нам нужен только выходной порт для сброса, поэтому мы обозначили 0 в поле счетчика входных проб. и мы помещаем 1 в поле количества выходных проб .
Нажмите на PROBE_OUT. вкладка порт. Поскольку сброс — это 1-битный сигнал, мы помещаем 1 в поле probe_width, и мы также помещаем 0x1 в поле начального значения поэтому он начинается с высокой «1». Затем нажмите ОК. и Создать . Теперь Vivado начнет синтезировать VIO.
После того, как Vivado завершит синтез VIO, нам нужно добавить его в наш дизайн, объявив для него компонент и создав его экземпляр в файле counter_top.vhdl. файл, как показано ниже.
Сначала добавьте объявление компонента для vio_reset. в разделе объявления компонента в counter_top.vhdl файл.
-- Declare vio_reset COMPONENT vio_reset PORT( clk : IN STD_LOGIC; probe_out0 : OUT STD_LOGIC_VECTOR(0 DOWNTO 0) ); END COMPONENT;
Теперь VIO готов, и мы готовы синтезировать дизайн. Но перед этим нам нужно изменить настройку синтеза flatten_hierarchy. на Нет .
Нажмите Запустить синтез. а затем ОК .
Когда Vivado завершит синтез, нажмите Открыть синтезированный дизайн. .
Измените макет на отладка нажав Макет а затем Отладка .
Вставка потока проверки отладки
Наш синтезированный дизайн теперь содержит vio_reset instance, и пришло время указать сигналы, которые мы хотим исследовать. Это можно сделать тремя способами:
- Вставка из файла VHDL
- Вставка из списка соединений
- Вставка из файла xdc/tcl
Мы будем использовать первые два метода, а третий оставим для дальнейшего изучения.
Вставка из файла VHDL
Этот метод — самый простой и быстрый способ вставить зонд, особенно если он составного типа (массив или запись). Но это требует добавления кода в файлы дизайна, кода VHDL, который является избыточным в реальном продукте.
Мы можем вставить зонд в файл проекта VHDL следующим образом:
- Объявление специального атрибута с именем MARK_DEBUG
- Прикрепите сигнал, который мы хотим исследовать, с помощью этого атрибута
- И активируйте его, присвоив ему значение «true», как показано ниже:
-- ATTRIBUTE DECLARATION -- ATTRIBUTE MARK_DEBUG : STRING; ATTRIBUTE MARK_DEBUG OF count : SIGNAL IS "true";
Примечание. нам нужно объявить атрибут только один раз в каждом файле проекта VHDL, что позволит нам прикрепить его к нескольким сигналам.
Из синтезированного дизайна видно, что сигнал количество в обоих counter_1_inst и counter_2_inst перечислены в разделе Неназначенные сети отладки. и помечен значком ошибки как в Netlist и Схема .
Вставка из списка соединений
Этот метод вставки также прост, но он требует, чтобы вы сначала синтезировали проект, а затем вручную щелкали по каждому сигналу, чтобы пометить его для отладки. Это может быть утомительно, если дизайн большой и вы хотите отслеживать много сигналов.
Мы проверим триггер выходного порта. в обоих счетчиках с помощью Netlist . Мы можем сделать это либо из окна Netlist или Схема найдя сигнальную сеть, а затем щелкните правой кнопкой мыши на нем и выберите Отметить отладку. .
В окне Netlist найдите триггер. в разделе counter_1_inst → Сети → триггер . Затем щелкните его правой кнопкой мыши и выберите Отметить отладку. .
В окне схемы найдите триггер. вывод из counter_2_inst . Затем щелкните его правой кнопкой мыши и выберите Отметить отладку. .
Мы видим, что теперь они перечислены в разделе Неназначенные сети отладки. .
Создание ядра отладки ILA
Теперь пришло время создать ядро отладки ILA. Нам нужно создать пробник для каждого сигнала, который мы хотим проанализировать. Самый простой способ — воспользоваться мастером Vivado Set Up Debug. .
Нажмите Настроить отладку. а затем нажмите Далее. .
Vivado перечислит все сигналы отладки и автоматически захватит домен часов. Здесь мы видим, что наши четыре сигнала перечислены. Вы можете удалить сигналы, которые вам не интересны, или добавить лишние сигналы, но мы будем использовать их все.
Примечание. нам не нужно использовать все сигналы, которые мы пометили как отладочные.
Нажмите Далее. .
Теперь настроим ILA, выбрав глубину FIFO. и установите флажок Захват управления. . Мы можем оставить FIFO равным 1024, поскольку для нашего примера этого достаточно.
Нажмите Далее. .
Теперь мы видим, что Vivado нашла одни часы и создаст одно отладочное ядро.
Нажмите Готово. .
Теперь мы можем видеть ядро отладки ILA с четырьмя зондами, добавленными на вкладку отладки. и окно Netlist .
ВАЖНО: Очень важно сохранить ограничение на этом этапе, чтобы его можно было добавить в проект. В противном случае мы рискуем потерять ядро ILA.
Нажмите кнопку Сохранить. или нажмите Ctrl+S.
Назовите файл ila_core. и нажмите ОК .
ila_core.xdc файл будет добавлен к ограничению и включает в себя код и настройки для ILA.
Давайте посмотрим на содержимое файла. Вы можете открыть файл, перейдя в окно исходного кода → разверните папку ограничений → разверните constr_1. .
Во-первых, мы видим, что файл добавляет атрибут отладки к сигналам, которые мы пометили как отладочные с помощью вставки списка цепей.
Далее мы видим создание и настройку ядра ILA.
Далее мы видим создание, настройку и подключение для каждого зонда.
Далее мы видим создание концентратора отладки (dbg_hub ).
Концентратор отладки отвечает за связь между Vivado IDE и ядрами отладки (ILA и VIO). Мы видим, что он определяет тактовую частоту (по умолчанию 300 МГц). Вам нужно изменить эти часы, чтобы они соответствовали вашей тактовой частоте, и сохранить файл.
Примечание. часы, подключенные к ILA и Debug_hub, должны быть автономными.
Теперь ILA завершена и сохранена. Нам нужно повторно запустить синтез, чтобы можно было добавить ILA к синтезированному дизайну.
Нажмите Запустить синтез. а затем ОК .
Когда Vivado завершит синтез, нажмите Открыть синтезированный дизайн. а затем на Схема .
Теперь мы видим, что Vivado добавила в наш дизайн ILA и Debug_Hub и подключила сигналы отладки к датчикам ILA.
Теперь мы готовы реализовать наш проект и сгенерировать битовый поток, чтобы мы могли его протестировать.
Нажмите Выполнить реализацию . а затем ОК .
После того, как Vivado завершит реализацию, нажмите Создать битовый поток. а затем ОК .
После того, как Vivado завершит создание битового потока, нажмите Открыть диспетчер оборудования. а затем на Открыть цель, и, наконец, Автоматическое подключение. .
Далее нам нужно запрограммировать FPGA с битовым файлом (*.bit) и файлом отладочного зонда (*.ltx). Vivado автоматически найдет их для вас.
Нажмите Запрограммировать устройство. а затем в Программа .
Настройка триггеров ILA
После программирования устройства мы видим, что макет графического интерфейса Vivado изменился, а новый hw_ila_1 панель инструментов открылась, содержащая несколько окон.
Мы уменьшим некоторые окна, которые нам не нужны, чтобы нам было удобно работать.
В параметрах панели управления выберите hw_vio_1. и снимите флажок Настройка захвата. .
Кроме того, закройте hw_vios вкладку, потому что когда мы проверили hw_vio_1 , он был добавлен в Настройку триггера. окно.
Теперь нам нужно добавить сброс кнопку на VIO, чтобы мы могли управлять сбросом .
Нажмите hw_vio_1 а затем добавьте сброс как показано на рисунке ниже.
Мы видим, что hw_vio_1 теперь содержит сброс зонд.
Измените значение сброса in vio_reset на 1, если это не 1.
Теперь мы добавим триггеры, которые будем использовать. Изменение значения триггерного сигнала приведет к тому, что ILA начнет запись исследуемых сигналов.
Допустим, мы хотим запустить (начать запись) по переднему фронту выходного порта trigger. из counter_1_inst . Для этого выполните следующие действия:
- Перейдите к Настройке триггера — hw_ila_1 окно
- Нажмите + значок, чтобы добавить новый триггер, и выберите counter_1_inst/trigger. и нажмите ОК.
- Мы видим, что триггер добавлен, и теперь нам нужно настроить условие. Нажмите на поле Значение . и выберите R (переход от 0 к 1) . Нажмите на поле Оператор . и выберите ==(равно)
Мы также изменим положение триггера на 32, что означает, что он будет записывать 32 сэмпла до события триггера в дополнение к тому, что следует после него.
Теперь триггер настроен и готов к срабатыванию.
Теперь мы переходим к окну сигнала. чтобы добавить сигналы, которые мы хотим просмотреть. Во-первых, давайте увеличим внутреннее окно, чтобы получить лучший обзор.
Во-вторых, нам нужно добавить в зонд несколько недостающих сигналов. Обычно Vivado автоматически добавляет все назначенные сигналы, но в данном случае этого не произошло.
Теперь мы изменим основание числа count. сигнал для Unsigned, поскольку за ним легче следить.
Щелкните правой кнопкой мыши количество. имя сигнала, а затем выберите основание счисления а затем Без подписи .
Запуск ILA и VIO
Теперь мы закончили настройку и настройку ILA и готовы запустить ее.
ILA имеет два режима работы:Немедленно и триггер .
Немедленный режим
Немедленный режим немедленно запускает ILA и начинает запись сэмплов напрямую, пока FIFO не заполнится.
Нажмите Запустить триггер немедленно. кнопка.
Теперь мы можем видеть записанные образцы в окне сигнала. Мы видим, что оба считаются сигналы 0, и оба триггер сигналы низкие «0» потому что сброс активен.
Режим запуска
Режим триггера требует, чтобы мы установили условие хотя бы для одного триггера и активировали его. ILA будет продолжать ждать, пока состояние активированного триггера не станет истинным, а затем начнет запись сэмплов напрямую, пока FIFO не заполнится.
Мы уже добавили триггер и настроили его на R (переход от 0 к 1). .
Запуск ILA с одним триггером
Изменить сбросить вернуться к 1 из vio_reset .
Нажмите на окно Статус hw_ila_1. . Мы видим, что статус ядра — Idle. так как нет спусковых крючков. Нажмите Выполнить триггер. кнопку, и это активирует триггер.
Теперь мы видим, что статус ядра изменился на ожидание триггера. . После сброса высокий, сигнал триггера не активен (порт триггер из counter_1_inst ), и ILA ждет.
Теперь давайте изменим сброс до 0 чтобы счетчики начали работать.
Теперь мы видим, что ILA сработала и записала образцы, а статус ядра снова изменился на Idle. .
Мы видим красную вертикальную линию (маркер) на переднем фронте нашего триггерного сигнала (порт триггер из counter_1_inst ) и находится на позиции 32. . Мы также можем убедиться, что сигнал количество ведет себя правильно и сигнал counter_1_inst/trigger имеет высокий уровень в течение четырех тактов между 12 и 15 (выход задерживается на один такт).
Если мы немного уменьшим масштаб, мы также сможем проверить поведение count и триггер сигналы для counter_2_inst .
Запуск ILA с несколькими триггерами
Мы можем использовать комбинацию триггеров для сложных или сложных состояний. Чтобы зафиксировать несколько непересекающихся временных рамок в одном и том же сигнале, мы можем использовать несколько триггеров, которые срабатывают многократно.
Например, предположим, что мы хотим срабатывать, когда количество сигнал от counter_1_inst равно 9 (count ==9) и когда count сигнал от counter_2_inst больше 2 (количество> 2). Чтобы сделать это и разделить FIFO на четыре временных окна, выполните следующие действия:
- Изменить сброс вернуться к 1 из vio_reset
- Удалить предыдущую проверку триггера:
- Добавить оба количества сигналы как триггеры:
- Настройте количество сигналов для counter_1_inst до (количество ==9):
- Настройте количество сигналов для counter_2_inst до (число> 2):
- Установите количество окон на 4. и глубину FIFO до 256 и позиция до 32 .
- Нажмите кнопку Выполнить. кнопку, и это взведет курок. Обратите внимание, что в окне Статус hw_ila_1 , статус захвата теперь окно 1 из 4 потому что у нас четыре окна.
Изменить сбросить вернуться к 0 из vio_reset .
Maximize the waveform window. We see now that we have four windows and a trigger associated with each window. Notice that these windows are independent and not continuous.
The ILA waits for the trigger event to happen, and when it does, the ILA uses the first window to record 256 samples. It then immediately waits for the next trigger until all the windows are full.
Running ILA with Auto re-trigger mode
ILA has a nice feature called Auto re-trigger that will automatically arm the trigger after it gets triggered. It is useful when monitoring events that occur seldom and you want to run a test overnight. Or you can use it when the trigger happens so often and fast that you cannot arm the trigger manually to capture the samples repeatedly.
Let us assume that the output port trigger of counter_2_inst gets asserted every 3 hours, and you want to record the data each time it happens. To use the Auto trigger, follow these steps:
- Change reset back to 1 from vio_reset
- Remove the previous trigger probe
- Add trigger_2_OBUF signal as trigger:
- Configure the trigger to the condition to equal (==) and falling edge F(1-to-0 transition)
- Configure the number of windows to 1 and FIFO depth to 1024, and position to 32:
- Click on Auto re-trigger button:
- Finally, change reset back to 0 from vio_reset:
We can see now that the waveform window is getting refreshed and updated as the trigger happen. It is fast, but the behavior is noticeable.
Click on Stop trigger and toggle Auto re-trigger .
Running ILA with Capture mode
Another feature of ILA is the Capture mode . In some cases, you are not interested in recording all the data but rather capture a specific sample. Capture mode helps you filter out data and record only the samples you are interested in.
Let’s say we are only interested in sampling when the output port trigger of counter_1_inst is ‘1’ AND the output port trigger of counter_2_inst is ‘0’.
To use Capture mode to achieve this, follow these steps:
- Change reset back to 1 from vio_reset
- Remove the previous trigger probe
- From the dashboard, Uncheck Trigger Setup and check Capture Setup . Notice that a Capture Setup window will appear. From the Settings – hw_ila_1 window, Change Capture mode to BASIC , the window to 1, the FIFO depth to 1024, and position to 1:
- Add trigger_2_OBUF , and counter_1_inst/trigger from the Capture Setup window:
- Configure counter_1_inst/trigger to the condition equal (==) and 1 (logical one) :
- Configure trigger_2_OBUF to the condition equal (==) and 0 (logical zero) :
- Change the Capture Condition to Global AND :
- Click on the Run trigger button and then change reset to 0 from vio_reset :
As we can see from the image below, the waveform has only recorded data when counter_1_inst’s count signal is 13, 14, 15, or 0. Any other counts are filtered out because counter_1_inst/trigger is high on these counts only.
Conclusion
In this tutorial, we learned about ILA and VIO and different use-cases for them. ILA and VIO are excellent options for on-chip debugging. They are free, easy to use, flexible, scalable, and simple yet offer advanced features. The use of multiple triggers and Capture mode helps you achieve a complex debugging scheme.
VHDL
- Учебное пособие - Написание комбинационного и последовательного кода
- В облако бесконечности и дальше
- Базовый ввод и вывод C#
- Базовый ввод/вывод C++
- C Вход Выход (ввод/вывод)
- Ввод, вывод и импорт Python
- Базовый ввод и вывод Java
- D-защелка
- C - Вход и выход
- RightHand Robotics и Element Logic запускают интегрированное роботизированное решение для сбора деталей