Files
templates/tools/firmware-build/fpga/README.md
T
Andrey 62c0492bfd feat(firmware-build): Добавь сборку и паспорта проектов ПЛИС
Подключи ISE, Vivado и Quartus к общему итератору версии и HDL-паспорту. Проверяй новый bit/sof до создания manifest, SHA-256 и архива выпуска.

Добавь установку локальных команд ISE, инструкции переноса и регрессионные проверки успешных и прерванных сборок.
2026-10-23 14:16:21 +03:00

242 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Контроль прошивок ПЛИС: Xilinx ISE, Vivado и Altera Quartus
Для ISE: запустите `INSTALL_ISE.bat`, укажите `.xise`, затем используйте
созданный в проекте `build_firmware.bat`. [Краткая инструкция](ISE_PORTING.md).
Шаблон подключает к существующему проекту ПЛИС общий механизм
[`firmware-info`](../../../c/firmware-info/README.md): сохраняемый итератор
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 добавьте экземпляр:
```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:
```vhdl
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:**
```bat
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:**
```bat
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:**
```bat
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:
```bat
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. Результаты и проверка
```text
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 относится к файлу программатора целиком и хранится снаружи образа.
Проверить сохранённый файл можно общим инструментом:
```bat
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`;
номер версии при этом не меняется:
```bat
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,
графическое окно не открывается.
```bat
rem Запускает проверки адаптера и управляющих сценариев без лицензии САПР.
python -m unittest discover -s tools/firmware-build/fpga/tests -v
```
Шаблон пока не подключён к конкретной плате. Полный синтез и чтение паспорта
на железе требуют установленной САПР, проекта и платы; хостовые тесты эти
проверки не заменяют.
Команды сверены с руководствами производителей:
[ISE Command Line Tools UG628](https://docs.amd.com/v/u/en-US/devref),
[Vivado: запуск синтеза и реализации UG939](https://docs.amd.com/r/2023.1-English/ug939-vivado-designing-with-ip-tutorial/Step-8-Launch-Synthesis-and-Implementation),
[Quartus: полный Tcl flow](https://www.intel.com/content/www/us/en/docs/programmable/683432/22-1/the-tcl-shell-in-interactive-mode-example.html).