FPGA Project Build System - fpga-lib/site_scons GitHub Wiki
Система сборки предназначена для автоматизации рутинных операций при работе с FPGA проектами и предоставляет следующие возможности:
- поддержка множественных вариантов (конфигураций) сборки;
- задание параметров проекта в виде пары "ключ : значение" в текстовых файлах;
- указание исходных файлов (hdl, constraints) в виде списка в текстовых файлах;
- генерирование различных целевых файлов, таких как скрипты для сборки, конфигурационные файлы IP ядер, вспомогательные файлы hdl или Tcl с параметрами проекта и т.д.;
- компиляция библиотек симулятора, как библиотеки моделей используемых IP ядер, блочных дизайнов, HLS IP и т.п., так и рабочей библиотеки проекта (work library);
- создание проекта САПР FPGA (в настоящее время поддерживается только Xilinx Vivado);
- запуск симулятора в GUI режиме и на прогон в консоли (с автоматической компиляцией библиотек);
- запуск сборки целевого проекта FPGA (синтез, размещение и разводка) до получения выходного файла (bitstream);
- запуск САПР FPGA (с автоматической сборкой всех зависимостей).
Система сборки построена на основе SCons и осуществляет все действия с учётом необходимости выполнения: производит отслеживание зависимостей и запускает инструменты только если действие реально необходимо. Язык описания сборочных скриптов Python.
Не является секретом то, что при работе над проектами, связанными с использованием FPGA, приходится использовать достаточно сложный инструментарий (синтезаторы, симуляторы, вспомогательные средства, IDE и т.п.), эффективная работа с которым зачастую может вызывать затруднения. В частности, указание значения какого-либо параметра (частота генератора, ширина шины и т.п.) может влиять на различные этапы работы и использоваться разными инструментами. Для этого нужно организовать способ передачи значения параметра во всех необходимых случаях: в HDL, при создании IP ядер, в свойствах проекта FPGA. На выручку в подобных случаях приходит Tcl
, но, к сожалению, этот способ нельзя назвать удобным и универсальным. Кроме того, при изменении того или иного параметра требуется, как правило, пересборка только тех частей проекта, которые зависят от этого параметра, т.е. нужно строить "дерево" зависимостей и выполнять действия по требованию (если зависимость изменилась). С этим Tcl
справиться не может в принципе, т.к. не приспособлен для этого. Для решения этой и сопутствующих задач и предназначена описываемая сборочная система на основе SCons
.
Помимо сборки по зависимостям ещё одной насущной потребностью при разработке ПО в целом (а не только при работе с FPGA) является возможность создавать так называемые конфигурации, т.е. способность получать на выходе разные выходные продукты в зависимости от тех или иных настроек проекта. При этом сами исходные файлы проекта как правило остаются неизменными, а изменения касаются служебной части проекта. Наиболее типовым примером использования конфигураций при разработке традиционного ПО является генерирование выходных файлов Release/Debug, отличающихся уровнем оптимизации, наличием встроенных отладочных символов и др. При разработке кода для FPGA так же возникает подобная необходимость хотя и со своими особенностями.
Кроме автоматизации процесса сборки по зависимостям сборочная система предлагает и поддерживает так называемые сборочные варианты (сборочные конфигурации в другой, более традиционной, терминологии — "вариант" является термином SCons
).
Сборочный вариант — это отдельный набор конфигурационных файлов, задающих параметры, списки исходных файлов, используемых IP ядер, констрейнов и т.д., а также возможных сценариев сборки. Каждый сборочный вариант является независимым от других, что позволяет использовать произвольное количество сборочных вариантов совершенно различного (индивидуального) назначения без увеличения сложности работы. При этом существует возможность выделить общую часть сборочных вариантов в отдельном месте, что позволяет избежать дублирования одинаковых частей конфигурации.
SCons
как сборочная система определяет основные подходы к выполнению процесса сборки. В частности, предлагаемая модель иерархической сборки используется для организации вариантов (конфигураций) сборки, где каждый вариант позволяет осуществлять процессы подготовки необходимых файлов (целей), компиляцию библиотек, запуск моделирования и синтеза и т.д. по отдельному, определяемому только параметрами текущего варианта, сценарию. Это достигается тем, что каждый вариант имеет свои собственные настройки: параметры проекта, списки исходных файлов для синтеза и симулятора, перечень и настройки IP ядер, файлы констрейнов и т.д.
Таким образом, из одних и тех же исходных файлов проекта можно получать существенно разные результаты в зависимости от назначения варианта — в частности, вести проект для различных целевых плат и разных FPGA, осуществлять работу над отдельными модулями проекта, создавая для них отдельные верификационные окружения, и т.п.
Типовой пример: пока целевая плата с FPGA находится в разработке и монтаже, работа зачастую ведётся на отладочной плате (Dev Kit), а в дальнейшем проект переносится на целевую плату. Нередко бывает, что на отладочной и целевой платах стоят FPGA в разных корпусах, что неизбежно приводит к необходимости портирования проекта, что легко достигается созданием разных сборочных вариантов, отличающихся как минимум спецификацией целевой FPGA и файлами констрейнов.
Другой пример. Часто бывает удобным (а то и необходимым) произвести верификацию и синтез отдельного модуля (или группы модулей) проекта, особенно, если функциональность модуля является достаточно сложной. Для выполнения этой работы также хорошо подходит концепция сборочных вариантов: в этом случае как обычно создаётся отдельный вариант, для которого описывается всё необходимое верификационное окружение для данного модуля. При этом файловая структура исходных файлов HDL остаётся неизменной.
Для облегчения старта предлагается простой проект-шаблон, содержащий примеры использования системы сборки в виде трёх сборочных вариантов (по названиям отладочных плат). Для установки на локальный компьютер можно поступить следующим образом:
git clone --recursive https://github.com/fpga-lib/vivado-boilerplate.git
либо
git clone --branch=<branch-name> https://github.com/fpga-lib/vivado-boilerplate.git
git submodule update --init --recursive
Помимо этого существует более развитый пример, значительно лучше подходящий для рабочих проектов. Подробное описание примера.
Целевой проект строится по следующей схеме (конкретные пути могут быть произвольными, ниже приведён пример того, как это может быть):
.
├──/build
│ ├──/main
│ │ ├──/sim
│ │ ├──/src
│ │ └──/syn
│ └──/test
│ ├──/sim
│ ├──/src
│ └──/syn
├──/site_scons
├──/src
│ ├──/cfg
│ │ ├──/main
│ │ │ ├──/<...>
│ │ │ └── main.scons
│ │ └──/test
│ │ ├──/<...>
│ │ └── test.scons
│ ├──/sim
│ └──/syn
└── SConstruct
Пример содержит два сборочных варианта: main
и test
, расположенных в директории src/cfg/
. Система создаёт соответствующие директории в build
с исполнительными окружениями для запуска процессов моделирования, синтеза и т.д.
Здесь файлами, которые необходимо править вручную, являются:
-
SConstruct
, являющийся корневым файлом сборочной системы, работа которой начинается с его анализа; -
src/syn/*
иsrc/sim/*
, где находятся исходные файлы HDL; -
src/cfg/<variant name>/*
со*.scons
файлом во главе, в котором находится описание всех сценариев сборки для данного варианта.
Директория site_scons
является служебной и предназначена для обеспечения работы сборочной системы.
Директория build
и всё её содержимое является продуктом работы сборочной системы и создаётся автоматически. Технические подробности будут приведены далее, в данный момент следует отметить, что в директории build
создаются директории по именам вариантов, т.е. каждый вариант имеет собственные продукты генерации: IP ядра, симуляционные библиотеки, проект САПР FPGA и т.д.
Описанный подход позволяет перенести всю управляющую часть проекта в небольшое количество текстовых файлов, из которых создаются всё необходимое для целевой работы. В частности, проект САПР Vivado в данном случае не является большой ценностью — его можно безопасно удалить (например, после серии экспериментов, когда параметры проекта изменялись средствами GUI, и нет желания восстанавливать их вручную) и сгенерировать заново за короткое время. Это же обстоятельство значительно облегчает работу с системами управления версиями, т.к. отсутствует необходимость помещать под контроль значительное количество файлов, назначение части которых не всегда понятно без детального разбора. Под контроль версий попадает лишь небольшое количество относительно небольших конфигурационных файлов.
Ещё одно важное обстоятельство состоит в том, что управление всеми частями проекта — и то, что идёт на синтез, и то, что попадает на моделирование, и управление созданием IP ядер, — всё это управляется из одного источника: конфигурационных текстовых файлов. Например, если необходимо изменить значение тактовой частоты, которая влияет на синтез, на создание IP PLL и на тестбенч симулятора, то достаточно это значение указать только в одном конфигурационном файле, далее сборочная система автоматически создаст все нужные цели (скрипты, описания IP ядра, заголовочные HDL и Tcl файлы с параметрами для синтеза и симуляции).
Поддержка иерархической сборки со стороны SCons
даёт возможность создавать варианты сборки как часть иерархии сборочного процесса. Технически это осуществляется с помощью задания сценариев в файлах SConstruct
и SConscript
(они же файлы *.scons
; можно использовать любой способ именования, но в случае <name>.scons
удобнее работать с этими файлами в текстовом редакторе, т.к. в этом случае можно задать файлу осмысленное имя, по которому сразу видно, с каким вариантом осуществляется работа).
SConstruct
определяет конкретный вариант, который используется в работе, а так же задаёт общие свойства сборки всех вариантов, после чего управление передаётся сборочному сценарию варианта (SConscript
/*.scons
). Подробнее см. Build Variants.
Сценарии сборки — это описание целей сборки и их зависимостей, оформленное в виде скрипта SCons
, который является файлом на языке Python
, находящимся в корневой директории сборочного варианта — SConscript
или <variant-name>.scons
. Более подробно см. Сценарии сборки.
Для работы сборочной системы требуется Python
версии не ниже 3.6 и SCons
не ниже версии 3.1.2. Предпочтительно установить свежий SCons
из репозитория PyPi
:
pip install scons
Запуск сборки инициируется командой:
scons [variant=<[path/]variant name>] [<target>]
Если аргументы команды scons
отсутствуют, то выполняется сборка целей по умолчанию для сборочного варианта так же по умолчанию. Сборочный вариант по умолчанию задаётся в файле SConstruct
, а цели по умолчанию — в скрипте сборочного варианта (список целей по умолчанию указывается с помощью Default()
).
При запуске scons
может быть полезным указывать некоторые ключи, например:
- -Q: подавляет сообщения "Reading/Building", которые могут загромождать вывод сборки.
- -D: заставляет программу автоматически искать корневой файл сборки
SConstruct
, собирает цели, отмеченныеDefault()
. Этот ключ позволяет осуществлять запуск из любой директории внутри проекта, что удобно. - -s: подавляет печать запускаемых команд.
Чтобы не указывать эти ключи каждый раз руками, их можно поместить в переменную окружения операционной системы SCONSFLAGS
, например:
$ setenv SCONSFLAGS "-Q"