Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: set_false_path Как правильно задать в TimeQuest
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
gin
Всем добрый день!
Есть следующий вопрос - в проекте имеется 2 клоковых домена. Между ними происходит обмен данными. Как задать в TimeQuest условие, чтобы он не учитывал пути между этими доменами в расчете?
Как я понимаю, есть команда set_false_path :

set_false_path -from [get_clocks __sourceClock] -to [get_clocks __destinationClock]

но как в ней описать клоки, которые формируются на внутренних PLL?
myq
Цитата(gin @ Mar 7 2017, 14:08) *
Всем добрый день!
Есть следующий вопрос - в проекте имеется 2 клоковых домена. Между ними происходит обмен данными. Как задать в TimeQuest условие, чтобы он не учитывал пути между этими доменами в расчете?
Как я понимаю, есть команда set_false_path :

set_false_path -from [get_clocks __sourceClock] -to [get_clocks __destinationClock]

но как в ней описать клоки, которые формируются на внутренних PLL?


Почитайте нашего коллегу с форума http://www.kit-e.ru/articles/plis/2010_10_54.php

А вообще - это команда, использовать которую *нельзя*.
Надо сетфальспасить только конкретные пути. Это приходит с опытом, поэтому убеждать не буду.
Shivers
Цитата(gin @ Mar 7 2017, 14:08) *
но как в ней описать клоки, которые формируются на внутренних PLL?

Сначала объявить эти клоки, а потом сделать их асинхронными через set_false_path.
Timmy
Цитата(gin @ Mar 7 2017, 14:08) *
Всем добрый день!
Есть следующий вопрос - в проекте имеется 2 клоковых домена. Между ними происходит обмен данными. Как задать в TimeQuest условие, чтобы он не учитывал пути между этими доменами в расчете?
Как я понимаю, есть команда set_false_path :

set_false_path -from [get_clocks __sourceClock] -to [get_clocks __destinationClock]

но как в ней описать клоки, которые формируются на внутренних PLL?

Для задания асинхронных клоков нужно пользоваться командой set_clock_groups а не set_false_path.
Чтобы автоматически описать клоки от внутренних PLL, есть команда derive_pll_clocks.
Также можно вручную их описать с помощью create_generated_clock.
Для сокращения длинных плохо читаемых автоматически созданных имён можно использовать макроподстановки TCL.
gin
Цитата(Shivers @ Mar 7 2017, 15:26) *
Сначала объявить эти клоки, а потом сделать их асинхронными через set_false_path.


Я наверное не совсем точно описал задачу.
Описаны входные клоки:

Код
derive_clock_uncertainty
create_clock -period "50 MHz" -name {clk_sys} {clk_sys}
create_clock -period "322.265625 MHz" -name {clk_ref} {clk_ref}
derive_pll_clocks


Из этих входных клоков затем формируются клоки (на PLL), на которых работает внутренняя логика. И для этих внутренних клоков нужно написать false path. Но эти внутренние клоки имеют какие то сложные внутренние названия. Вот как их узнать и задать?
Timmy
Цитата(gin @ Mar 7 2017, 16:03) *
Из этих входных клоков затем формируются клоки (на PLL), на которых работает внутренняя логика. И для этих внутренних клоков нужно написать false path. Но эти внутренние клоки имеют какие то сложные внутренние названия. Вот как их узнать и задать?

Узнать - из отчёта TimeQuest по всем клокам.
gin
Цитата(Timmy @ Mar 7 2017, 16:14) *
Узнать - из отчёта TimeQuest по всем клокам.


То есть я правильно понял Вас?
Вот например, в отчете у меня есть клок rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_i
nst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divclk

и есть клок pll_sys_inst|pll_sys_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk

и я могу их использовать в команде set_false_path как sourceClock и destinationClock

Timmy
Цитата(gin @ Mar 7 2017, 17:05) *
То есть я правильно понял Вас?
Вот например, в отчете у меня есть клок rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_i
nst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divclk

и есть клок pll_sys_inst|pll_sys_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk

и я могу их использовать в команде set_false_path как sourceClock и destinationClock

Конечно, можете, только в фигурные скобки обязательно ставьте, или через макроподстановку.
Dr.Alex
Цитата(gin @ Mar 7 2017, 14:08) *
Между ними происходит обмен данными.

Если таки "происходит обмен данными", то фолспасить есесно нельзя.

Можно правда и совсем не констрейнить, но только если этот обмен идёт через чужую корку (например фифо), которая уже правильно законстрейнена внутри.
gin
Цитата(Timmy @ Mar 7 2017, 17:23) *
Конечно, можете, только в фигурные скобки обязательно ставьте, или через макроподстановку.


Спасибо!
Т.е. команда будет выглядеть следующим образом?

set_false_path -from {get_clocks rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_i
nst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divclk
} -to {get_clocks pll_sys_inst|pll_sys_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk
}
И чем отличаются фигурные скобки от квадратных? В Альтеровском примере они вроде как квадратные

Цитата(Dr.Alex @ Mar 7 2017, 17:39) *
Если таки "происходит обмен данными", то фолспасить есесно нельзя.

Можно правда и совсем не констрейнить, но только если этот обмен идёт через чужую корку (например фифо), которая уже правильно законстрейнена внутри.


Ну естественно там все по феншую сделано biggrin.gif , обмен происходит без потерь данных. Вопрос именно в том, чтобы дать указание анализатору времянок не учитывать этот асинхронный путь, так как он его правильно учитывать не сможет, а только отчет мне перегружает своими предупреждениями.
Dr.Alex
Цитата(gin @ Mar 7 2017, 17:44) *
Ну естественно там все по феншую сделано biggrin.gif , обмен происходит без потерь данных. Вопрос именно в том, чтобы дать указание анализатору времянок не учитывать этот асинхронный путь, так как он его правильно учитывать не сможет, а только отчет мне перегружает своими предупреждениями.

Сами-то поняли чё сказали? Если УЖЕ всё по феншую, то и никаких указаний от вас уже не требуется.

Если же переход через клок-домены всё-таки самопальный и никто кроме вас его ещё не констрейнил, то констрейнить НАДО, но ФОЛСПАСИТЬ НЕЛЬЗЯ.
Timmy
Цитата(gin @ Mar 7 2017, 17:44) *
Спасибо!
Т.е. команда будет выглядеть следующим образом?

set_false_path -from {get_clocks rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_i
nst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divclk
} -to {get_clocks pll_sys_inst|pll_sys_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk
}
И чем отличаются фигурные скобки от квадратных? В Альтеровском примере они вроде как квадратные

set_false_path -from [get_clocks {rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_
inst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divclk}
] -to [get_clocks {pll_sys_inst|pll_sys_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divcl
k}
]
По поводу скобок учебник языка TCL почитайте. В большинстве примеров фигурные скобки не нужны, так как имена клоков не содержат внутри себя символов макроподстановки( [] и $ )
gin
Цитата(Timmy @ Mar 7 2017, 17:54) *
set_false_path -from [get_clocks {rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_
inst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divclk}
] -to [get_clocks {pll_sys_inst|pll_sys_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divcl
k}
]
По поводу скобок учебник языка TCL почитайте. В большинстве примеров фигурные скобки не нужны, так как имена клоков не содержат внутри себя символов макроподстановки( [] и $ )



Спасибо! Буду теперь знать, а то с tcl практически не приходилось иметь дело

Цитата(Dr.Alex @ Mar 7 2017, 17:50) *
Сами-то поняли чё сказали? Если УЖЕ всё по феншую, то и никаких указаний от вас уже не требуется.

Если же переход через клок-домены всё-таки самопальный и никто кроме вас его ещё не констрейнил, то констрейнить НАДО, но ФОЛСПАСИТЬ НЕЛЬЗЯ.


Не понял, а почему собственно нельзя?
Ведь false path просто убирает из анализа данные пути (которые между двумя клоками), так как их фактически невозможно обконстрейтить, они ведь асинхронные.

Shivers
Цитата(gin @ Mar 7 2017, 19:13) *
Ведь false path просто убирает из анализа данные пути (которые между двумя клоками), так как их фактически невозможно обконстрейтить, они ведь асинхронные.

Так и есть. Просто бытует мнение, что если set_false_path заменить на что то более нейтральное, к примеру на set_multycycle_path или set_max_delay, то фиттер расположит триггеры-источники и триггеры-приемники разных клоковых доменов рядом, а не как бог на душу положит. В этом есть свой резон, особенно если границу клоковых доменов пересекают не отдельные сигналы, а целые шины, разряды которых могут сильно "расползтись" по кристаллу. Но на практике я не встречал, чтобы set_false_path ломал логику схемы. Т.е. все работает и с set_false_path.
Dr.Alex
Цитата(gin @ Mar 7 2017, 19:13) *
Ведь false path просто убирает из анализа данные пути (которые между двумя клоками), так как их фактически невозможно обконстрейтить, они ведь асинхронные.

Их не только можно обконстрейнить, а нужно.
Если разброс в длинах путей превысит 1 период приёмного клока, то ваш клок-домэйн-кроссинг работать не будет.
Конечно, если вы сделаете строб, запаздывающий на 100 тактов от данных, то можно и не констрейнить. Но вряд ли кто-то так делает.

Shivers говорит что он не встречал, чтобы такой разброс был, а вот я встречал.
Зато к примеру я не встречал, чтобы какой-то прожект не разводился на 10 МГц тактовой.
Но это не значит что тактовую не надо констрейнить, тем более что это просто.
Shivers
Все не так страшно. Простой расчет: сигнал сопровождения к шине (т.е. строб) задерживается на 2 такта пересинхронизации в приемной части. Это значит, что данные могут задержаться не более чем на 2 такта относительно прихода строба. Если приемная частота 100 МГц, получаем 20нс - это очень много, откуда в ПЛИС такие задержки роутинга через матрицу интерконнекта? Далее, из приемной части должен прийти сигнал подтверждения приема. который задерживается на 2 такта в пересинхронизаторах передающей части, прежде чем выставятся новые данные. Итого, разброс задержек для шины между двумя клоковыми доменами составляет +/- 2 такта, или около +/- 20н (100 МГц), что очень много.
Опасность возникает, только если частоты под гигагерц, или если на границе клоковых доменов добавлена логика (изредка встречается, хотя я бы руки за такое отрывал) - вот тогда действительно нужно использовать малтисайкл 2.
gin
Цитата(Shivers @ Mar 8 2017, 11:28) *
Все не так страшно. Простой расчет: сигнал сопровождения к шине (т.е. строб) задерживается на 2 такта пересинхронизации в приемной части. Это значит, что данные могут задержаться не более чем на 2 такта относительно прихода строба. Если приемная частота 100 МГц, получаем 20нс - это очень много, откуда в ПЛИС такие задержки роутинга через матрицу интерконнекта? Далее, из приемной части должен прийти сигнал подтверждения приема. который задерживается на 2 такта в пересинхронизаторах передающей части, прежде чем выставятся новые данные. Итого, разброс задержек для шины между двумя клоковыми доменами составляет +/- 2 такта, или около +/- 20н (100 МГц), что очень много.
Опасность возникает, только если частоты под гигагерц, или если на границе клоковых доменов добавлена логика (изредка встречается, хотя я бы руки за такое отрывал) - вот тогда действительно нужно использовать малтисайкл 2.


Полностью согласен, задержка при передаче от триггера к триггеру (если между ними нет комбинационной логики) в современных ПЛИС занимает мало времени. Так что констрейтить, думаю там действительно не стоит, а то это уже какой то паранойей попахивает)
gin
Что то я совсем не так делаю...

Не хочет Квартус отключать выбранные пути из анализа. Из-за этого к чертям все времянки летят. Когда анализирую отдельно основную часть проекта (которая на 156 Мгц работает) - он пишет, что может ее и на 230 МГц вытянуть. Когда подключаю дополнительный модуль, работающей на 50 МГц, который изредка обменивается данными с основным, то все рушится. Вместо 156 Квартус дает только 105 МГц (это при том, что раньше он 230 гарантировал!!!). И в отчете как раз междоменные и заваливают частоту.

И как мне этот проклятый констрейт правильно задать?!
Golikov A.
да вроде не сложно

set_false_path -from [get_clocks clk_1] -to [get_clocks clk_2]
set_false_path -from [get_clocks clk_2] -to [get_clocks clk_1]

или
set_false_path -rise_from <clk_1> -rise_to <clk_2>
set_false_path -rise_from <clk_2> -rise_to <clk_1>
ну и от падающего до восходящего и наоборот если есть работы по разным фронтам

не забывайте что надо как вперед, так и назад
gin
Цитата(Golikov A. @ Mar 30 2017, 12:58) *
да вроде не сложно

set_false_path -from [get_clocks clk_1] -to [get_clocks clk_2]
set_false_path -from [get_clocks clk_2] -to [get_clocks clk_1]

или
set_false_path -rise_from <clk_1> -rise_to <clk_2>
set_false_path -rise_from <clk_2> -rise_to <clk_1>
ну и от падающего до восходящего и наоборот если есть работы по разным фронтам

не забывайте что надо как вперед, так и назад


Тоже так подумал, что надо в обе стороны описывать, вроде помогло. Вот что значит, поплакался на форуме, и заработало))
_Anatoliy
Цитата(Timmy @ Mar 7 2017, 16:03) *
Для сокращения длинных плохо читаемых автоматически созданных имён можно использовать макроподстановки TCL.

Очень заинтересовало Ваше сообщение. Надоело после команды derive_pll_clocks врукопашную править имена всех клоков на смысловые. Не сможете ли примерчик подкинуть?
gin
Цитата(_Anatoliy @ Mar 30 2017, 14:45) *
Очень заинтересовало Ваше сообщение. Надоело после команды derive_pll_clocks врукопашную править имена всех клоков на смысловые. Не сможете ли примерчик подкинуть?


Кстати да, а то писать эти длинные имена вручную очень утомительно. Да и при изменениях в проекте эти имена ведь тоже меняются. Хочется автоматизировать
DuHast
Цитата(gin @ Mar 30 2017, 10:25) *
И как мне этот проклятый констрейт правильно задать?!

Сделайте через GUI в TimeQues. Команда будет продублирована в командной строке. Скопируйте её и вставте в свой SDC файл.
Timmy
Цитата(_Anatoliy @ Mar 30 2017, 14:45) *
Очень заинтересовало Ваше сообщение. Надоело после команды derive_pll_clocks врукопашную править имена всех клоков на смысловые. Не сможете ли примерчик подкинуть?

Код
set rx_clk_name {rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_inst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divc
lk}
set sys_clk_name {pll_sys_inst|pll_sys_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}

set_false_path -from [get_clocks $rx_clk_name] -to [get_clocks $sys_clk_name]

# и ещё больше можно упростить:
set rx_clk [get_clocks $rx_clk_name]
set sys_clk [get_clocks $sys_clk_name]
set_false_path -from $rx_clk -to $sys_clk

_Anatoliy
Цитата(Timmy @ Mar 31 2017, 08:10) *
Код
set rx_clk_name {rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_inst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divc
lk}
set sys_clk_name {pll_sys_inst|pll_sys_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}

set_false_path -from [get_clocks $rx_clk_name] -to [get_clocks $sys_clk_name]

# и ещё больше можно упростить:
set rx_clk [get_clocks $rx_clk_name]
set sys_clk [get_clocks $sys_clk_name]
set_false_path -from $rx_clk -to $sys_clk

Спасибо! Но это как раз понятно. Здесь строчку
rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_i
nst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divclk

всё равно придётся писать вручную (копипастить). Например у меня название клока такое spll1|pll1_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|vco1ph[0], а после пересборки проекта вполне может вместо vco1ph[0] оказаться vco1ph[1],естественно сыпятся все ограничения. Тогда приходится ручками перебивать все имена. Я эту ситуацию имел ввиду.
Timmy
Цитата(_Anatoliy @ Mar 31 2017, 09:31) *
Спасибо! Но это как раз понятно. Здесь строчку
rx_10g_inst|rx_10g_inst|xv_xcvr_10gbaser_nr_inst|ch[0].sv_xcvr_10gbaser_native_i
nst|g_fpll.altera_pll_156M~PLL_OUTPUT_COUNTER|divclk

всё равно придётся писать вручную (копипастить). Например у меня название клока такое spll1|pll1_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|vco1ph[0], а после пересборки проекта вполне может вместо vco1ph[0] оказаться vco1ph[1],естественно сыпятся все ограничения. Тогда приходится ручками перебивать все имена. Я эту ситуацию имел ввиду.

Можно попробовать получить идентификатор и имя выходного пина PLL по имени clock net:
Код
foreach_in_collection net [get_nets "clk"] {
  puts [get_net_info -name $net]
  puts [set pin_id [get_net_info -pin $net]]
  puts [set pin_name [get_pin_info -name $pin_id]]
}
А потом непосредственно сделать имя клока из имени пина, или, по-научному, перебрать все клоки, и выбрать те, у которых target равен $pin_name
_Anatoliy
Цитата(Timmy @ Mar 31 2017, 14:03) *
Можно попробовать получить идентификатор и имя выходного пина PLL по имени clock net:
Код
foreach_in_collection net [get_nets "clk"] {
  puts [get_net_info -name $net]
  puts [set pin_id [get_net_info -pin $net]]
  puts [set pin_name [get_pin_info -name $pin_id]]
}
А потом непосредственно сделать имя клока из имени пина, или, по-научному, перебрать все клоки, и выбрать те, у которых target равен $pin_name

Спасибо! Как появится "окно" в работе обязательно попробую.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.