OparinVD 0 19 января, 2022 Опубликовано 19 января, 2022 · Жалоба Приветствую всех! Давно я кручусь вокруг этой темы, много раз возвращался к похожим веткам на форуме, перечитал мануалы от Xilinx, но не дается оно мне. Есть ощущение, что не хватает легкого волшебного пендаля, чтоб всё встало на свои места, и чтоб над головой лампочка, как в мультике, загорелась. Что я хочу получить: Хочу навести красоту, наподобие стандартных корок - чтоб жмешь разные галочки в GUI, и в зависимости от этого подключались разные HDL-ные или IPcore-ные внутренности, и менялось, например количество внешних портов. Что умею на данные момент: 1) Могу накидать форму для GUI в IP packager'е - тут всё интуитивно понятно. Могу играть с Enablement dependency, включая/выключая порт. Вижу сгенерированный tcl-скрипт для GUI с функциями proc update_PARAM_VALUE... и proc validate_PARAM_VALUE... 2) Независимо от этого могу на основе Export Block Design создать свой скриптик, который будет с учетом внешних условностей делать create_cell'ы и соединять их connect_net'ами. Не могу понять, как мне скрестить первый и второй пункты. Сейчас у меня GUI - просто пустышка, а скрипт могу запустить только вручную, например, для восстановления проекта из git. По всей вероятности всё должно работать автоматически: кинул Ipcore на канвас, изменил параметры - запустился скрипт, который подтянул нужные исходники, создал топ-левел и т.д. Запустил валидацию BD, пошла пропаганда параметров - опять запустился тот же скрипт. Как этого добиться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 15 часов назад, OparinVD сказал: кинул Ipcore на канвас, изменил параметры - запустился скрипт, который подтянул нужные исходники, создал топ-левел и т.д. Запустил валидацию BD, пошла пропаганда параметров - опять запустился тот же скрипт. Боюсь, что именно так: "бросил на канвас и всё завертелось" не получится. Рисование BD в GUI есть операция ручная. И все действия там ручные. В противоположность скрипты, будучи запущенными, всё делают без вмешательства. Но там и описание получается текстом (местами малочитебельным). Насколько понял, вы имеете в виду подход через IP Integrator. Если речь только про IP ядра, которые можно традиционно инстанцировать в HDL, там рам всё проще: сгенерил из скрипта корку и всё. Параметры корки скрипту передать. А с IP Integrator процесс несколько иной. Я делаю так: исходно рисуется BD, экспортируется Tcl скрипт, из которого выдираю непосредственно описание инстансов и межсоединений (оно там ближе к концу компактно лежит). Далее это помещаю в свой скрипт-шаблон между прологом и эпилогом, получается нечто такое: #================================================================================ # # Prologue # source $BUILD_SRC_DIR/cfg_params.tcl source $BUILD_SRC_DIR/impl_env.tcl set bd_name noc_slon set bd_path "${PROJECT_NAME}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd" set cips_name versal_cips_mamont puts "\n======== Create block design \"$bd_name\" ========" create_bd_design "${bd_name}" update_compile_order -fileset sources_1 open_bd_design ${bd_path} #------------------------------------------------------------------------------- # # BD Configuration Section # create_bd_cell -type ip -vlnv xilinx.com:ip:versal_cips:3.1 ${cips_name} set_property -dict [ \ list CONFIG.PS_PMC_CONFIG " \ PMC_REF_CLK_FREQMHZ ${PMC_REF_CLK} \ PS_NUM_FABRIC_RESETS 0 \ PS_USE_PMCPL_CLK0 0 \ PS_USE_PMCPL_CLK1 0 \ PS_USE_PMCPL_CLK2 0 \ PS_USE_PMCPL_CLK3 0 \ SMON_ALARMS Set_Alarms_On \ SMON_ENABLE_TEMP_AVERAGING 0 \ SMON_TEMP_AVERAGING_SAMPLES 8 \ " \ CONFIG.PS_PMC_CONFIG_APPLIED {1} \ ] \ [get_bd_cells ${cips_name}] apply_bd_automation -rule xilinx.com:bd_rule:cips -config { \ board_preset {No} \ boot_config {Custom} \ configure_noc {Add new AXI NoC} \ debug_config {Custom} \ design_flow {Full System} \ mc_type {None} \ num_mc {1} \ pl_clocks {None} \ pl_resets {None} \ } \ [get_bd_cells ${cips_name}] # Create interface ports set CH0_DDR4_0_0 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddr4_rtl:1.0 CH0_DDR4_0_0 ] set S00_AXI [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S00_AXI ] set_property -dict [ list \ CONFIG.ADDR_WIDTH {64} \ CONFIG.ARUSER_WIDTH {0} \ <...> CONFIG.WUSER_BITS_PER_BYTE {1} \ CONFIG.WUSER_WIDTH {0} \ ] $S00_AXI set sys_clk0_0 [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 sys_clk0_0 ] set_property -dict [ list \ CONFIG.FREQ_HZ {200000000} \ ] $sys_clk0_0 # Create ports set clk [ create_bd_port -dir I -type clk -freq_hz 250000000 clk ] set_property -dict [ list \ CONFIG.ASSOCIATED_BUSIF {S00_AXI} \ ] $clk # Create instance: axi_noc_0, and set properties set axi_noc_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_noc:1.0 axi_noc_0 ] set_property -dict [ list \ CONFIG.LOGO_FILE {data/noc_mc.png} \ CONFIG.CONTROLLERTYPE {DDR4_SDRAM} \ <...> CONFIG.MC_EN_ECC_SCRUBBING {false} \ CONFIG.MC_INIT_MEM_USING_ECC_SCRUB {false} \ ] $axi_noc_0 set_property -dict [ list \ #CONFIG.DATA_WIDTH {64} \ #CONFIG.CONNECTIONS {MC_0 { read_bw {1720} write_bw {1720} read_avg_burst {4} write_avg_burst {4}} } \ CONFIG.CONNECTIONS {MC_0 { read_bw {12500} write_bw {12500} read_avg_burst {4} write_avg_burst {4}} } \ CONFIG.CATEGORY {pl} \ ] [get_bd_intf_pins /axi_noc_0/S00_AXI] set_property -dict [ list \ CONFIG.ASSOCIATED_BUSIF {S00_AXI} \ ] [get_bd_pins /axi_noc_0/aclk0] # Create interface connections connect_bd_intf_net -intf_net S00_AXI_1 [get_bd_intf_ports S00_AXI] [get_bd_intf_pins axi_noc_0/S00_AXI] connect_bd_intf_net -intf_net axi_noc_0_CH0_DDR4_0 [get_bd_intf_ports CH0_DDR4_0_0] [get_bd_intf_pins axi_noc_0/CH0_DDR4_0] connect_bd_intf_net -intf_net sys_clk0_0_1 [get_bd_intf_ports sys_clk0_0] [get_bd_intf_pins axi_noc_0/sys_clk0] # Create port connections connect_bd_net -net clk_1 [get_bd_ports clk] [get_bd_pins axi_noc_0/aclk0] # Create address segments assign_bd_address -offset 0x00000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces noc_tg/Data] [get_bd_addr_segs axi_noc_0/S00_AXI/C0_DDR_LOW0] -force #================================================================================ # # Epilogue # #------------------------------------------------------------------------------- # # BD Final Tasks Section # validate_bd_design make_wrapper -files [get_files ${bd_path}] -top add_files -norecurse ${PROJECT_NAME}.gen/sources_1/bd/${bd_name}/hdl/${bd_name}_wrapper.v update_compile_order -fileset sources_1 puts "\n-------- Export simulation for \"$bd_name\" --------" set sim_top_name [get_property top [get_filesets sim_1]] set_property top ${bd_name}_wrapper [get_filesets sim_1] generate_target simulation [get_files ${bd_path}] -force export_simulation -of_objects [get_files ${bd_path}] -simulator questa -absolute_path -force -directory ${SIM_SCRIPT_DIR} set_property top $sim_top_name [get_filesets sim_1] #-------------------------------------------------------------------------------- И уже в этом скрипте правлю по месту то, что надо. Управляющие параметры передаются через подключаемые файлы. С этого момента данный скрипт является основным для BD - если что-то надо подправить на уровне GUI интегратора, то делаю это в GUI и смотрю, какую команду Vivado выдаёт в консоль. Добавляю (или меняю) это в этом скрипте. Но чаще всего достаточно поправить прямо в тексте. После генерирования BD в GUI интегратора всё это легко проверяется. Автоматизация достигается сама собой, а параметризация через внешние файлы. Вся эта кухня управляется системой сборки, дабы автоматизировать генерирование скриптов и запуск инструментов по зависимостям (например, при изменении каких-либо параметров), но можно и руками запускать или из пакетного файла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OparinVD 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 6 hours ago, dxp said: Боюсь, что именно так: "бросил на канвас и всё завертелось" не получится. Рисование BD в GUI есть операция ручная. И все действия там ручные Да, речь про IPI. Только я имел в виду, что "всё завертелось" бы не вокруг моего IP, а внутри него в результате изменений параметров через GUI корки или через распространение параметров от соседей. Хотя заметил у вас команду apply_bd_automation - взял на заметку, похоже тоже пригодится. Как-то так tcl-скрипт и технологию его "набивки" я себе и представлял. На практике руку еще не набивал, но тут хотя бы всё понятно - бери и делай. Не могу понять, как связать действия в GUI настройки корки с таким скриптом. Например, я кинул свой IPcore на канвас IPI, потом дабл-кликом зашел в GUI для его конфигурации, изменил значение property, которое меняет внутреннюю структуру моего IP, (например, для простоты меняет количество инстансов какого-нибудь субмодуля). Закрыл GUI - что происходит дальше? Как мне эти изменения передать моему скрипту? Или даже по-другому. Как пользоваться Customization Parameter'ами при упаковке IPcore? С теми параметрами, что вытащены с топ-левела HDL, всё понятно - настройка на уровне HDL и происходит. А как пользоваться дополнительными property? Они же, наверно, должны настраивать IPcore на уровне TCL? PS: по рекомендациям в соседних темах я, к сожалению, не смог заглянуть в недра стандартных корок - не разобрался. Например, понял механику того, как повесить хук на Вивадовские функции, но совершенно не понял, как с помощью этого инструмента отследить, что происходит при настройке стандартных корок... Т.е. я могу добавить в функцию что-то свое новое, но как мне это поможет заглянуть в "старое"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба Опытные люди тут на форуме объяснили, что cells в BD не параметризуются снаружи, т.е. тут автоматизации не достичь. Поэтому только через Tcl. BD ж по сути Tcl и есть, просто в графическом виде. Ну, строго говоря, там внутреннее описание не Tcl (раньше было XML, сейчас JSON), но суть та же: используется некий язык для описания параметров и межсоединений. Зато в Tcl можно экспортировать и потом запуском Tcl скрипта создать весь BD. Собственно, это вышеприведённый скрипт и делает. У меня он запускается на этапе создания проекта. У нас подход такой, что проекты (xpr) ценности не представляют и являются продуктом, которые генерирует система сборки исходя из заданных параметров. Вот на этом этапе этот скрипт и запускает в качестве хука для скрипта создания проекта. Что касается 11 минут назад, OparinVD сказал: Например, я кинул свой IPcore на канвас IPI, потом дабл-кликом зашел в GUI для его конфигурации, изменил значение property, которое меняет внутреннюю структуру моего IP, (например, для простоты меняет количество инстансов какого-нибудь субмодуля). Закрыл GUI - что происходит дальше? Как мне эти изменения передать моему скрипту? то после этого действия вы увидите в консоли Вивады тиклевую команду, которая выполнила это действие. Вот эту команду и добавить в скрипт (или если она там есть, но с другими параметрами, то подкорректировать эти параметры). Т.е. по сути выполнить действие через GUI IPI с целью подсмотреть, как это действие выполнить командой. И перенести после этого в скрипт. Так скрипт будет всегда делать автоматически все нужные действия. Для проверки правильности можно просто удалить из проекта BD и запустить скрипт из консоли. Он должен будет родить BD заново. После этого проверить правильность через тот же GUI IPI. Но это нечасто приходится делать - обычно структура BD как-то на первых этапах уже "кристаллизуется", потом уже только параметры меняются. А это легко передаётся в Tcl скрипт через включаемые файлы. А чтобы не забывать пересоздать BD при изменении влияющего параметра служит как раз система сборки, которая отслеживает зависимости - например, изменился параметр, который влияет на BD в том числе, - и собирает все нужные цели. Если при этом надо пересоздать проект, то и это делается (это ненакладная цель - 6-7 секунд на это уходит на моей не самой быстрой машине). Таким образом, если не надо менять структуру (наличие тех или иных cell'ов и их межсоединения), то править скрипт BD не приходится. Всё пересобирается автоматом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OparinVD 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба С топ-левельным BD всё понятно, это я умею. Автосборка еще не запущена, но скрипты для нее уже готовы. Речь всё-таки о другом. Возьмем, например, стандартный axis_interconnect. Если зайти в его GUI и поиграть с настройками, то внутри будут появляться и xbar'ы, и конвертеры частоты или ширины, меняться количество портов и т.д. Как это всё происходит? Подсмотреть команду несложно. Например, для изменения количества входных портов будет так: set_property -dict [_list_ CONFIG.NUM_SI {2}] [get_bd_cells axis_interconnect_1] А дальше что? Кто и как подцепляет внутри интерконнекта дополнительный s_coupler и добавляет порт на xbar? Эта магия работает на уровне HDL или на TCL? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 32 минуты назад, OparinVD сказал: Например, для изменения количества входных портов будет так: set_property -dict [_list_ CONFIG.NUM_SI {2}] [get_bd_cells axis_interconnect_1] А вы возьмите откатите сделанное в GUI действие. И запустите эту команду из консоли. Что произойдёт с интерконнектом? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OparinVD 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба Всё тут же перерисовывается и в сторону увеличения, и в сторону уменьшения количества. И в "закрытом" и в "раскрытом" состоянии Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба Хотите сказать, что действие, выполненное через GUI, не выполняется с помощью команды, которую же сама Vivado генерит на это действие? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OparinVD 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба Вовсе нет... Как раз наоборот, результат идентичный. Я хочу сказать, что вроде как не параметризуемый снаружи cell вполне себе меняет внутреннюю структуру и подтягивает разные исходники в зависимости от параметров... Чего-то подобного я и хочу добиться от своей корки Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 35 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба Приветствую! 1 hour ago, dxp said: Опытные люди тут на форуме объяснили, что cells в BD не параметризуются снаружи Я так понял TC говорит про возможность автоматизации генерации каcтомных BD внутри IP корки при изменении параметров оной на BD. Как это например делается в IP AXI interconnect или AXI Ethernet. На сколько я знаю внятного описания как это правильно делать внутри IP integrator нет. В свое время я пытался разбираться с этим пытаясь копировать то как это делается в вышеприведенных (или других похожих) корках. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OparinVD 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба Вот, именно про это! И да, прочитав, основные юзер-гайды, я не нашел ничего вразумительного на этот счет. В разделе про упаковку кастомного IP написаны очевидные вещи про добавление property, его тип, зависимости и т.д., а что делать с ними дальше - не понятно. С чего начать? Как заглянуть внутрь процессов в том же axis_interconnect? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fguy 5 20 января, 2022 Опубликовано 20 января, 2022 (изменено) · Жалоба 1 час назад, RobFPGA сказал: Я так понял TC говорит про возможность автоматизации генерации каcтомных BD внутри IP корки при изменении параметров оной на BD. Как это например делается в IP AXI interconnect или AXI Ethernet. На сколько я знаю внятного описания как это правильно делать внутри IP integrator нет. Можно попробовать завернуть блок hier в ip ядро, но опять же реконфигурации там не будет. В последних вивадах часть штатных ядер для видео переписали на хлс и они параметризованы как по параметрам работы, так и по портам. Тема конфигурируемых и универсальных (без привязки к чипу, версии вивады и частоте) ядер на хлс для меня так же интересна, но останавливает необходимость контроля результатов синтеза для более менее сложных ядер и необходимость подбора по ним интервалов обработки и т.п. Изменено 20 января, 2022 пользователем fguy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 35 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 4 minutes ago, OparinVD said: С чего начать? Как заглянуть внутрь процессов в том же axis_interconnect? Тут уже было пару тем по этому вопросу, я там приводил некоторые примеры возможности заглянуть в процессы генерации IP. Кроме непосредственного втупливания в tcl код (часто как баран на новые ворота ) я пробовал два пути - первый это стандартный хук процедур в TCL с выводом в лог что и в какой последовательности вызывается. Второй в принципе тоже самое, в коде TCL IP integrator встречается 2 переменные установка которых включает дебаговый вывод последовательности выполнения части процедур в IP integrator. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OparinVD 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба а как принудительно включить вывод debug-log'а? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 35 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 27 minutes ago, OparinVD said: а как принудительно включить вывод debug-log'а? В сорцах IP integration (ifx_common_xgui_util.tcl) встречается такое proc ifx_debug_enabled {} { global env if {[info exists env(XIL_IFX_DEBUG)]} { set n [namespace current] if {[string match "*$n*" $env(XIL_IFX_DEBUG)] || [string match "*IFX_ALL*" $env(XIL_IFX_DEBUG)]} { return 1 } } return 0 } proc ifx_debug_trace_enabled {} { global env if {[info exists env(XIL_IFX_TRACE)]} { set n [namespace current] if {[string match "*$n*" $env(XIL_IFX_TRACE)] || [string match "*IFX_ALL*" $env(XIL_IFX_TRACE)]} { return 1 } } return 0 } Соответственно если создать переменные окружения XIL_IFX_DEBUG и/или XIL_IFX_TRACE со строкой имени интересующего namespace или глобального "IFX_ALL" то должен выводится некий отладочный лог работы IP integration. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться