Перейти к содержанию
    

Timing constraints для source synchronous интерфейса на Gowin

Доброго всем времени суток!

Пытаюсь понять, как у Gowin описать констрейнты для синхроного интерфейса, у которого выходные регистры для сигналов интерфейса тактируются от PLL, а тактовый сигнал для передаваемых данных генерируется с помощью ODDR. Суть задачи вполне типовая и хорошо описана, например, в документации на Альтеру:
image.png.ee1f889db788ada3c8c9e2a4efa9a4dd.png

Констрейнты для тактового сигнала Альтера предлагает описывать так:
 

create_clock -name input_clock -period 10.000 [get_ports clk_in]
create_generated_clock -name common_clock -source \
	[get_pins PLL|inclk[0]] [get_pins PLL|clk[0]]
create_generated_clock -name output_clock -source \
	[get_pins DDR|ddio_outa[0]|muxsel] [get_ports clk_out]

Для Gowin это выглядит приблизительно так:

create_clock -name sys_clk_i -period 20 -waveform {0 10} [get_ports {sys_clk_i}]
create_generated_clock -name clk -source [get_ports {sys_clk_i}] -multiply_by 12 -divide_by 5 [get_pins {main_pll_inst/rpll_inst/CLKOUT}]
create_generated_clock -name clk_o -source [get_pins {clk_oddr_inst/Q0}] -multiply_by 1 [get_pins {clk_o_obuf/O}]

В результате Gowin ругается совершенно странным образом:

ERROR  (TA2004) : "constraints/timing.sdc":3 | Cannot get clock with name ''
WARN  (TA1052) : Generated clock is ignored

Т.е. он должен был бы найти тактовый сигнал clk, но не находит ничего. Кто-нибудь имел опыт решения подобной задачи на Gowin?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а зачем вам вообще тактовый сигнал clk? Я всегда просто на порт сажал клок, а там дальше софт сам разбирался откуда он идет и какие его соотношения

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, des00 сказал:

а зачем вам вообще тактовый сигнал clk? Я всегда просто на порт сажал клок, а там дальше софт сам разбирался откуда он идет и какие его соотношения

Чтобы на него можно сослаться при описании выходного тактового сигнала, идущего через ODDR. Gowin имеет проблемы с автоматической генерацией тактовых сигналов после PLL.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, makc said:

Чтобы на него можно сослаться при описании выходного тактового сигнала, идущего через ODDR. Gowin имеет проблемы с автоматической генерацией тактовых сигналов после PLL.

так clk это логическое имя, не физическое. он вообще у вас никак не обозначен в последней строке. он нужен что бы тактовые группы прописать(если делать по красоте), мультициклы, ложные пути т.д.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, des00 сказал:

так clk это логическое имя, не физическое. он вообще у вас никак не обозначен в последней строке. он нужен что бы тактовые группы прописать(если делать по красоте), мультициклы, ложные пути т.д.

Совершенно верно, но среда понимает, что тактирование выходного триггера ODDR осуществляется этим тактовым сигналом и должна осуществлять привязку к нему. Но этого, похоже, не происходит, т.к. то ли я слишком многого от неё хочу, то ли нужно писать по-другому. В этом, отчасти, и состоит вопрос - как правильно описать констрейнты для этого случая (параллельная шина параллельно с тактовым сигналом для неё)? У Xilinx всё было просто, здесь же как-то не получается.

PS: Обратите внимание, что в примере Альтеры тоже не упоминается промежуточный логический тактовый сигнал. Но, однако, у них это работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

create_generated_clock -name clk -source [get_ports {sys_clk_i}] -multiply_by 12 -divide_by 5 [get_pins {main_pll_inst/rpll_inst/CLKOUT}]

create_generated_clock -name clk_o -source [get_clocks clk] -multiply_by 1 [get_pins {clk_o_obuf/O}]
или
create_generated_clock -name clk_o -source [get_pins {main_pll_inst/rpll_inst/CLKOUT}] -multiply_by 1 [get_pins {clk_o_obuf/O}]

А если так.

Софт не видит тактового сигнала на  -source [get_pins {clk_oddr_inst/Q0}], хотя говорит об этом странно (Cannot get clock with name ''")

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 часов назад, honinbo сказал:
create_generated_clock -name clk_o -source [get_clocks clk] -multiply_by 1 [get_pins {clk_o_obuf/O}]

Это вызывает ошибку

WARN  (TA1013) : "constraints/timing.sdc":6 | Option "-source" should not be a collection of clock, all_inputs and all_outputs

 

11 часов назад, honinbo сказал:
create_generated_clock -name clk_o -source [get_pins {main_pll_inst/rpll_inst/CLKOUT}] -multiply_by 1 [get_pins {clk_o_obuf/O}]

Этот вариант среда проглотила, правда я так уже пробовал. В результате в таймингрепорте появляется строчка "No timing paths to get frequency of htclk_o!", что означает только одно - этот тактовый сигнал в анализе не участвует. Такое впечатление, что Gowinовский софт не понимает,что внутренний сигнал тактирует выходные триггера, подключенные к выходным буферам ПЛИС, указанным в set_output_delay для портов, связанных с этим тактовым сигналом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё поэкспериментировал с параметрами генерируемых тактовых сигналов и параметрами set_output_delay и пока получается, что если в качестве тактового сигнала у set_output_delay указать выходной тактовый сигнал c выхода ODDR (clk_o), то анализатор просто игнорирует данный set_output_delay, т.к. по всей видимости не видит связи между clk и clk_o. Не помогает даже вариант с прямым описанием и указанием связи через offset:

create_generated_clock -name clk_o -source [get_nets {clk}] -offset 3 [get_pins {clk_o_obuf/O}]

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё-таки он видит связь между этими тактовыми сигналами, но для понимания этого факта  необходимо было добавить строчку в sdc:

report_timing -setup -max_paths 100 -from_clock [get_clocks {clk}] -to_clock [get_clocks {clk_o}]

Но в целом, кажется, я напал на правильный путь решения этой проблемы и неоценимую помощь в этом мне оказала статья от Xilinx - AR63222 - Why and when is set_multicycle_path needed to constrain the input and output paths.pdf

В итоге получается приблизительно следующее описание:

create_generated_clock -name clk -source [get_ports {sys_clk_i}] -multiply_by 12 -divide_by 5 [get_pins {main_pll_inst/rpll_inst/CLKOUT}]
create_generated_clock -name clk_o -source [get_nets {clk}] -offset 2.819 [get_pins {clk_o_obuf/O}]
set_output_delay -clock [get_clocks {clk_o}] -max 2.2 -rise [get_ports {dio[*]}]
set_multicycle_path -setup 2 -from [get_clocks {clk}] -to [get_ports {dio[*]}]
set_multicycle_path -hold 1  -from [get_clocks {clk}] -to [get_ports {dio[*]}]
report_timing -setup -max_paths 100 -from_clock [get_clocks {clk}] -to_clock [get_clocks {clk_o}]

2.819 ns это оценочное значение задержки по выходу clk_o_obuf/O от выхода Q0 ODDR до пина корпуса. Его в принципе не сложно вытащить.
2.2 ns это требуемое значение Tsu на стороне приёмника данных.

Прошу покритиковать найденное решение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 hours ago, makc said:

Прошу покритиковать найденное решение.

жаль нет установленного по от говин, так бы покрутил. но если по логике вещей, единственное что режет глаз это задержки. По идее там же как минимум 3-4 coner case и все такое, для них задержки должны быть разные. И у вас действительно мультицикловая передача? или вы просто сдвигаете фронт сигнала для приема? Для задержек, ЕМНП только один вид мультицикла задается, hold двигается автоматически.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, des00 сказал:

или вы просто сдвигаете фронт сигнала для приема?

Да, необходимо сдвинуть фронт, по которому принимающая сторона будет защелкивать данные. Выдаваемый наружу фронт сдвинут относительно внутреннего его запустившего на 2.819, но если не сделать multicycle, то STA начинает использовать его в качестве фронта, по которому приемник должен защелкнуть данные. Это оказывается невыполнимым априори, т.к. задержки на других выходах приблизительно такие же и мы получаем кучу нерелевантных ошибок в STA.

 

8 минут назад, des00 сказал:

Для задержек, ЕМНП только один вид мультицикла задается, hold двигается автоматически.

Я отталкивался от статьи и рекомендации Xilinx. Возможно они просто перебдели, но мне это показалось логичным, особенно в контексте Gowin, у которого ничего автоматически похоже не делается. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 hours ago, makc said:

Прошу покритиковать найденное решение.

Главные критики - лог и репорты.

Если софт считает, то что вам нужно, то и хорошо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 минут назад, honinbo сказал:

Главные критики - лог и репорты.

Если констрейнты описаны неправильно или не описаны вообще, то ругани не будет, поэтому лог и репорт совсем не показатели. 

8 минут назад, honinbo сказал:

Если софт считает, то что вам нужно, то и хорошо.

Вопрос как раз в том, чтобы правильно донести до софта то, что мне нужно и, как оказалось, это не так просто. В частности меня не устраивает ручная подстройка фазы генерируемого выходного такового сигнала, но похоже по-другому Gowin пока не умеет и скорее всего в ближайшее время уметь не будет, т.к. Lattice по описанию точно такой же.

PS: Пытался найти пример для просветления в тестовом проекте Gowin для DDR3, но там тихий ужас - констрейнты есть только на тактовый сигнал и ни на что более. 🤦‍♂️

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

1 hour ago, makc said:

Да, необходимо сдвинуть фронт, по которому принимающая сторона будет защелкивать данные. Выдаваемый наружу фронт сдвинут относительно внутреннего его запустившего на 2.819, но если не сделать multicycle, то STA начинает использовать его в качестве фронта, по которому приемник должен защелкнуть данные. Это оказывается невыполнимым априори, т.к. задержки на других выходах приблизительно такие же и мы получаем кучу нерелевантных ошибок в STA.

Да это то понятно, просто ЕМНП для сдвигов момента семплирования нужно указывать только -setup к -end клоку. Hold там двигается автоматически. Если задать setup/hold 2/1 как у вас это вариант анализа, когда -end клок идет в 2 раза реже. В общем если есть картинка как ПО делает анализ, рекомендую глянуть картинку)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возьмусь утверждать что эта строка неверная

create_generated_clock -name clk_o -source [get_nets {clk}] -offset 2.819 [get_pins {clk_o_obuf/O}]

Почему, потому что source synchronous должен констрейниться относительно выхода клока - порта (выхода физического пада микросхемы), а не какого то баффера внутри.

Собственно, надо использовать этот констрейнт из примера Альтеры в первом посте, посколько он правильный де-юро, т.е. как в учебнике. С говин не работал, но шансов что они свою трактовку в туле сделали - ноль.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...