_4afc_ 25 29 июля, 2019 Опубликовано 29 июля, 2019 · Жалоба Есть необходимость создания проекта под Artix в Vivado: АЦП -> ФНЧ -> ЦАП Цель - на простом проекте отработать навыки работы с констрейнами в Vivado. Вводные: АЦП - выходы LVDS, тактовая данных (64МГц) - тактируют плис ФНЧ - КИХ на частоте 384 МГц ЦАП - КМОП 32 МГц Пока пытаюсь сделать упрощённый вариант - генерировать синус на ЦАП по 16 точкам. Вопрос 1 У меня есть ноги CLK64_P и CLK64_N, из них я создаю клок CLK64 методом: Spoiler IBUFDS #( .DIFF_TERM("FALSE"), .IBUF_LOW_PWR("TRUE"), .IOSTANDARD("DEFAULT") ) IBUFDS_inst ( .O(CLK64), .I(CLK64_P), .IB(CLK64_N) ); Удивлён, что констрейн на клок приходится задавать для CLK64_P а не для CLK64, это правильно? #create_clock -add -name sys_clk_pin -period 15.625 -waveform {0 7.8125} [get_ports { CLK64_P }]; сколько цифр после точки можно вводить? Vivado понимает 7.8125 или округлит до 7.81? Вопрос 2 Мне нужны частоты 384МГц и 32МГц, 384МГц получаю так: Spoiler PLLE2_BASE #( .BANDWIDTH("OPTIMIZED"), // OPTIMIZED, HIGH, LOW .CLKFBOUT_MULT(18), // Multiply value for all CLKOUT, (2-64) .CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB, (-360.000-360.000). .CLKIN1_PERIOD(15.625), // Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz). // CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: Divide amount for each CLKOUT (1-128) .CLKOUT0_DIVIDE(3), .CLKOUT1_DIVIDE(36), .CLKOUT2_DIVIDE(1), .CLKOUT3_DIVIDE(1), .CLKOUT4_DIVIDE(1), .CLKOUT5_DIVIDE(1), // CLKOUT0_DUTY_CYCLE - CLKOUT5_DUTY_CYCLE: Duty cycle for each CLKOUT (0.001-0.999). .CLKOUT0_DUTY_CYCLE(0.5), .CLKOUT1_DUTY_CYCLE(0.5), .CLKOUT2_DUTY_CYCLE(0.5), .CLKOUT3_DUTY_CYCLE(0.5), .CLKOUT4_DUTY_CYCLE(0.5), .CLKOUT5_DUTY_CYCLE(0.5), // CLKOUT0_PHASE - CLKOUT5_PHASE: Phase offset for each CLKOUT (-360.000-360.000). .CLKOUT0_PHASE(0.0), .CLKOUT1_PHASE(0.0), .CLKOUT2_PHASE(0.0), .CLKOUT3_PHASE(0.0), .CLKOUT4_PHASE(0.0), .CLKOUT5_PHASE(0.0), .DIVCLK_DIVIDE(1), // Master division value, (1-56) .REF_JITTER1(0.0), // Reference input jitter in UI, (0.000-0.999). .STARTUP_WAIT("FALSE") // Delay DONE until PLL Locks, ("TRUE"/"FALSE") ) PLLE2_BASE_inst ( // Clock Outputs: 1-bit (each) output: User configurable clock outputs .CLKOUT0(CLK384), // 1-bit output: CLKOUT0 .CLKOUT1(CLK32), // 1-bit output: CLKOUT1 .CLKOUT2(CLKOUT2), // 1-bit output: CLKOUT2 .CLKOUT3(CLKOUT3), // 1-bit output: CLKOUT3 .CLKOUT4(CLKOUT4), // 1-bit output: CLKOUT4 .CLKOUT5(CLKOUT5), // 1-bit output: CLKOUT5 // Feedback Clocks: 1-bit (each) output: Clock feedback ports .CLKFBOUT(CLK_FB), // 1-bit output: Feedback clock .LOCKED(LOCKED), // 1-bit output: LOCK .CLKIN1(CLK64), // 1-bit input: Input clock // Control Ports: 1-bit (each) input: PLL control ports .PWRDWN(1'b0), // 1-bit input: Power-down .RST(1'b0), // 1-bit input: Reset // Feedback Clocks: 1-bit (each) input: Clock feedback ports .CLKFBIN(CLK_FB) // 1-bit input: Feedback clock ); Мне надо прописывать констрейн на клок CLK384 или Vivado сам поймёт что он и всё что от него тактируется работает на частоте 384МГц? Вопрос 3 Как лучше получить частоту 32 МГц - своим счётчиком или с PLL? Вопрос 4 Счётчики в Vivado оптимизируются? В ISE я брал 32 разрядный регистр, делел на нём 3 разрядный счётчик и при синтезе у меня старшие разряды отбрасывались и получался 3 разрядный счётчик в Vivado я что-то этого не замечаю, он что пытается развести 32 разряда? Вопрос 5 Как передавать данные между блоками работающими на частотах 64, 384, 32 МГц - напрямую или ставить регистры типа FIFO для надёжности? Вопрос 6 Хочется сделать выходные и входные триггеры и разместить их рядом с ножками - как это описать в констрейнах и как задать время запаздывания/распространения? Вопрос 7 Файл .xdc - один на проект или можно создать некую иерархию из .xdc файлов? констрейны только в .xdc? В верилоге сразу указать нельзя? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 29 июля, 2019 Опубликовано 29 июля, 2019 · Жалоба 12 minutes ago, _4afc_ said: Удивлён, что констрейн на клок приходится задавать для CLK64_P а не для CLK64, это правильно? ЛВДС достаточно законстрейнить в одном нете, второй подтянется автоматом - это нормально 13 minutes ago, _4afc_ said: Мне надо прописывать констрейн на клок CLK384 или Vivado сам поймёт что он и всё что от него тактируется работает на частоте 384МГц? Выходные из PLL получают свои автоматические констрейны при генерации через IPCore. В вашем случае не понятно, так как просто показано подключение (через макрос или IP ядро?), поэтому я бы советовал сгенерировать Ядро и просто подключить (там констрейны буду созданы автоматически на все выходные неты) 15 minutes ago, _4afc_ said: Как лучше получить частоту 32 МГц - своим счётчиком или с PLL? Лучше PLL если позволяют ресурсы и опять же через Визард. Тогда синтез и имплементация не будет нуждаться в дополнительных констрейнах. Да и сгенерить 2 частоты можно сразу с одного PLL 17 minutes ago, _4afc_ said: Счётчики в Vivado оптимизируются? Если правильно описать, то там вообще логика не будет использована (видимая). По этому поводу ознакомтесь с Carry Save Adder. 18 minutes ago, _4afc_ said: Как передавать данные между блоками работающими на частотах 64, 384, 32 МГц - напрямую или ставить регистры типа FIFO для надёжности? Можно FIFO, если данных много или не понятны циклы автоматов в разных доменах. В простейших случаях достаточно CDC. 19 minutes ago, _4afc_ said: Хочется сделать выходные и входные триггеры и разместить их рядом с ножками - как это описать в констрейнах и как задать время запаздывания/распространения? Для физического расположения используйте Floorplanning синтезированного проекта, для размещения нужных блоков на кристалле (assign pblock). 20 minutes ago, _4afc_ said: Файл .xdc - один на проект или можно создать некую иерархию из .xdc файлов? Иерархию - нет. Но разные типы констрейнов хранить в разных файлах можно и даже считается хорошим тоном. После создания просто укажите Таргет файл и туда будут писаться созданные констрейны. Подробнее тут 22 minutes ago, _4afc_ said: констрейны только в .xdc? В верилоге сразу указать нельзя? Можно и в коде. Но это не всегда нужно/удобно, хотя вполне реально. Также детальнее тут Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 29 июля, 2019 Опубликовано 29 июля, 2019 · Жалоба Приветствую! О сколько вопросов ... Может проще сначала user guide почитать 1 Вы же в констрейне клок "привязываете" к входной ноге, поэтому и get_ports {CLK64_P}. При желании можете задать клок начиная в любой точке цепи НО с соответствующим выбором примитива (gets_pins ... ) являющегося источником. 2. Vivado автоматом находит все PLL и генерирует для них производные клоки. При этом надо помнить что по умолчанию все эти клоки считаются синхронными друг к другу. Поэтому если в дизайне этого не требуется, надо не забыть "развязать" их set_clock_groups -name CG_async -asynchronous -group [get_clocks -include_generated_clocks sys_clk_pin ]. А то будете ловить странные ошибки таймингов между этими клоками. 3. смотря для чего 4. Как и в ISE - Все регистры выходы которых не используются, или имеют константное значение, удаляются на этапе синтеза и P&R. 5 зависит от того какие данные. 7 из файлов .xdc можно лепить иерархию. Можно привязывать отдельные xdc файлы к отдельным модулям как по типу модуля (cell) так и к конкретному инстансу. Можно использовать .tcl в качестве файлов constains и писать вычисляемые constain с циклами, условиями, блек-джеком, и Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба 14 hours ago, RobFPGA said: из файлов .xdc можно лепить иерархию А как это? Что-то я нигде не встречал такого, чтобы прямо вложенные файлы были. Можно линк на UG какой-то? И на это тоже: 14 hours ago, RobFPGA said: Можно привязывать отдельные xdc файлы к отдельным модулям как по типу модуля (cell) так и к конкретному инстансу Про Тикль слыхал, но опять таки нигде не видел. Наверное потому что мои проекты слишком маленькие Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Doka 4 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба 16 hours ago, RobFPGA said: из файлов .xdc можно лепить иерархию. Можно привязывать отдельные xdc файлы к отдельным модулям как по типу модуля (cell) так и к конкретному инстансу. Можно использовать .tcl в качестве файлов constains и писать вычисляемые constain с циклами, условиями 1. я под иерархией всегда понимал возможность соурсить внутри одного xdc другой - в этом смысле получается, что иерархия невозможна. в плане того, что проект можно дробить на несколько еирархичных xdc, в которых описываются ограничения для конкретных инстансов иерархичного дизайна - да... можно, но что удивительно, полез сейчас в хелп и обнаружил у read_xdc замечательгые опции -ref -cells, вот уж воистину - век живи, век учись!!! день удался! 2. что-то я как ни пытался не смог заставить работать if & for внутри файлов XDC (non-project mode) , а внутренности XDC писать в тикле ( без read_xdc) вивадо не разрешает, но например этот фокус прокатывал c SDC в Cadence Genus, и, как я понял, всё что можно писать в XDC можно подсмотреть по: Vivado% help -category XDC Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба 6 minutes ago, Doka said: под иерархией всегда понимал возможность соурсить внутри одного xdc другой Вот и я так же 5 minutes ago, Doka said: полез сейчас в хелп Это какой-то юзергайд или просто опция Вивады? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Doka 4 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба 36 minutes ago, Nick_K said: Это какой-то юзергайд или просто опция Вивады? help read_xdc Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба Приветствую! 1 hour ago, Doka said: и обнаружил у read_xdc замечательгые опции -ref -cells, Именно это я и имел в виду под иерархией. Ну а, чтобы пользовать блек-джек и в констрейнах надо задавать тип файла .tcl. И тогда можно резвится на полную Например в зависимости от наличия портов в top подключать пины Spoiler ### MGT pins 3..0 if {[llength [get_ports -quiet {dp_c2m_p}]] >= 4} { set_property PACKAGE_PIN J5 [get_ports {dp_c2m_n[0]} ] ... } # 7..4 if {[llength [get_ports -quiet {dp_c2m_p}]] >= 8} { set_property PACKAGE_PIN V3 [get_ports {dp_c2m_n[4]} ] ... } Или на лету патчить нетлист: Spoiler # board_misc.tcl proc pcie_mmcm_ref_replace {i_pcie {old_line 0} {new_line 7}} { set old_net [get_nets -of [get_pins "${i_pcie}/inst/gt_top_i/pipe_wrapper_i/pipe_clock_int.pipe_clock_i/pipe_txoutclk_out"]] set old_pin [get_pins "${i_pcie}/inst/gt_top_i/pipe_wrapper_i/pipe_lane\[${old_line}\].gt_wrapper_i/gth_channel.gthe2_channel_i/TXOUTCLK"] set new_pin [get_pins "${i_pcie}/inst/gt_top_i/pipe_wrapper_i/pipe_lane\[${new_line}\].gt_wrapper_i/gth_channel.gthe2_channel_i/TXOUTCLK"] disconnect_net -pinlist $new_pin connect_net -hier -net $old_net -object $new_pin disconnect_net -pinlist $old_pin common::send_msg_id ">> MISC: 00-000" "INFO" ">> Replace PIPE MMCM reference clock from $old_pin to $new_pin" } pcie_mmcm_ref_replace "i_pcie_sys/i_xdma/inst/pcie3_ip_i" 0 7 Или автоматизировать подключения debug # board_dbg.tcl source -notrace $script_dir/../tcl/dbg_proc.tcl ... set ila_obj [create_debug_core u_ila_1 ila] set_property C_DATA_DEPTH 2048 $ila_obj ... mk_probe $ila_obj [DATA_AND_TRIGGER] | DATA add_2probe $ila_obj [get_nets {m00_ctrl_araddr[*]}] ... connect_2probe $ila_obj Ну или .... реализуйте любые фантазии ... Одна проблемка с путями к файлам - Vivado упирается и не дает легким способом использовать относительные пути в .tcl. Так как директория запуска различна, а для разных процессов. Приходится лепить костыли. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба Спасибо за пояснения и особенно примеры. Возник вопрос по Констрейнам и дабы не плодить других тем спрошу здесь: Как записать net в false_path, но при этом чтобы разводило максимально близко к источнику. Ибо есть проект и там по одному net'у времянка точно падает, но это учтено в последующей логике. Если оставить net как есть, вылазят слаки. Если закинуть в false_path, то оно его закидывает чёрт и куда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 2 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба Так а просто "прибить гвоздями" через set_property LOC [get_cells ] ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба 1 hour ago, gosha-z said: Так а просто "прибить гвоздями" через set_property LOC [get_cells ] ? Впринципе можно, но проблема в мусштабируемости. Если для параметра в один коннект "прибить" можно, то что сделать если переконфигурировать на 10-20-30 портов? можно развести конечно заранее и обконстрейнить, а потом убрать, но как-бы тоже вариант так себе Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба Приветствую! 4 hours ago, Nick_K said: Как записать net в false_path, но при этом чтобы разводило максимально близко к источнику. А смысл? Если цепь false_path то разницы куда впихнет не должно быть. Если разница есть - то это уже не false_path - значит нужно обконстрейнить чем то другим - set_max_delay, set_multicycle_path, ... Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 25 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба 23 hours ago, RobFPGA said: 1 Вы же в констрейне клок "привязываете" к входной ноге, поэтому и get_ports {CLK64_P}. При желании можете задать клок начиная в любой точке цепи НО с соответствующим выбором примитива (gets_pins ... ) являющегося источником. Добавил констрейн: create_clock -add -name sys_clk32_pin -period 31.250 -waveform {0 15.625} [get_pins { CLK32 }]; получил в ответ [Vivado 12-508] No pins matched 'CLK32'. [Vivado 12-4739] create_clock:No valid object(s) found for '-objects [get_pins CLK32]'. Что не так? 23 hours ago, RobFPGA said: 4. Как и в ISE - Все регистры выходы которых не используются, или имеют константное значение, удаляются на этапе синтеза и P&R. В варианте делителя в 37,5 раза: reg [6:0] Count3; always @( posedge CLK) begin Count3<=Count3+1; if (Count3[6:0]==7'd74) begin DAC_MCLK=~DAC_MCLK; Count3<=7'd0; end else if ((Count3[6:0]==7'd55)||(Count3[6:0]==7'd37) ||(Count3[6:0]==7'd18)) begin DAC_MCLK=~DAC_MCLK; end end когда Count3 был 32бита похоже не оптимизировал т.к. ругался на слаки в битах старше десятого, возможно из-за конструкции Count3[31:0]==32'd74 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба Приветствую! get_pins Это для поиска пинов для примитивов/cell внутри дизайна get_ports Это для внешних портов FPGA Откройте ваш дизайн после синтеза в Open Synthesys и тыкая мышкой по схему смотрите полное названия того куда попали во вкладке General - Name Понятное дело не оптимизировал - вы же явно указали в операции сравнения использовать всю ширину счетчика. Да и если просто напишете Count3==18 тоже будет весь счетчик в сравнении использоваться. У меня привычка уже давно - разрядность счетчиков, регистров, ... задавать автоматом в зависимости от максимальной величины localparam CNT_WH = $clog2(MAX_CNT_VAL); Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 25 30 июля, 2019 Опубликовано 30 июля, 2019 · Жалоба 2 hours ago, RobFPGA said: get_pins Это для поиска пинов для примитивов/cell внутри дизайна Откройте ваш дизайн после синтеза в Open Synthesys и тыкая мышкой по схему смотрите полное названия того куда попали во вкладке General - Name Не нахожу вкладку General - Name Тыкая мышкой удалось подобрать 4 имени для клоков чтобы не ругался при открытии синтеза, но в варнингах 2 имени не подключились Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться