Tool vivado🔗
Environment variables🔗
Переменные сборочного и исполнительного окружения удобно задать в сборочном скрипте:
#-------------------------------------------------------------------------------
#
# Environment
#
envx['ENV']['DISPLAY'] = os.environ['DISPLAY']
envx['ENV']['HOME'] = os.environ['HOME']
envx['ENV']['XILINX'] = env.XILINX
envx['ENV']['MENTOR'] = env.MENTOR
envx['ENV']['MGLS_LICENSE_FILE'] = env.MGLS_LICENSE_FILE
envx['ENV']['XILINX_VIVADO'] = env.XILINX_VIVADO
envx['XILINX_VIVADO'] = env.XILINX_VIVADO
envx['XILINX_HLS'] = env.XILINX_HLS
envx['QUESTABIN'] = env.QUESTABIN
envx['QUESTASIM'] = env.QUESTASIM
envx['VENDOR_LIB_PATH'] = env.VENDOR_LIB_PATH
envx['ROOT_PATH'] = dirs.ROOT
envx['BUILD_PATH'] = dirs.BUILD
где env
и dirs
— объекты с параметрами, получаемые:
а конфигурационные файлы env.yml
и dirpath
представляют собой нечто подобное:
#
# env.yml
#
parameters:
XILINX : = os.environ['XILINX']
MENTOR : = os.environ['MENTOR']
XILINX_TOOL_VERSION : '2021.2'
QUESTA_TOOL_VERSION : '2021.1'
XILINX_VIVADO : = os.path.join(XILINX, 'Vivado', XILINX_TOOL_VERSION)
XILINX_HLS : = os.path.join(XILINX, 'Vitis_HLS', XILINX_TOOL_VERSION)
MGLS_LICENSE_FILE : = os.path.join(MENTOR, 'license.dat')
QUESTABASE : = os.path.join(MENTOR, QUESTA_TOOL_VERSION, 'questasim')
QUESTABIN : = os.path.join(QUESTABASE, 'bin')
QUESTASIM : = os.path.join(QUESTABASE, 'linux_x86_64', 'vsim')
VENDOR_LIB_NAME : = 'xlib-vv' + XILINX_TOOL_VERSION + '-qs' + QUESTA_TOOL_VERSION
VENDOR_LIB_PATH : = os.path.join(MENTOR, 'vendor', VENDOR_LIB_NAME, 'func')
#
# dirpath.yml
#
import : main
options:
suffix : _DIR
parameters:
ROOT : = os.path.abspath(str(Dir('#')))
LIB : = os.path.join(ROOT, 'lib')
SRC : = os.path.join(ROOT, 'src')
COMMON : = os.path.join(SRC, 'cfg', 'common')
CFG : = os.path.join(SRC, 'cfg', main.VARIANT_NAME)
SCRIPT : = os.path.join(CFG, 'script')
SRC_SYN : = os.path.join(SRC, 'pl', 'syn')
SRC_SIM : = os.path.join(SRC, 'pl', 'sim')
CFG_LOCAL : = os.path.join(CFG, 'env')
CFG_COMMON : = os.path.join(COMMON, 'env')
SCRIPT_COMMON : = os.path.join(COMMON, 'script')
BUILD : = os.path.join(ROOT, 'build', main.VARIANT_NAME)
Из описанных переменных окружения далее формируются пути к исполняемым файлам внешних инструментов и строится структура файлов и директорий для синтезатора и симулятора.
#-------------------------------------------------------------------------------
#
# Tool 'vivado'
#
...
VIVADO = os.path.join(env['XILINX_VIVADO'], 'bin', 'vivado')
HLS = os.path.join(env['XILINX_HLS'], 'bin', 'vitis_hls')
...
env['BUILD_SYN_PATH'] = os.path.join(env['BUILD_PATH'], 'syn')
...
#-------------------------------------------------------------------------------
#
# Tool 'questa'
#
...
env['VLOGCOM'] = os.path.join(env['QUESTABIN'], 'vlog')
env['VCOMCOM'] = os.path.join(env['QUESTABIN'], 'vcom')
env['VLIBCOM'] = os.path.join(env['QUESTABIN'], 'vlib')
env['VMAPCOM'] = os.path.join(env['QUESTABIN'], 'vmap')
env['VSIMCOM'] = os.path.join(env['QUESTABIN'], 'vsim')
...
env['BUILD_SIM_PATH'] = os.path.join(env['BUILD_PATH'], 'sim')
env['SIM_CMD_SCRIPT'] = os.path.join(env['ROOT_PATH'], 'site_scons', 'site_tools', 'questa.tcl' )
...
ЗАМЕЧАНИЕ
Переменная envx['BUILD_PATH']
задаёт базовый путь для текущей сборки – место, где создаются все продукты генерации, начиная от генерируемых исходных и заголовочных файлов и заканчивая проектом синтезатора, скриптами симулятора и т.п.
Как правило, значение этой переменной связано с именем сборочного варианта – так проще избежать путаницы: все продукты генерации, компиляции, симуляции, синтеза и т.д. воздаются в директории с тем же именем, что и имя сборочного варианта, включая относительный путь.
Однако, существует возможность указать любой произвольный путь для целевой сборки, определив переменную сборочного окружения envx['BUILD_PATH']
соответствующим образом. Это позволяет, в частности, генерировать разные целевые сборки из одного и того же сборочного варианта, указав, например, разные параметры сборки (через аргументы командной строки), и, что крайне важно, такой подход позволяет запускать эти сборки параллельно.
Возможность запускать сборки параллельно актуальна при прогоне тестов на симуляторе: можно запустить несколько длительных тестов из одного и того же сборочного варианта, указав параметром разные пути к исходным файлам тестов. За счёт многоядерности современных процессоров достигается существенная экономия времени тестирования.
Переменные общего назначения🔗
Name | Description | Default Value |
---|---|---|
VIVADO_VERNUM |
Номер используемой версии САПР Vivado |
Извлекается из env['XILINX_VIVADO'] |
VIVADO_PROJECT_NAME |
Название проекта САПР Vivado | 'vivado_project' |
TOP_NAME |
Имя модуля верхнего уровня | 'top' |
DEVICE |
Наименование ПЛИС | 'xc7a200tfbg676-2' |
VIVADO_PROJECT_MODE |
Режим работы с САПР. В настоящее время поддерживается только Project Mode |
True |
SYNCOM |
Команда запуска САПР в пакетном режиме |
VIVADO + ' -mode batch' |
SYNSHELL |
Команда запуска САПР в интерактивном режиме |
VIVADO + ' -mode tcl' |
SYNGUI |
Команда запуска САПР в графическом режиме |
VIVADO + ' -mode gui' |
HLSCOM |
Команда запуска HLS компилятора | HLS |
SYN_TRACE |
Опция управления трассировкой команд |
' -notrace' |
SYN_JOURNAL |
Опция ведения журнала | ' -nojournal' |
PROJECT_CREATE_FLAGS |
Опции, передаваемые Tcl команде create_project . Типовое значение -f (force),что вынуждает САПР FPGA создавать проект даже если он открыт |
'' |
HLSFLAGS |
Флаги компилятора HLS | '' |
VERBOSE |
Управляет печатью полной командной строки выполняемого действия |
True |
Директории и пути🔗
Name | Description | Default Value |
---|---|---|
CFG_PATH |
Директория текущего сборочного варианта |
os.path.abspath(os.curdir) |
CONFIG_SEARCH_PATH |
Список путей, по которым осуществляется поиск конфи- гурационных файлов во время работы сканера (обработка секции import в конфигу-рационных файлах) |
env['CFG_PATH'] |
BUILD_SRC_PATH |
Директория, куда помещаются сгенерированные исходные файлы (*.svh, *.tcl) |
os.path.join(env['BUILD_PATH'], 'src') |
BUILD_SYN_PATH |
Директория, в которой создаётся исполнительное окружение для синтеза (проект, IP ядра и т.п.) |
os.path.join(env['BUILD_PATH'], 'syn') |
IP_OOC_PATH |
Директория для IP ядер, скриптов, библиотеки симуляционных моделей |
os.path.join(env['BUILD_SYN_PATH'], 'ip_ooc') |
BD_OOC_PATH |
Директория для блочных дизайнов, создаваемых out-of-context |
os.path.join(env['BUILD_PATH'], 'bd') |
BUILD_HLS_PATH |
Директория для создания проектов HLS, скриптов их создания и компи- ляции и репозитория целевых IP ядер |
os.path.join(env['BUILD_SYN_PATH'], 'hls') |
INC_PATH |
Список путей, в которых произво- дится поиск включаемых файлов. Поиск автоматически выполняется в директориях, где расположены исходные файлы, и INC_PATH дополняет этот список элементами, в которых исходных файлов нет, но есть включаемые — например, BUILD_SRC_PATH |
'' |
IP_SCRIPT_DIRNAME |
Имя директории, в которую поме- щаются скрипты для обслужива- ния IP ядер. Сама директория располагается в IP_OOC_PATH |
'_script' |
BD_SCRIPT_DIRNAME |
Имя директории, в которую помещаются Tcl скрипты создания OOC блочных дизайнов. Сама директория располагается в BD_OOC_PATH |
'_script' |
SIM_SCRIPT_DIRNAME |
Имя директории, где поме- щаются скрипты для создания симуляционных библиотек IP ядер, блочных дизайнов, HLS IP ядер и т.п. |
'sim_script' |
SIM_SCRIPT_PATH |
Директория, содержащая скрипты для создания симуляционных библиотек IP ядер, блочных дизайнов, HLS IP ядер и т.п. |
os.path.join(env['BUILD_SYN_PATH'], env['SIM_SCRIPT_DIRNAME']) |
HLS_SCRIPT_DIRNAME |
Имя директории, в которую помещаются скрипты для создания и компиляции HLS IP |
'_script' |
HLS_IP_NAME_SUFFIX |
Суффикс для имён HLS IP | '_hlsip' |
Расширения файлов🔗
Name | Description | Default Value |
---|---|---|
CONFIG_SUFFIX |
конфигурационные файлы | 'yml' |
TOOL_SCRIPT_SUFFIX |
скрипты | 'tcl' |
IP_CORE_SUFFIX |
IP ядра | 'xci' |
BD_SUFFIX |
Блочные дизайны | 'bd' |
DCP_SUFFIX |
Design Checkpoint. Архив, содержащий результат работы САПР: синтезированный проект, разведённый, синтезированное IP ядро и т.п. |
'dcp' |
BITSTREAM_SUFFIX |
выходной файл | 'bit' |
CONSTRAINTS_SUFFIX |
констрейны | 'xdc' |
VIVADO_PROJECT_SUFFIX |
проект Vivado | 'xpr' |
V_SUFFIX |
Verilog | 'v' |
SV_SUFFIX |
SystemVerilog | 'sv' |
V_HEADER_SUFFIX |
Verilog header | 'vh' |
SV_HEADER_SUFFIX |
SystemVerilog header | 'svh' |
HLS_TARGET_SUFFIX |
HLS IP repository archived item | 'zip' |
USER_DEFINED_PARAMS |
Пользовательские параметры, передаваемые на этап создания проекта САПР путём создания соответствующих переменных в скрипте, который создаёт проект Vivado |
{} |
Builders🔗
Перечислены билдеры и псевдобилдеры. Билдеры как правило не используются напрямую, т.к. они имеют вполне определённый интерфейс запуска, который далеко не всегда удобен, поэтому в скрипте сборочных сценариев обычно используются псевдобилдеры, которые по сути являются "обёртками" вокруг самих билдеров.
IpCreateScript🔗
True builder
Генерирует Tcl скрипт, с помощью которого создаётся IP ядро.
IpCreateScripts🔗
Pseudo-builder
Генерирует Tcl скрипты для создания IP ядер из списка конфигурационных файлов. Создаёт скрипты по схеме <name>-create.tcl
. Использует билдер IpCreateScript
.
Пример использования:
IpSynScript🔗
True builder
Генерирует скрипт для out-of-context синтеза IP ядра.
IpSynScripts🔗
Pseudo-builder
Генерирует Tcl скрипты для синтеза IP ядер из списка конфигурационных файлов. Создаёт скрипты по схеме <name>-syn.tcl
. Использует билдер IpSynScript
.
Пример использования:
IpCreate🔗
True builder
Создаёт IP ядро.
CreateIps🔗
Pseudo-builder
Создаёт IP ядра по списку скриптов, сгенерированы с помощью IpCreateScripts
. Использует билдер IpCreate
.
Пример использования:
IpSyn🔗
True builder
Синтезирует IP ядро в режиме out-of-context.
SynIps🔗
Pseudo-builder
Синтезирует IP ядра, используя в качестве зависимостей скрипты, созданные IpSynScrips
и файлы самих IP ядер. Использует билдер IpSyn
.
Пример использования:
BdCreate🔗
True builder
Создаёт блочный дизайн на основе Tcl скрипта, описывающего используемые элементы (cells), их межсоединения и порты. Блочный дизайн создаётся в виде отдельно стоящего Vivado проекта (out-of-context). В дальнейшем блочный дизайн из такого проекта может быть подключен в рабочий проект. Методика подготовки Tcl скрипта описана по ссылке.
CreateOocBd🔗
Pseudo-builder
Создаёт проекты с блочными дизайнами на основе списка конфигурационных файлов. Использует BdCreate
билдер.
HlsCSynthScript🔗
True builder
Создаёт Tcl скрипт для создания HLS проекта и его компиляции. Зависимостью является yml
файл параметров HLS. В результате создаётся Tcl скрипт с командами создания HLS проекта и его компиляции до элемента IP репозитория. Пример целевого скрипта:
--------------------------------------------------------------------------------
#
# This file is automatically generated. Do not edit the file!
#
#--------------------------------------------------------------------------------
set PROJECT_NAME adder
set TOP_NAME adder
set DEVICE xc7a50tftg256-1
set SOLUTION_NAME sol_1
# Project structure
open_project -reset ${PROJECT_NAME}
# Add syn sources
add_files -cflags "-g -DDATA_WIDTH=4" /opt/slon/xilinx/build-system-examples/src/hls/adder/src/adder.cpp
# Add sim sources
add_files -tb -csimflags "-g -I/opt/cad/mentor/2021.1/questasim/include -I/opt/cad/xilinx/Vitis_HLS/2021.2/include" /opt/slon/xilinx/build-system-examples/src/hls/adder/tb/main.cpp
set_top ${TOP_NAME}
# Add solution
open_solution -reset -flow_target vivado ${SOLUTION_NAME}
set_part ${DEVICE}
create_clock -period 8.0ns -name adder_clk
set_clock_uncertainty 25%
# Add hooks
source /opt/slon/xilinx/build-system-examples/src/cfg/7a50t/hls/adder/directives.tcl
csynth_design
export_design -rtl verilog -format ip_catalog -ipname adder -version 1.0 -vendor slon -library hls -output /opt/slon/xilinx/build-system-examples/build/7a50t/syn/hls/ip/adder.zip
exit
#--------------------------------------------------------------------------------
CreateHlsCSynthScript🔗
Pseudo-builder
Псевдобилдер, получающий аргументом список конфигурационных HLS yml
файлов и осуществляющий запуск для каждого из них билдера HlsCSynthScript
. Пример использования:
HlsCSynth🔗
True builder
Билдер выполняет создание HLS проекта и его компиляцию, в результате которой создаётся элемент IP репозитория, пригодный для использования в качестве IP ядра в целевом проекте. Напрямую не используется, вызывается из псевдобилдера LaunchHlsCSynth
(см. ниже)
LaunchHlsCSynth🔗
Pseudo-builder
Служит для запуска создания и компиляции HLS проектов. Пример использования:
где,HlsCSynScripts
— список скриптов, полученных в результате работы CreateHlsCSynthScript
, hls
— список конфигурационных yml
файлов HLS.
HlsIpSynScripts🔗
Pseudo-builder
Псевдобилдер осуществляет генерирование скриптов создания IP ядер из HLS IP репозитория, созданного инструментами, описанными выше. Полученные скрипты далее используются точно так же, как и скрипты для синтеза IP ядер, получаемые из конфигурационных yml
файлов IP ядер.
Использование результата:
# IP scripts
IP_Create_Scripts = envx.IpCreateScripts(ip) # скрипты создания IP из yml описания
IP_Syn_Scripts = envx.IpSynScripts(ip) # скрипты синтеза IP
HLS_IP_Syn_Scripts = envx.HlsIpSynScripts(HlsCsyn) # скрипты синтеза HLS IP
# IP cores
IP_Cores = envx.CreateIps(IP_Create_Scripts) # создание IP ядер
All_IP = IP_Cores + HlsCsyn # полный список IP ядер: пользовательских и HLS
All_IP_Syn_Scripts = IP_Syn_Scripts + HLS_IP_Syn_Scripts # скрипты для синтеза всех IP ядер
IP_OOC_Syn = envx.SynIps(All_IP_Syn_Scripts, All_IP) # синтез всех IP ядер
CfgParamsHeader🔗
True builder
Создаёт заголовочные файлы HDL с параметрами, взятыми из указанных конфигурационных файлов. Генерируется пара файлов:
<hdl-param-filename>.svh
;<hdl-param-filename>_pkg.svh
,
где <hdl-param-filename>
– имя целевого файла, задаваемое в скрипте сборочного сценария при вызове билдера.
Если в конфигурационном файле, являющимся зависимостью, определён раздел options
, в котором, в свою очередь, определены параметры prefix
, suffix
, то значения этих параметров конкатенируются с именами рабочих параметров, соответственно до и после:
Результат:
<hdl-param-filename>.svh
:
<hdl-param-filename>_pkg.svh
:
...
package <hdl-param-filaname>;
...
localparam int PARAMS_DATA = 10;
localparam int PARAMS_WIDTH = 8;
...
endpackage
...
Для параметров поддерживается три типа:
- целый знаковый
int
; - с плавающей точкой
real
; - строковый
string
.
Типы параметров используются в package и выводятся из типов параметров конфигурационных (yaml) файлов.
CreateCfgParamsHeader🔗
Pseudo-builder
Может принимать в качестве зависимостей строку с именами файлов, разделёнными пробелом, или список. Создаёт полный (абсолютный) путь для каждого файла и вызывает билдер CfgParamsHeader
.
Пример использования:
hdl_param_deps = 'main.yml clk.yml'
...
CfgParamsHeader = envx.CreateCfgParamsHeader(os.path.join(envx['BUILD_SRC_PATH'], 'cfg_params.svh'), hdl_param_deps)
CfgParamsTcl🔗
True builder
Создаёт Tcl файл с параметрами, взятыми из указанных конфигурационных файлов. Как и билдер по генерированию включаемых HDL файлов, данный билдер распознаёт раздел options
с параметрами prefix
и suffix
, используя их сходным образом:
#
# dirpath.yml
#
options:
suffix : _DIR
parameters:
SRC_SYN : = '{' + os.path.join('src', 'syn') + '}'
SRC_SIM : = '{' + os.path.join('src', 'sim') + '}'
Результат:
CreateCfgParamsTcl🔗
Pseudo-builder
Может принимать в качестве зависимостей строку с именами файлов, разделёнными пробелом, или список. Создаёт полный (абсолютный) путь для каждого файла и вызывает билдер CfgParamsTcl
.
Пример использования:
CfgParamsTcl = envx.CreateCfgParamsTcl(os.path.join(envx['BUILD_SRC_PATH'], 'cfg_params.tcl'), 'params.yml')
VivadoProject🔗
True builder
Создаёт проект САПР Vivado.
CreateVivadoProject🔗
Pseudo-builder
Принимает в качестве зависимостей исходные файлы HDL, файлы констрейнов и IP ядер. Генерирует имя целевого файла, обрабатывает список зависимостей, формируя полные (абсолютные) пути для каждого файла HDL и констрейнов, подготавливает результирующий список и вызывает билдер VivadoProject
. Целевым файлом является <project name>.prj
, который является копией project name>.xpr
. Такое решение используется по той причине, что САПР Vivado в процессе работы постоянно изменяет xpr
файл, что делает его непригодным в качестве цели для системы сборки. С другой стороны, целевой файл должен быть релевантным к изменениям настроек проекта, т.к. система сборки проверяет актуальность файла по MD хэшу. Копия файла проекта достаточно хорошо отвечает вышеперечисленным требованиям.
Пример использования:
xpr_hook = read_sources('xpr_hook.yml')
...
xpr_deps = 'src_syn.yml xdc.yml'.split() + xpr_hook
...
VivadoProject = envx.CreateVivadoProject(xpr_deps , IP_Cores)
SynthVivadoProject🔗
True builder
Выполняет синтез проекта. Целевым файлом является <top name>
.dcp, расположенный в <project name>.runs/synth_1
.
LaunchSynthVivadoProject🔗
Pseudo-builder
Осуществляет подготовку и запуск проекта на синтез. Принимает в качестве зависимостей целевой файл проекта и перечень исходных файлов, который может быть представлен в виде строки с именами файлов, разделёнными пробелом, либо в виде списка. Запускает билдер SynthVivadoProject
.
Пример использования:
src_syn = read_sources('src_syn.yml')
xdc = read_sources('xdc.yml')
...
syn_deps = src_syn + xdc
...
VivadoProject = envx.CreateVivadoProject(xpr_deps , IP_Cores)
...
SynthVivadoProject = envx.LaunchSynthVivadoProject(VivadoProject, syn_deps)
ImplVivadoProject🔗
True builder
Производит этапы размещения и разводки проекта (place and route). Целевым файлом является битстрим <project name>.runs/impl_1/<top level>.bit
LaunchImplVivadoProject🔗
Pseudo-builder
Выполняет формирование целевого пути и запускает билдер ImplVivadoProject
.
Пример использования:
SynthVivadoProject = envx.LaunchSynthVivadoProject(VivadoProject, syn_deps)
ImplVivadoProject = envx.LaunchImplVivadoProject(SynthVivadoProject)
OpenVivadoProject🔗
True builder
Запускает САПР Vivado в графическом режиме с переходом в директорию проекта и загрузкой проекта. При этом проверяются зависимости и при необходимости выполняется сборка по всей цепочке. Типовой сценарий построен так, что при запуске проекта в графическом режиме проверяется актуальность целевого файла проекта и целевых файлов синтезированных IP ядер. Смысл этого в том, чтобы когда проект запущен в графическом режиме, все "пререквизиты" (проект и IP ядра) были в актуальном состоянии, и пользователь сразу мог приступить к синтезу проекта, не ожидая завершение посторонних заданий (которые в том числе "засоряют" лог сообщений), и, самое главное, чтобы всё требуемое было в актуальном состоянии, чтобы пользователю не нужно было следить за этим, поменяв тот или иной параметр сборочного варианта.
LaunchOpenVivadoProject🔗
Pseudo-builder
Запускает билдер OpenVivadoProject
с фиктивной целью, что вынуждает билдер всегда включать цель в граф зависимостей как находящуюся в неактуальном состоянии.
Пример использования:
VivadoProject = envx.CreateVivadoProject(xpr_deps , IP_Cores)
...
OpenVivadoProject = envx.LaunchOpenVivadoProject(VivadoProject)