Golikov A.
Feb 25 2015, 16:07
Всем привет!
задача такая, надо по SPI slave передать данные размером 32+64+6*32 бита и контрольная сумма (итого 37-38 байт)
SPI - slave, на частоте сравнимой с основным клоком, потому асинхронный, синхронизация по CS
Данные рождаются спонтанно, по каким-либо событиям, а забираются мастером как у того будет настроение, потому решил воткнуть фифо.
Посылка важна целиком, то есть если мастер бросил принимать в середине посылку, она должна быть отброшена разом, и следующая опять должна быть целиком.
В результате у меня получается такая схема:
SPI - передатчик, которому надо на вход выставить 8 битное данные, а он их выдавит асинхронно на выход. Он сигналом отмечает как забрал данные, и внешняя схема может выставлять следующие данные.
FIFO сделал параллельное, которое засасывает сразу всю посылку. Сделал его не одним фифо на (32+64+6*32) бит, а поставил 1+2+6 32 битных отдельных FIFO.
И вот теперь самое интересное. Надо как -то данные с выхода FIFO перепихать на вход SPI передатчика. И что-то у меня ничего умнее чем огромный мультиплексор на 9 8-битных слов в одно не получается. А еще по ходу перещелкивания он будет подсчитывать контрольную сумму, и добавить ее в конце, то есть мультиплексор 10-11 в 1. Ресурсы не жмут, но как-то не красиво выходит, может кто предложит какое-то более изящное решение?
Может 90 битный SPI будет более правильным решением?
blackfin
Feb 25 2015, 16:39
Цитата(Golikov A. @ Feb 25 2015, 19:07)

.. поставил 1+2+6 32 битных отдельных FIFO.
А зачем такой изврат? Нужно сделать
один отдельный FIFO
на 18 слов, причем, 32-х битных.
Если там 37-38 байт, то сделать FIFO на байт, так, 128-256, и обычный 8-битный SPI... Ну или 64-128 16-битных слов... Или... Что-то там очень много проблем придумано из ниоткуда.
Golikov A.
Feb 25 2015, 17:17
Цитата
А зачем такой изврат? Нужно сделать один отдельный FIFO на 18 слов, причем, 32-х битных.
возможность параметризовать, сейчас 32+64+6*32, а завтра 8*32, или 2*32+64+6*32, каждый раз генерить новое фифо - муторно. Ноэто не главное, конечно можно было бы просто сразу сделать FIFO 90 бит. Это не решает основной задачи, как эти 90 бит оптимально перепихать в 8 выход SPI
Цитата
Если там 37-38 байт, то сделать FIFO на байт, так, 128-256, и обычный 8-битный SPI... Ну или 64-128 16-битных слов... Или... Что-то там очень много проблем придумано из ниоткуда.
как отсекать целую посылку, если мастер решил в середине утомиться и бросить принимать ее, надо ее всю целиком выкинуть, и быть готовым отдавать следующую. Если всю посылку 9 байт, повернуть в последовательную, то надо будет определять когда конец, и делать дополнительно вычитывалку оставшихся байт
Цитата(Golikov A. @ Feb 26 2015, 01:17)

как отсекать целую посылку, если мастер решил в середине утомиться и бросить принимать ее, надо ее всю целиком выкинуть, и быть готовым отдавать следующую. Если всю посылку 9 байт, повернуть в последовательную, то надо будет определять когда конец, и делать дополнительно вычитывалку оставшихся байт
выкинуть фифо и сделать многобуферный регистровый файл (например 4/8D) с памятью тегов и шириной слова данных 8 бит.
blackfin
Feb 25 2015, 17:30
Цитата(Golikov A. @ Feb 25 2015, 20:17)

Это не решает основной задачи, как эти 90 бит оптимально перепихать в 8 выход SPI..
Вам не знакомо такое явление, как регистр сдвига с параллельной загрузкой?
Цитата(blackfin @ Feb 26 2015, 00:30)

Вам не знакомо такое явление, как регистр сдвига с параллельной загрузкой?
если новый пакет не формируется, пока не была попытка считать старый, то это будет лучший вариант, по простоте и реализации (и црц посчитать и пакет из "фифо" сбросить)
ЗЫ. многобуферный регистровый файл, позволит просто добавить перезапрос пакета если вдруг потребуется
Цитата(Golikov A. @ Feb 25 2015, 20:17)

как отсекать целую посылку, если мастер решил в середине утомиться и бросить принимать ее,
А как это вообще по SPI можно отследить? По тому, что он поднял CS? Так сделайте FIFO не 8(16,32)-битное, а 9 (17, 33) битное, где старший бит показывает конец посылки - чтобы автомат мог пропустить ненужные данные до конца.
Golikov A.
Feb 25 2015, 18:58
Цитата
Вам не знакомо такое явление, как регистр сдвига с параллельной загрузкой?
я иногда задаю "детские" вопросы, но сейчас не этот случай
Цитата
выкинуть фифо и сделать многобуферный регистровый файл (например 4/8D) с памятью тегов и шириной слова данных 8 бит.
а теги зачем?
Фактически вы предлагает заменить FIFO на память, такой некий кеш, правильно я понимаю, сохранять строчками и вычитывать словами. И самому следить за последовательностью.
Цитата
если новый пакет не формируется, пока не была попытка считать старый, то это будет лучший вариант, по простоте и реализации (и црц посчитать и пакет из "фифо" сбросить)
то есть все сходятся на том что надо делать 90 битный сдвиговый регистр и не придумывать? Если так то его можно и наружу выдавливать побитово, вместо того чтобы по 8 бит сдвигать и в SPI пихать.
Цитата
А как это вообще по SPI можно отследить? По тому, что он поднял CS? Так сделайте FIFO не 8(16,32)-битное, а 9 (17, 33) битное, где старший бит показывает конец посылки - чтобы автомат мог пропустить ненужные данные до конца.
да CS - синхронизатор, упал в 0 - готовим новый пакет, не важно забрали или нет, если 1 выкидываем что осталось. Расширить фифо на 1 и использовать этот бит как флаг? Ну может быть...
в 90 битном сдвиговом регистре смущает времянка. Ведь чем больше бит, тем больше времени надо чтобы они все разом присвоились. А если он еще и сдвигаться будет по 8 бит...
blackfin
Feb 25 2015, 19:11
Цитата(Golikov A. @ Feb 25 2015, 21:58)

то есть все сходятся на том что надо делать 90 битный сдвиговый регистр и не придумывать?
Не все, конечно. Я бы сделал на трех счетчиках (два - 7-ми разрядных и один - 3-х разрядный), двух регистровых файлах (на 38 байт каждый) и на регистре сдвига на 8 бит.
Цитата(Golikov A. @ Feb 25 2015, 21:58)

Ведь чем больше бит, тем больше времени надо чтобы они все разом присвоились. А если он еще и сдвигаться будет по 8 бит...
Бред какой то... Чем больше бит, тем все они за один такт и присвоятся - тем времени меньше, но ресурсов больше. Чем меньше бит, тем больше тактов надо, чтобы их обработать, пропуская их по очереди.
Цитата(Golikov A. @ Feb 25 2015, 21:58)

Расширить фифо на 1 и использовать этот бит как флаг? Ну может быть...
Да, если времени достаточно, чтобы, пока мастер заново не активирует CS, пропустить старые данные.
Можно сделать FIFO шириной 9*4=36 бит, где каждый из байтов может быть помечен как крайний в пакете. Можно сделать два FIFO - в одном данные, во втором - длины пакетов. И пропускать сразу весь пакет, зная длину. Но, уже, придется делать свое описание FIFO, а не пользоваться готовыми IP, чтобы уметь пропускать сразу N данных, а не считывать их по одному.
То есть, если надо принимать решение за 1 такт, я бы применил ОЗУ, шириной кратное тому, чему кратны пакеты - то есть, если они всегда имеют целое число 8-битных байт - то 8-битное, если целое число 16-битных - то 16-битное, и т.д., и второе ОЗУ, работающее в режиме FIFO, передающее длины пакетов. И предусмотрел бы в первом FIFO возможность пропустить N (недосланных) слов за раз. Или, если можно долго пропускать байты - то лишний бит-флаг конца пакета, и автомат, пропускающий ненужные байты.
Golikov A.
Feb 25 2015, 20:39
Цитата
Не все, конечно. Я бы сделал на трех счетчиках (два - 7-ми разрядных и один - 3-х разрядный), двух регистровых файлах (на 38 байт каждый) и на регистре сдвига на 8 бит.
можно поподробнее, что-то я не очень понимаю
Цитата
Бред какой то... Чем больше бит, тем все они за один такт и присвоятся - тем времени меньше, но ресурсов больше. Чем меньше бит, тем больше тактов надо, чтобы их обработать, пропуская их по очереди.
имелось ввиду что если присваивается 90 битный регистр, то это можно делать с меньше частотой, чем 2 45 битных регистра. Достаточное время на установку больше становиться. Ячейки дальше друг от друга, больше проводов, длиннее пути... то есть таская 90 битный регистр боюсь в частоте потерять
Про ОЗУ подумаю, но все равно как-то не складно все выходит...
blackfin
Feb 26 2015, 04:40
Цитата(Golikov A. @ Feb 25 2015, 23:39)

можно поподробнее, что-то я не очень понимаю
Чтобы ответить "поподробнее", нужно знать:
1. Надо ли использовать два клоковых домена, один - для записи в FIFO, второй - для чтения из FIFO по SPI?
2. Может ли мастер SPI работать в 32-х битном режиме?
3. Всегда ли в FIFO записывается одинаковое количество байт?
4. Нужно ли иметь возможность записывать в FIFO новые данные и читать (по SPI) данные ранее записанные в FIFO одновременно?
Golikov A.
Feb 26 2015, 05:46
1. не обязательно, можно, но с учетом что клок SPI есть вообще только на время передачи, а также есть разрешающий сигнал который показывает что данные на входе SPI можно менять
2. это не важно с точки зрения мастера, он вычитывает всю посылку. Паузы между словами быть не должно, мастер не будет ждать. 32 битный режим плох только тем что неудобно на лету считать контрольную сумму, изначально данные рождаются без нее, а задерживать их на подсчет не хочется, канал надежный, потому сумма примитивная 16 бит от суммы байт по всему сообщению.
3. длинна посылки фиксирована
4. естественно да, иначе зачем городить фифо. Более того нужно если вычитывание посылки по SPI прервалось со стороны мастера, отбросить ее целиком, и в следующих заход выдать новую целиковую посылку. Досылать хвост старой недопустимо.
Цитата(Golikov A. @ Feb 26 2015, 02:58)

а теги зачем?
а без тегов как вы узнаете заполненность буфера и его очередность ?
Golikov A.
Feb 26 2015, 09:05
мне же fifo надо, можно следить куда положено, откуда уже забрано...
В итоге образовалось еще одно FIFO на входе SPI.
данные идут в группу параллельных FIFO по которым продвигаются посылками на выход (благо у меня дофига брамов

)
потом по падению cs из этой группы фифо извлекаются очередные данные и по 8 бит пихаются в выходное фифо SPI, считается контрольная сумма и кладется туда же в след. Данные выходного FIFO выдавливаем наружу по SPI. Сигнал CS используется также как сброс выходного фифо. Таким образом если мастер решает что он устал, он поднимает CS, выходное фифо сбрасывается и тем самым откидывается хвост не забранной посылки.
Теперь мне осталось правильно обконстраинить переход FIFO-SPI
SPI асинхронный со своим клоком, данные для него готовит FIFO с другим клоком. По идее надо обеспечить чтобы до любых действий с клоком SPI, на его входе данные уже стояли. Достаточно ли выждать паузу в 1 клок после появления данных на выходе FIFO, до первого клока SPI, чтобы быть уверенным что данные до него дошли?
я использую сигнал valid - который показывает что на выходе FIFO верные данные, как обконстраинить время за которое данные с выхода FIFO должны дойти до входа SPI. Ведь setup констраина не хватает, клоки SPI и FIFO же независимы.
Цитата(Golikov A. @ Feb 25 2015, 19:07)

Данные рождаются спонтанно, по каким-либо событиям, а забираются мастером как у того будет настроение, потому решил воткнуть фифо.
Прошу уточнить одну важную деталь: положим, в ФИФО уже лежит пакет данных, полностью готовый к отправке, и тут спонтанно рождается ещё один пакет. А мастер пока молчит, как рыба(CS неактивен). Следует ли отбросить старый пакет и готовиться отправлять сразу новый, или всё-таки отправить сначала старый?
Golikov A.
Feb 26 2015, 10:22
отбрасывается предыдущий пакет, заменяется на новый с флагом что произошло переполнение...
то есть фифо 10 пакетов
приняли 10 - пихнули в фифо
приняли 11 - ждем
приняли 12, заменили 11 на 12, и поставили флаг ждем
и так далее...
как мастер проснулся, начал забирать то в фифо будет запихан уже этот новый пакет с флагом переполнения, и дальше опять по новой...
На самом деле сейчас более актуально как обконстреинить переход FIFO-SPI
Цитата(Golikov A. @ Feb 26 2015, 16:05)

мне же fifo надо, можно следить куда положено, откуда уже забрано...
вам не простое фифо нужно, а фифо пакетов с возможностью сброса/замены пакета. Кстати подобным образом построены "фифо" в современных свичах.
ЗЫ. Простите за прямоту, но у меня складывается впечатление, что в погоне за быстрым результатом, вы, вместо анализа задачи, рассмотрения вариантов ее решения и их сильных/слабых сторон, занимаетесь так называемым быдлокодерством. Т.е. наспех, каким-то образом вкорячиваете что бы работало, а потом усиленно со всей этой ..... пытаетесь взлететь (с) Старый анекдот.
Golikov A.
Feb 26 2015, 16:57
Не все как раз наоборот.
Быстро сляпать как раз не сложно, да и реализовано в целом. Сейчас есть время покрутить посмотреть.
на текущий момент у меня есть SPI модуль с FIFO 8 бит на входе, с возможностью сброса этого FIFO.
в Это фифо я буду класть только 1 пакет, отправился - хорошо, нет, его сбросят.
Дальше есть параллельное 90 битное фифо, куда грузятся посылки. По сигналу самая старая из него извлекается и перекладывается в FIFO SPI. На этом я теряю тактов 5 до начала обмена, а дальше перекладка идет во время обмена, заодно считается контрольная сумма.
И есть генератор пакетов, который готовит пакет и кладет его в параллельное фифо, при этом если FIFO переполнено, пакет снабжается флагом переписи пакета, и данные в нем меняются на свежие, и так пока пакет не уйдет в FIFO.
Так что схема рабочая, и никакого быдлокода я не вижу, фифо - стандартные элемнеты, брамы меня не жмут.
Осталось последние и самое сейчас важное:
как обконстраинить путь от FIFO SPI до выхода в биты, при условии что они работают на разных клоках
blackfin
Feb 26 2015, 17:14
Цитата(Golikov A. @ Feb 26 2015, 19:57)

Осталось последние и самое сейчас важное:
как обконстраинить путь от FIFO SPI до выхода в биты, при условии что они работают на разных клоках
set_false_path
Golikov A.
Feb 26 2015, 17:23
да мне не исключить надо, мне бы как раз добавить...
у меня есть FIFO оно выдает сигнал VALID когда на выходе появляются данные.
старший бит этих данных через мультиплексор идет на выходной пин FPGA (spi data out).
Младшие биты идут в сдвиговый регистр, который защелкивается по клоку SPI и дальше двигается.
С первым клоком SPI выходной пин (spi data out) переключается со старшего бита данных из FIFO на старший бит сдвигового регистра.
то есть мне надо
1. задать чтобы время за которое сигнал старшего бита идет с выхода FIFO на ножку ПЛИС было не более 10 нСек (например), тогда выдержав паузу 1 клок после появления сигнала валид, я могу гарантировать что на пине уже стоят данные.
2. задать чтобы время за которое сигнал идет от младших битов выхода фифо, до регистра SPI было не более 10нСек (например), тогда выдержав паузу 1 клок после появления сигнала валид до первого рывка клока SPI я могу гарантировать что сдвиговый регистр SPI защелкнет правильные данные
3. Наверное надо задать время распространения сигнала от старшего бита сдвигового регистра до выхода на ножку FPGA (spi data out) не более полуклока SPI. Учтет ли это время переключения мультиплексора?...
можно кстати это как-то обконстреинить не в общем файле констраинов, а именно в verilog модулях как время путей данных или это уже совсем глупость?
Цитата(Golikov A. @ Feb 26 2015, 20:23)

да мне не исключить надо, мне бы как раз добавить...
у меня есть FIFO оно выдает сигнал VALID когда на выходе появляются данные.
Раз вы используете сигнал VALID, это подразумевает, что в момент активации SPI CS, сигнал VALID может быть неактивен. Таким образом, в клок домене "SPI CS" необходимо по единственному фронту CS синхронизировать VALID, принять решение - передавать данные или нет, и передать это решение обратно в системный клок домен, синхронизировав бит решения с системным клоком. И вы ничего не сказали, как собираетесь это выполнять. А в случае сброса фифо с заменой на новые данные будет ещё интереснее.
Golikov A.
Feb 26 2015, 20:36
он не то что может быть, а он 100% не активен. после того как упадет CS выбиреться посылка из верхнего FIFO - 1 такт, запихается первый байт в FIFO SPI - это еще 2 такта, провалиться на нижний уровень, и выставиться на выходе ножки и регистре SPI. И вот тут проблема.
хочется быть уверенным что после появления данных на выходе нижнего FIFO они дойдут до регистра SPI и выхода за какое-то определенное время. Потому и хочу обконстрайнить данный факт чтобы синтезатор и прочие механизмы это учитывали.
Все это будет учитывать SPI мастер, либо фиксированной задержкой после опускания CS, либо получая сигнал VALID, опустив CS он не будет ничего делать с клоком, пока не выдержит необходимую паузу, а дальше все будет хорошо, данные будут готовы и будут идти непрерывным потоком.
как констраин то такой написать, вот в чем вопрос...
Вообще, междоменные переходы объявляют как set_false_path, так как нельзя предсказать, какое там будет время из-за непредсказуемого отношения фаз клоков в доменах. А целостность данных обеспечивают схемотехнически, применяя правильные для переходов структуры. Так что, если у Вас там FIFO, то надо применить двухклоковое FIFO, оно само обеспечить правильный междоменный переход без лишних констрейнов.
Golikov A.
Feb 27 2015, 13:49
не работает оно 2 клоковое. Клок то у SPI не постоянный... Я с этого фифо и начинал, ан фиг вам... Прежде чем слово выдавиться надо его поклокать.
1. мне надо ограничить величину времени распространения сигнала от выхода FIFO через мультиплексор до ножки.
2. мне надо ограничить величину времени распространения сигнала от выхода FIFO до сдвигового регистра SPI, причем именно чтобы сигнал до него дошел и выставился на входах защелки стабильно.
вот только как это описывается...
по идее 1 это setup определяет, то есть задав setup для клока FIFO я сразу эту величину получу... (или холд все время путаю). И вот я сейчас думаю, наверное 2 тот же самый сетап.
время распространения сигнала от FIFO до любых других элементов, которые могут использовать его по своему усмотрению - это же setup? да?
Цитата(Golikov A. @ Feb 27 2015, 16:49)

вот только как это описывается...
это, например, set_max_delay -datapath_only
А, также, можете объявить клоки связанными друг с другом, одной частоты, и там уже сетапы будут работать.
Но, все это костыли. Лучше опишите такое фифо, которое позволяет штатно работать с остановленным клоком с одной стороны. Вот, почитайте, очень хорошая описание, как это делается:
Вдогонку - такое FIFO придется делать на распределенной памяти, чтобы чтение из него было асинхронным, в смысле, чтобы не требовало лишнего клока на выдачу данных из ОЗУ.
Golikov A.
Feb 27 2015, 21:39
спасибо погляжу.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.