Pull to refresh

Comments 30

Классная статья!

оставьте в комментариях идеи для новых статей.

Инференс DSP-слайсов и когда он не работает :)

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

Тут проще наверное посмотреть ваш кусок кода, и попробовать понять, почему он не упаковывает. Обычно с этим каки-либо проблем не возникает

Я думаю вы понимаете, к чему я веду – у нас есть подряд несколько стоящих триггеров и умная среда проектирования может решить в благих целях сэкономить нам немножко ресурсов, упаковав их в аппаратный сдвиговый регистр. Такого конечно же желательно не допускать.

Почему не допускать? Те же триггеры, только внутри одного блочка. Или там какие-то недотриггеры?

Да я вот щас только подумал про это, есть в ультраскейлах аппаратный cdc, вроде бы должно быть примерно то же самое, но я не уверен.

Это интересный вопрос. Для исключения метастабильности нужно несколько триггеров, но не принципиально будут ли это отдельные триггеры или внутри встроенного сдвигового регистра.

Меня тоже смутило это утверждение. Какая разница как упакованы триггеры, аппаратным SHR или по отдельности ? Их работа от этого меняться не должна.

Так же хочу усомниться в аналогичном тезисе относительно цепочек задержки - не вижу причины по которой "упакованная" цепочка должна давать другую задержку нежели аналогичная пачка отдельно стоящих триггеров. Прошу привести временные диаграммы для пояснения этого момента. Такое может произойти только в том случае, если время tsetup у триггреров внутри сдвигового регистра отличается от этого же параметра дискретных триггеров. Но с чего бы такому произийти внутри одной микросхемы где все элементы выполнены на одном кристалле по одной и той же технологии ?

Но с чего бы такому произийти внутри одной микросхемы где все элементы выполнены на одном кристалле по одной и той же технологии ?

Для начала, одна "технология" это некая библиотека примитивов, включая множество вариантов FF-ов, разной нагрузочной способности например. У которых параметры могут быть весьма разными.
Во вторых, никто не обещал, что "внутри" LUT-а в режиме сдвигового регистра есть какие-то буквальные FF-ы. Это может быть и мелкая память, где указатели записи и чтения ходят по кругу с некоторой задержкой, что как раз и объясняет невозможность моментального сброса такого "регистра". Впрочем, учитывая десятки лет которые тот же Xilinx вылизывает свои CLB, так может быть и что-то промежуточное, собранное на уровне транзисторов а не типовых примитивов. Но про это нам конечно же не расскажут ибо секрет фирмы. Хотя может быть в патентах что-то можно найти.
Квартус и вовсе в явном виде блочную память рисует, как я вижу в статье, хоть и без указателей. Указатели, впрочем, там тоже есть, как минимум для работы этой же памяти в режиме FIFO, но видимо они скрыты на схеме. Это вообще типовое поведение для Альтеры - не показывать пользователю лишних подробностей, чтобы он лишний раз не волновался.

Так же хочу усомниться в аналогичном тезисе относительно цепочек задержки - не вижу причины по которой "упакованная" цепочка должна давать другую задержку нежели аналогичная пачка отдельно стоящих триггеров.

@checkpointа можно цитату из статьи, где про это написано, а то я чет не понял?

Я вот про это:

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

А дело та оказывается в том, что ваша умная среда проектирования берет и ваши триггеры упаковывает в аппаратный сдвиговый регистр, что приводит лишь к тому, что у вас увеличивается латентность в тактах, но не меняется длина цепей.

Если триггеры будут добавлены, не важно как, в виде отдельно стоящих или в виде регистра, у них все равно будет ненулевая задержка распространения пропорцинальная количеству этих триггеров в цепочке. Пользователь @old_bear правильно подметил, что мы не знаем как конкретно реализованы триггеры внутри регистра, и тут могут быть различные спекуляции, но задержка всё равно должна появляться и весьма существенная. Поэтому, я бы прежде всего анализировал результат синтеза, возможно что синтезатор считает такие цепочки бесполезными и удаляет их. А прагма говорит ему что так делать не стоит. :)

а, я имел в виду несколько другое.

Тут я про случай, когда два элемента стоят очень далеко после плейсмента, и как вариант это решить - это вставить несколько триггеров в цепочку, типа разбить цепь на несколько коротких отрезков.

Если триггеры будут упаковываться в srl, то латентность увеличится, а цепь будет такой же длинной

Понятно. Я думал задача обратная - увеличить задержку для выравнивания фронтов.

Да, там как раз недотриггеры, то есть совсем не триггеры.

При оптимизации, цепочки сдвиговых регистров упаковываются в примитивы типа srl16 или srlc32e. Эти сдвиговые регистры построены вокруг технологии LUTRAM. Центральная идея технологии LUTRAM в том, что Look Up Table 5-в-1 функционально работает так же, как память с пятью битами адреса на входе и одним битом данных на выходе. Когда вы загружаете в LUT таблицу истинности, вы задаёте значение 1 бита на выходе для любой возможной комбинации 5 бит на входе. Если 5 бит на входе рассматривать как адрес, то LUT 5-в-1 будет работать как память шириной 1 бит и глубиной 32 значения. В базовом сценарии таблица истинности для LUT вычисляется на этапе имплементации прошивки и загружается в процессе загрузки битстрима в кристалл, т.е. является фиксированной всё время работы кристалла, то есть работает как LUTROM (Read Only Memory). Однако Xilinx добавил в свои LUT-ы возможность менять "таблицу истинности" run-time, но не более одного бита за такт (возможно изменить только тот бит таблицы истинности, на который указывают 5 бит "адреса" на входе LUT-a). В итоге внутри LUT-а можно сохранять данные, и LUT может функционировать как эквивалент регистра (если вы не меняете 5 бит "адреса" на входе LUT-а), или как эквивалент памяти на 32 бита (если вы управляете адресами на входе). На основе этой же идеи собраны упомянутые примитивы сдвиговых регистров.

TLDR - если ваш код оптимизировался в примитив сдвигового регистра, то вы по сути изменяете таблицу истинности внутри LUT-a.

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

p.s. аппаратный cdc, который упомянул @KeisN13 в своём ответе - это совсем другая история. Примитив называется HARD_SYNC, физически расположен снаружи слайсов, содержит в себе цепочку 1-битных регистров, каждый из которых обладает более короткой постоянной времени выхода из метастабильного состояния. Таких регистров в кристалле очень мало, ресурс ценный, тянуть дорожки до них далеко, предполагаю что оптимизатор никогда их не заиспользует по собственному желанию.

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

Кстати, подсказки есть, один из ведущих инженеров Xilinx на форумах намекал на реализацию.

Воу, круто, спасибо за инфу.

Извините за шакальное качество картинок, вырезал их из видоса, который снял несколько лет назад xD

Необходимая вещь при замене умножения на сдвиг со сложением

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

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

Прокомментирую немного более развёрнуто.

При шифровании и дешифровании по методу RSA используются блоки по 512 и 1024 бита уже как норма (наверно, есть уже и больше).

Вся современная криптография построена на возведении в гигантскую (тоже порядка нескольких сотен) степень этих 1024х-битных чисел, т. е. перемножении в кольце 1024х разрядных двоичных чисел.

Способов перемножения больших чисел много, один из них - сдвиг со сложением.

К примеру, смотри тут https://fpga-e.ru/wp-content/uploads/kit145150-1.pdf

И вот, чтобы перемножить два 1024х-битных числа, необходимо реализовать 1024х битный сдвиговый регистр. Соответственно, все биты должны в нём сдвигаться одновременно (!), что при больших числах вызывает определённые сложности. Возможно, синтезатор про это тоже "знает" и пытается как-то оптимизировать процесс.

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

Если вы знаете, чем объясняется такое различие, напишите об этом комментариях.

ИМХО, у выбранной микросхемы ПЛИС просто нет готового сдвигового регистра с сигналом установки в лог "1", поэтому синтезатор чтобы как-то выйти из положения собрал схему из отдельных триггеров.

И снова "для начинающих" превращается в талмуд на кучу страниц.

Некий регистр<=Некий регистр<<1;

Некий регистр[0]<=Вход;

Вот и все его описание. Олвейс я опустил, ибо и так понятно, регистр ж.

Напишите о параметризации в циклах for в квартусе. Оно работает не всегда, точнее почти никак(именно внутри Always). Возможно, есть какие то настройки среды?

Ну да, прикинь, если это для начинающего плисовода надо знать, представь што тебя ждет когда ты выйдешь хотя бы на уровень среднечка.

А вот с этим

Некий регистр<=Некий регистр<<1;

Некий регистр[0]<=Вход;

далеко не уедешь

А что ждёт на уровне середняка?

И все же - напишите про for. Оно действительно не всегда работает как надо, verilog+quartus.

Не сочтите за навязчивость, но все же. Я имел ввиду задачи, скажем, "сделать кодер/декодер такого-то протокола" - вобщем - что именно даётся условному середнячку в качестве тз?

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

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

ПЛИС это не только умение реализовать алгоритм, этот алгоритм еще надо уметь запустить на заданной тактовой частоте.

В качестве вопроса для среднечка может быть такой: приведите хотя бы пять возможных причин нарушений по сетап и методы борьбы с ними?

Sign up to leave a comment.

Articles