Jump to content

    
Sign in to follow this  
yes

нужна помощь клуба по CDC (прототипирование на Ultrascale, а потом ASIC)

Recommended Posts

подогнали мне коллеги кучу кода где повсеместно используется комбинаторная логика на пересечении доменов

как-то так :

один домен clkA (~166М) dataA

другой clkB (~40M) dataB update

clkA clkB асинхронные (с разных кварцев)

верхний уровень (софт) гарантирует, что update появляется только тогда, когда данные dataA не меняются. ну и соответственно в то время как dataA меняются update=0

---------

update это импульс длительностью 1 такт clkB

комбинаторная логика выглядит так - update&(логическая функция от dataA) ну и выходы этих функций подключены к CE или D триггеров dataB (@clkB)

vivado на это ругается (critical warning) и _чсх_ после наработки в 10мин-2часа происходит сбой (я подозреваю, что происходит ошибочная запись в регистры dataB, когда update=0, а dataA меняются.

но увы после модификации кода (то есть добавление dataC (@clkB) и перезащелкиваниz dataA->dataC через синхронизатор в котором специальный сигнал dataAready и его перенос в clkB - ну то есть как я считаю правильно и vivado говорит ОК и соответственно вся логика в clkB) - все-равно происходят сбои (мне кажется, что реже, но может это самообман - вобщем MTBF зависит скорее от какого то расклада по ПЛИС, а не от RTL)

ситуация усложняется тем, что программист сделал ковидную прививку и выпал из процесса, то есть дать в ПЛИС флаг, чтобы подсветить ошибку или хотя бы объяснить как и что он пишет - пока не возможно. то есть core dumped ну и типа усё  

======================

вопросы есть ли теоретическое объяснение (а совсем хорошо, пример логики, которая может выдавать глитчи из такого RTL кода (0 & (some logic @clkA)) -> clkB

при этом два случая:

вариант на ПЛИС - причем эта логика update@clkB & (логическая функция от dataA@clkA) помещается всегда в один LUT - 3-5 входов

вариант для ASIC-а - собрать пример такой логики на and/or/not, чтобы прохождение глитчей не блокировалось при update=0 (опровергающий пример - я не смог придумать)

----------------

собственно меня коллектив травит :), говорят, что все это фигня и я выдумываю и надо искать ошибку в других местах...

 

Share this post


Link to post
Share on other sites

Приветствую!

 

Случай  конечно же тяжелый и без  конкретных логов и  анализов тяжело судить.   

Но что то мне кажется что ваш коллектив прав  :yes3:  Ведь  как вы говорите глюки продолжаются даже  когда вы сначала добавляете честный синхронизатор  на  dataA -> dataC перед тем как делать лог. функции  update с dataС.
А раз частота глюков, как вам кажется, зависит от  P&R  то скорее всего причина неполные  или неправильные  timing констрейны.

 

Удачи! Rob.  

Share this post


Link to post
Share on other sites
Quote

верхний уровень (софт) гарантирует, что update появляется только тогда, когда данные dataA не меняются. ну и соответственно в то время как dataA меняются update=0

---------

update это импульс длительностью 1 такт clkB

разве это не классический синхронизатор? держим dataA, запускаем через CDC генерацию update из домена clkA в домен clkB, захватываем dataA. Все по класике. Единственное что в случае

Quote

комбинаторная логика выглядит так - update&(логическая функция от dataA) ну и выходы этих функций подключены к CE или D триггеров dataB (@clkB)

update должен быть последним в цепочке AND для данных или идти на CE. Ну т.е. как бы не совсем правильно, но если софт не тупой, то в целом ничего криминального)

ЗЫ. мне кажется что ошибка не в этом.

 

Share this post


Link to post
Share on other sites
9 hours ago, yes said:

update это импульс длительностью 1 такт clkB

комбинаторная логика выглядит так - update&(логическая функция от dataA) ну и выходы этих функций подключены к CE или D триггеров dataB (@clkB)

vivado на это ругается (critical warning) и _чсх_ после наработки в 10мин-2часа происходит сбой (я подозреваю, что происходит ошибочная запись в регистры dataB, когда update=0, а dataA меняются.

но увы после модификации кода (то есть добавление dataC (@clkB) и перезащелкиваниz dataA->dataC через синхронизатор в котором специальный сигнал dataAready и его перенос в clkB - ну то есть как я считаю правильно и vivado говорит ОК и соответственно вся логика в clkB) - все-равно происходят сбои (мне кажется, что реже, но может это самообман - вобщем MTBF зависит скорее от какого то расклада по ПЛИС, а не от RTL)

А нет ли у вас зависимости формируемой лог. функции от сразу нескольких сигналов, прошедших через CDC SYNC? Из описания это непонятно. И есть ли зависимость update от такого же рода сигналов? И вообще - сколько таких dataA -> dataB, вместе составляющих, видимо, нечто единое целое? Не нарушается ли именно _сочетание_ значений этого массива?

Edited by Raven
Дополнение

Share this post


Link to post
Share on other sites
9 hours ago, yes said:

верхний уровень (софт) гарантирует, что update появляется только тогда, когда данные dataA не меняются. ну и соответственно в то время как dataA меняются update=0

Вот это слабое место, софт гарантирует. А сколько тактов до, и сколько после он гарантирует?

Я бы посоветовал сделать так - поднять частоту 40 до 166/4 и сделать клоки синхронными (в констрейнтах). Сразу увидите что за логика в CDC, и хорошо ее подожмете. Может быть малтисайкл понадобится, кто знает. Софт .. надо убедиться, что программист не только про сетап знает, но и про холд. Вот и дадите ему контретные цифры в тактах.

Share this post


Link to post
Share on other sites

спасибо за ответы.

по поводу синхронной времянки - незаконстрейненых путей нету

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

update - это безусловный сигнал в clkB (ТС счетчика) по нему генерится прерывание в процессор (кроме переноса данных) - вобщем такая схема синхронизации лет 10 уже нами применяется и пороков не было

dataA/B это большой массив - для каждого инстанса бит по 200-300, ну и инстансов таких сотни - то есть в целом пакет килобайт 10. структуру dataA можно представить как поле адреса, в котором указывается куда в dataB копируется (собственно биты вот этого поля адреса и участвуют в комбинаторной логике с update), а остальное это "данные" - для них соединение напрямую dataA->dataB (то есть dataA.Q -> dataB.D без какой-то логики) и мне кажется, что тут все чисто

------------------------

я пока разбираюсь - все это не так быстро, увы - ну и в некий тупик зашел - ближайших планах повесить внутрисхемный анализатор на какую-то группу dataB и по флагу ошибки из процессора это защелкнуть...

 

Share this post


Link to post
Share on other sites

А вот есть у вас такой сигнал dataAready, который тоже проходит через  SYNC:

16 hours ago, yes said:

но увы после модификации кода (то есть добавление dataC (@clkB) и перезащелкиваниz dataA->dataC через синхронизатор в котором специальный сигнал dataAready и его перенос в clkB - ну то есть как я считаю правильно и vivado говорит ОК и соответственно вся логика в clkB) - все-равно происходят сбои (мне кажется, что реже, но может это самообман - вобщем MTBF зависит скорее от какого то расклада по ПЛИС, а не от RTL

Правильно ли я понимаю, что именно по нему происходит запись многобитового dataC в какой-то регистр в домене clkB? А сколько времени в тактах синхронизатора проходит между стабилизацией значений на линиях dataA и выдачей dataAready?

Edited by Raven
Дополнение

Share this post


Link to post
Share on other sites

Приветствую!

2 hours ago, yes said:

по поводу синхронной времянки - незаконстрейненых путей нету

Чудеса прям. Но  отсутствие ошибок не означает автоматом полноту констрейнов. Взять тот же  false_path который хоть и метит пути как покрытые констрейном, но может попортить крови из за неконтролируемой в процессе P&R  задержки для  данных в таком пути.  
Чисто логически  - после  синхронизации данных из dataA в  dataС  вы получаете  синхронный дизайн (для upate, dataC и dataB)  и ни о каких  гличах  говорит уже  не имеет смысла. Конечно же если результат лог. функций update и dataС  вы используете только на CE и  D  входах триггеров, но не на C. А раз  глюки при этом  все же продолжаются значит  источник их в другом месте.   

 

Удачи! Rob.    

Share this post


Link to post
Share on other sites
4 hours ago, Raven said:

А вот есть у вас такой сигнал dataAready, который тоже проходит через  SYNC:

Правильно ли я понимаю, что именно по нему происходит запись многобитового dataC в какой-то регистр в домене clkB? А сколько времени в тактах синхронизатора проходит между стабилизацией значений на линиях dataA и выдачей dataAready?

 

dataC и dataAready - это был некий мой патч (который не помог) - то есть мне казалось, что если я перезащелкну в домене clkB в регистр и дальше у меня вся логика будет синхронной и будет покрываться констрейном. задержка от готовности данных до dataAready @clkB  -  3 такта clkA, сам синхронизатор 2FF и еще пару тактов clkB (3 clkA + 4-5 clkB) 

но предлагаю этот патч не рассматривать дальше - не помогло

 

3 hours ago, RobFPGA said:

Чудеса прям. Но  отсутствие ошибок не означает автоматом полноту констрейнов. Взять тот же  false_path

да, чудеса - пока еще не разобрался - не могу поймать.

ну а false_path-ы я по результатам предыдущего обсуждения поубирал и заменил на асинхронные группы клоков

 

я кстати еще атрибутов ASYNC_REG наставил на dataA dataB - вроде обещают, что ставить будет рядом триггера с этим атрибутом

----------------

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

 

Share this post


Link to post
Share on other sites

Приветствую!

21 hours ago, yes said:

я кстати еще атрибутов ASYNC_REG наставил на dataA dataB - вроде обещают, что ставить будет рядом триггера с этим атрибутом

Атрибут  ASYNC_REG  работает только для  цепочки подавления метастабильности, то есть для триггеров на одном клоке. В этом случаете Vv буде их стараться ставить рядом. Для регистров в  разных  клоках  это не работает.  Тут только руками  set_max_delay прописывать.  

 

Удачи! Rob.

Share this post


Link to post
Share on other sites
1 hour ago, yes said:

dataC и dataAready - это был некий мой патч (который не помог) - то есть мне казалось, что если я перезащелкну в домене clkB в регистр и дальше у меня вся логика будет синхронной и будет покрываться констрейном. задержка от готовности данных до dataAready @clkB  -  3 такта clkA, сам синхронизатор 2FF и еще пару тактов clkB (3 clkA + 4-5 clkB) 

но предлагаю этот патч не рассматривать дальше - не помогло

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this