[Из песочницы] ECO Flow в Vivado или работа в режиме редактирования нетлиста
Аннотация
В статье рассмотрен режим работы Vivado, позволяющий вносить изменения в проект на уровне редактирования списка соединений (в дальнейшем — нетлиста). Описаны как сам режим ECO, так и некоторые нюансы, которые появляются во время работы в нём. Приведён демонстрационный пример и описана полная последовательность действий для получения результата, в работоспособности которой может убедиться каждый желающий. Статья будет полезна для «общего развития» FPGA-разработчикам, а особенно — тем, кто часто отлаживает проекты в Logic Analyzer. Надеюсь, работа в этом режиме вызовет интерес у разработчиков, работающих с большими кристаллами, время компиляции в которых может достигать часов (а то и десятков часов), поскольку в этом режиме время, затрачиваемое на имплементацию, при внесении изменений в нетлист может сократиться до буквально пары минут.
Оглавление
- Аннотация
- Введение
- 1. ECO: краткий обзор
- 2. Design Сheckpoint
- 3. Разработка тестового проекта
- 3.1. Создание проекта
- 3.2. Создание и добавление HDL файлов в проект
- 3.3.Создание проекта MicroBlaze и работа в IP Integrator
- 3.4.Синтез и имплементация
- 3.5.Написание программы для MicroBlaze
- 3.6.Запуск программы и отладка
- 4. Переход в режим ECO
- 5. ECO: описание интерфейса
- 6. Внесение изменений в проект
- 6.1. Создание новых элементов в нетлисте
- 6.2. Изменение свойств/параметров компонентов
- 6.3. Подключение других цепей к пробникам и ILA
- 6.4. Замена портов ввода/вывода
- 7. Сравнительный анализ
- 8. Заключение
- 9. Домашнее задание
- Библиографический список
Введение
Зачастую, когда мне приходится читать лекцию или вести семинар, я всегда стараюсь рассказать несколько больше, нежели предполагает программа. Так было на последних трёх семинарах, посвящённых работе с одноядерными Zynq-7000S. В этот раз было интересно посмотреть, насколько аудитория знает о некоторых «скрытых» режимах работы с Vivado. Вопрос был достаточно прост: «Кто-нибудь из присутствующих знает про режим ECO Flow?» Сразу за вопросом последовал, что называется, «лес рук, чему я особенно не удивился.
Желание несколько просветить разработчиков хотя бы о наличии этого режима в Vivado, не говоря уже о демонстрации работы в нём, появилась у меня очень давно. Но по какой-то загадочной причине, я «впрягся» в написание руководств по сборке проектов с использованием MicroBlaze и работе с ним. Однако, после недавних семинаров стало очевидно, что писать про ECO Flow всё таки нужно.
Цель статьи — дать общее представление о режиме ECO в среде Vivado [1], предоставляемой компанией Xilinx для своих кристаллов и показать на реальном примере работу в этом режиме, стараясь указать «тонкие» моменты и проанализировать его достоинства и недостатки.
Задачи, которые поставлены в этой статье:
- разработать тестовый пример, по возможности содержащий и демонстрирующий все (или хотя бы большинство) возможностей работы в режиме ECO;
- выполнить имплементацию проекта;
- пояснить понятие Design Checkpoint;
- описать переход в режим работы ECO;
- внести правки в нетлист и получить файл прошивки FPGA;
- убедиться в корректности внесенных изменений;
- составить сводную таблицу времени, затрачиваемого на стандартное внесение изменений в проект и сравнить его со временем, затрачиваемым в режиме 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 — создаваемые по умолчанию dcp-файлы (1 — «постсинтез-» и 3 — «постимплемент-»: после оптимизации (_opt), после размещения (_placed) и после трассировки (_routed))
В проектном режиме работы с Vivado (Project Mode [8]) файлы .dcp создаются автоматически. Но при работе в непроектном режиме (Non-ProjectMode [8]) пользователь сам должен следить за тем, чтобы «снимки» текущего состояния проекта записывались. Для этого следует использовать соответствующие Tcl команды [9, 10].:
write_checkpoint
read_checkpoint
О том, зачем, как и какие файлы dcp следует открывать, будет рассказано далее.
3. Разработка тестового проекта
Чтобы продемонстрировать на тестовом проекте возможности ECO, он должен содержать следующее:
- Элементы, которых нет в исходном нетлисте или элементы, у которых можно изменять функционал. Например, завести светодиод на кнопку — и в исходном проекте он будет загораться по нажатию, а в измененном — по нажатию он будет гаснуть. То есть нужно будет добавить в нетлист инвертор, которого нет в исходном проекте.
- Элементы, у которых можно менять содержимое. Например, таблица истинности в LUT или содержимое блочной памяти. Причём изменение содержимого блочной памяти тут будет более предпочтительным, поскольку изменение LUT мы уже выполним в п.1, когда будем создавать дополнительный инвертор.
- ILA — для возможности замены подключённых цепей на другие цепи. То есть, не трогая сам ILA, мы попробуемчерез нетлист заменить подключенные к нему выбранные в исходном проекте цепи на другие.
- Перепутанные выводы. Предположим, что при проектировании печатной платы ее разработчик выполнил pin-swap двух выводов для удобства разводки, не согласовав это с разработчиком FPGA, т.е. внёс ошибку путаницы rx с tx UART. В режиме ECO мы должны будем восстановить правильность подключения.
3.1. Создание проекта
Находим иконку Vivado и кликаем по ней два раза, откроется окно приветствия (рис. 2)
Рисунок 2 — Окно приветствия Vivado
Для создания нового проекта нажимаем кнопку Create Project. Нажатие кнопки вызывает мастер создания нового проекта. После его появления нажимаем кнопку Next (рис. 3).
Рисунок 3 — Окно мастера создания нового проекта
Вводим название проекта, в поле Project Name пишем «eco_flow». Указываем, где будет располагаться проект: в поле Project location укажите директорию с проектом. У меня она будет «F:/Projects/FPGA-Systems/eco_flow/projects/vivado». Если установить галочку «create project subdirectory» — будет создана дополнительная папка с именем проекта. Нажимаем Next (рис. 4).
Рисунок 4 — Ввод имени проекта и его расположения
Создаем мы обыкновенный проект, поэтому просто выбираем тип проекта RTL. На текущем этапе не будем добавлять какие-либо файлы в проект, поэтому поставим галку «Do not specify sources at this time» и нажимаем Next (рис. 5).
Рисунок 5 — Выбор типа создаваемого проекта
Работать мы будем с платой Arty [2], поэтому выберем кристалл, который на ней установлен: xc7a35tcsg324–1. Нажимаем Next (рис. 6).
Примечание: я специально не выбираю готовую плату из шаблона доступных плат. Это сделано для того, чтобы можно было вручную делать ошибки, которые потом мы будем исправлять.
Рисунок 6 — Выбор кристалла xc7a35tcsg324–1
Заключительным в мастере настройки нового проекта будет окно Summary создаваемого проекта. Нажимаем Finish (рис. 7).
Рисунок 7 — Окно кратких сведений создаваемого проекта
3.2. Создание и добавление HDL файлов в проект
Здесь мы создадим два модуля: просто мигающий светодиод и блочную память, которая постоянно считывается (фактически, это имитация памяти коэффициентов фильтра, значения которых мы потом попробуем изменить).
Для создания и добавления нового файла в проект воспользуемся мастером, который вызывается по нажатию на синий плюс (рис. 8).
Рисунок 8 — Вызов мастера создания добавления файлов в проект
В появившемся окне выбираем «Add or create design sources» и кликаем Next (рис. 9).
Рисунок 9 — Выбор типа, создаваемого или добавляемого файла
Выбираем Create file, после чего в появившемся окне в поле File name вводим имя создаваемого файла flash_led, нажимаем ОК (рис. 10).
Рисунок 10 — Создание нового файла и ввод его имени
После этого фал появится в списке добавляемых. Нажимаем Finish (рис. 11)
Рисунок 11 — Список добавляемых или создаваемых файлов
Теперь появился мастер создания шаблона для файла. Поскольку я использую VHDL, то я могу изменить имя архитектуры на rtl. Создаем два пина нашего модуля: iclk с направлением «in» (тактовый сигнал нашего модуля) и oled с направлением «out» (выход, подключаемый к светодиоду). Нажимаем ОК (рис. 12).
Рисунок 12 — Мастер создания шаблона модуля (для VHDL)
Теперь наш модуль находится в дереве проекта (рис. 13).
Рисунок 13 — Созданный модуль flash_led
Модуль должен выполнять простую функцию: просто моргать светодиодом с периодом в 1 секунду. Забегая вперед, скажу, что тактовая частота нашего проекта будет равна 100 МГц, а сам модуль Вам ещё пригодится при выполнении домашнего задания.
Замените содержимое файла на следующее (листинг 1 (текстовый варинт листинга 1 см. в приложении А)). Код достаточно прост, и не требует дополнительных комментариев для пояснения его работы.
Листинг 1 — Код модуля flash_led
Теперь создайте новый модуль, который должен называться brom_reader, его порты iclk с направлением «in», и odout[7:0] с направлением «out» (повторите действия с рис. 8 по рис. 12).
Если все сделано правильно, то в дереве проекта должен появиться модуль brom_reader (рис. 14).
Рисунок 14 — Модуль brom_reader в дереве проекта
Замените содержимое модуля следующим текстом (листинг 2 (текстовый вариант листинга 2 см. в приложении Б)). Здесь потребуется несколько комментариев:
- Строка 13: типу std_logic_vector создается псевдоним. Те, кто работает с VHDL часто используют тип данных «std_logic_vector ()». Чтобы каждый раз не писать эти длинные названия, можно объявить псевдоним (alias) и потом использовать его на протяжении всего кода модуля.
- Строки 14–20: стандартное объявление двухмерного массива натуральных чисел и инициализация массива (создается память с числами).
- Строка 22: использование псевдонима (alias) slv для объявления сигнала
- Строки 23–24: использование атрибута синтеза [11]. Для чего он здесь прописан? Мы создали достаточно маленький двумерный массив (строки 15–20) — и, вероятнее всего, во время синтеза он будет оптимизирован и реализован в виде распределённой памяти на LUT. А так как мы хотим разместить массив именно в блочной памяти (BRAM- Block RAM), нам необходимо об этом в явном виде сказать синтезатору, что и делается с помощью атрибутов синтеза. Подробнее о них читайте в руководстве по синтезу Vivado в [11].
В остальном все должно быть понятно: мы создали ROM-память, из которой непрерывно, последовательно и циклически считывается ее содержимое.
Листинг 2 — код модуля brom_reader
3.3. Создание проекта MicroBlaze и работа в IP Integrator
Теперь мы создадим проект с MicroBlaze. Еще раз обращу Ваше внимание на то, что есть пошаговое руководство на русском по созданию проектов на софт‑процессоре MicroBlaze для новичков [11, 12].
Для создания блочного проекта необходимо создать Block Design. Выбираем Create Block Design, вводим имя system и нажимаем ОК (рис. 15).
Рисунок 15 — Создание нового Block Design и задание его имени
На поле Diagram добавляются ядра из IP каталога Vivado, либо RTL модули, написанные на VHDL/Verilog/SystemVerilog. Найдем в IP каталоге модуль MicroBlaze, для этого нажмите синий крестик и в поле поиска введите «MicroBlaze» и выберите его (рис. 16).
Рисунок 16 — Добавление IP ядра MicroBlaze на рабочее поле Diagram
После добавления MicroBlaze на рабочее поле, воспользуемся экспресс настройками софт-процессора. Выберите Run Block Automation и выставите настройки в соответствии с рис. 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
- Процессор работает и шлет «Hello World: cycle» в консоль, однако мы не видим слов в консоли, поскольку выполнили неверное подключение rx и tx. Дополнительным сигнализатором работы процессора, является мигающий светодиод LD1.
- Выполняются транзакции по интерфейсу AXI-Lite от процессора до UART
- Блочная память считывается и выдает корректные значения.
Для начала подключаем 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 — Програ