Подключи ISE, Vivado и Quartus к общему итератору версии и HDL-паспорту. Проверяй новый bit/sof до создания manifest, SHA-256 и архива выпуска. Добавь установку локальных команд ISE, инструкции переноса и регрессионные проверки успешных и прерванных сборок.
17 KiB
Контроль прошивок ПЛИС: Xilinx ISE, Vivado и Altera Quartus
Для ISE: запустите INSTALL_ISE.bat, укажите .xise, затем используйте
созданный в проекте build_firmware.bat. Краткая инструкция.
Шаблон подключает к существующему проекту ПЛИС общий механизм
firmware-info: сохраняемый итератор
SemVer, время сборки в UTC, Git build ID, manifest, SHA-256 и архив выпуска.
Параметры кристалла, выводы, частоты, ограничения и транспорт чтения регистров
задаёт проект платы.
Цепочка: проект → Tcl своей САПР → identity.py из этого каталога → общий
c/firmware-info/tools/identity.py. Итератор, правила Git и архивирования
используются те же, что для CCS и Keil.
Файлы и зависимости
| Файл | Назначение | Зависимости |
|---|---|---|
firmware_identity.example.json |
Начальная конфигурация изделия и счётчика | Копируется в проект |
INSTALL_ISE.bat, ise_project.py |
Автоматическая установка локальных BAT, JSON, HDL и памятки из .xise |
Windows, Python 3.9+ |
ise-build.bat, ise_bootstrap.py, ise-project.md |
Шаблоны локальной команды сборки и памятки | Копируются установщиком в проект |
identity.py |
Генерация Verilog-2001/VHDL-93 и контроль готового файла | Python 3.9+, stdlib, общий identity.py из templates |
common.tcl |
Пути, язык, вызовы Python, обработка отказов | Tcl 8.5+ в САПР |
ise.tcl |
Полная сборка .xise до .bit |
Xilinx ISE / xtclsh |
vivado.tcl |
Полная сборка .xpr до .bit |
Vivado Project Mode |
quartus.tcl |
Полная сборка .qpf до .sof |
Altera/Intel Quartus II или Prime / quartus_sh |
Python 3 должен быть доступен как python из окружения САПР. Если ISE или
Quartus подставляет старый Python, передайте путь к python.exe шестым
аргументом. Git в PATH нужен для хешей; при недоступном Git получается
явный NOGIT000, локальная сборка продолжается.
1. Конфигурация проекта
Скопируйте firmware_identity.example.json рядом с .xise, .xpr или .qpf
под именем firmware_identity.json. Пример намеренно требует заменить имя
кристалла; задайте своё изделие и точный part number.
| Поле | Смысл |
|---|---|
product |
Имя изделия, например MY_FPGA_BOARD |
target |
Точное обозначение кристалла; информационное поле, настройки part в проекте не меняет |
version |
Последний занятый номер [major, minor, patch]; в примере [0, 1, 0] |
increment_version |
true включает общий сохраняемый итератор; false оставляет ручную версию |
Первая подготовка примера выдаёт 0.1.1. Следующий pre-build выдаёт 0.1.2, включая попытки после ошибки синтеза. Переносы: 0.1.999 → 0.2.0, 0.255.999 → 1.0.0. После 255.255.999 сборка останавливается. Post-build номер не увеличивает. Clean не сбрасывает конфигурацию.
Храните этот JSON в Git. Каталог build/ добавьте в .gitignore проекта;
файлы результатов САПР также должны игнорироваться, иначе они пометят сборку
как dirty. Одна конфигурация JSON обслуживает только одну сборку одновременно.
Для независимых ревизий платы используйте отдельные JSON и выходные каталоги.
2. Подключение паспорта к логике
Генератор создаёт generated/firmware_identity.v и
generated/firmware_identity.vhd. Tcl добавляет в проект только выбранный
язык. Паспорт — комбинационный ROM из 12 слов по 16 бит:
| Относительный адрес слова | Значение |
|---|---|
| 0 | Версия контракта: 1 |
| 1, 2, 3 | Major, minor, patch |
| 4 | Год, 2000..2199 |
| 5 | Месяц в битах 15..8, день в 7..0 |
| 6 | Час UTC в битах 15..8, минута в 7..0 |
| 7 | Секунда UTC |
| 8..11 | Восемь ASCII-символов build ID, первый символ пары в старшем октете |
| 12..15 | Ноль |
Адреса относительные, без привязки к CPU, AXI, Avalon, SPI, Modbus или SETCAN.
Базовый адрес в системе назначает проект. Это тот же порядок слов, что в
firmware_info_to_registers(). Порядок байтов на конкретной шине задаёт
адаптер проекта.
В верхний модуль Verilog добавьте экземпляр:
wire [15:0] identity_data; // 16-битное слово паспорта для мультиплексора чтения шины проекта.
firmware_identity u_identity ( // Экземпляр генерируемого до синтеза паспорта текущей сборки.
.word_addr(identity_word_offset), // Четыре младших бита относительного адреса слова в выделенном окне регистров.
.word_data(identity_data) // Выход должен участвовать в ответе шины, чтобы синтезатор сохранил паспорт.
); // Выбор окна и тактовое согласование выполняет логика проекта.
Для VHDL объявите component в declarative part архитектуры и подключите его в теле архитектуры; component не требует заранее анализировать generated entity:
component firmware_identity is -- Объявление размещается до begin архитектуры верхнего уровня.
port ( -- Интерфейс совпадает с генерируемой entity firmware_identity.
word_addr : in std_logic_vector(3 downto 0); -- Относительный адрес одного из 12 слов паспорта.
word_data : out std_logic_vector(15 downto 0) -- Данные для ответа шины проекта.
); -- Закрывает список портов компонента.
end component; -- Привязка к entity из work выполняется при elaboration.
signal identity_data : std_logic_vector(15 downto 0); -- Объявляется до begin и подключается к чтению регистров.
-- Следующий экземпляр размещается после begin архитектуры верхнего уровня.
u_identity : firmware_identity -- Создаёт экземпляр паспорта без примитивов производителя.
port map ( -- Согласует имена сигналов проекта с интерфейсом компонента.
word_addr => identity_word_offset, -- Четырёхбитный сигнал относительного адреса слова задаёт проект.
word_data => identity_data -- Выход включается в мультиплексор ответа хосту.
); -- Завершает подключение экземпляра.
identity_word_offset, декодер окна и ответ шины реализуйте в проекте.
Паспорт не имеет clock/reset, чтение комбинационное; при необходимости
зарегистрируйте ответ в тактовом домене шины. Без подключения выхода синтезатор
удалит паспорт. Смена языка существующего проекта требует удалить прежний
generated-файл из списка исходников, чтобы не получить два одноимённых модуля.
3. Полная сборка
Команды запускаются из корня проекта в командной строке с настроенным
окружением соответствующей САПР. В примерах templates подключён как
lib/templates. Проект должен уже содержать свой top, part и UCF/XDC/QSF.
Сценарии регистрируют generated-исходник в существующем проекте и выполняют
полную цепочку до файла программирования.
Аргументы общие: project config output image verilog|vhdl [python].
Пути разрешаются относительно начального рабочего каталога. image — точный
путь результата вашей САПР, а output — отдельный каталог паспорта и архивов;
передача output не меняет настройки выходного каталога САПР.
ISE:
rem Собирает существующий ISE-проект, в котором BitGen создаёт top.bit рядом с .xise.
xtclsh "lib/templates/tools/firmware-build/fpga/ise.tcl" "board.xise" "firmware_identity.json" "build/ise" "top.bit" verilog
Используется Generate Programming File -force rerun_all: XST, реализация
и BitGen выполняются заново. Логический false от процесса считается ошибкой.
Vivado:
rem Замените board.runs/impl_1/top.bit реальным путём .bit выбранного implementation run.
vivado -mode batch -source "lib/templates/tools/firmware-build/fpga/vivado.tcl" -tclargs "board.xpr" "firmware_identity.json" "build/vivado" "board.runs/impl_1/top.bit" verilog
Берётся активный implementation run и его родительский synthesis run;
нестандартные имена runs поддерживаются. Оба запуска сбрасываются, затем
выполняются синтез и реализация до write_bitstream. После wait_on_run
отдельно проверяется PROGRESS, поэтому завершение с ошибкой не вызывает упаковку.
Altera / Intel Quartus:
rem Собирает текущую revision из .qpf; image должен совпадать с результатом Assembler.
quartus_sh -t "lib/templates/tools/firmware-build/fpga/quartus.tcl" "board.qpf" "firmware_identity.json" "build/quartus" "output_files/board.sof" vhdl
execute_flow -compile запускает полную компиляцию с Assembler.
Для другой revision передайте седьмой аргумент после пути к Python:
rem Укажите реальный Python 3 и отдельный JSON счётчика ревизии B.
quartus_sh -t "lib/templates/tools/firmware-build/fpga/quartus.tcl" "board.qpf" "identity_B.json" "build/quartus_B" "output_files/board_B.sof" vhdl "C:/Python313/python.exe" "board_B"
Не добавляйте второе увеличение версии в существующие pre-flow/pre-synthesis hooks. Эти Tcl-файлы предназначены для запуска полной сборки из командной строки; их нельзя подключать как вложенные hooks этапов синтеза. Для выпуска через данную схему запускайте указанный сценарий, в том числе после работы в GUI.
4. Результаты и проверка
build/vivado/
generated/
firmware_identity.h
firmware_identity.v
firmware_identity.vhd
firmware_identity.json
firmware/
HASH_YYYY-MM-DD_HH-MM-SS_UTC+3/
top.bit
top.bit.manifest.json
top.bit.sha256
firmware_identity.v
firmware_identity.json
Для VHDL архив содержит выбранный .vhd, для Quartus — .sof вместо .bit.
Manifest и .sha256 также создаются рядом с исходным файлом программирования.
Хеш и дата архивной папки берутся из pre-build, дата имени переводится в UTC+3;
в самом паспорте остаётся UTC. Знак + у build ID означает изменённые исходники
или templates. firmware_identity.h — сопутствующий результат общего генератора;
FPGA-сценарии используют HDL.
Упаковка отклоняет отсутствующий, пустой или не обновившийся после prepare
файл. Проверяется содержимое и время записи: повторная запись тех же байтов
допускается. Это защита от старого результата; она не проверяет наличие паспорта
внутри vendor bitstream. Правильность подключения подтверждается чтением всех
12 регистров с работающей ПЛИС и сравнением с fpga.register_words в manifest.
SHA-256 относится к файлу программатора целиком и хранится снаружи образа.
Проверить сохранённый файл можно общим инструментом:
rem Проверяет размер и SHA-256 указанного файла по созданному рядом manifest.
python "lib/templates/c/firmware-info/tools/identity.py" verify --image "board.runs/impl_1/top.bit" --manifest "board.runs/impl_1/top.bit.manifest.json"
Для локального экспорта папки выпуска повторите только finish с --export;
номер версии при этом не меняется:
rem Копирует текущую архивную папку и проверяет SHA-256 экспортной копии.
python "lib/templates/tools/firmware-build/fpga/identity.py" finish --metadata "build/vivado/generated/firmware_identity.json" --output "build/vivado/firmware" --export "D:/Firmware/FPGA"
Шаблон выпускает .bit и .sof. Преобразование в .mcs, .bin, .pof или
.rbf, загрузка на плату и публикация в сетевую базу требуют отдельного
проектного этапа. Контрольная сумма нативного образа не переносится на
преобразованный файл: для него создайте отдельные seal/verify общим инструментом.
Проверки и состояние
Хостовые тесты проверяют эталон всех 12 слов, совпадение Verilog/VHDL, итератор, свежесть результата, повреждение SHA-256, архив и экспорт. Реальные Tcl-сценарии исполняются в Tcl из Python tkinter с заменой API производителей; Python-генератор и упаковка выполняются полностью. Нужен Python с tkinter/Tcl, графическое окно не открывается.
rem Запускает проверки адаптера и управляющих сценариев без лицензии САПР.
python -m unittest discover -s tools/firmware-build/fpga/tests -v
Шаблон пока не подключён к конкретной плате. Полный синтез и чтение паспорта на железе требуют установленной САПР, проекта и платы; хостовые тесты эти проверки не заменяют.
Команды сверены с руководствами производителей: ISE Command Line Tools UG628, Vivado: запуск синтеза и реализации UG939, Quartus: полный Tcl flow.