|
|
  |
Констрейны для регистрирования данных от АЦП |
|
|
|
Jul 11 2013, 18:57
|
Частый гость
 
Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227

|
Доброго времени суток. помогите с вопросом: какие констрейны нужно задавать для АЦП тактируемого от клока с ПЛИС? Есть отладочная плата на stratix_IV и два мезанина с 2-мя АЦП на каждом, тактирую их от входящего на ПЛИС клока (125 МГц) без преобразований, через виртуальную дифф. пару (подаю прямой и инвертированный клок). Для регистрирования входных данных использую выходящие от 4-х АЦП клоки DCO. Если использую только 2 АЦП - всё хорошо, как только добавляю ещё 2 в проект, начинаются непонятки. TimeQuest говорит что всё нормально, но в SignalTap-е вместо принимаемого тестового синуса появляется всякий мусор. Я задавал такие констрейны: CODE set_time_format -unit ns -decimal_places 3 #************************************************************** # Create Clock #**************************************************************
create_clock -name "clk" -period 8.000ns [get_ports {clk}] create_clock -name altera_reserved_tck -period 100.000 -waveform {0.000 50.000} [get_ports altera_reserved_tck]
derive_pll_clocks -create_base_clocks
# Описание клоков, выдаваемых АЦП: create_generated_clock -name clk_112_0A -source [get_ports {clk}] [get_ports {clk_112_0A}] create_generated_clock -name clk_112_1A -source [get_ports {clk}] [get_ports {clk_112_1A}] create_generated_clock -name clk_112_0B -source [get_ports {clk}] [get_ports {clk_112_0B}] create_generated_clock -name clk_112_1B -source [get_ports {clk}] [get_ports {clk_112_1B}]
# Описание задержки выходного DCO клока на АЦП, относительно входного: set_clock_latency -source 4.5 [get_clocks {clk_112_0A}] set_clock_latency -source 4.5 [get_clocks {clk_112_1A}] set_clock_latency -source 4.5 [get_clocks {clk_112_0B}] set_clock_latency -source 4.5 [get_clocks {clk_112_1B}]
# Описание созданных клоков, идущих на АЦП: create_generated_clock -name chanel_0A_clk_112 -source [get_ports {clk}] [get_ports {chanel_0A_clk_112}] create_generated_clock -name chanel_0A_clk_112n -invert -source [get_ports {clk}] [get_ports {chanel_0A_clk_112n}] create_generated_clock -name chanel_1A_clk_112 -source [get_ports {clk}] [get_ports {chanel_1A_clk_112}] create_generated_clock -name chanel_1A_clk_112n -invert -source [get_ports {clk}] [get_ports {chanel_1A_clk_112n}] create_generated_clock -name chanel_0B_clk_112 -source [get_ports {clk}] [get_ports {chanel_0B_clk_112}] create_generated_clock -name chanel_0B_clk_112n -invert -source [get_ports {clk}] [get_ports {chanel_0B_clk_112n}] create_generated_clock -name chanel_1B_clk_112 -source [get_ports {clk}] [get_ports {chanel_1B_clk_112}] create_generated_clock -name chanel_1B_clk_112n -invert -source [get_ports {clk}] [get_ports {chanel_1B_clk_112n}]
#************************************************************** # Set Clock Uncertainty #************************************************************** derive_clock_uncertainty
#************************************************************** # Set Multicycle #************************************************************** set_multicycle_path -from clk_112_0A -to clk_112_0A -setup 1 set_multicycle_path -from clk_112_0A -to clk_112_0A -hold 1 set_multicycle_path -from clk_112_1A -to clk_112_1A -setup 1 set_multicycle_path -from clk_112_1A -to clk_112_1A -hold 1 set_multicycle_path -from clk_112_0B -to clk_112_0B -setup 1 set_multicycle_path -from clk_112_0B -to clk_112_0B -hold 1 set_multicycle_path -from clk_112_1B -to clk_112_1B -setup 1 set_multicycle_path -from clk_112_1B -to clk_112_1B -hold 1
#************************************************************** # Set Input Delay #************************************************************** set_input_delay -add_delay -clock [get_clocks {altera_reserved_tck}] 20.000 [get_ports {altera_reserved_tdi}] set_input_delay -add_delay -clock [get_clocks {altera_reserved_tck}] 20.000 [get_ports {altera_reserved_tms}]
set ext_Tsu_typ 2.9 set ext_Th_typ 3.0
# Входная задержка данных от АЦП по исходящему от АЦП клоку: set_input_delay -clock "clk_112_0A" -add_delay -max [expr $ext_Tsu_typ] [get_ports {chanel_0A_dat_112[*]}] set_input_delay -clock "clk_112_0A" -add_delay -min [expr $ext_Th_typ] [get_ports {chanel_0A_dat_112[*]}] set_input_delay -clock "clk_112_1A" -add_delay -max [expr $ext_Tsu_typ] [get_ports {chanel_1A_dat_112[*]}] set_input_delay -clock "clk_112_1A" -add_delay -min [expr $ext_Th_typ] [get_ports {chanel_1A_dat_112[*]}] set_input_delay -clock "clk_112_0B" -add_delay -max [expr $ext_Tsu_typ] [get_ports {chanel_0B_dat_112[*]}] set_input_delay -clock "clk_112_0B" -add_delay -min [expr $ext_Th_typ] [get_ports {chanel_0B_dat_112[*]}] set_input_delay -clock "clk_112_1B" -add_delay -max [expr $ext_Tsu_typ] [get_ports {chanel_1B_dat_112[*]}] set_input_delay -clock "clk_112_1B" -add_delay -min [expr $ext_Th_typ] [get_ports {chanel_1B_dat_112[*]}]
#************************************************************** # Set Output Delay #************************************************************** set_output_delay -add_delay -clock [get_clocks {altera_reserved_tck}] 20.000 [get_ports {altera_reserved_tdo}]
#************************************************************** # Set Clock Groups #************************************************************** set_clock_groups -asynchronous -group {clk} set_clock_groups -asynchronous -group {clk_112_0A} set_clock_groups -asynchronous -group {clk_112_1A} set_clock_groups -asynchronous -group {clk_112_0B} set_clock_groups -asynchronous -group {clk_112_1B} set_clock_groups -asynchronous -group {altera_reserved_tck}
#************************************************************** # Set False Path #**************************************************************
# Исключаем анализ путей сигналов разрешения: set_false_path -from * -to [get_ports chanel_0A_OE_n] set_false_path -from * -to [get_ports chanel_1A_OE_n] set_false_path -from * -to [get_ports chanel_0B_OE_n] set_false_path -from * -to [get_ports chanel_1B_OE_n] set_false_path -from * -to [get_ports chanel_0A_SPI_CS_n] set_false_path -from * -to [get_ports chanel_1A_SPI_CS_n] set_false_path -from * -to [get_ports chanel_0B_SPI_CS_n] set_false_path -from * -to [get_ports chanel_1B_SPI_CS_n] Кроме того, подскажите: - Нужно ли задавать задержки клока и данных на плате, или при условии их равенства они компенсируются? (при приведённых констрейнах я пробовал их описывать, но это ничего не дало, к тому же я их мерил вручную осциллографом, и весьма не уверен в их точности); - Как лучше задавать задержку выходящего от АЦП клока DCO, относительно входящего clk - через clock latency или прописывать через параметр -offset? - По поводу задержки на портах, как я понимаю, для min/max входной задержки нужно указывать min/max Tco. В даташите на АЦП я нашёл только параметры Tso и Th, могу ли я использовать их в этих целях? - Правильно ли я понимаю, что если Th для группы входного клока ~ 0.3 ns, это не есть хорошо? В приведённом sdc файле я использовал мультициклы. Без них Th~ 0.3 ns, с ними ~ 8 ns, но проект всё равно нормально не работает ( Если есть какие соображения у кого - поделитесь пожалуйста!
|
|
|
|
|
Jul 13 2013, 09:20
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Имею внешний генератор 250 MHz, с него через разветвитель тактов подаю их на два АЦП и на ПЛИС. Подобрал фазу тактовой частоты внутри ПЛИС, по которой данные с АЦП записываются в ПЛИС (и вся ПЛИС работает на этой сдвинутой по фазе частоте, и еще на двух более низких, тоже с той же задержкой). TimeQuest сам мне ничем помочь не смог, кроме как показывал "укладывается - не укладывается". А констрейны у меня были такие... на правильность не претендую... может, что-то полезное подсмотрите. Больше боролся с тем, чтобы TimeQuest не анализировал того, что не надо. CODE #******************************************************************************* # Time Information
# Формат времени set_time_format -unit ns -decimal_places 3
# Задержки тактов для АЦП по плате ( t(ns) = L(mm) / 150 ) # Задержка распространения рассчитана на калькуляторе Saturn PCB # Microstrip, W = 0.250 mm, H = 0.345 mm, FR-4 STD, 0.18 + 0.18 µm (Zo = 77 Ohm) set ADC1clk_min [expr 53.453 * 0.00563] set ADC1clk_max [expr 55.604 * 0.00563] set ADC2clk_min [expr 50.640 * 0.00563] set ADC2clk_max [expr 54.596 * 0.00563]
# Задержки преобразования в АЦП (1.9 valid,min | 2.8 pd,typ | 3.8 pd,max) set ADCtco_min 1.8 set ADCtco_max 3.8
# Задержки данных из АЦП по плате set ADC1dat_min [expr 15.893 * 0.00563] set ADC1dat_max [expr 42.767 * 0.00563] set ADC2dat_min [expr 15.325 * 0.00563] set ADC2dat_max [expr 34.516 * 0.00563]
# Задержки тактов для ПЛИС set PLDclk_min [expr 14.693 * 0.00563] set PLDclk_max [expr 15.099 * 0.00563]
#******************************************************************************* # Create Clock
# Входные такты (сдвинуты на полпериода, потому что инверсные) create_clock -name plc -period 250MHz -waveform {2.0 4.0} [get_ports {PLC_N}]
# Сигнал синхронизации (инверсный) create_clock -name trc -period 1MHz -waveform {0 10.0} {TRC_N}
# Внешние виртуальные такты для тактирования АЦП create_clock -name clka -period 250MHz
# Виртуальные такты, тактирующие шину связи с MCU create_clock -name clkb -period 120MHz
# Преобразование выбора ПЛИС в тактовый сигнал, чтобы игнорировать create_clock -name pls_n -period 120MHz [get_ports PLS_N]
#******************************************************************************* # Create Generated Clock
# Делитель частоты синхронизации create_generated_clock -name trig2 -divide_by 2 \ -source {Trigger|trig1} [get_nets {Trigger|trig2}]
#******************************************************************************* # Derive PLL Clocks
# Определить такты с ФАПЧ derive_pll_clocks -create_base_clocks
# Добавить такты в набор (коллекцию) set clkf altpll|altpll_component|auto_generated|pll1|clk[0] set clkm altpll|altpll_component|auto_generated|pll1|clk[1] set clks altpll|altpll_component|auto_generated|pll1|clk[2]
#******************************************************************************* # Derive Clocks (найти все незаданные такты, по умолчанию задается 1 GHz)
# derive_clocks
#******************************************************************************* # Derive Clock Uncertainty
derive_clock_uncertainty
#******************************************************************************* # Set Clock Uncertainty
# set_clock_uncertainty
#******************************************************************************* # Set Clock Latency
# set_clock_latency
#******************************************************************************* # Set Input Delay
# Канал 1 set_input_delay \ -clock clka -min \ [expr $ADC1clk_min + $ADCtco_min + $ADC1dat_min - $PLDclk_max] \ {S1D_N[*] S1D_P} set_input_delay \ -clock clka -max \ [expr $ADC1clk_max + $ADCtco_max + $ADC1dat_max - $PLDclk_min] \ {S1D_N[*] S1D_P}
# Канал 2 set_input_delay \ -clock clka -min \ [expr $ADC2clk_min + $ADCtco_min + $ADC2dat_min - $PLDclk_max] \ {S2D_P[*] S2D_N[*]} set_input_delay \ -clock clka -max \ [expr $ADC2clk_max + $ADCtco_max + $ADC2dat_max - $PLDclk_min] \ {S2D_P[*] S2D_N[*]}
## set_input_delay -clock clkb -min 0 [get_ports PLS_N] ## set_input_delay -clock clkb -max 0 [get_ports PLS_N]
#******************************************************************************* # Set Output Delay
# Запрос прерывания в MCU, задержка не важна set_output_delay -clock clkb -min 0 [get_ports PLIRQ_N] set_output_delay -clock clkb -max 0 [get_ports PLIRQ_N]
#******************************************************************************* # Set Multicycle Path
# По setup помогает, но не по hold # set_multicycle_path -setup -from line -to $clkf 4 # set_multicycle_path -hold -from $clkm -to line 2
# set_multicycle_path -setup -from S1Dp[*] -to $clkf 2 # set_multicycle_path -hold -from S1Dp[*] -to $clkf 1
# set_multicycle_path -setup -from S2Dn[*] -to $clkf 2 # set_multicycle_path -hold -from S2Dn[*] -to $clkf 1
# Сдвинуть окно от тактов АЦП до ПЛИС set_multicycle_path -from clka -to $clkf -start 2 set_multicycle_path -from clka -to $clkf -hold 0
# Расширить окно от тактов ПЛИС до запроса в микроконтроллере set_multicycle_path -from $clkm -to clkb -start 2 set_multicycle_path -from $clkm -to clkb -hold 1
set_multicycle_path -from Bridge|Bus.dat[*]* -to $clkf -setup 2 set_multicycle_path -from Bridge|Bus.dat[*]* -to $clkf -hold 1
set_multicycle_path -from Bridge|wrp -to [get_keepers *] -setup 2 set_multicycle_path -from Bridge|wrp -to [get_keepers *] -hold 1
#set_multicycle_path -from Bridge|wrp -to $clkf -setup 2 #set_multicycle_path -from Bridge|wrp -to $clkf -hold 1
#******************************************************************************* # Set Minimum Delay # act as low-level overrides of the setup and hold relationships
# set_min_delay
#******************************************************************************* # Set Maximum Delay # act as low-level overrides of the setup and hold relationships
# set_max_delay
#******************************************************************************* # Set Clock Groups
# Не анализировать синхронизацию от сети # set_clock_groups -asynchronous -group {line} -group {pls_n} set_clock_groups -asynchronous -group {trc trig2} set_clock_groups -asynchronous -group {pls_n}
#******************************************************************************* # Set False Path
# Запретить проверку по PLS_N # set_false_path -from [get_clocks pls_n]
# set_false_path -from nodes Signal_m:Signal|sdb[*] # [get_nodes {Bridge_m:Bridge.ADB[*]}]
# Работает, но не помогает # set_false_path -from [get_ports {ADB[*]}]
# set_false_path -through [get_registers Bus|dat[*]] # set_false_path -through [get_nets Bridge|Bus.dat[*]~*] set_false_path -through [get_nets Bridge|Bus.adr[*]] ### set_false_path -through [get_nets Bridge|Bus.dat[*]*] ### set_false_path -through [get_nets *|Bus.dat[*]*] #### set_false_path -through [get_nets *|Bus.dat[*]] # set_false_path -through [get_keepers dat[*]]
set_false_path -through [get_nets Bridge|Bus.dat[*]*] set_false_path -through [get_nets Memory|Bus.dat[*]*] set_false_path -from {Memory_m:Memory|ramsp_mf:sbm|altsyncram:altsyncram_component|altsyncram_8qf1:au to_generated|ram_block1a*} \ -to {Control_m:Control|*}
# Работает, помогает # set_false_path -through [get_nets Signal|sdb[*]]
# Работает, помогает, на пределе set_false_path -from Signal|sdb[*] -to Trigger|* set_false_path -from Signal|sdb[*] -to Control|* ## set_false_path -from Signal|sdb[*] -to SerDAC|* ### set_false_path -from TimeItp|itshrg[*]
set_false_path -to [get_ports TEST]
set_false_path -from Trigger|* -to Control|* ## set_false_path -from Trigger|* -to Signal|Bus.dat[*]*
#******************************************************************************* # Set Max Skew
# set_max_skew -from [get_ports {ADB[*] ADV_N OE_N WE_N PLS_N}] 4 set_max_skew -to [get_ports {PDWN* S2SYN TRHYS}] 8 ## set_max_skew -to [get_ports {DACSYNn LDACn DACSCL DACDIN}] 2 set_max_skew -to [get_ports {ITCH ITDCH_N ITRQ_N}] 2
|
|
|
|
|
Jul 16 2013, 06:50
|

Местный
  
Группа: Свой
Сообщений: 375
Регистрация: 9-10-09
Из: Свердловский регион
Пользователь №: 52 845

|
Посмотрите в Chip Planner'е по периметру кристалла, куда приходят сигналы от АЦП, на какие ноги. С этих ног сигналы идут внурть кристалла. У меня было так, что сигналы от АЦП приходили на соседние ноги ПЛИС, то есть сосредоточены были достаточно близко друг к другу, а вот сигналы от них внутрь кристалла уходили кто куда, один в центр, другой в верхний правый угол, третий в нижний левый (ну я немного приукрасил))). При такой разводке ловил описанные вами глюки. Сделал тот компонент, который отвечал за десериализацию и регистрацию данных АЦП, как Logic Lock Region, подтянул его в чип-планере поближе к входным ногам и теперь все работает стабильно. А вот мой sdc файл: Код derive_clock_uncertainty create_clock -period "50 MHz" -name {inp_clock_50MHz} {inp_clock_50MHz} create_clock -period "100 MHz" -name {inp_refclk} {inp_refclk} #create_clock -period "120 MHz" -name {inp_DCO_0_p} {inp_DCO_0_p} #create_clock -period "120 MHz" -name {dco_1} {pr:pr_inst|deserializer_buffer:deserializer_buffer_inst|adc_capture:adc_capture_pm|dco_1} derive_pll_clocks set_clock_groups -exclusive -group {pr_inst|pll_inst|altpll_component|auto_generated|pll1|inclk[0] pr_inst|pll_inst|altpll_component|auto_generated|pll1|clk[0]} set_clock_groups -exclusive -group {inp_clock_50MHz pr_inst|controller_ddr3_inst|writer_reader_pm|compDDR3_pm|dev_ddr3_inst|uni_ddr3 _inst|pll0|upll_memphy|auto_generated|pll1|clk[0]} set_clock_groups -exclusive -group {inp_refclk pr_inst|mypciexpress_x8_inst|pcie_inst|wrapper|altpcie_hip_pipen1b_inst|stratix_ iv.stratixiv_hssi_pcie_hip|coreclkout} У меня закомментарены строчки для ацпешной ноги DCO, не помню уже, что я с ней хотел сделать, возможно как раз и пытался побороть аналогичную проблему. А так, как видите, вообще нет ни каких констрейнов для АЦП (я ни в коем разе не говорю, что их не должно быть, я просто не знаю какие констрейны нужны и как их правильно прописать, но проект работает стабильно, не глючит).
|
|
|
|
|
Jul 16 2013, 07:54
|
Частый гость
 
Группа: Свой
Сообщений: 76
Регистрация: 8-04-11
Из: Ростов-на-Дону
Пользователь №: 64 227

|
Всем спасибо, вроде разобрался. Когда собирал этот проект, для начала решил не пихать сразу всю логику, а проверить правильность распиновки, регистрирования и пр., и чтоб фиттер не обрезал регистры, на которые я принимал данные, я назначил их выходы как порты. Далее Quartus сам присвоил им пины, которые ему понравились, и сконфигурировал их как GND. Уж не знаю конкретно почему, но именно это и являлось причиной столь непонятного поведения.
|
|
|
|
|
Aug 2 2013, 09:28
|
Группа: Новичок
Сообщений: 7
Регистрация: 25-04-12
Из: Зеленоград
Пользователь №: 71 554

|
Есть необходимость описать путь, задержка на котором не важна. Цитата(ViKo @ Jul 13 2013, 13:20)  А констрейны у меня были такие... на правильность не претендую... может, что-то полезное подсмотрите. Больше боролся с тем, чтобы TimeQuest не анализировал того, что не надо.  Пробую сделать по аналогии. Все варианты Quartus благополучно игнорирует следущим образом: строка в sdc: set_false_path -through [get_nets system:system|module_a:i_module_a|module_b:i_module_b|c_out] сообщение QuartusII : Warning: Ignored filter at FPGA.sdc(46): system:system|module_a:i_module_a|module_b:i_module_b|c_out could not be matched with a net Перепробовал много вариантов. Подскажите что я делаю не так?
|
|
|
|
|
Aug 2 2013, 11:43
|
Группа: Новичок
Сообщений: 7
Регистрация: 25-04-12
Из: Зеленоград
Пользователь №: 71 554

|
Цитата(R6L-025 @ Aug 2 2013, 15:32)  А вы уверены что то, что вы описываете, имеет тип 'nets' ? Посмотрите в TimeQuest есть ли такой элемент с таким типом, возможно там будет тип pins или ещё какой. Собственно в этом и есть проблема: он ругается на все типы, как если бы не было самого сигнала c_out . Однако, может я что-то не понимаю, но сигнал объявлен как output в модуле и по-идее он не должен при оптимизации выкинуться. Попытка в TimeQuest узнать тип элемента выдаёт следущее: "could not be matched with a port or pin or register or keeper or net".
|
|
|
|
|
Aug 2 2013, 12:09
|
Группа: Новичок
Сообщений: 7
Регистрация: 25-04-12
Из: Зеленоград
Пользователь №: 71 554

|
Цитата(R6L-025 @ Aug 2 2013, 16:02)  А Вы RTL Wiewer проверяли существование вашего порта? Мм... нет, как-то не подумал. Но во-первых на всякий случай поставил (*noprune*) . Во-вторых точно так же ведут себя ВСЕ порты модуля. ПС: RTL Viewer всё-таки посмотрю чуток по-позже, когда проект заново соберётся.
|
|
|
|
|
Aug 2 2013, 13:51
|
Группа: Новичок
Сообщений: 7
Регистрация: 25-04-12
Из: Зеленоград
Пользователь №: 71 554

|
Цитата(R6L-025 @ Aug 2 2013, 16:02)  А Вы RTL Wiewer проверяли существование вашего порта? Да. В RTL Viewer сигналы присутствуют. В Technology Map Viewer (post-mapping) некоторые имена уже отличаются.
|
|
|
|
|
Aug 6 2013, 12:05
|
Группа: Новичок
Сообщений: 7
Регистрация: 25-04-12
Из: Зеленоград
Пользователь №: 71 554

|
Проблема решена. Подсказка нашлась тут: http://www.altera.com/support/software/tim...false-path.html "When the objects are timing nodes, the false path only applies to the path between the two nodes." Т.е. констрейны "set_false_path -through " с типом объекта не "get_registers" с большой долей вероятности будут отбраковываться квартусом.
|
|
|
|
|
Aug 6 2013, 12:46
|
Группа: Новичок
Сообщений: 7
Регистрация: 25-04-12
Из: Зеленоград
Пользователь №: 71 554

|
Цитата(_Anatoliy @ Aug 6 2013, 16:36)  Ищите ответ в отчёте,таймквест показывает какие констрейны он отбраковал. С точки зрения информативности отчёт в таймквесте самый неудобный, лучше искать в варнингах.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|