Jump to content

    

Констрейны в Vivado и культура описания проекта

Есть необходимость создания проекта под 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? В верилоге сразу указать нельзя?

 

Share this post


Link to post
Share on other sites
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? В верилоге сразу указать нельзя?

Можно и в коде. Но это не всегда нужно/удобно, хотя вполне реально. Также детальнее тут

Share this post


Link to post
Share on other sites

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

О сколько вопросов ... Может проще сначала user guide почитать :biggrin:

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 с циклами, условиями, блек-джеком, и  :girl_dance:

Удачи! Rob.

Share this post


Link to post
Share on other sites
14 hours ago, RobFPGA said:

из файлов .xdc можно лепить иерархию

А как это? Что-то я нигде не встречал такого, чтобы прямо вложенные файлы были. Можно линк на UG какой-то?

И на это тоже:

14 hours ago, RobFPGA said:

Можно привязывать отдельные xdc файлы к отдельным модулям  как по типу модуля (cell) так и к конкретному инстансу

Про Тикль слыхал, но опять таки нигде не видел. Наверное потому что мои проекты слишком маленькие

Share this post


Link to post
Share on other sites
16 hours ago, RobFPGA said:

из файлов .xdc можно лепить иерархию.  Можно привязывать отдельные xdc файлы к отдельным модулям  как по типу модуля (cell) так и к конкретному инстансу. Можно использовать .tcl в качестве файлов constains и  писать вычисляемые constain с циклами, условиями

1. я под иерархией всегда понимал возможность соурсить внутри одного xdc другой - в этом смысле получается, что иерархия невозможна. в плане того, что проект можно дробить на несколько еирархичных xdc, в которых описываются ограничения для конкретных инстансов иерархичного дизайна - да... можно, но что удивительно, полез сейчас в хелп и обнаружил у read_xdc замечательгые опции -ref -cells, вот уж воистину - век живи, век учись!!!  :umnik2:

день удался! :yahoo:

 

 

2. что-то я как ни пытался не смог заставить работать if & for внутри файлов XDC (non-project mode) ,  а внутренности XDC писать в тикле ( без read_xdc) вивадо не разрешает,

но например этот фокус прокатывал c SDC в Cadence Genus, и, как я понял, всё что можно писать в XDC можно подсмотреть по:   Vivado% help -category XDC

Share this post


Link to post
Share on other sites
6 minutes ago, Doka said:

под иерархией всегда понимал возможность соурсить внутри одного xdc другой

Вот и я так же

5 minutes ago, Doka said:

полез сейчас в хелп

Это какой-то юзергайд или просто опция Вивады?

Share this post


Link to post
Share on other sites
36 minutes ago, Nick_K said:

Это какой-то юзергайд или просто опция Вивады?

help read_xdc

1380370957_Screenshotfrom2019-07-3011-31-10.thumb.png.6deda1c2c7cb7782089d154c79bdb4e0.png

Share this post


Link to post
Share on other sites

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

1 hour ago, Doka said:

и обнаружил у read_xdc замечательгые опции -ref -cells,

Именно это я и имел в виду под иерархией. 

Ну а, чтобы пользовать блек-джек и :girl_dance: в констрейнах надо задавать тип файла  .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.

Share this post


Link to post
Share on other sites

Спасибо за пояснения и особенно примеры.

Возник вопрос по Констрейнам и дабы не плодить других тем спрошу здесь:

Как записать net в false_path, но при этом чтобы разводило максимально близко к источнику.

Ибо есть проект и там по одному net'у времянка точно падает, но это учтено в последующей логике. Если оставить net как есть, вылазят слаки. Если закинуть в false_path, то оно его закидывает чёрт и куда.

Share this post


Link to post
Share on other sites

Так а просто "прибить гвоздями" через set_property LOC [get_cells ] ?

Share this post


Link to post
Share on other sites
1 hour ago, gosha-z said:

Так а просто "прибить гвоздями" через set_property LOC [get_cells ] ?

Впринципе можно, но проблема в мусштабируемости. Если для параметра в один коннект "прибить" можно, то что сделать если переконфигурировать на 10-20-30 портов? можно развести конечно заранее и обконстрейнить, а потом убрать, но как-бы тоже вариант так себе

Share this post


Link to post
Share on other sites

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

4 hours ago, Nick_K said:

Как записать net в false_path, но при этом чтобы разводило максимально близко к источнику.

А смысл?  Если  цепь  false_path то разницы куда впихнет не должно быть. Если разница есть - то это уже не   false_path - значит нужно обконстрейнить чем то другим - set_max_delay,  set_multicycle_path, ...  

Удачи! Rob.

Share this post


Link to post
Share on other sites
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

 

Share this post


Link to post
Share on other sites

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

get_pins   Это для поиска  пинов для примитивов/cell внутри дизайна

get_ports   Это для внешних портов FPGA

Откройте ваш  дизайн после синтеза  в Open Synthesys  и тыкая мышкой по схему  смотрите полное названия того куда попали во вкладке General - Name

 Понятное дело не оптимизировал - вы же явно указали в операции сравнения использовать всю ширину счетчика.  Да и если просто напишете 

Count3==18 тоже будет весь счетчик в сравнении использоваться.

У меня привычка уже давно -  разрядность счетчиков, регистров, ... задавать  автоматом в зависимости от максимальной величины

localparam CNT_WH = $clog2(MAX_CNT_VAL);  

Удачи! Rob.

Share this post


Link to post
Share on other sites
2 hours ago, RobFPGA said:

get_pins   Это для поиска  пинов для примитивов/cell внутри дизайна

Откройте ваш  дизайн после синтеза  в Open Synthesys  и тыкая мышкой по схему  смотрите полное названия того куда попали во вкладке General - Name

 

 

Не нахожу вкладку General - Name

 

Тыкая мышкой удалось подобрать 4 имени для клоков чтобы не ругался при открытии синтеза, но в варнингах 2 имени не подключились

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