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

Констрейнты при переходе из одного клокового домена в другой.

Вообщем, такая ситуация.

 

Есть источник входных данных, который по своему клоку(CLK_WR) выдает 8 бит. Есть выходной, так сказать "потребитель", который эти же данные принимает, но уже со своим клоком(CLK_RD).

Данные от источника идут не сплошным потоком, а частями, пакетами.

 

Для передачи между ними, я использовал FPGA-шную встроенную SRAM(буфер так сказать). Входные данные записываются в этот буфер. Затем, когда он заполнится(пакет принят), я устанавливаю спец. флаг и принимающая часть по этому флагу, начинает читать из буфера и по окончании чтения сбрасывает флаг. По сброшенному флагу, "источник данных" начинает запись в буфер следующий пакет.

 

Проблема в том, что кроме передачи пакета, надо также передавать спец. число с адресом этого пакета.

Я cделал так: 1.vhdl

 

Сигналы '1' на входах FLAG_SET и FLAG_CLR имеют длительность в 5-10 периодов WR_CLK, так что однозначно распознаются. Да и сам пакет передается без искажений и наложения одного пакета на другой.

 

Проблема состоит в том, что время от времени, портится значение PKT_ADDR_OUT.

То есть при переходе от одного CLK домена в другой, сигналы FLAG_POLL и PKT_ADDR_OUT передаются с разными задержками, в результате чего PKT_ADDR_OUT читается в тот момент, когда оно меняется.

 

Каким образом мне ограничить разницу во временах прихода флага и данных? Какие из constraints за это отвечают?

 

Среда разработки: Quartus, используется "classic timing analiser"

 

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

1.vhdl.txt

Изменено пользователем Amper25

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


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

В общем случае нужно использовать асинхронное FIFO для передачи данных между клоковыми доменами.

Почитать можно здесь:

http://www.sunburst-design.com/papers/Cumm...002SJ_FIFO1.pdf

http://www.sunburst-design.com/papers/Cumm...002SJ_FIFO2.pdf

Для передачи флагов нужно использовать синхронизаторы для исключения явления метастабильности.

 

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

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


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

Мне пришлось использовать все таки не FIFO а двупортовую RAM, так как блоки RAM как раз кратны размерам пакета, а исполььзование FIFO приведет к дополнительным затратам по RAM, да и значительно усложнит контроллеры RX и TX блоков.

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


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

Мне пришлось использовать все таки не FIFO а двупортовую RAM, так как блоки RAM как раз кратны размерам пакета, а исполььзование FIFO приведет к дополнительным затратам по RAM, да и значительно усложнит контроллеры RX и TX блоков.

 

Никаких дополнительных расходов RAM. В основе FIFO точно такая же двухпортовая память, которая может точно так же кратна размеру пакета (как максимум). Преимущество такого решения состоит в том, что сейчас Вам приходится дожидаться окончания заполнения памяти пакета, а в случае использования FIFO обработку пакета в другом тактовом домене можно будет начать практически сразу. Если при этом сделать механизм записи пакета по CLK_WR сделать более интеллектуальным (с учетом флага заполненности FIFO), то можно сэкономить память, т.к. пропадает требование хранения полного пакета в памяти FIFO.

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


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

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

Если в этот буфер добавить еще запись адреса пакета, то размер еще увеличится(что не есть хорошо, так как RAM и так в притык).

 

Мне нужен совет как правильно ввести временные ограничения на сигналы.

В первом временном домене, устанавливается PKT_ADDR, и такт спустя FLAG_POLL. Во втором домене когда TAKT_POLL = '1', сигнал в PKT_ADDR еще не успевает установится в требуемое значение, так как временные ограничения не установлены. (То есть разница задержми сигналов TAKT_POLL и PKT_ADDR больше одного такта первого домена)

Изменено пользователем Amper25

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


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

Мне нужен совет как правильно ввести временные ограничения на сигналы.

В первом временном домене, устанавливается PKT_ADDR, и такт спустя FLAG_POLL. Во втором домене когда TAKT_POLL = '1', сигнал в PKT_ADDR еще не успевает установится в требуемое значение, так как временные ограничения не установлены. (То есть разница задержми сигналов TAKT_POLL и PKT_ADDR больше одного такта первого домена)

 

 

ИМХО не правильно вы сделали, у вас все почему то формируется в одном домене CLK_WR и совершенно не учтен домен CLK_RD.

 

Как уже вам сказали воспользуйтесь синхронизаторами и простейшим механизмом handshake.

 

Т.е. сигнал установки из домена передающей стороны, защелкивает адрес и через синхронизаторы возводит флаг ready на приемной стороне и флаг busy на передающей.

 

Сигнал сброса из приемной стороны сбрасывает флаг ready на приемной стороне и через синхронизаторы сбрасывает флаг busy на передающей.

 

Синхронизаторы вводят задержку в 2-5 тактов частоты, за это время сигнал из адресного регистра устаканиться в новом домене, ну для надежности можете еще set_max_delay сделать.

 

Если адрес это адрес в этой памяти, откуда нужно взять пакет, то я бы сделал асинхронный flip-flop ram buffer. Т.е. всю логику адреса зашил бы в него, при этом можно дробить память на 2^N буферов.

Делается он не сложно, достаточно хорошо работает. Если не получиться, пишите. вышлю код.

 

Преимущество такого решения состоит в том, что сейчас Вам приходится дожидаться окончания заполнения памяти пакета, а в случае использования FIFO обработку пакета в другом тактовом домене можно будет начать практически сразу

 

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

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


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

Если адрес это адрес в этой памяти, откуда нужно взять пакет, то я бы сделал асинхронный flip-flop ram buffer. Т.е. всю логику адреса зашил бы в него, при этом можно дробить память на 2^N буферов.

 

Нет, это адрес не в этой памяти, а, вообще, некий абстрактный адрес, и его надо рассматривать просто как 8 бит данных.

 

 

Как уже вам сказали воспользуйтесь синхронизаторами и простейшим механизмом handshake.

 

Т.е. сигнал установки из домена передающей стороны, защелкивает адрес и через синхронизаторы возводит флаг ready на приемной стороне и флаг busy на передающей.

 

Сигнал сброса из приемной стороны сбрасывает флаг ready на приемной стороне и через синхронизаторы сбрасывает флаг busy на передающей.

 

Синхронизаторы вводят задержку в 2-5 тактов частоты, за это время сигнал из адресного регистра устаканиться в новом домене, ну для надежности можете еще set_max_delay сделать.

 

Да у меня именно так и сделано. FLAG_POLL - это и есть этот "busy/empty" флаг.

 

Насчет 2-5 тактов для установки адресного регистра, это конечно поможет. Но я не хотел брать с потолка эти 2-5 тактов таким образом чтобы их с запасом хватало на компенсацию разницы задержек сигнала с 8 бит данными и сигнала с флагом.

 

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

 

MAX_SKEW подойдет для этих целей?

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


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

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

 

Вы ничего не сказали про свойства этих тактовых сигналов. Как соотносятся их частоты и фазы?

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


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

Вы ничего не сказали про свойства этих тактовых сигналов. Как соотносятся их частоты и фазы?

 

А это в принципе и не важно.

 

WR_CLK - 50..90 MHz.

RD_CLK - 100MHz.

 

Фазы соответственно никак не соотносятся.

Изменено пользователем Amper25

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


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

Да у меня именно так и сделано. FLAG_POLL - это и есть этот "busy/empty" флаг.

 

еще раз повторяю, у вас сделано не так (!!!)

 

у вас все формируется в одном домене CLK_WR и совершенно не учтен домен CLK_RD.

 

Надо сделать так :

 

сигнал установки из домена CLK_WR защелкивает адрес (CLK_WR), ставит флаг busy на своей строне (CLK_WR), через синхронизатор (CLK_WR -> CLK_RD) ставит флаг ready на приемной стороне (CLK_RD).

 

Сигнал сброса из приемной стороны CLK_RD, сбрасывает флаг ready на приемной стороне (CLK_RD) и через синхронизатор (CLK_RD->CLK_WR) сбрасывает флаг busy на передающей стороне (CLK_WR).

 

каждый блок видит регистры установленные в своем собственном домене сигналами своего клокового домена !!!

 

а у вас в коде блок в домене CLK_RD видит флаг поставленный в домене CLK_WR, тогда уж будте добры пропустите его тоже через пару тригеров домена CLK_RD.

 

Чувствуете разницу ??

 

Выбор синхронизатора зависит от вида сигналов установки, сброса. В среднем в синхронизаторе стоит 2-3 тригера. что и дает задержку в 2-3 такта.

 

Делал такое много раз, ни разу цепи не констрейнил. при синхронизаторах вида Pulse-Pulse с 3 мя такатми задержки, все работало без проблем.

 

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

 

я вам уже сказал set_max_delay из тайм квеста или его аналог в классическом анализаторе.

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


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

ИМХО не правильно вы сделали, у вас все почему то формируется в одном домене CLK_WR и совершенно не учтен домен CLK_RD.

 

Как уже вам сказали воспользуйтесь синхронизаторами и простейшим механизмом handshake.

 

Т.е. сигнал установки из домена передающей стороны, защелкивает адрес и через синхронизаторы возводит флаг ready на приемной стороне и флаг busy на передающей.

 

Сигнал сброса из приемной стороны сбрасывает флаг ready на приемной стороне и через синхронизаторы сбрасывает флаг busy на передающей.

 

Синхронизаторы вводят задержку в 2-5 тактов частоты, за это время сигнал из адресного регистра устаканиться в новом домене, ну для надежности можете еще set_max_delay сделать.

 

Если адрес это адрес в этой памяти, откуда нужно взять пакет, то я бы сделал асинхронный flip-flop ram buffer. Т.е. всю логику адреса зашил бы в него, при этом можно дробить память на 2^N буферов.

Делается он не сложно, достаточно хорошо работает. Если не получиться, пишите. вышлю код.

 

 

Извините, что вмешиваюсь, а можно выслать этот код и буду очень рад если он еще и на VHDL :) И не могли бы Вы порекомендовать литературу или рассказать более подробно про handshake

 

P. S. Просто знаю, что Вы работаете на Verilog (SystemVerilog)

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


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

еще раз повторяю, у вас сделано не так (!!!)

 

 

 

у вас все формируется в одном домене CLK_WR и совершенно не учтен домен CLK_RD.

 

 

 

Надо сделать так :

 

сигнал установки из домена CLK_WR защелкивает адрес (CLK_WR), ставит флаг busy на своей строне (CLK_WR), через синхронизатор (CLK_WR -> CLK_RD) ставит флаг ready на приемной стороне (CLK_RD).

 

Вообщем, я не совсем корректно объяснил. Роль регистров со стороны RD_CLK у меня выполнял блок, читающий из буфера. Но в результате суммарно получался 1 такт задержки, которого не хватало.

 

Сейчас сделал блок синхронизатора в точности как описал des00, и все работает без проблем. Задержку флагов поставил на 3-4 такта. Constraints решил не ставить, так как врятли Quartus разведет сигналы таким образом, что время их распространения составит 4 такта 100MHz.

 

PS: установка MAX_DELAY избавила от багов и при задержке в 1 такт, но все таки решил переделать в более нормальном виде.

 

Всем спасибо.

 

PPS: Maverick, если устроит вариант на VHDL могу выложить.

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


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

Извините, что вмешиваюсь, а можно выслать этот код и буду очень рад если он еще и на VHDL :) И не могли бы Вы порекомендовать литературу или рассказать более подробно про handshake

 

P. S. Просто знаю, что Вы работаете на Verilog (SystemVerilog)

 

эти модули я как раз делал в своем VHDL ом "прошлом", так что вам везет %)

 

в атаче 2 варианта синхронный с двойным буферированием и асинхронный с четверным, комментарии на русском, разобраться не сложно.

 

 

также статья про handshake протоколы на стыках тактовых доменов.

 

Удачи !!!

Buffer2D.vhd

aBuffer4D.vhd

PulseSyncronizer.vhd

async_signals.pdf

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


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

эти модули я как раз делал в своем VHDL ом "прошлом", так что вам везет %)

 

в атаче 2 варианта синхронный с двойным буферированием и асинхронный с четверным, комментарии на русском, разобраться не сложно.

также статья про handshake протоколы на стыках тактовых доменов.

 

Удачи !!!

 

Спасибо большое, за файлы!

Поискал по форуму нашел про handshake http://electronix.ru/forum/index.php?showt...935&hl=FIFO , но все равно как то до конца не уяснил.

А имеет ли значение, например, если эти частоты формируются внутри ПЛИС, например с помощью PLL, и не являются внешними, другими словами например "multiclock" проект в ПЛИС и для стыков тактовых доменов тоже нужен handshake? Т.е. handshake использовать всегда при работе на нескольких частотах или нет, чтобы избежать метастабильности?

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


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

А имеет ли значение, например, если эти частоты формируются внутри ПЛИС, например с помощью PLL, и не являются внешними, другими словами например "multiclock" проект в ПЛИС и для стыков тактовых доменов тоже нужен handshake? Т.е. handshake использовать всегда при работе на нескольких частотах или нет, чтобы избежать метастабильности?

 

Вопрос не совсем понял. я делаю так.

 

1. Если нужно передать большой поток данных, то естественно ставим асинхронное фифо, асинхронную память и т.д.

 

2. Если нужно передать флаг (статуса например) то тут проще сделать на синхронизаторах и handshake протоколе. Протокол здесь нужен только в том случае, если работа мастера и слейва зависит от этого флага (как в примере автора темы).

 

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

 

Насчет синхронизаторов возможны варианты :

 

1. Если частоты синфазны (кратные частоты идущие с одного PLL) то на стыке можно поставить только логику выравнивания длительности стробов, данных + прописать констрейны перекоса клоков.

 

2. В противном случае сделаю как описано выше.

 

Правда в 1 ом случае, если это не сломает вам логику(!!!) проще вколотить синхронизаторы и забыть, что клоки должны быть синфазные %))

 

Насчет метастабильности, не так страшен черт как его малютка. Внимательно разберитесь что это такое, как с этим бороться и когда с этим стоит бороться.

 

метастабильность вызывает изменение асинхронного сигнала в момент работы.

 

Если этот сигнал статический то никакой метастабильности не будет и бороть некого.

 

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

 

Или ваш блок гарантировано не будет работать (например сброс лежит, разрешения нет) до того как этот сигнал устаканиться, то опять же бороть некого.

 

 

Удачи !!!

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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