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

Расслабление констрейнов по клоку, используемому только внутри модуля

Вводная:

Vivado, VU13P

У всего проекта интерфейсный клок и клок вычислителя.Клок вычислителя (clk_core) в несколько раз выше интерфейсного (clk_ctrl).

Сам проект содержит под сотню вычислителей,с которыми общаются на интерфейсном клоке, а сами вычислители молотят на клоке вычислителя.

Для улучшения QoR закрепил каждый вычислитель на конретные pBlock (до этого результаты WNS по конфигу 1 и конфигу 2 или 3 существенно различались).

 

 

Собственно все эксперименты по синтезу & PnR провожу в трёх конфигах:

конфиг 1 флоу с одним вычислителем

конфиг 2 флоу с одном SLR, полностью забитым вычислителями

конфиг 3 кристалл полностью забит вычислителями

 

 

Так вот - несмотря на то, что по факту ничего не поменялось (все вычислители зафикшены на pBlock) результаты в кейсе 2 и 3 деградируют по WNS.

Появилось подозрение, что в этих кейсах вивадо пытается построить CLOCK ROOT от SLR/всего кристалла, что не является для меня необходимым.

Все вычислительные клоки каждого вычислителя не обязаны быть синхронными между собой,  а коммуницируют вычислители с центром управления на медленном интерфейсном клоке, хочется дать вивадо информацию о том, чтобы позволить строить клоковое дерево независимо внутри каждого вычислителя и соответствующим образом выбирать локалько CLOCK ROOT.

 

 

Вопрос

Поскольку рантайм адовый - не хочется тратить время на эксперименты, а описать послабления наверняка:

1. Правильно ли понимаю, что для начала надо поименовать все клоки разных вычислителей?

Можно ли применить create_generated_clock к порту модуля?

2. Правильно ли будет потом применить между этими клоками  set_clock_groups -asynchronous ? Как  перенесёт вивадо эту команду с числом аргументов свыше сотни?

3. Либо надо писать set_clock_groups для пар каждого с каждым? Вот вроде как чутка похожий кейс: https://forums.xilinx.com/t5/Timing-Analysis/Asynchronous-inter-clock-paths-failed-to-meet-timing/td-p/761677

 

 

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


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

Постою послушаю (ц)

По поводу пункта 2 - если между блоками (и клоками тоже) нет никакого взаимодействия, то вряд ли set_clock_groups -asynchronous даст какой-либо эффект. Ваша задача заставить построить clock tree не так, как этого хочет сама вивада. А она, по всей видимости делает один Clock root. Я пытался недавно решать подобную задачу, наставив bufg, сгенерировав тем самым обособленные клоки. Но при превышении этих bufg количества примерно 24 она их не смогла развести (см. UG949, High Fanout Clocks). Может быть в вашем случае будет достаточно породить клоки не на каждый отдельный вычислитель, а столько, сколько вивада сможет разместить.

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


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

59 minutes ago, Doka said:

Появилось подозрение, что в этих кейсах вивадо пытается построить CLOCK ROOT от SLR/всего кристалла, что не является для меня необходимым.

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

В целом, Вам уже более развёрнуто ответили:

 

create_generated_clock можно назначить или на клоковый вход синхронного элемента или на порты клоковых элементов. Есть в доках.

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


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

5 minutes ago, TRILLER said:

При увеличении заполнения кристалла некоторые элементы вычислителей, скорее всего, размазываются по многим регионам.
Я бы настоятельно рекомендовал локализовать непосредственно вычислители из конфиг 2 в отдельные блоки

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

поэтому меня и удивило, что QoR так сильно зависит от "соседей":

конфиг 1 соседей нет

конфиг 2 соседи только в SLR

конфиг 3 соседи - весь кристалл

 

% утилизации каждого pBlocks в текущем конфиге не выше 70

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


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

Вообще-то не должен, только опосредованно.
Вычислитель влезает в один тактовый регион?
Сколько у Вас Clock Skew на плохих путях? Если до 400пик - то это нормально и улучшить что-то в ряд ли получится. Да и не стоит.
Сколько регионов пересекает поломанный путь?

 

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


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

2 hours ago, TRILLER said:

Вычислитель влезает в один тактовый регион?

Сколько регионов пересекает поломанный путь?

тут немного всё сложно, в том плане, что из-за того, что разные CLOCKREGION имеют разные размеры (отличающиеся почти в 2 раза), то вычислители объединены в мини-кластеры таким образом, чтобы  bPlock были сформированы из таких CLOCKREGIONs чтобы размеры (в LUT) получившихся bPlock были +/- идентичны.

На данный момент у меня один bPlock это квадрат 2х2 CLOCKREGION

 

2 hours ago, TRILLER said:

Сколько у Вас Clock Skew на плохих путях? Если до 400пик - то это нормально и улучшить что-то в ряд ли получится. Да и не стоит.

в конфиге 1 после роутинга -0.2нс

в конфиге 2/3 от -1.5нс до -6 нс в зависимости от условий

 

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


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

1 hour ago, Doka said:

в конфиге 1 после роутинга -0.2нс

в конфиге 2/3 от -1.5нс до -6 нс в зависимости от условий

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

(* dont_touch = "true" *)wire       clkd_ibuf;
(* dont_touch = "true" *)wire       clkd;
(* dont_touch = "true" *)wire       clkj;

IBUFDS u_clkd_ibuf(
    .I                  (CLK_200_P),
    .IB                 (CLK_200_N), 
    .O                  (clkd_ibuf));    

BUFG u_clkd(
    .I                  (clkd_ibuf), 
    .O                  (clkd));  	

BUFG u_clkj(
    .I                  (clkd_ibuf), 
    .O                  (clkj)); 

В констейнах:

set_false_path -through [get_pins {u_aaa/u_clkd_ibuf/O}]
create_clock -period 5.000 -name clkd [get_pins u_aaa/u_clkd/O]
create_clock -period 5.000 -name clkj [get_pins u_aaa/u_clkj/O]
set_clock_groups -name async_groups -asynchronous -group clkd -group clkj

Позволяет надёжно развязать клоки из одного источника. Всё остальное ненадёжно(или не нашёл..)
Поставьте по буферу на кластер. Если не поможет, тогда надо схему ковырять, на мой взгляд.
Да, IBUFDS нужно заменить на BUFG, если внутренне сгенерированный клок.

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


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

Не могу ничего сказать про Vivado, но Quartus лучше реагирует на -exclusive, чем на -asynchronous.

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


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

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

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

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

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

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

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

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

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

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