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

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

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

как-то так :

один домен 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 (опровергающий пример - я не смог придумать)

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

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

 

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


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

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

 

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

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

 

Удачи! Rob.  

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


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

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. Ну т.е. как бы не совсем правильно, но если софт не тупой, то в целом ничего криминального)

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

 

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


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

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, вместе составляющих, видимо, нечто единое целое? Не нарушается ли именно _сочетание_ значений этого массива?

Изменено пользователем Raven
Дополнение

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


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

9 hours ago, yes said:

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

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

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

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


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

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

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

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

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

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

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

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

 

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


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

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

16 hours ago, yes said:

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

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

Изменено пользователем Raven
Дополнение

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


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

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

2 hours ago, yes said:

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

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

 

Удачи! Rob.    

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


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

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 - вроде обещают, что ставить будет рядом триггера с этим атрибутом

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

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

 

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


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

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

21 hours ago, yes said:

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

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

 

Удачи! Rob.

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


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

1 hour ago, yes said:

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

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

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

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


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

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

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

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

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

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

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

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

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

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