fpga-systems-magazine

ECO Flow в Vivado или работа в режиме редактирования нетлиста. Часть 1.

Главная » Статьи » Xilinx » Xilinx Vivado
KeisN13
27.09.2019 05:59
5005
0
0.0

Оглавление

Продолжение во второй части
  • 4. Переход в режим ECO 
  • 5. ECO: описание интерфейса 
  • 6. Внесение изменений в проект 
    • 6.1. Создание новых элементов в нетлисте 
    • 6.2. Изменение свойств/параметров компонентов
    • 6.3. Подключение других цепей к пробникам и ILA 
    • 6.4. Замена портов ввода/вывода 
  • 7. Сравнительный анализ 
  • 8. Заключение 
  • 9. Домашнее задание 
  • Библиографический список 
 

В статье очень много картинок не в спойлерах (140 штук). Пожалуйста, будьте внимательны, если заходите с телефона

Аннотация

В статье рассмотрен режим работы Vivado, позволяющий вносить изменения в проект на уровне редактирования списка соединений (в дальнейшем – нетлиста). Описаны как сам режим ECO, так и некоторые нюансы, которые появляются во время работы в нём. Приведён демонстрационный пример и описана полная последовательность действий для получения результата, в работоспособности которой может убедиться каждый желающий. Статья будет полезна для «общего развития» FPGA-разработчикам, а особенно — тем, кто часто отлаживает проекты в Logic Analyzer. Надеюсь, работа в этом режиме вызовет интерес у разработчиков, работающих с большими кристаллами, время компиляции в которых может достигать часов (а то и десятков часов), поскольку в этом режиме время, затрачиваемое на имплементацию, при внесении изменений в нетлист может сократиться до буквально пары минут.

 

 

Введение

 
Зачастую, когда мне приходится читать лекцию или вести семинар, я всегда стараюсь рассказать несколько больше, нежели предполагает программа. Так было на последних трёх семинарах, посвящённых работе с одноядерными Zynq-7000S. В этот раз было интересно посмотреть, насколько аудитория знает о некоторых «скрытых» режимах работы с Vivado. Вопрос был достаточно прост: «Кто-нибудь из присутствующих знает про режим ECO Flow?» Сразу за вопросом последовал, что называется, «лес рук, чему я особенно не удивился.

Желание несколько просветить разработчиков хотя бы о наличии этого режима в Vivado, не говоря уже о демонстрации работы в нём, появилась у меня очень давно. Но по какой-то загадочной причине, я «впрягся» в написание руководств по сборке проектов с использованием MicroBlaze и работе с ним. Однако, после недавних семинаров стало очевидно, что писать про ECO Flow всё таки нужно.

Цель статьи – дать общее представление о режиме ECO в среде Vivado [1], предоставляемой компанией Xilinx для своих кристаллов и показать на реальном примере работу в этом режиме, стараясь указать «тонкие» моменты и проанализировать его достоинства и недостатки.

Задачи, которые поставлены в этой статье:
  1. разработать тестовый пример, по возможности содержащий и демонстрирующий все (или хотя бы большинство) возможностей работы в режиме ECO;
  2. выполнить имплементацию проекта;
  3. пояснить понятие Design Checkpoint;
  4. описать переход в режим работы ECO;
  5. внести правки в нетлист и получить файл прошивки FPGA;
  6. убедиться в корректности внесенных изменений;
  7. составить сводную таблицу времени, затрачиваемого на стандартное внесение изменений в проект и сравнить его со временем, затрачиваемым в режиме ECO, а также инкрементной имплементации.

К сожалению, физически проверить методологию на достаточно «тяжёлом» кристалле (например, Virtex UltraScale) у меня возможности нет. Но, думаю, даже тот пример, который будет приведен – с проверкой на скромном Artix-7, установленном на плате Arty [2], окажется достаточно показательным. В процессе написания я буду опираться на несколько основных документов, в которых описан режим ECO [3], [4], [5]. Используемая версия Vivado (и, соответственно, документации) – 2017.4.

Небольшое отступление: да в руководстве много картинок и «банальщины» о том, как создать проект, собрать процессорную систему на MicroBlaze, работе в IP Integrator, отладке и т.д. Если Вы опытны и просто хотите прочитать об ECO – пожалуйста, перейдите сразу к главе 4: «Переход в режим ECO». Если же Вы не знаете, как собирать проект на MicroBlaze, ни разу не работали в IP Integrator, или любите руководства в стиле пошаговых иллюстраций – буду только рад, если Вы уделите дополнительные 75-90 минут представленному материалу. И, всё же, я надеюсь, что кто-нибудь выполнит руководство полностью, с проверкой в железе.

1. ECO: краткий обзор

ECO – Engineering change orders [6] («порядок внесения инженерных изменений») – это режим, в котором возможно внести изменения в нетлист, синтезированного или имплементированного проекта с минимальным влиянием на исходный нетлист. В Vivado имеется режим ECO, в котором возможно изменять так называемые Design Checkpoint проекта(см. далее), имплементировать внесённые изменения, выполнять генерацию необходимых отчётов для изменённого нетлиста и генерировать по нему файл прошивки FPGA.

Наиболее типичное применение данного режима:
  • Изменение пробников и подключаемых линий логических анализаторов (ILA – IntegratedLogicAnalyzer) при отладке проекта. Пользователь может изменить набор подключаемых к ILA линий, избежав при этом полной повторной имплементации проекта.
  • Переназначение цепей, подключенных к ножкам ПЛИС. В случае, если разработчиком проекта, схемотехником или разработчиком печатной платы была допущена ошибка в назначении ножек (например, rx перепутан с tx), а проект на FPGA уже был имплементирован, таким способом можно выполнить переназначение портов в нетлисте, избежав повторной полной имплементации (т. е. синтеза, мапинга, оптимизации, размещения, трассировки – со всеми сопутствующими затратами машинного времени и ресурсов) проекта.
  • Выполнение анализа «Что_если?» (редактирование содержимого памяти, изменение функционала LUT, улучшение таймингов и т.д.)

Основная задача работы в режиме ECO – экономия времени и избегание повторной имплементации проекта, при внесении изменений на этапе настройки или отладки проекта. Многие знакомы с режимом инкрементной имплементации, который в ECO также используется, однако в ECO, по сравнению с инкрементной имплементацией, быстрее удаётся получить файл прошивки и быстрее выполнить текущую итерацию отладки.

Примечание: работа в режиме ECO возможна только с Design Сheckpoint.

2. Design Сheckpoint

Маршрут проектирования делится на несколько составных частей:, включая синтез и имплементацию. Имплементация в свою очередь делится на подэтапы: различные оптимизации, размещение и трассировку. Промежуточные этапы маршрута проектирования при этом сохраняются в некий «контейнер», который называется Design Checkpoint (DCP) [7]. Это файл, имеющий расширение «.dcp». Design Checkpoint содержит:

  • Текущий нетлист (в зависимости от этапа маршрута проектирования), включая все оптимизации, выполненные до записи dcp-файла.
  • Ограничения, наложенные на проект (design constraints).
По умолчанию, Vivado создаёт четыре файла dcp: один – на этапе синтеза модуля верхнего уровня проекта (если выполняется синтез в режиме out-of-context, то для всех модулей, которые синтезируются в out-of-context, создается свой файл dcp) и три – на этапе имплементации. Эти файлы можно найти в папках:
«Название_проекта.runs/название_синтеза/название_топ_модуля.dcp»

«Название_проекта.runs/название_импелементации/».

На рис. 1 показан пример расположения и файлы .dcp, которые создаются по умолчанию для некоторого абстрактного проекта.

1_0

1_1
Рисунок 1 – создаваемые по умолчанию dcp-файлы (1 – «постсинтез-» и 3 – «постимплемент-»: после оптимизации (_opt), после размещения (_placed) и после трассировки (_routed))

В проектном режиме работы с Vivado (Project Mode [8]) файлы .dcp создаются автоматически. Но при работе в непроектном режиме (Non-ProjectMode [8]) пользователь сам должен следить за тем, чтобы «снимки» текущего состояния проекта записывались. Для этого следует использовать соответствующие Tcl команды [9, 10].:

write_checkpoint <file_name>.dcp
read_checkpoint <file_name>.dcp

 
О том, зачем, как и какие файлы dcp следует открывать, будет рассказано далее.

3. Разработка тестового проекта

Чтобы продемонстрировать на тестовом проекте возможности ECO, он должен содержать следующее:
  1. Элементы, которых нет в исходном нетлисте или элементы, у которых можно изменять функционал. Например, завести светодиод на кнопку – и в исходном проекте он будет загораться по нажатию, а в измененном – по нажатию он будет гаснуть. То есть нужно будет добавить в нетлист инвертор, которого нет в исходном проекте.
  2. Элементы, у которых можно менять содержимое. Например, таблица истинности в LUT или содержимое блочной памяти. Причём изменение содержимого блочной памяти тут будет более предпочтительным, поскольку изменение LUT мы уже выполним в п.1, когда будем создавать дополнительный инвертор.
  3. ILA – для возможности замены подключённых цепей на другие цепи. То есть, не трогая сам ILA, мы попробуемчерез нетлист заменить подключенные к нему выбранные в исходном проекте цепи на другие.
  4. Перепутанные выводы. Предположим, что при проектировании печатной платы ее разработчик выполнил pin-swap двух выводов для удобства разводки, не согласовав это с разработчиком FPGA, т.е. внёс ошибку путаницы rx с tx UART. В режиме ECO мы должны будем восстановить правильность подключения.

3.1. Создание проекта

Находим иконку Vivado и кликаем по ней два раза, откроется окно приветствия (рис. 2)

2
Рисунок 2 – Окно приветствия Vivado

Для создания нового проекта нажимаем кнопку Create Project. Нажатие кнопки вызывает мастер создания нового проекта. После его появления нажимаем кнопку Next (рис. 3).

3
Рисунок 3 – Окно мастера создания нового проекта

Вводим название проекта, в поле Project Name пишем «eco_flow». Указываем, где будет располагаться проект: в поле Project location укажите директорию с проектом. У меня она будет «F:/Projects/FPGA-Systems/eco_flow/projects/vivado». Если установить галочку «create project subdirectory» – будет создана дополнительная папка с именем проекта. Нажимаем Next (рис. 4).

4
Рисунок 4 – Ввод имени проекта и его расположения

Создаем мы обыкновенный проект, поэтому просто выбираем тип проекта RTL. На текущем этапе не будем добавлять какие-либо файлы в проект, поэтому поставим галку “Do not specify sources at this time” и нажимаем Next (рис. 5).

5
Рисунок 5 – Выбор типа создаваемого проекта

Работать мы будем с платой Arty [2], поэтому выберем кристалл, который на ней установлен: xc7a35tcsg324-1. Нажимаем Next (рис. 6).
Примечание: я специально не выбираю готовую плату из шаблона доступных плат. Это сделано для того, чтобы можно было вручную делать ошибки, которые потом мы будем исправлять.

6
Рисунок 6 – Выбор кристалла xc7a35tcsg324-1

Заключительным в мастере настройки нового проекта будет окно Summary создаваемого проекта. Нажимаем Finish (рис. 7).

7
Рисунок 7 – Окно кратких сведений создаваемого проекта

3.2. Создание и добавление HDL файлов в проект

Здесь мы создадим два модуля: просто мигающий светодиод и блочную память, которая постоянно считывается (фактически, это имитация памяти коэффициентов фильтра, значения которых мы потом попробуем изменить).

Для создания и добавления нового файла в проект воспользуемся мастером, который вызывается по нажатию на синий плюс (рис. 8).



8
Рисунок 8 – Вызов мастера создания добавления файлов в проект
 
В появившемся окне выбираем «Add or create design sources» и кликаем Next (рис. 9).

9
Рисунок 9 – Выбор типа, создаваемого или добавляемого файла

Выбираем Create file, после чего в появившемся окне в поле File name вводим имя создаваемого файла flash_led, нажимаем ОК (рис. 10).

10
Рисунок 10 – Создание нового файла и ввод его имени

После этого фал появится в списке добавляемых. Нажимаем Finish (рис. 11)

11
Рисунок 11 – Список добавляемых или создаваемых файлов

Теперь появился мастер создания шаблона для файла. Поскольку я использую VHDL, то я могу изменить имя архитектуры на rtl. Создаем два пина нашего модуля: iclk с направлением «in» (тактовый сигнал нашего модуля) и oled с направлением «out» (выход, подключаемый к светодиоду). Нажимаем ОК (рис. 12).



12
Рисунок 12 – Мастер создания шаблона модуля (для VHDL)

Теперь наш модуль находится в дереве проекта (рис. 13).

13
Рисунок 13 – Созданный модуль flash_led

Модуль должен выполнять простую функцию: просто моргать светодиодом с периодом в 1 секунду. Забегая вперед, скажу, что тактовая частота нашего проекта будет равна 100 МГц, а сам модуль Вам ещё пригодится при выполнении домашнего задания.

Замените содержимое файла на следующее (листинг 1 (текстовый варинт листинга 1 см. в приложении А)). Код достаточно прост, и не требует дополнительных комментариев для пояснения его работы.



л1
Листинг 1 – Код модуля flash_led

Теперь создайте новый модуль, который должен называться brom_reader, его порты iclk с направлением «in», и odout[7:0] с направлением «out» (повторите действия с рис. 8 по рис. 12).

Если все сделано правильно, то в дереве проекта должен появиться модуль brom_reader (рис. 14).



14
Рисунок 14 – Модуль brom_reader в дереве проекта

Замените содержимое модуля следующим текстом (листинг 2 (текстовый вариант листинга 2 см. в приложении Б)). Здесь потребуется несколько комментариев:

 Строка 13: типу std_logic_vector создается псевдоним. Те, кто работает с VHDL часто используют тип данных «std_logic_vector()». Чтобы каждый раз не писать эти длинные названия, можно объявить псевдоним (alias) и потом использовать его на протяжении всего кода модуля.
  1. Строки 14-20: стандартное объявление двухмерного массива натуральных чисел и инициализация массива (создается память с числами).
  2. Строка 22: использование псевдонима (alias) slv для объявления сигнала
  3. Строки 23-24: использование атрибута синтеза [11]. Для чего он здесь прописан? Мы создали достаточно маленький двумерный массив (строки 15-20) – и, вероятнее всего, во время синтеза он будет оптимизирован и реализован в виде распределённой памяти на LUT. А так как мы хотим разместить массив именно в блочной памяти (BRAM- Block RAM), нам необходимо об этом в явном виде сказать синтезатору, что и делается с помощью атрибутов синтеза. Подробнее о них читайте в руководстве по синтезу Vivado в [11].
 В остальном все должно быть понятно: мы создали ROM-память, из которой непрерывно, последовательно и циклически считывается ее содержимое.



л2
Листинг 2 – код модуля brom_reader

3.3. Создание проекта MicroBlaze и работа в IP Integrator

Теперь мы создадим проект с MicroBlaze. Еще раз обращу Ваше внимание на то, что есть пошаговое руководство на русском по созданию проектов на софт‑процессоре MicroBlaze для новичков [16].
Для создания блочного проекта необходимо создать Block Design. Выбираем Create Block Design, вводим имя system и нажимаем ОК (рис. 15).



15
Рисунок 15 – Создание нового Block Design и задание его имени
 
На поле Diagram добавляются ядра из IP каталога Vivado, либо RTL модули, написанные на VHDL/Verilog/SystemVerilog. Найдем в IP каталоге модуль MicroBlaze, для этого нажмите синий крестик и в поле поиска введите “MicroBlaze” и выберите его (рис. 16).

16

Рисунок 16 – Добавление IP ядра MicroBlaze на рабочее поле Diagram

После добавления MicroBlaze на рабочее поле, воспользуемся экспресс настройками софт-процессора. Выберите Run Block Automation и выставите настройки в соответствии с рис. 17. Нажмите ОК.

17
Рисунок 17 – Экспресс настройки MicroBlaze

После этого на рабочем поле Diagram появятся несколько новых IP ядер, включая генератор тактовых частот и локальную память процессора [11, 12]. Нажмите кнопку Regenerate для оптимизации рабочего поля (рис. 18).


Рисунок 18 – Базовое включение MicroBlaze

Выполним настройку некоторых модулей в соответствии с нашей платой Arty. Настроим модуль генерирования сетки тактовых частот clk_wiz_1. Для вызова настроек модуля кликаем по нему два раза левой кнопкой мышки. В окне настроек устанавливаем значение входной тактовой частоты 100МГц, поскольку именно генератор на 100МГц установлен на плате [12]. Также устанавливаем тип источника как однополярный (рис. 19). Перейдём во вкладку Output Clocks, где настроим выходные частоты модуля.





Рисунок 19 – Настройка параметров входной частоты
 
Во вкладке Output Clocks мы зададим только одну частоту, основную частоту нашей процессорной системы и остальных модулей. Установим её равной 100МГц (рис. 20).


Рисунок 20 – настройка параметров выходной частоты

Прокрутите вниз для настройки дополнительных служебных сигналов. Мы уберем сигнал сброса Reset, который не будем использовать. Снимите с него галочку (рис. 21). Остальные настройки нам не нужны, нажимаем ОК.




Рисунок 21 – Настройка служебных сигналов

Теперь объявляем вход clk_in1 модуля clk_wiz_1 внешним, фактически делаем из него input нашего Block Design. Для этого нажимаем на clk_in1 правой кнопкой мыши и выбираем Make External (рис. 22).


Рисунок 22 – Делаем порт clk_in1 внешним

Как видим появился порт clk_in1_0 (рис. 23).


Рисунок 23 – Входной порт clk_in1_0

В модуле управления сбросом нашей процессорной системы подключим два неиспользуемых входа (внешний сброс и дополнительный сброс) к неактивному логическому уровню «1». Сделаем это с помощью IP блока, который называется constant. Для этого щелкнем синем крестике вверху, затем в строке поиска вводим «const»» и выберем модуль constant.




Рисунок 24 – Поиск IP блока constant в списке доступных IP

Выполним настройку модуля xlconstant_0, щелкнув по нему дважды левой кнопкой мыши. В строке значение (Const val ) вводим 1, в строке ширина (Const Width) вводим 1, нажимаем ОК (рис. 25)




Рисунок 25 – Настройка модуля xlconstant_0

Выполним подключение выхода dout модуля xlconstant_0 ко входам ext_reset_in и aux_reset_in модуля rst_clk_wiz_1_100M. Просто соедините эти порты мышкой (рис. 26).




Рисунок 26 – Подключение неиспользуемых портов к константе


Добавим модуль UART, найдя его в каталоге доступных IP ядер (рис.27).


Рисунок 27 – Поиск модуля UART в списке доступных IP блоков

Выполним настройку модуля axi_uartlite_0, установив настройки передачи в соответствии с рис. 28. Затем нажимаем ОК.




Рисунок 28 – Настройки модуля axi_uartlite_0

Теперь подключим модуль axi_uartlite_0 к процессору. Воспользуемся для этого автоматизированным методом. Нажимаем в верху Run Connection Automation и выбираем что к чему подключить (AXI вход UART к AXI MicroBlaze) рис. 29.




Рисунок 29 – Подключение axi_uartlite_0 к процессору

Интерфейс UART является стандартным и выделен в отдельный тип интерфейсов в Vivado IP Integrator. В пункте 2 на рис. 29 мы сказали, что хотим сделать rx и tx модуля axi_uartlite_0 внешними. Если вы раскроете интерфейс, то увидите это. Не смущайтесь, что в интерфейсе всего один синий провод, позже, когда создадим HDL обертку проекта, вы увидите, что там два порта (rx и tx).
Нажмите кнопку Regenerate Layout. После этого рабочее поле Block Design будет оптимизировано и схема примет ид, как на рис. 30. Убедитесь, что вы корректно выполнили подключение. Если на этом этапе все нормально, продолжим, если есть ошибки, выполните построение процессорной системы заново.




Рисунок 30 – Промежуточный этап сборки процессорной системы.
 
Давайте добавим еще один модуль на шину AXI. Это будет модуль GPIO, выход которого мы подключим на светодиод. Найдите в списке доступных IP блоков модуль AXI GPIO и добавьте его на рабочее поле (рис. 31).


Рисунок 31 – Модуль AXI GPIO в списке доступных IP

Выполните настройку модуля, в соответствии с рис. 32 (использовать будем только один канал и один выход).




Рисунок 32 – Настройки модуля axi_gpio_0

Выполним подключение модуля axi_gpio_0 к процессору и сделаем выход внешним. Нажмите Run Connection Automation и поставьте все галочки (рис.33).




Рисунок 33 – Подключение axi_gpio_0 к процессору

Нажмите кнопку Regenerate Layout и убедитесь, что все подключения соответствуют рис. 34.




Рисунок 34 – Сборка процессорной cистемы.
 
Теперь добавим модуль отладки ILA. Предположим, что мы хотим просмотреть транзакции на шине AXI Lite для модуля UART. Находим в списке доступных IP модуль ILA (Integrated Logic Analyzer) рис. 35.


Рисунок 35 – IP блок ILA в списке доступных

Здесь мы используем некоторое подобие так называемого HDL Insertion Flow, когда модули отладки мы добавляем непосредственно в HDL код. Напомню, что выполнять поиск цепей для отладки вы можете и в нетлисте после синтеза. Такой подход называется Netlist Insertion Flow.
Так как мы хотим отлаживать AXI транзакции, то должны настроить тип пробника ILA как AXI (параметр Monitor Type в блоке ILA). Этот режим установлен по умолчанию, поэтому просто подключаем вход SLOT_0_AXI блока ila_0 к шине AXI, транзакции на которой мы хотим просмотреть. В нашем случае это шина, идущая от интерконнекта до модуля axi_uart_0 (рис. 36). Также подключаем тактовый сигнал для модуля к clk нашей системы и нажимаем кнопку Regenerate Layout.




Рисунок 36 – Подключение ila_0 к AXI шине axi_uart_0

По умолчанию длина записываемых данных установлена 1024, что вполне достаточно для просмотра транзакции.
Теперь добавим наши RTL модули в Block Design, для этого выберите модуль flash_led, нажмите правой кнопкой мыши и затем выберите Add Module to Block Design (это работает только в Vivado не ниже версии 2017.1).




Рисунок 37 – добавление модуля flash_led на поле Diagram

Подключите вход iclk модуля flash_led_0 к тактовому сигналу нашей системы, а порт oled сделайте внешним (правой кнопкой мыши по порту, затем выберите Make Exernal). Нажимаем кнопку Regenerate Layout.

 Если всё сделано корректно, то должно получиться как на рис. 38.



Рисунок 38 – Промежуточный этап построения проекта в IP Integrator

Повторите аналогичные действия, для добавления модуля brom_reader. Подключите его тактовый вход iclk к тактовой цепи, НО не объявляете выход odout[7:0] внешним. Нажмите Regenerate Layout. Если все сделано корректно, то должно получиться как на рис. 39.



Рисунок 39 – Промежуточный этап построения проекта в IP Integrator

Теперь, добавим еще один ILA и подключим его к выходу odout[7:0] модуля brom_reader_0.

Находим IP блок ILA в списке доступных (рис. 35) и добавляем на поле Diagram. Выполним его настройку, дважды щелкнув по нему мышкой. Устанавливаем Monitor Type в значение Native (отлаживаем мы не шину AXI, а простые цепи). Остальное оставим по умолчанию. Перейдите во вкладку Probe_Ports(0..7) рис. 40.




Рисунок 40 – Настройка ILA
 
Настроим ширину пробника. Установим значение ширины равное 8 (рис. 41), поскольку именно 8 бит – ширина шины выхода odout[7:0] модуля brom_reader_0. Нажимаем ОК.


Рисунок 41 – Настройка ширины пробников ILA

Подключите выход odout[7:0] модуля brom_reader_0 ко входу probe_0[7:0] модуля ila_1, а вход clk модуля ila_1 подключите к тактовой цепи нашего проекта. Нажмите кнопку Regenerate Layout, и, если все корректно, должно получиться как на рис. 42.




Рисунок 42 –Промежуточный этап построения проекта в IP Integarator

Осталось только добавить кнопку и напрямую с ней включенный светодиод.
Создадим порт ввода, нажав на пустом месте нашей блок схемы правой кнопкой мыши и выбрав Create Port (рис. 43).


Рисунок 43 – Создание порта в IP Integrator

После появления мастера настроек порта, введите его имя ibtn, укажите направление input и, если нужно разрядность. Нажмите OK (рис. 44).





Рисунок 44 – Мастер настройки нового порта (кнопка ibtn)

После этого порт появится на поле Diagram (рис. 45).


Рисунок 45 – созданный порт ibtn

Создайте еще один порт с названием obtn_led, направлением output (повторите действия на рис. 43-44).
Теперь просто соединяем порт ibtn c obtn_led, нажимаем Regenerate Layout. Должно получиться как на рис. 47.




Рисунок 46 – Собранный проект в IP Integrator

Проверим, что нет ошибок в текущем Block Design, нажав на кнопку Validate Design. Если все корректно, но Vivado выдаст соответствующее сообщение. Нажимаем OK и сохраняем текущий Block Design (рис. 48).




Рисунок 47 – Проверка корректности собранного проекта в IP Integrator

3.4. Синтез и имплементация

Перейдите во вкладку Sources, нажмите на system правой кнопкой мыши и выберите пункт Create HDL Wrapper (создать HDL обертку нашего Block Design) рис. 48.


Рисунок 48 – Создание обертки проекта

После этого Vivado предложит либо обновлять вручную HDL обертку при внесении изменений в Block Design, либо делать это автоматически. Оставляем автоматическое обновление и нажимаем OK (рис. 49).


Рисунок 49 – Варианты обновления HDL обертки

Теперь укажем, что модуль system_wrapper является Top-модулем. Нажимаем правой кнопкой мыши на system_wrapper и выбираем Set as Top (рис. 50).


Рисунок 50 – Делаем модуль system_wrapper топ модулем

Теперь выполним синтез модуля system_wrapper, нажав на кнопку Run Synthesis (рис. 51).

Примечание: для подключения блоков отладки мы использовали фактически HDL Insertion Flow [4], то есть фактически вставляли в код наши ILA блоки и подключали к ним цепи. Нет никакой разницы как вы создаете и подключаете цепи для отладки: через HDL или Netlist. В конечном итоге ECO работает именно с синтезированным или имплементированным нетлистом, который хранится в Design Checkpoint.


Рисунок 51 – Запуск синтеза проекта

После нажатия на кнопку Run Synthesis нажмите ОК и дождитесь окончания синтеза.

После окончания синтеза будет выведено окно, в котором будет предложено запустить имплементация, открыть результаты синтеза или посмотреть отчеты. Откройте результаты синтеза (рис. 52).


Рисунок 52 – Открытие результатов синтеза

Теперь подключим ножки в нашем проекте. Делается это с помощью Pin Planer. Чтобы его открыть нажмите Window→I/O Ports (рис. 54).


Рисунок 53 – Открытия окна для назначения пинов

Используя Reference Manual [12] для Arty назначим ножки (рис. 54).

БУДЬТЕ ВНИМАТЕЛЬНЫ!!! Я специально перепутал ножки для rx и tx модуля UART!

Назначьте ножки в соответствии с рис. 54.


Рисунок 54 – Назначение ножек проекта (rx и tx UART перепутаны специально)

Нажмите кнопку сохранить, после чего Vivado укажет, что вы не создавали файл проектных ограничений, и предложит его создать Введите имя файла constr и нажмите ОК (рис. 55).


Рисунок 55 – Создание файла проектных ограничений

Теперь мы можем выполнить имплементацию нашего проекта и сгенерировать файл прошивки. Нажмите на кнопку Generate Bistream, затем OK и дождитесь окончания процедуры (рис. 56).


Рисунок 56 – Расположение кнопки Generate Bitstream

После окончания генерации Bitstream появится окно дальнейших действий. Нажмите Cancel (рис. 57)


Рисунок 57 – Окно дальнейших действий после создания битсрима

3.5. Написание программы для MicroBlaze

Теперь выполним разработку ПО для MicroBlaze. Это выполняется в среде Xilinx Software Development Kit (SDK). Для того чтобы сообщить SDK информацию о собранной процессорной системе (IP ядрах, их адресации на шине AXI) необходимо выполнить экспорт в SDK. Это делается с помощь File → Export → Export Hardware (рис. 58).

Рисунок 58 – Экспорт информации о процессорной системе в SDK

В появившемся окне не устанавливайте галочку Include Bitstream. Отставьте параметры по умолчанию и нажмите OK (рис. 59).

Рисунок 59 – Окно параметров экспорта

Теперь запустим SDK. Для этого выберите File → Launch SDK


Рисунок 60 – запуск SDK

Дождитесь окончания выполнения служебных операций SDK. После их окончания можем приступить к созданию нового проекта. Выбираем File → New → Application Project.


Рисунок 61 – Создание нового проекта в SDK

Введите название нового проекта MB_run, нажмите Next (рис. 62)


Рисунок 62 – Настройка нового проекта

В окне готовых шаблонов выберите создание приложения Hello World и нажмите Finish (рис. 63)


Рисунок 63 – Выбор шаблона создаваемого проекта

Откройте файл helloworld.c (расположение которого показано на рис. 64) и замените его содержимое кодом программы, показанным в листинге 3, и сохраните результат.


Рисунок 64 – Расположение файла helloworld.c


Листинг 3 – Заменённое содержимое файла helloworld.c

Программа отсылает «Hello World: cycle» примерно 1 раз в 2 секунды и моргает светодиодом LD1 (красной компонентой) также приблизительно 1 раз в 2 секунды.

3.6. Запуск программы и отладка

После завершения написания кода и сборки процессорной системы необходимо убедиться, что:

 Светодиод LD4 загорается по нажатию кнопки BTN0
  1. Процессор работает и шлет «Hello World: cycle» в консоль, однако мы не видим слов в консоли, поскольку выполнили неверное подключение rx и tx. Дополнительным сигнализатором работы процессора, является мигающий светодиод LD1.
  2. Выполняются транзакции по интерфейсу AXI-Lite от процессора до UART
  3. Блочная память считывается и выдает корректные значения.
 Для начала подключаем Arty к компьютеру. Выполним настройку терминала, в котором должны будут показываться сообщения UART. Это можно сделать стандартными средствами SDK. В SDK имеется терминал, расположенный внизу (рис. 65).
Если терминала нет, то его можно найти в Window → Show View → Others → Xilinx → SDK Terminal (рис. 65).



Рисунок 65 – Открытие встроенного терминала в SDK

Установите настройки терминала, в соответствии с рис. 66. Номер COM-порта может отличаться.




Рисунок 66 – Настройка SDK терминала

Теперь перейдём в Vivado и выполним программирование FPGA.
Нажимаем Open Hardware Manager и переходим в режим программирования и отладки. Выбираем Open Target и нажимаем автоматическое подсоединение Auto Connect (рис. 67)


Рисунок 67 – Открытие Hardware Manager и подключение в ПЛИС

Выбираем из списка наш кристалл и заливаем в него прошивку (рис. 68)



Рисунок 68 – Программирование ПЛИС

В появившемся диалоговом окне следует проверить, что выбраны нужные файлы прошивки .bit и список подключаемых цепей .ltx (рис.69) и затем нажать кнопку Program.




Рисунок 69 – Выбор файла прошивки и списка цепей

Если все сделано корректно, светодиод LD4 должен мигать, а по нажатию на кнопку BTN0 должен загораться светодиод LD4.
Теперь заставим процессор выполнять нашу программу по отправке данных в UART и мигать красной компонентой светодиода LD1.
Переключаемся обратно в SDK, кликаем правой кнопкой по нашему проекту MB_run, после чего выбираем Run As → Launch on Hardware (System Debugger), как показано на рис. 70. Мы заливаем сразу релиз программы, и не будем выполнять пошаговую отладку.




Рисунок 70 – Запуск исполняемой программы процессора

Подождав несколько секунд, видим, что светодиод LD1 мигает, но сообщения в SDK Terminal не появляются, поскольку rx и tx перепутаны.
Теперь давайте убедимся в том, что, транзакции до модуля UART всё-таки доходят.
Переключаемся в Vivado. Надеюсь, что вы помните, что мы подключали два ILA: один на транзакцию по шине AXI для UART, а второй к выходу блочной памяти. Но у нас в списке оказалось три ILA (рис. 71).


Рисунок 71 – Окно подключенных ILA

К сожалению, в результате оптимизации и синтеза, такое может случаться и это следует учитывать, как и то, что в результате оптимизации и различных настроек синтеза могут меняться названия цепей. Тем не менее, мы сможем провести отладку и убедиться, что транзакции до модуля UART все-таки доходят. Но нам нужно их «поймать», то есть настроить триггер, условие, по которому начнется запись состояния линий, к которым подключен ILA.
Дважды кликните мышкой по hw_ila_1 чтобы открыть окно временных диаграмм и окна настроек.
В окне Trigger Setup установите, триггер. Нажмите на синий крестик и в списке доступных цепей выберите цепь, показанную на рис. 72. И нажмите OK.




Рисунок 72 – Выбор триггера для запуска ILA

Примечание: мы работаем с интерфейсом AXI-Lite, в котором достаточно много сигналов. Не буду расписывать здесь функции, которые возложены на те или иные сигналы интерфейса. Если Вам интересно подробнее узнать об этом, пожалуйста, обратитесь к руководству [14].

Теперь установим параметры срабатывания триггера. Поскольку активный уровень сигала RVALID это «1», то скажем, что необходимо начать запись, когда этот сигнал будет равен «1». Установите значение срабатывания, как показано на рис. 73. И затем нажмите кнопку запуска триггера.




Рисунок 73 – Запись данных с ILA по срабатыванию триггера

Теперь, из этого гигантского списка цепей, которые имеются в интерфейсе найдем шину, которая отвечает за данные. Эта шина показана на рис. 74


Рисунок 74 – Цепь с данными на шине AXI-Lite

Измените отображаемое состояние шины на ASCII. Для этого кликните правой кнопкой мыши по шине, затем выберите Radix, затем ASCII (рис. 76).




Рисунок 75 – Выбор представления данных на шине *WDATA[31:0]

После этого мы увидим на шине часть нашего сообщения, которое отсылает процессор. Это частично подтверждает, что транзакция проходит корректно (рис. 76).




Рисунок 76 – ASCII представление данных на шине *WDATA[31:0]

Попробуйте повторить самостоятельно действия с рис.71 по рис. 76 для hw_ila_2, который подключён к выходу модуля чтения блочной памяти. Устанавливать триггер не требуется. Если всё будет сделано корректно, то картинка должна быть аналогичной рис. 77.




Рисунок 77 – данные, считываемые из блочной памяти

На этом сборка тестового проекта завершена, и мы можем приступить к редактированию нашего нетлиста и работе в режиме ECO.


Читайте продолжение во второй части

 

5005
0
0.0

Всего комментариев : 0
avatar

FPGA-Systems – это живое, постоянно обновляемое и растущее сообщество.
Хочешь быть в курсе всех новостей и актуальных событий в области?
Подпишись на рассылку

ePN