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

Как проще и правильней переходить с clk на clk_xN и обратно

Добрый день, коллеги.

Основная логика работает на базовой частоте, а небольшая выделенная часть, например, BlockRAM - на удвоенной или утроенной.
Как это лучше реализовать, если учесть, что [высокая] частота BRAM близка к максимальной для данного ПЛИСа.

Про идею можно почитать тут:
  1. https://cpufpga.files.wordpress.com/2016/04...s_isca_2016.pdf слайд 74
  2. https://www.xilinx.com/support/answers/68595.html
  3. http://citeseerx.ist.psu.edu/viewdoc/downl...p1&type=pdf


Вопросы/требования:
1) оба клока (clk, clk_x2) должны быть выходами PLL или необязательно?
2) надо обойтись без синхронизаторов и async fifo
3) надо ли дополнительно констрейнить или САПР сам правильно всё понимает?

По клокам, я предполагаю, что снаружи надо генерить более высокую частоту с низким джиттером (т.е. clk_xN), а внутри - делить её уже на N.

Как достоверно определять 1-й такт из N?

Код
always @ (posedge clk_xN) begin
  if (clk) blablabla;
end


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

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


Ссылка на сообщение
Поделиться на другие сайты
идея использования нескольких частот выглядит не очень
нельзя ли отказаться от clk, а считать всё на clk_x2 ?
А где надо получать сигнал разрешения счёта enable/valid локально из clk_x2?

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


Ссылка на сообщение
Поделиться на другие сайты
1. Необязательно. Есть три варианта: А) первый клок входной, второй берется с PLL В) Оба клока берутся с PLL С) Первый клок с PLL, а второй получен делением из первого клока.
2. Клоки должны быть синхронными, тогда не нужны синхронизаторы. Во всех трех вариантах выше клоки синхронны.
3. На мой взгляд, констрейнить проще всего вариант С, поэтому вариант С тул скорее всего распознает самостоятельно.

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Doka @ Nov 3 2017, 13:10) <{POST_SNAPBACK}>
идея использования нескольких частот выглядит не очень
нельзя ли отказаться от clk, а считать всё на clk_x2 ?
А где надо получать сигнал разрешения счёта enable/valid локально из clk_x2?

Этот вариант с одной стороны выглядит проще, но
1. приведет к лишней дополнительной логике для enable-сигналов. (При работе на основной частоте можно много где обойтись без них, что не увеличит тайминг пути)
2. нужно будет на все такие пути прописывать кратный multicycle, тк (скорей всего) основная логика и так упирается в основную частоту.

Цитата(Shivers @ Nov 3 2017, 14:22) <{POST_SNAPBACK}>
1. Необязательно. Есть три варианта: А) первый клок входной, второй берется с PLL В) Оба клока берутся с PLL С) Первый клок с PLL, а второй получен делением из первого клока.

А я бы поставил на вариант В. По сравнению с С, в нем задержки двух выходов pll смогут автоматически подстроится оптимальным образом для двух клоков деревьев.
А в варианте С нет возможности так гибко двигать задержкой клока после делителя (особенно с учетом требования синхронной передачи данных в обе стороны между клоковыми доменами).

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


Ссылка на сообщение
Поделиться на другие сайты
PLL в FPGA - это не только PLL, но и "корень тактовых деревьев" - то есть это обеспечивает выравнивание фаз/задержек тактовых сигналов по всему чипу (ну или его части - если всего два такта, то P&R все сам сделает без подсказок)
поэтому в ПЛИС ПЛЛ много всякой фигни, типа дополнительных клоков, которые 90% случаев не нужны и т.п.
то есть клоки с выхода ПЛЛ обязательно, или в некоторых продвинутых ПЛИС хардварные "клок манагеры", которые умеют делить клок, обычно тулзами склеиваются в PLL IP - то есть проще подать на pll внешний клок и из нее выдать 1:1 и 1:N (тул должен разобраться, через какой примитив это пойдет)
upd - хотя подавать на вход тактовую в N раз выше (тем более предельную для ПЛИС) кажется очень странной затеей, не зря же в ПЛИС столько ПЛЛ-ей впихивают

констрейны _естественно_ нужны - это
create_clock и create_derived_clock

никаких синхронизаторов не нужно, выделять строб не нужно -
если допустимо, что высокочастотная часть N тактов выполняет одно и то же, например пишет в одну и ту же ячейку памяти одно и то же
если на выходе памяти стоит регистр тактируемый 1:N , и тул не ругается на путь до этого регистра (то есть успевает за период t/N) то и на выходе не надо ничего

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


Ссылка на сообщение
Поделиться на другие сайты
Задача по большей части решилась, при условии, что в домене удвоенной частоты писать не if (clk), а if (tff)
а tff - переключается каждый такт по удвоенной частоте. т.е. tff равен либо clk либо ~clk, но это обычный триггер, а не клок.

Проект собрался с clk_x2 = 714 MHz на Ultrascale+ (период 1.4ns).
Без Post-route PhysOpt - -0.02ns, PhysOpt вывел слаки в плюс.

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(myq @ Nov 3 2017, 16:19) <{POST_SNAPBACK}>
Задача по большей части решилась, при условии, что в домене удвоенной частоты писать не if (clk), а if (tff)
а tff - переключается каждый такт по удвоенной частоте. т.е. tff равен либо clk либо ~clk, но это обычный триггер, а не клок.

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

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Timmy @ Nov 3 2017, 17:33) <{POST_SNAPBACK}>
В этом случае вы не будете точно знать фазу медленного клока, а как повезёт при сбросе.
Для точного определения фазы можно в медленном клок домене запустить однобитовый счётчик, а в быстром - синхронно выделять фронты на его выходе, в результате не придётся заводить клок непосредственно на логические входы.


Да, была такая проблема, решил оставить на потом. Хорошее решение!

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация