Jump to content

    

использование ILA в Vivado non-project CLI-mode

1 hour ago, dxp said:

Вообще, в чём смысл этого разбиения на пробники?

Вообще смысл в том, что один пробник работает на одной частоте. То есть если есть несколько частот, то нужно столько же пробников.

Share this post


Link to post
Share on other sites
14 минут назад, Nick_K сказал:

Вообще смысл в том, что один пробник работает на одной частоте. То есть если есть несколько частот, то нужно столько же пробников.

С дебаг корами не путаете? Вроде клок на ядро подаётся, не на пробник.

Share this post


Link to post
Share on other sites

Приветствую!

23 hours ago, dxp said:

Т.е. идеологически правильно всё-таки на этапе P&R подключать сигналы на логизатор?

Тут кому как нравится.

Я в основном отлаживаю после синтеза.  Поэтому цепляю  ILA в полный нетлист. Но при этом заранее (если нужно)  мечу в исходниках важные мне цепи как MARK_DEBUG и  DEBUG_GROUP.  При этом не нужно каждый раз пере-синтезировать проект если нужно поменять probe.  А полный нетлист  создается  не после синтеза, а в процессе elaboration. То есть перед началом P&R или в процессе open_synthesis_design. Да и фактически debug_hub и ILA создаются и компилируются в проект  на этапе optimization в начале P&R.

Но для такой схемы вроде есть ограничение - когда вы в исходнике  цепляете модуль с  готовым ila_hub  внутри типа Debug_bridge тогда могут быть быть конфликты при подключении ILA  к dbg_hub через constrains.  Но такое у меня было давно так что сейчас не скажу точно. Ну и ряд  возможностей ILA типа внешний trig input/output проще использовать через rtl. 

Не нравится мне пихать все в один probe так как соответственно растет размер trigger логики  соответсвенно сложность P&R при высокой частоте клока для probe. К тому же для отдельных  probe можно задать тип - trigger_data/trigger_only/data_only для оптимизации ресурсов.  Тут дело вкуса.  У меня обычно уже есть темплейты для подключения в разные probe в нужной последовательности  всех основных шин и конструкций которые я применяю в дизайне.  Поэтому и подключение получается простое и быстрое,  и на отладке на wave не выглядит кашей. 

C Альтера  лучше и не сравнивать - после Vivado  работа с SignalTap одно расстройство :cray:

21 hours ago, Nick_K said:

Вообще смысл в том, что один пробник работает на одной частоте. То есть если есть несколько частот, то нужно столько же пробников.

Это разные ILA могут работать на разной частоте.  А  probe  в пределах одной ILA  работают на одной тактовой.   

Удачи! Rob.

Share this post


Link to post
Share on other sites
1 час назад, RobFPGA сказал:

Но для такой схемы вроде есть ограничение - когда вы в исходнике  цепляете модуль с  готовым ila_hub  внутри типа Debug_bridge тогда могут быть быть конфликты при подключении ILA  к dbg_hub через constrains.

А эти хабы - они сами автоматом генерятся или тоже можно/нужно этим рулить?

 

Ещё столкнулся с такой неприятностью. Завожу второе ядро (для другого тактового домена, на 250 МГц):

 

create_debug_core ila250 ila
set_property ALL_PROBE_SAME_MU true [get_debug_cores ila250]
set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores ila250]
set_property C_ADV_TRIGGER false [get_debug_cores ila250]
set_property C_DATA_DEPTH 1024 [get_debug_cores ila250]
set_property C_EN_STRG_QUAL false [get_debug_cores ila250]
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores ila250]
set_property C_TRIGIN_EN false [get_debug_cores ila250]
set_property C_TRIGOUT_EN false [get_debug_cores ila250]
set_property port_width 1 [get_debug_ports ila250/clk]

connect_debug_port ila250/clk [get_nets -hier -filter {NAME =~ user_clk}]

 

получаю на opt_design ошибку:

[DRC MDRV-1] Multiple Driver Nets: Net app_tlp_bridge/<const0> has multiple drivers: 
pcie_port/pcie_i/inst/inst/pcie_top_i/pcie_7x_i/pcie_block_i/CFGAERECRCCHECKEN, 
pcie_port/pcie_i/inst/inst/pcie_top_i/pcie_7x_i/pcie_block_i/CFGAERECRCGENEN, 
app_tlp_bridge/GND/G, 
and pcie_port/pcie_i/inst/inst/pcie_top_i/pcie_7x_i/cfg_err_aer_headerlog_set_INST_0/O.

В проекте нет ни такой цепи - вообще какое-то странное имя, ни сами эти сигналы я не трогаю - это внутренние сигналы корки. Не сталкивались с подобным?

 

Ещё когда руками цепляешь сигналы на отладку через гуйню ихнюю (Synthesis->Set Up Debug), там иногда появляются сигналы, у которых тактовый домен неопределён (undefined) или multiple (это обычно относится к шинам, где у части сигналов тактовый домен тоже undefined). И приходится руками это разруливать - или удалять такие сигналы, или принудительно назначать клок, хотя как правило такие сигналы - это те, которые дооптимизировались на синтезе до константного состояния.

 

Вот в случае скриптового подхода как с этим бороться? И не от этого ли ошибка у меня возникает?

Share this post


Link to post
Share on other sites

Приветствую!

Хаб  генерируется автоматом если Vivado видит в нетлисте хоть одну  ILA  какого либо типа а хаба в нетлисте нет. 

Ошибка странная -  и на первый взгляд к ILA отношение не имеет, тем более цепи GND и const0. Надо бы открыть  synthesis design  с уже подключенным some_debug.tcl и посмотреть что там и как.  Обычно проблемы бывают когда часть портов у probe остаются не подключены. 

Отношение цепи к конкретному клоку  GUI  пытается вычислить отслеживая клок у примитива от которого у цепи драйвер. В tcl тоже можно  так делать - найти драйвера у цепи, и брать клок. Естественно не всегда это получается сделать однозначно  - либо клок еще не определен на этом этапе.  Либо  несколько клоков.  Либо например в шине затесался другой клок или оптимизировало часть сигналов в константу.  

Как пример простенький скрипт который выводит все драйвера и имя их клоков по имени цепи

proc net_clocks {net_name} {
  set cells [all_fanin -flat -only_cells -startpoints_only [get_pins -of [get_nets $net_name]]]

  foreach cell $cells {
    set clock [get_clocks -of [get_cells $cell]]
    puts ">> cell:$cell -> clock:$clock"
  } 
}

 Но этот скрипт выведет несколько клоков  на цепь  если цепь например подключена на выход BRAM  у которой 2 разных клока.  Так что можно/нужно в скрипте городить доп. проверку и фильтрацию для определения таких случаев.  Если не лень :biggrin:

Удачи! Rob.

Share this post


Link to post
Share on other sites
14 часов назад, RobFPGA сказал:

Ошибка странная -  и на первый взгляд к ILA отношение не имеет, тем более цепи GND и const0. Надо бы открыть  synthesis design  с уже подключенным some_debug.tcl и посмотреть что там и как.  Обычно проблемы бывают когда часть портов у probe остаются не подключены. 

Да, вы правы, эта ошибка не имеет отношения (во всяком случае прямого) к ILA. Убрал эти скрипты из констрейнов, ошибка всё равно выскакивает. Что-то сломалось, но что, не понимаю. Ничего вроде не делал, код вообще не трогал, только (* mark_debug="true" *) выставлял. Уже и проект пересоздал. И виваду перезагружал. Без толку. :( Гугление приводил на xilinx forum, но и там ответа нет. Советуют посмотреть на RTL нетлист и на синтезированный. Ну да, есть эта цепь, на GND она сидит. Не видно там никаких множественных драйверов. Да и откуда они у неё могут взяться - это ж сам по себе просто уровень постоянки логического 0. Синтез никакие предупреждений не даёт.

Share this post


Link to post
Share on other sites

Приветствую!

Меня смущает  вот эта  цепь :

pcie_port/pcie_i/inst/inst/pcie_top_i/pcie_7x_i/cfg_err_aer_headerlog_set_INST_0/O

Явно это выход  - и он не должен на земле сидеть - может где случайно занулили выход?

Удачи! Rob.

Share this post


Link to post
Share on other sites

Да, смотрю по схематику, уже на RTL вижу, что вот эти сигналы:

 

pcie_port/pcie_i/inst/inst/pcie_top_i/pcie_7x_i/pcie_block_i/CFGAERECRCCHECKEN, 
pcie_port/pcie_i/inst/inst/pcie_top_i/pcie_7x_i/pcie_block_i/CFGAERECRCGENEN, 
and pcie_port/pcie_i/inst/inst/pcie_top_i/pcie_7x_i/cfg_err_aer_headerlog_set_INST_0/O.

это выходы с PCIe Integrated Block, и они прокинуты в мой модуль (по схеме) и там почему-то посажены на ноль. Соответственно, это конфликтует с местным сигналом модуля (app_tlp_bridge/GND/G). По коду смотрю, там пустой сигнал, никуда в модуле не подключен, просто прокинут через интерфейс и всё. Дальше входного порта в модуле не идёт (просто входит в SV интерфейс вместе с остальными сигналами интерфейса дотащен до входного порта модуля). И я же ничего там не трогал и всё работало. :(

 

В логе синтеза вижу (и всегда оно там было):

 

WARNING: [Synth 8-3848] Net cfg\.aer_ecrc_check_en in module/entity app_tlp_bridge_m does not have driver.

 

Это как раз этот самый сигнал. Такое впечатление, что синтезатор, обнаружив, что входной сигнал (который не используется) в воздухе, зацепил его на землю. А на разводке отказалось, что оно не в воздухе, а идёт с порта другого модуля, и вот тут конфликт. Но ведь работало же и ничего не менял там. Я слегка в замешательстве. 

Share this post


Link to post
Share on other sites

Приветствую!

55 minutes ago, dxp said:

Это как раз этот самый сигнал. Такое впечатление, что синтезатор, обнаружив, что входной сигнал (который не используется) в воздухе, зацепил его на землю. А на разводке отказалось, что оно не в воздухе, а идёт с порта другого модуля, и вот тут конфликт. Но ведь работало же и ничего не менял там. Я слегка в замешательстве. 

Скорее всего какие то конфликты из за  interface и modport.  Может из за раздельной компиляции корок и модулей с интерфейсами. Хорошо что  хоть знаете где копать.

Удачи! Rob.

Share this post


Link to post
Share on other sites

Вопрос к уважаемому @RobFPGA

 

Управление ILA ядрами и сигналами для них из скрипта реально рулит - очень облегчает жизнь. "Ностальгировал" по SignalTap'у, но познав этот "дзен", мнение поменялось. :smile: Спасибо вам за идею и реализацию!

 

В процессе работы возникло несколько практических вопросов, хотелось бы узнать ваше мнение и подход. 

 

1. Методология добавления сигнала в дебаг предполагает два основных шага: 1) добавить директиву mark_debug к сигналу в исходнике; 2) добавить сигнал в пробник ILA ядра в скрипте. Тут всё вроде просто и понятно, но на практике нередко возникает неудачное добавление, если что-то сделано неаккуратно - например, имя задано с ошибкой или задаёшь шину, указав [*] у сигнала, а сигнал одиночный (копи-пастой добавляешь сигнал и по недосмотру не убираешь маску). И вот этот момент надо как-то контролировать. Я сейчас дожидаюсь фазы opt_design, и там уже в runme.log можно смотреть сообщения. Если вижу, что какой-то сигнал не добавился,  останавливаю дальнейшую сборку (т.к. в ней нет смысла) и разбираюсь, что не так. Это несколько неудобно - можно прозевать момент контроля, да и глазами отсматривать каждый раз тоже утомительно. Нет ли идей, как этот процесс бы автоматизировать - например, если какой-то сигнал не добавился, то останавливать сборку. Мне пока приходит только одна идея (не проверял): перевести severity с WARNING на ERROR.

 

2. Иногда бывает, что сигнал несмотря на mark_debug, не избегает оптимизации. Например, в сигнал адреса, передаваемый в PCIe, содержит два младших бита нулевыми (выравнивание на 32-разрядное слово),  и эти два бита он вроде не выбрасывает, но кодирует иначе: основной сигнал addr[63:2] и ещё два u_ila_0_addr_1, u_ila_0[0:0]. Ясно, что сигналы-то нули, но контролировать адрес со сдвигом неудобно. Выручает объединение этих сигналов в виртуальную шину. Сталкивались с таким? Можно ли как-то подавить такую оптимизацию?

 

3. Работа с waveform. Для удобства работы располагаю сигналы в определённом порядке, подсвечиваю разными цветами, добавляю разделители, создаю перечисления (enumaration) - особенно полезно для КА. К сожалению, при перезагрузке формат частично портится - вивада перетасовывает сигналы, слетают цвета, исчезают разделители и т.д. Искал, где она это сохраняет, нашёл файлики *.wcfg. Думал, вот оно, дело в шляпе. Но не тут-то было. Просто так загрузить оно не даёт - ругается на то, что wave config уже загружен. Попытка выгрузить и загрузить (через консольные команды) тоже положительного результата не даёт. Самое главное, что этот wave config - это только часть всего. Там ещё нужно wdb грузить (базу с сигналами), а может и не нужно - вивада при подключении к таржету сама вытаскивает сигналы, если была сработка (триггер). Кроме того, wave config - это хорошо, но это только временные диаграммы сигналов. А нужны же ещё настройки запуска и прочее. Это всё содержится в dashboard. Как его создавать командами, не нашёл. В конце концов, командами удалось загрузить сигналы из wdb и загрузить wave config, но это позволяет только смотреть сигналы, но не запускать захват новых по триггеру. В итоге, как обычно создаю через GUI dashboard, руками добавляю триггер, загружаю прошивку и переподключаюсь к target (чтобы оно получило из него информацию о ILA ядрах - актуально, когда добавлены новые сигналы), после удаляю сигналы с waveform и запускаю свой скрипт добавления сигналов на waveform, чтобы было в формате, как мне надо - например:

 

add_wave -into {hw_ila_data_2.wcfg} -radix hex -color lime    {app_tlp_bridge/bmdwc/cqueue_empty}
add_wave -into {hw_ila_data_2.wcfg} -radix hex -color lime    {app_tlp_bridge/bmdwc/cqueue_pop}     
...
add_wave_virtual_bus -into {hw_ila_data_2.wcfg} -radix hex -color pink tlp_rd_cmd_address
    add_wave -into {tlp_rd_cmd_address} -radix hex  -color lime    {app_tlp_bridge/tlpf/tlp_rd_cmd_addr}
    add_wave -into {tlp_rd_cmd_address} -radix hex  -color lime    {app_tlp_bridge/tlpf/tlp_rd_cmd_addr_1}
    add_wave -into {tlp_rd_cmd_address} -radix hex  -color lime    {app_tlp_bridge/tlpf/tlp_rd_cmd_addr_1}

add_wave -into {hw_ila_data_2.wcfg} -radix hex      -color magenta {app_tlp_bridge/tlp_former/sendfsm}
...
и т.д.
  

Кстати, enumeration я тут не задаю, она их где-то запомнила и без ошибок подставляет сама.

 

Способ не очень нравится - костыльно это. Но сильно экономит на ручном форматировании каждый раз. А как вы работаете с дебажным окном? Есть какие-то лайфхаки или не паритесь - видно сигнал да и ладно?:smile:

 

UPD. 4. Создание ILA ядер скриптом не позволяет использовать порты ядер - например, trig_in/trig_out, которые предназначены для организации цепочки запуска по триггеру одного из ядер (это нужно, когда ловишь сигналы в двух тактовых доменах одновременно). Накопал в доке, что для этого надо ядра инстанцировать на уровне исходника. Приходилось ли вам делать это - инстанцировать ядра в исходниках или как-то иначе обходились?

Share this post


Link to post
Share on other sites

Приветствую!

6 hours ago, dxp said:

1. ... Нет ли идей, как этот процесс бы автоматизировать - например, если какой-то сигнал не добавился, то останавливать сборку. Мне пока приходит только одна идея (не проверял): перевести severity с WARNING на ERROR.

Думаю  что основной контроль полноты подключения надо делать на этапе  добавления ILA и создания портов probe.  Мой пример  скриптов это только  минимальный функционал для демонстрации идеи.  Для удобства и полноты контроля можно навернуть свой parsing engine  над  стандартными  get_nets, get_pins.  Например add_2probe $ila_obj [select_nets -strict_num -wave_name "bus_name" {hier_path/net_name[11:8]} ]. Где  select_nets  своя функция которая парсит  нестандартный/расширенный шаблон поиска выполняя несколько вызовов get_nets/get_pins. А доп. опции  использую для вариантов контроля полноты подключения и задания параметров отображения.  И если что не так как ожидалось то сигналить о неполадках подключения отдельным логом или сообщениями.

Также  фактически выгодно не подключать цепи к probe сразу, а сначала сформировать список цепей, отсортировать, проверить их,  а только затем одним махом сделать коннект к prob. Это значительно  экономит время так как процесс последовательного подключения  большого количества  цепей к probe  очень медленный. 

Spoiler

### dbg_proc.tcl
  
set sig_list {}

proc mk_probe {{ila u_ila_0} {mode DATA_AND_TRIGGER}} {
  global sig_list
  
  set sig_list {}
  ....
}

proc add_2probe {ila nets_obj} {
  global sig_list
  ...
  set nets_obj [lsort -dictionary $nets_obj]
  set sig_list [concat $sig_list $nets_obj]
  ...
}

proc connect_2probe {ila} {
  global sig_list
  
  set len [llength $sig_list]
  
  if {len>0} {
    some_checking $sig_list ...
    connect_debug_port -channel_start_index 0 $probe_obj $sig_list
    set sig_list {}
  } else { 
    # Errors log ...
  }
}

### connect_dbg.tcl 
  ...
  mk_probe   $ila_obj ...
  add_2probe $ila_obj ...
  add_2probe $ila_obj ...
  ...
  connect_2probe $ila_obj 
    

 

6 hours ago, dxp said:

2. ...  Ясно, что сигналы-то нули, но контролировать адрес со сдвигом неудобно. Выручает объединение этих сигналов в виртуальную шину. Сталкивались с таким? Можно ли как-то подавить такую оптимизацию?

Увы сталкивался. Но  как то меня это особо не доставало так что решений наверное и не искал.   Опять же в рамках вышеприведенного варианта можно добавить в скрипт для подключения контроль  полноты добавления  шин, отслеживание что цепи являются константами 0/1, и.т.д. 

6 hours ago, dxp said:

3. Работа с waveform.

Увы - я сейчас что сапожник без сапог -  В связи со сменой работы уже несколько месяцев вокруг ни единой Xilinx росинки железки.:unknw::cray:Теперь  я "наслаждаюсь" SignalTap-ом по полной :bad:.  Так что как  работать  с debug я уж и забывать стал.  Да и перед этим особо много не работал.  В основном тем же способом что и вы  скриптами  форматировал окна. А без железки  debug не откроешь. Так что ни чего конкретно сейчас не скажу.  На сколько помню,  почти все в wavе можно управлять и конфигурить через скрипты. Так же как и опциями  запуска ILA. Как пример у меня  на tcl была написана оболочка к JTAG to AXI Master на которой я запускал "программы"  конфигурации и управления внутренней периферией пока  программисты рожали нормальный софт. 

Увы по каким то причинам  при работы в debug GUI не все команды транслируются в tcl log. Поэтому сложно сразу разобраться что и как правильно делать.  Жду что после Нового Года обзаведусь новой железкой для экспериментов (напоминание Санте  :acute:). 

6 hours ago, dxp said:

UPD. 4. Создание ILA ядер скриптом не позволяет использовать порты ядер - например, trig_in/trig_out, которые предназначены для организации

Тут нужно понимать что корка подключаемая в скрипте создается как balck_box  и только на этапе opt_design генерируется и линкуется в netlist.  И  увы - даже если при создании указать в опциях C_TRIGIN_EN trueC_TRIGOUT_EN true, black_box корка создается без этих портов (как минимум в v18.3,  непорядок :diablo:).  Если это поправят то думаю что можно через правку net-листа создавать нужные коннекшены после создания и добавления ILA. В RTL же корка вставляется с пол пинка - как обычный IP модуль.  Но увы только ручками. 

Интерфейс работы с Vivado очень гибок - фактически вы можете делать с нетлистом все что захотите  - в том числе добавлять корки/примитивы и конектить их в любую точку иерархии.  Но естественно при неких начальных затратах для создания нужной и удобной вам инфраструктуры такого инструментария. 

Тема эта очень интересна в том числе ECO flow для быстрой смены точек контроля (некий аналог rapidrecompile)  - жаль что нет достаточно времени (да и ленив я) чтобы делать все как положено :to_become_senile:

Удачи! Rob.

Share this post


Link to post
Share on other sites
On 12/17/2019 at 9:04 AM, dxp said:

Выручает объединение этих сигналов в виртуальную шину. Сталкивались с таким? Можно ли как-то подавить такую оптимизацию?

Если правильно понял проблему, то решение следующее(было найдено в ответах на сайте xilinx).

1) открыть implemented design

2) write_debug_probe -force [имя файла]

3) закрыть implemented design.

Я в tcl не копенгаген и пишу по памяти, могу ошибиться в написании, но суть именно такая. Я давно такой скрипт написал и всегда запускаю. Помогает.

Edited by Strob

Share this post


Link to post
Share on other sites

Вопрос не в том, как добавить скриптом сигналы в дебаг, а в том что вивада оптимизирует часть сигналов, несмотря на (* mark="true" *) - например, есть шина данных: 

 

(* mark_debug="true" *) logic [63:0] data;

 

после синтеза на дебаге вижу:

 

<path>/data[0]...<path>/data[31], u_ila_0_data[32]...u_ila_0_data[63]

 

т.е. получается, что не одна шина, как задано исходно, а две. И чтобы видеть это единой шиной, приходится объединять это в виртуальную шину. К сожалению, как исходная шина будет разбита (и будет ли) заранее неизвестно, поэтому процесс автоматизации скриптом не поддаётся.

 

Вопрос был в том, как подавить такой разбиение шины оптимизатором P&R. 

Share this post


Link to post
Share on other sites

Это вместо (* mark_debug="true" *)?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this