Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: последовательный интерфейс
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
skilful
Добрый день.

Имеется ПЛИС Циклон (питание 3.3 В) и микроконтроллер AVR (питание 5 В).
Хочу связать их по SPI.

Хотел затактировать приемник в ПЛИС от микроконтроллера.

По записи данных в ПЛИС хочу поставить двухклоковую фифошку. С этим вроде вопросов вроде не возникает --
контроллер, когда ему надо выставляет бит данных и делает синхронизирующий импульс.
Таким образом, сколько битов передается от МК в ПЛИС столько и будет синхроимпульсов от МК.


По чтению данных из ПЛИС хочу тоже хочу поставить двухклоковую фифошку.
Вот тут вопрос -- когда я логикой ПЛИС запишу в фифо данные -- как мне контроллером узнать, что данные уже есть в фифо?
У фифо есть сигнал "не пустое", но этот сигнал появляется при наличии синхроимпульсов от МК.

То есть мне нужно генерить "пустые" синхроимпульсы для ПЛИС и ждать, когда появится сигнал фифо "не пустое"?

Может быть изначально я неверно начал делать?

Может быть ПЛИС должна тактировать микроконтроллер? Если да, то как быть с преобразованием 3.3 В в 5 В? И сигнал нужно через PLL пускать?


Спасибо
Lmx2315
Вы по SPI хотите связать мк и плис, значит у вас один будет мастером а другой слейвом. Допустим МК мастер - пишете данные по тактам , считываете внутри ПЛИС по изменению чипселекта .
Так как ПЛИС - слейв то она либо должна регулярно опрашиваться микроконтроллером ,либо должна вырабатывать для него прерывания если хочет что-то сообщить.
Зачем фифо в ПЛИС - не понял, в плис ставите сдвиговый регистр , заполняете его по фронту или спаду сигнала клоков SPI , фронт или спад определяете спомощью внутренней частоты плис которая вам там всё синхронизирует.
skilful
для примера, допустим, внутри ПЛИС 10 регистров по 64 бита каждый.

содержимое регистров может быть доступным для записи/чтения как со стороны ПЛИС, так и со стороны МК.

еще я не понимаю как я буду писать в эти регистры по SPI с частотой МК, если в этот момент в них пишет ПЛИС на своей частоте.

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


Про определение фронта или спада клока SPI не понял.
У меня частота ПЛИС близка к частоте AVR
stu
правильно по поводу: "надо опрашивать состояние". Но есть interrupt. Его в МК можно использовать по уровню, а не по фронту или спаду. Т. е. fifo не пустой, прерывание в нуле(к примеру) и значит надо с него тянуть данные, все прочли - установили.
Я делал rs-485 между MC<->FPGA<->ПК и два fifo (rx, tx). А список адресов для выполнения задач плиской через дешифратор (.eq[]) как enable для того или иного действия, а выдачу на МК по case
Lmx2315
..разделите регистры , пусть плис пишет в свои а мк в свои.
skilful
а как мне "разделенные" регистры связать?
да и не сильно это усложнит логику?

для упрощения объяснения задачи -- пусть будет регистр внутри ПЛИС счетным.
То есть ПЛИС инкрементирует его постоянно, но может и записать начальное значение.

МК тоже может записать начальное значение, а может и просто считать.
Lmx2315
пусть ПЛИС пишет в счётные регистры, а МК их считывает.
А если МК надо будет их стереть или записать туда другое начальное значение - пусть мк пишет в свой регистр, который мониторит плис ,
и если плис прочтёт там требование стереть счётный регистр - пусть она и стирает, или заполняет тем что пришло от мк в его регистр.

Сделайте так чтобы от мк к плис шли команды и данные , храните их в регистре команд и данных . Мониторьте их в ПЛИС и поступайте в соответствии с ними.
мониторить можно по сигналу - чипселект.
Torpeda
Цитата(skilful @ Sep 11 2012, 10:41) *
а как мне "разделенные" регистры связать?
да и не сильно это усложнит логику?

для упрощения объяснения задачи -- пусть будет регистр внутри ПЛИС счетным.
То есть ПЛИС инкрементирует его постоянно, но может и записать начальное значение.

МК тоже может записать начальное значение, а может и просто считать.

В деталях проблема не ясна но отвечу на что понял...
1) Вы работаете с SPI интерфейсом.
Это значит что один конец мастер, а другой слейв.
Сделайте МК мастером. Это значит что только он инициирует передачу данных.

2) Как сделать доступ в один и тот-же регистр и со стороны МК и со стороны ПЛИС по записи.
-Придумайте протокол обмена по SPI: код команды, адрес, данные.
-Когда МК даёт команду записи в регист, она принимается SPI декодером команд (в виде автомата)
-Декодер команды останавливает ПЛИС и меняет регистр
-Декодер команды перезапускает ПЛИС с новым значением

3) как сказать МК, что ПЛИС сменила значение регистра
- по прерыванию
- по SPI. В этом случае надо "завести" регистр состояния ПЛИС и читать его переодически командой SPI.
Например, ПЛИС взводит бит состояния в 1 при последней записи в регистр, а при чтении регистра состояния этот бит автоматически обнуляется.

4) что от чего тактировать....
- проще всего SPI склок выдавать из МК (задайте нужную конфигурацию МК SPI)
- ПЛИС должна иметь свой генератор клока выше частоты SPI клока
- Все входные SPI сигналы в ПЛИС привязать к внутреннему клоку через ресинхронизаторы (2 тригера)
- анализируя уровни SPI входов при помощи соответствующего автомата - декодировать SPI поток данных.

Вот как-то так...

---------------------
Есчё добавлю...
SPI понятие розтяжимое....
Фактически надо говорить о СТЕКЕ протоколов.
В этом случае SPI - это только описание доступа к каналу передачи (клок, данные) - канальный уровень
Дальше идёт формат команды SPI (код команды, адрес, данные)
Дальше интерпретатор команд (напр. чтение из регистра 1 выполняется со сбросом бита состояния, а регистра 2 без таких-же действий) - прикладной уровень
troiden
Цитата(Torpeda @ Sep 11 2012, 12:09) *
- Все входные SPI сигналы в ПЛИС привязать к внутреннему клоку через ресинхронизаторы (2 тригера)

Эмм... Зачем синхронный интерфейс превращать в асинхронный?
Torpeda
Цитата(troiden @ Sep 11 2012, 11:19) *
Эмм... Зачем синхронный интерфейс превращать в асинхронный?

синхронность понятие относительное....
У ПЛИС свой клок а у МК свой - всё асинхронно.
troiden
Цитата(Torpeda @ Sep 11 2012, 12:25) *
синхронность понятие относительное....
У ПЛИС свой клок а у МК свой - всё асинхронно.

SPI подразумевает передачу наряду с данными тактового сигнала - на нем и должен работать сам приемопередатчик SPI. А все манипуляции с пересинхронизацией должны выполняться уже после, на уровне внутренних шин ПЛИСа.
skilful
Цитата(Torpeda @ Sep 11 2012, 11:09) *
В деталях проблема не ясна но отвечу на что понял...
1) Вы работаете с SPI интерфейсом.
Это значит что один конец мастер, а другой слейв.
Сделайте МК мастером. Это значит что только он инициирует передачу данных.

2) Как сделать доступ в один и тот-же регистр и со стороны МК и со стороны ПЛИС по записи.
-Придумайте протокол обмена по SPI: код команды, адрес, данные.
-Когда МК даёт команду записи в регист, она принимается SPI декодером команд (в виде автомата)
-Декодер команды останавливает ПЛИС и меняет регистр
-Декодер команды перезапускает ПЛИС с новым значением

3) как сказать МК, что ПЛИС сменила значение регистра
- по прерыванию
- по SPI. В этом случае надо "завести" регистр состояния ПЛИС и читать его переодически командой SPI.
Например, ПЛИС взводит бит состояния в 1 при последней записи в регистр, а при чтении регистра состояния этот бит автоматически обнуляется.

4) что от чего тактировать....
- проще всего SPI склок выдавать из МК (задайте нужную конфигурацию МК SPI)
- ПЛИС должна иметь свой генератор клока выше частоты SPI клока
- Все входные SPI сигналы в ПЛИС привязать к внутреннему клоку через ресинхронизаторы (2 тригера)
- анализируя уровни SPI входов при помощи соответствующего автомата - декодировать SPI поток данных.

Вот как-то так...

---------------------
Есчё добавлю...
SPI понятие розтяжимое....
Фактически надо говорить о СТЕКЕ протоколов.
В этом случае SPI - это только описание доступа к каналу передачи (клок, данные) - канальный уровень
Дальше идёт формат команды SPI (код команды, адрес, данные)
Дальше интерпретатор команд (напр. чтение из регистра 1 выполняется со сбросом бита состояния, а регистра 2 без таких-же действий) - прикладной уровень



я примерно тоже самое сделал -- только с фифошками.
вопрос встал -- как сообщить микроконтроллеру, что запрошенные данные считаны и их можно забирать из фифо чтения.
вы написали, что делать прерывание. но получается сигнал прерывания (фифо чтения не пустое) будет привязан к клоку ПЛИС, а не МК.
То есть мне нужно после получения прерывания выдержать паузу на МК и потом генерить клок от МК к ПЛИС, чтобы забирать данные из фифо чтения?


Torpeda
Цитата(troiden @ Sep 11 2012, 11:31) *
SPI подразумевает передачу наряду с данными тактового сигнала - на нем и должен работать сам приемопередатчик SPI. А все манипуляции с пересинхронизацией должны выполняться уже после, на уровне внутренних шин ПЛИСа.

ОК.
Вижу Вы любитель проблем sm.gif
На канальном уровне всё просто - клок и данные. Захлопнул их в тригер и нет проблем...

Предположим также что вы извернулись, и вам хватило тактов SPI фрейма на то, чтобы принять команду и декодировать её.
И даже вы смогли правильно обконстрейнить всё для STA (и даже неизвестную задержку линии от МК к ПЛИС смогли правильно учесть...)
Это не всем удаётся, ибо количество клоков ограничено числом бит в фрейме. Некоторые начинают тригера с negedge клоком использовать и прочую асинхронщину (типа заводить логику на ресеты...), а про тайминг констрейны в этом случае я вообще молчу.....
Вот вам и асинхронщина началась.

А дальше наверно надо и команду интерпретировать.... ПЛИС то от своего генератора работает и асинхронна к вашему SPI, который повешен на внешний клок.
Надо как-то клок домены суметь вязывать....

---------
Поэтому-то я и рекомендую начинающим дурью не маяться - привязать все SPI сигналы к ПЛИС клоку и делать тревиальный синхронный цифровой дизайн.

Цитата(skilful @ Sep 11 2012, 11:43) *
я примерно тоже самое сделал -- только с фифошками.
вопрос встал -- как сообщить микроконтроллеру, что запрошенные данные считаны и их можно забирать из фифо чтения.
вы написали, что делать прерывание. но получается сигнал прерывания (фифо чтения не пустое) будет привязан к клоку ПЛИС, а не МК.
То есть мне нужно после получения прерывания выдержать паузу на МК и потом генерить клок от МК к ПЛИС, чтобы забирать данные из фифо чтения?

Зачем фифошки?
Ну если очень хочется....
" сигнал прерывания (фифо чтения не пустое) будет привязан к клоку ПЛИС" - очень хорошо. МК предполагает что все прерывания вообще асинхронны (кнопку-то к прерыванию подключать вас не смущает?).
"То есть мне нужно после получения прерывания выдержать паузу на МК и потом генерить клок от МК к ПЛИС, чтобы забирать данные из фифо чтения" - сразу забирайте. Зачем вам пауза? ПЛИС сначала фиксирует данные в ФИФО, а потом генерит прерывание.
troiden
Попорядку sm.gif
Цитата(Torpeda @ Sep 11 2012, 12:44) *
Предположим также что вы извернулись, и вам хватило тактов SPI фрейма на то, чтобы принять команду и декодировать её.

Простота - наше всё. Во фрейме только один признак команды - чтение или запись. Большего не надо.

Цитата(Torpeda @ Sep 11 2012, 12:44) *
И даже вы смогли правильно обконстрейнить всё для STA (и даже неизвестную задержку линии от МК к ПЛИС смогли правильно учесть...)

Задержки всех линий в первом приближении одинаковы, если это не так и разбежка в десяток наносекунд - надо карать трассировщика. Для связи МК -> ПЛИС никаких проблем, для обратной линии ПЛИС -> МК проблема и в асинхронном, и в синхронном дизайне одна и та же и никуда не пропадает.

Цитата(Torpeda @ Sep 11 2012, 12:44) *
А дальше наверно надо и команду интерпретировать....

Фрейм из 5 байт: 1 бит - признак команды, 15 бит - адрес регистра ПЛИСа, 3 байта - на данные чтения-записи. Интерпретируется без проблем.

Цитата(Torpeda @ Sep 11 2012, 12:44) *
ПЛИС то от своего генератора работает и асинхронна к вашему SPI, который повешен на внешний клок.
Надо как-то клок домены суметь вязывать....

У нас есть 40 тактов SPI-интерфейса между приходом двух посылок, за которые надо успеть пересинхронизироваться и провести запись данных в регистр. С чтением - веселее, но тоже просто решается.

Цитата(Torpeda @ Sep 11 2012, 12:44) *
Поэтому-то я и рекомендую начинающим дурью не маяться - привязать все SPI сигналы к ПЛИС клоку и делать тревиальный синхронный цифровой дизайн.

Этот подход жизнеспособен только на малых скоростях. Придет к вам SPI на 100 МГц - и хана.
Torpeda
Цитата(troiden @ Sep 11 2012, 12:01) *
У нас есть 40 тактов SPI-интерфейса между приходом двух посылок, за которые надо успеть пересинхронизироваться и провести запись данных в регистр. С чтением - веселее, но тоже просто решается.

Вот это как-то не очень понятно. О каких 40 тактах речь?
даём команду записи. Последний бит приходит на 40-м клоке. Где есчё 40 беруться для интерпретации?

Или вы предлагаете передавать фрейм из 40 бит + есчё дофига тактов клока на его интерпретацию?

Цитата(troiden @ Sep 11 2012, 12:01) *
Этот подход жизнеспособен только на малых скоростях. Придет к вам SPI на 100 МГц - и хана.

Вы правы.
1) Строить SPI при тактировании от внешнего клока надо только тогда, когда тактовый клок со стороны ПЛИС почти равен скорости SPI клока или меньше.
2) Правда на 100 МГц хана наступает и в вашем случае - при задани коректных STA констрейнов (как учесть например, что задержка на плате меняется от мин значения к макс, какие эти значения получаються, итд...)
Да и связать асинхронные клок домены (SPI - остальная часть ПЛИС) тоже непросто.....
skilful
вот чтобы всяких пересинхронизаций не было -- и думал взять двухклоковое фифо.
ПЛИС работает с ним на своей частоте, МК -- на своей.

То что все прерывания асинхронны я понимаю.
Я не понимаю следующего (может быть повторюсь) -- из "фифо чтения" читает МК на малой частоте, а пишет ПЛИС на бОльшей частоте.
Когда ПЛИС запишет на бОльшей частоте сигнал "фифо не пустое" выставится, но он будет привязан к клоку ПЛИС.

Из описания мегафункции Альтеры:

rdempty -- If asserted, indicates that the dcfifo is empty and disables the rdreq port. Synchronized with rdclk

wrempty -- Indicates that the dcfifo is empty. Delayed version of rdempty that is synchronized with wrclk.
Generated from the rdempty signal with a single synchronization register added to synchronize it to the wrclk clock domain.


Насколько я понял Вы предлагаете завести сигнал wrempty на прерывание МК?

Еще я не понимаю про "ресинхронизаторы (2 тригера)". Как с этим работать?

До этого думал что все "разноклоковые процессы" синхронизируются в двухклоковых фифо или же через PLL

troiden
Цитата(Torpeda @ Sep 11 2012, 13:12) *
Вот это как-то не очень понятно. О каких 40 тактах речь?
даём команду записи. Последний бит приходит на 40-м клоке. Где есчё 40 беруться для интерпретации?

Или вы предлагаете передавать фрейм из 40 бит + есчё дофига тактов клока на его интерпретацию?

Чуть подумав, 40 тактов превратилось в 16 - в случае, если за командой записи следует команда чтения.
Утрированно - пришла первая команда, на выходе контроллера выставились адрес, данные, признак операции и признак приема команды. Первые три будут там неизменны до окончания следующей команды записи либо до прихода адреса для чтения. А для этого надо как минимум 16 тактов. И да, дополнительные такты там есть sm.gif 3 байта данных - это 8 dummy + 16 бит данных. Сделано из-за чтения, для того чтобы можно было успеть пересинхронизироваться.

Цитата(Torpeda @ Sep 11 2012, 13:12) *
2) Правда на 100 МГц хана наступает и в вашем случае - при задани коректных STA констрейнов....

Зависит от кристалла. Шестой спартан 100 МГц примет без вопросов.

Цитата(Torpeda @ Sep 11 2012, 13:12) *
Да и связать асинхронные клок домены (SPI - остальная часть ПЛИС) тоже непросто.....

Отнюдь. См выше - у нас минимум 16 тактов стабильных данных. На внутреннюю частоту пересинхривается только признак приема команды, из него формируется импульс в один такт внутренней частоты, от которого и срабатывает дальнейшая логика.
skilful
Просимулировал в МоделСиме двухклоковую фифо (LPM_FIFO_DC)

Подал только клок записи. В процессе записи изменяется только wrempty. rdempty молчит.

Подал один и тот же клок на клоки чтения и записи. Сигнал wrempty изменяется при первой же записи.
Сигнал rdempty изменяется аж после 7 такта.

Значит пауза после получения прерывания все-таки нужна, если использовать двухклоковое фифо?

P.S. Примерно такой же декодер команд у меня и реализован:
1) адрес, бит записи/чтения -- 1 байт
2) дальше данные, которые игнорируются в случае чтения.


Torpeda
Цитата(skilful @ Sep 11 2012, 12:13) *
вот чтобы всяких пересинхронизаций не было -- и думал взять двухклоковое фифо.
ПЛИС работает с ним на своей частоте, МК -- на своей.

Еще я не понимаю про "ресинхронизаторы (2 тригера)". Как с этим работать?
До этого думал что все "разноклоковые процессы" синхронизируются в двухклоковых фифо или же через PLL

1) двухклоковых фифо, PLL и ресинхронизаторы - это способы как связать асинхронные клок домены.
2) ресинхронизаторы убирают метастабильность. Гдето тут была ветка про метастабильность и способы её подавления - стоит почитать.
В т.ч. и при помощи ФИФО.
http://electronix.ru/forum/index.php?showtopic=93650
3) Что вы будуте делать с ФИФО когда адрес чтения совпадёт с адресом записи?


Цитата(skilful @ Sep 11 2012, 12:13) *
То что все прерывания асинхронны я понимаю.
Я не понимаю следующего (может быть повторюсь) -- из "фифо чтения" читает МК на малой частоте, а пишет ПЛИС на бОльшей частоте.
Когда ПЛИС запишет на бОльшей частоте сигнал "фифо не пустое" выставится, но он будет привязан к клоку ПЛИС.

Это не проблема. МК привяжет асинхронное прерывание к своему клоку.

Цитата(skilful @ Sep 11 2012, 12:13) *
Из описания мегафункции Альтеры:
rdempty -- If asserted, indicates that the dcfifo is empty and disables the rdreq port. Synchronized with rdclk
wrempty -- Indicates that the dcfifo is empty. Delayed version of rdempty that is synchronized with wrclk.
Generated from the rdempty signal with a single synchronization register added to synchronize it to the wrclk clock domain.
Насколько я понял Вы предлагаете завести сигнал wrempty на прерывание МК?

http://electronix.ru/redirect.php?http://w...8Boston_CDC.pdf
Читать п.5.8.2 - Ваш случай.

Цитата(skilful @ Sep 11 2012, 13:05) *
Подал один и тот же клок на клоки чтения и записи. Сигнал wrempty изменяется при первой же записи.
Сигнал rdempty изменяется аж после 7 такта.
Значит пауза после получения прерывания все-таки нужна, если использовать двухклоковое фифо?

похоже тут не тупая задержка нужна, а надо 7 раз клок чтения передёрнуть, чтобы rdempty получить....

-----
Не тратьте время - выкинте все ФИФО, привяжите SPI к клоку ПЛИС и спокойно работайте.

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

Цитата(troiden @ Sep 11 2012, 12:40) *
Чуть подумав, 40 тактов превратилось в 16 - в случае, если за командой записи следует команда чтения.

Т.е. в вашем случае - конвеер. Чтобы прочитать данные надо выдать команду чтения, а потом какую-то другую, чтобы забрать данные.
Ну для вычетки массива - вариант, а для роботы с одиночными командами - только затраты на 2-е повторение.... Не всегда гут.
Может лутше SPI.CLK в 2 раза понизить?

Цитата(troiden @ Sep 11 2012, 12:40) *
Зависит от кристалла. Шестой спартан 100 МГц примет без вопросов.

100МГц на SPI.CLK означает что у вас есть полтакта (5нс) на все задержки распространения сигнала от [МК -to -FPGA.PAD- to - внутренний флоп FPGA ]....
Какая величина задержки на плате (при дорожке 10см напр)?
Какое минимальное её значение, а какое максимальное (это критично для сетап-холд таймингов)?
Какой реальный розбросс задержек на плате (skew)?
Какое сетап\холд требование для MISO на МК?

Цитата(troiden @ Sep 11 2012, 12:40) *
Отнюдь. См выше - у нас минимум 16 тактов стабильных данных. На внутреннюю частоту пересинхривается только признак приема команды, из него формируется импульс в один такт внутренней частоты, от которого и срабатывает дальнейшая логика.

А что если внутренняя частота меньше SPI.CLK? Хватит на ресинхронизацию и на обработку команды?
----------
Ну это на засыпку... sm.gif А ваше решение с конвеером в принципе хорошее. Но лутше всётаки отработать за одну команду команду.
skilful
Цитата(Torpeda @ Sep 11 2012, 14:47) *
1) двухклоковых фифо, PLL и ресинхронизаторы - это способы как связать асинхронные клок домены.
2) ресинхронизаторы убирают метастабильность. Гдето тут была ветка про метастабильность и способы её подавления - стоит почитать.
В т.ч. и при помощи ФИФО.
http://electronix.ru/forum/index.php?showtopic=93650
3) Что вы будуте делать с ФИФО когда адрес чтения совпадёт с адресом записи?



Это не проблема. МК привяжет асинхронное прерывание к своему клоку.


http://electronix.ru/redirect.php?http://w...8Boston_CDC.pdf
Читать п.5.8.2 - Ваш случай.


похоже тут не тупая задержка нужна, а надо 7 раз клок чтения передёрнуть, чтобы rdempty получить....

-----
Не тратьте время - выкинте все ФИФО, привяжите SPI к клоку ПЛИС и спокойно работайте.

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


Т.е. в вашем случае - конвеер. Чтобы прочитать данные надо выдать команду чтения, а потом какую-то другую, чтобы забрать данные.
Ну для вычетки массива - вариант, а для роботы с одиночными командами - только затраты на 2-е повторение.... Не всегда гут.
Может лутше SPI.CLK в 2 раза понизить?


100МГц на SPI.CLK означает что у вас есть полтакта (5нс) на все задержки распространения сигнала от [МК -to -FPGA.PAD- to - внутренний флоп FPGA ]....
Какая величина задержки на плате (при дорожке 10см напр)?
Какое минимальное её значение, а какое максимальное (это критично для сетап-холд таймингов)?
Какой реальный розбросс задержек на плате (skew)?
Какое сетап\холд требование для MISO на МК?


А что если внутренняя частота меньше SPI.CLK? Хватит на ресинхронизацию и на обработку команды?
----------
Ну это на засыпку... sm.gif А ваше решение с конвеером в принципе хорошее. Но лутше всётаки отработать за одну команду команду.


вот примерная схемка, которую думал сделать

Нажмите для просмотра прикрепленного файла
troiden
Цитата(Torpeda @ Sep 11 2012, 15:47) *
Т.е. в вашем случае - конвеер. Чтобы прочитать данные надо выдать команду чтения, а потом какую-то другую, чтобы забрать данные.

Не совсем. И для чтения, и для записи применяется одна команда. Именно чтобы не надо было повторять запрос введены промежуточные 8 бит - за это время успевает прощелкать и пересинхронизатор, и внутренний мультиплексор в ПЛИСовой части, который выставляет на шину данных SPI-контроллера значение нужного регистра. Для аналогии - фактически как чтение данных из любой конфигурационной флешки с SPI-интерфейсом, только там промежуточных бит нету sm.gif

Цитата(Torpeda @ Sep 11 2012, 15:47) *
100МГц на SPI.CLK означает что у вас есть полтакта (5нс) на все задержки распространения сигнала от [МК -to -FPGA.PAD- to - внутренний флоп FPGA ]....
Какая величина задержки на плате (при дорожке 10см напр)?
Какое минимальное её значение, а какое максимальное (это критично для сетап-холд таймингов)?
Какой реальный розбросс задержек на плате (skew)?
Какое сетап\холд требование для MISO на МК?

В случае записи данных в ПЛИС значение имеет только skew, оно вряд ли будет такое уж большое при адекватной разводке. В случае чтения - да, есть подводные камни. Однако и это решаемо с некоторыми изменениями дизайна. Никто же не мешает выдавать прочитанные данные на полтакта-такт SPI.CLK раньше, если мы точно знаем, что неустранимые задержки типа длинны трассы имеют вполне определенные большие значения. Тут есть поле для маневра, была бы потребность.

Цитата(Torpeda @ Sep 11 2012, 15:47) *
А что если внутренняя частота меньше SPI.CLK? Хватит на ресинхронизацию и на обработку команды?

Надо считать, если что - умножать тактовую ПЛИСа до нужных значений. Однако это в любом случае лучше трех-четырехкратного превышения частоты SPI.CLK для нормальной работы пересинхронизации на входе.

Цитата(skilful @ Sep 11 2012, 16:28) *
вот примерная схемка, которую думал сделать

Нажмите для просмотра прикрепленного файла

Когда будете так делать, досконально продумайте алгоритм чтения данных. Чтобы быть уверенным, что читаете то что нужно а не то что пришло когда-то раньше.
Torpeda
Цитата(troiden @ Sep 11 2012, 15:41) *
В случае записи данных в ПЛИС значение имеет только skew, оно вряд ли будет такое уж большое при адекватной разводке. В случае чтения - да, есть подводные камни. Однако и это решаемо с некоторыми изменениями дизайна. Никто же не мешает выдавать прочитанные данные на полтакта-такт SPI.CLK раньше, если мы точно знаем, что неустранимые задержки типа длинны трассы имеют вполне определенные большие значения. Тут есть поле для маневра, была бы потребность.

1) "если мы точно знаем," - в этом-то и дело. Как-бы их узнать.....
2) Как гарантировать стабильность задержки, тем более если она как вы сказали пару тактов?
Вы вообще когда нибудь прощитывали эти величины и их розбросс для разных материалов платы?

3) Выдавать раньше на пару тактов можна (введя пустые биты между адресом и данными), но кто сказал что задержка на плате как-то кратна тактовой частоте SPI.CLK?
что, длинной провода MISO будете данные относительно клока подстраивать на стороне МК?
Это как-то не хорошо... Розводчик шипко ругаться будет однако.... Да и тулзы для росчёта таких задержек надо где-то взять....

Цитата(skilful @ Sep 11 2012, 15:28) *
вот примерная схемка, которую думал сделать

1) Как эта схемка исключает чтение из адреса ФИФО в который идёт одновременно запись?
По-моему - никак. Прочтётся мусор.
2) при полном асинхронизме клоков записи и чтения, данные перепутаються (вы думаете что читаете текущее, а реально это предыдущее напр.).
skilful
исключаться должно программно. МК набил фифо записи как командами чтения, так и записи, например. А потом ждет ответа от фифо чтения.
в сигналы от фифо чтения все сильно и уперлось -- теперь пытаюсь понять Ваш метод с синхронизацией.


помогите разобраться с этим кодом
из http://electronix.ru/forum/index.php?showtopic=93650




посмотрите как по ссылке сделан SPI .

http://www.fpga4fun.com/SPI2.html

Вот в этом блоке привязывают внешний клок spi к внутренним клокам плис
------------------------------------------------------------------------------------------------------------------------------
We sample/synchronize the SPI signals (SCK, SSEL and MOSI) using the FPGA clock and shift registers.

// sync SCK to the FPGA clock using a 3-bits shift register
reg [2:0] SCKr; always @(posedge clk) SCKr <= {SCKr[1:0], SCK};
wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
wire SCK_fallingedge = (SCKr[2:1]==2'b10); // and falling edges

// same thing for SSEL
reg [2:0] SSELr; always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
wire SSEL_active = ~SSELr[1]; // SSEL is active low
wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge
wire SSEL_endmessage = (SSELr[2:1]==2'b01); // message stops at rising edge

// and for MOSI
reg [1:0] MOSIr; always @(posedge clk) MOSIr <= {MOSIr[0], MOSI};
wire MOSI_data = MOSIr[1];


Что тут происходит?
Alexey K
Вопрос.
Зачем один и тот же регистр делать доступным для записи как со стороны МК так и со стороны ПЛИС?
troiden
Цитата(Torpeda @ Sep 11 2012, 17:41) *
1) "если мы точно знаем," - в этом-то и дело. Как-бы их узнать.....
2) Как гарантировать стабильность задержки, тем более если она как вы сказали пару тактов?
Вы вообще когда нибудь прощитывали эти величины и их розбросс для разных материалов платы?

А эти вопросы скорее к разработчику платы, а не к программисту стоящего на плате ПЛИСа sm.gif Неужели программы-трассировщики не поддерживают расчет задержек в линиях? Даже примерно, до наносекунд?

Цитата(Torpeda @ Sep 11 2012, 17:41) *
3) Выдавать раньше на пару тактов можна (введя пустые биты между адресом и данными), но кто сказал что задержка на плате как-то кратна тактовой частоте SPI.CLK?

Точная кратность и не обязательна. Важно в Setup-hold попасть. Можно пойти дальше, поставить на MISO программируемую задержку в ПЛИСе sm.gif Получится своя маленькая аналогия калибровки DDR.

Цитата(Torpeda @ Sep 11 2012, 17:41) *
что, длинной провода MISO будете данные относительно клока подстраивать на стороне МК?

Боже упаси от подобных извращений sm.gif

В любом случае, всё это из разряда теории, надо всегда понимать применимость решений. Хочешь SPI на высоких частотах - будь добр ставь источник и получатель на вменяемых расстояниях. Если не получается - значит стоит задуматься над каким-нибудь другим интерфейсом, а не городить костыли к заранее неправильно спроектированному устройству.
skilful
там я выше приводил пример -- если он в роли таймера и нужна предустановка, чтение
troiden
Цитата(skilful @ Sep 11 2012, 18:14) *
там я выше приводил пример -- если он в роли таймера и нужна предустановка, чтение

Один регистр, на запись - предустановка
Один регистр, на чтение - текущее значение
А сам таймер - третий регистр, отдельно от этих двух. Так по-моему будет красивее.
Torpeda
Цитата(skilful @ Sep 11 2012, 16:52) *
исключаться должно программно. МК набил фифо записи как командами чтения, так и записи, например. А потом ждет ответа от фифо чтения.
в сигналы от фифо чтения все сильно и уперлось -- теперь пытаюсь понять Ваш метод с синхронизацией.

"МК набил фифо записи как командами чтения, так и записи, ..." - а ПЛИС при этом чё с этим ФИФО делает?
Ждёт его заполнения? По какому событию определяет заполнение?
Или ПЛИС одновременно его и читает (судя по схеме)? А что если перехлеснётся ПЛИС с МК?


Цитата(skilful @ Sep 11 2012, 16:52) *
Вот в этом блоке привязывают внешний клок spi к внутренним клокам плис
------------------------------------------------------------------------------------------------------------------------------
We sample/synchronize the SPI signals (SCK, SSEL and MOSI) using the FPGA clock and shift registers.
Что тут происходит?

так тут-же и написано: SCK, SSEL and MOSI пропускается через 2-х битовый shift registers.
Это и есть тот самый синхронизатор на 2-х тригерах, о котором я и говорил вначале.
skilful
Так я смотрю триггера 3 ?

// sync SCK to the FPGA clock using a 3-bits shift register

SCKr <= {SCKr[1:0], SCK};

Здесь происходит защелкивание SCK ?

wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
а тут на втором такте анализируется состояние сдвигового регистра. Если разряды 2,1 равны "01", то SCK_risingedge = True ?


Torpeda
Цитата(troiden @ Sep 11 2012, 17:13) *
А эти вопросы скорее к разработчику платы, а не к программисту стоящего на плате ПЛИСа sm.gif

нуда, ненадо учитывать ограничения PCB дизайнера - пусть крутиться как хочет потом.....
Цитата(troiden @ Sep 11 2012, 17:13) *
В любом случае, всё это из разряда теории, надо всегда понимать применимость решений.

Одно скажу точно, если вы пытаетесь построить корректно работающий SPI на высоких частотах, и у вас нет STA тайминг констрейна (SDC) со значением мин\макс внешних задержек - работать будет не всегда....
Это станет понятно, когда россчитать эти самые задержки и их возможный технологический розбросс, к чему я вас и пытаюсь подвести.
Даже при 10нс SPI.CLK это уже не так просто.


Цитата(skilful @ Sep 11 2012, 17:42) *
Так я смотрю триггера 3 ?

// sync SCK to the FPGA clock using a 3-bits shift register

SCKr <= {SCKr[1:0], SCK};

Здесь происходит защелкивание SCK ?

wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
а тут на втором такте анализируется состояние сдвигового регистра. Если разряды 2,1 равны "01", то SCK_risingedge = True ?

Это + детектор фронта.
troiden
Цитата(Torpeda @ Sep 11 2012, 18:49) *
нуда, ненадо учитывать ограничения PCB дизайнера - пусть крутиться как хочет потом.....

Процесс построен не так sm.gif После трассировки программист получает от PCB-дизайнера бумажку с получившимися задержками и пляшет уже от нее.
Ну не дело это для программиста - рассчитывать задержки. В идеале он видит максимум электрическую схему.
Александр77
Цитата(troiden @ Sep 11 2012, 18:58) *
После трассировки программист получает от PCB-дизайнера бумажку с получившимися задержками и пляшет уже от нее.
Ну не дело это для программиста - рассчитывать задержки.

Вся беда только в одном - Вы, как программист, оперируете дискретными временными отрезками (период между фронтами), а жизнь не настолько детерминирована.
Поэтому присоединюсь к совету сделать синхронный проект, в котором будут отслеживаться уровни данных, а также фронт тактового сигнала интефейса, и лишь затем производить остальные операции сдвига и тп.
troiden
Цитата(Александр77 @ Sep 11 2012, 22:28) *
Вся беда только в одном - Вы, как программист, оперируете дискретными временными отрезками (период между фронтами), а жизнь не настолько детерминирована.

Отнюдь. От подобного отучаешься за первые пару лет погружения в работу, особенно если нет мешающего багажа из компьютерного программирования.
Просто и в первом, и во втором подходе будут и свои плюсы, и свои минусы, проявляющиеся в разных местах. И от разработчика зависит, с чем у него больше душа лежит. Мне больше импонирует разбираться с пересинхронизацией исключительно внутренних сигналов ПЛИСа.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.