Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SGDMA почему-то байты пропускает
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
alexPec
Добрый день Всем.Думал, что разобрался с SGDMA, ан нет! Непонятные для меня вещи с этой штукой происходят, помогите прояснить, в чем дело. На рисунке диаграммы сигнал-тапа, фрагмент сопца (что касается этого ДМА) и дамп памяти в которую этот дма пишет данные.
Суть такая. Внешнее к сопцу устройство выдает отсчеты сигнала (четвертая строка сверху в сигнал-тапе) и сигнал Valid (пятая строка сверху), заведенный на одноименный сигнал стриминг-дма. Данные проходят через фифо на 1024 байта и попадают на вход SGDMA stream to memory (третья строка сверху).Зелеными линиями показано соответствие потока данных. До этого места как видно все ок, какие данные пришли, такие и попали на вход ДМА. Еще показаны адрес m_write_address (первая строка) и данные m_write_data (вторая строка). Если я правильно понял, это как раз адрес памяти куда дма пишет и данные, которые он пишет.Еще выведен строб записи m_write_write. Так вот по графику видно, что данные на выходе ДМА появляются все, но не все почему-то записываются в память. Синим выделено слово, которое например не записалось в память (на дампе это тоже видно, серым выделена клетка, где идет FD9A и сразу 008F, а должно быть FD9A,0000,008F). Опытным путем замечено, что такие пропуски появляются когда сигнал m_write_write затягивается, т.е. похоже когда шина загружается. Но при этом фифо для дма не переполняется (сигнал wrful_from_the_fifo_1, последняя строчка).
Я то думал фифо для того и нужно, чтоб если шина загружена - буферизировать данные, разгрузится - заталкивать в память. А получается шина загрузилась - пропустили байты и дальше.

Ну и детали. Клок для процессора, дма и сигнал-тапа - 80 МГц (pll0_c1 в сопце), клок для входных данных - 20 МГц (clk1 в сопце). Данные валятся пачками (пачка выделяется сигналом valid) по 2048 16 битных слов с периодичностью примерно раз в 1,5 мс. Мастеров на шине 3 - собственно процессор, дма дисплея (вытаскивает из памяти 16-разрядные слова с частотой 5 МГц) и упомянутый выше дма. Память у проца внешняя, асинхронная, программа, буфер видео, буфер для дма описанного и все остальное в ней лежит. Настройки компонентов дма в рисунках приложены. компонент ADC - просто сигналы avalon-st выведенные наружу.

Поделитесь пожалуйста идеями как победить, свои кончились.
vadimuzzz
у фифы не стоит галочка "Allow backpressure", да и у Timing Adapters тоже не везде. еще на диаграмме не выведен waitdatarequest или как его там - через который SGDMA показывает, что он не готов, он же должен использоваться для backpressure.
alexPec
Цитата(vadimuzzz @ Jan 10 2011, 17:37) *
у фифы не стоит галочка "Allow backpressure", да и у Timing Adapters тоже не везде. еще на диаграмме не выведен waitdatarequest или как его там - через который SGDMA показывает, что он не готов, он же должен использоваться для backpressure.

Спасибо VADIMUZZZ! Вроде помогли галки backpreassure, вроде не пропускает, но проверить точно не могу, поскольку появилась другая проблема: адрес начала записи стоит в дескрипторе 0x133128 (на рисунке область памяти с дескриптором ДМА), а писать начинает с 0х13392С (в рисунке с сигналтапом). По скриншоту дескриптора видно, что записал столько, сколько его просили, но КУДА? Проверил что действительно в памяти лежит (третий рисунок) - все тоже что и сигналтап говорит, писать начинает с 0x13392C. Понять не могу откуда этот адрес берется? Нигде его нет. При этом если предположить, что дма записал 0х1440 байт с 0х13392С, то получается, что конец записи - 0х134D6C. Но туда он не попадает, т.к. дескриптор находится по адресу 0х134580 и после трансфера он не портится. Зато данные, которые где-то в середине пакета попадают в начальный адрес 0х133128. Т.е. пишет он в отведенную область, но начало смещено. Причем при перезапуске ДМА адрес начала записи точно такой же. Из-за чего такое может быть? В софте абсолютно по сравнению со старым вариантом ничего не менял, просто поставил галки, скомпилировал, и залил тот же софт (только bsp перестроил, ато ругается на sysid).
Как быть? Что делать?

UPD:Сделал размер фифо вместо 1024 байта 512 байт - дма начал писать с адреса 0х13352С (вместо 0х13392С), т.е. ровно на 1024 байта меньше, чем с фифо на 1024 байта. Чума! Дескрипторы один в один. А как его заставить писать с начала?
vadimuzzz
а как вы определяете момент начала DMA-транзакции в сигналтапе? мне кажется, проблема в том, что либо длина в дескрипторе неверно выставлена, либо несколько транзакций в последовательные сегменты памяти проходит
alexPec
Цитата(vadimuzzz @ Jan 11 2011, 05:57) *
а как вы определяете момент начала DMA-транзакции в сигналтапе? мне кажется, проблема в том, что либо длина в дескрипторе неверно выставлена, либо несколько транзакций в последовательные сегменты памяти проходит

В сигнал тапе ставлю условие записи когда сигнал стрима Valid в 1 и когда m_write_write в 1. Как раз когда нажимаю кнопку (перезапускаю DMA) сигнал тап вываливает картинку, и там вот эти адреса. И с дампом памяти все вяжется
Длина в дескрипторе верная, на самом деле чуть больше 2048 слов: 2592.
А как можно отловить несколько транзакций последовательных или из-за чего может быть такое? Дело в том, что когда сигнал тап ставишь на авто перезапуск, то картинка меняется только по нажитю на кнопку (перезапуск ДМА). Дескриптор у меня один.

Вот такая мысль появилась: могут ли данные через фифо проходить как через сдвиговый регистр, т.е. на выходе первый байт появится не раньше чем через длину фифо тактов?
Если так, то более менее все вяжется: фифо на 1024х(8bitpersymbol x 2 symbolperbeat), т.е. на 2048 байт. тогда при начальном адресе 0х133128 получаем первый байт 0х133128+2048=0х133928 (у меня получается 0х13392С). Если сокращаем фифо в 2 раза то получаем первый байт 0х133128+1024=0х133528 (у меня получается 0х13352С).
В добавок к этому заметил, что при первом запуске дма (после реконфигурирования) память с 0х133128 по 0х133928 (или по 0х133528 если фифо 512 элементов) забита ерундой, а с 0х13392С до конца буфера - начало пакета. При повторном запуске что-то правдоподобное появляется в начале (то что с прошлого раза осталось в фифо).
Если действительно так, то лечится ли это? И как?
vadimuzzz
Цитата(alexPec @ Jan 11 2011, 12:36) *
В добавок к этому заметил, что при первом запуске дма (после реконфигурирования) память с 0х133128 по 0х133928 (или по 0х133528 если фифо 512 элементов) забита ерундой, а с 0х13392С до конца буфера - начало пакета.

такая фигня происходит, если фифа сконфигурирована в "Show Ahead" режиме, покажите настройки. Упс, просмотрел в начале. Настроек не видно, надо HDL поглядеть. а можно и не глядеть, сделать в начале программы транзакцию размером с фифо, чтобы хлам выбросить. хотя HDL все-таки интересно глянуть
alexPec
Цитата(vadimuzzz @ Jan 11 2011, 11:20) *
такая фигня происходит, если фифа сконфигурирована в "Show Ahead" режиме, покажите настройки. Упс, просмотрел в начале. Настроек не видно, надо HDL поглядеть. а можно и не глядеть, сделать в начале программы транзакцию размером с фифо, чтобы хлам выбросить. хотя HDL все-таки интересно глянуть

Написан параметр lpm_showahead = "OFF", ну может не то посмотрел, хдл от фифы прилагаю. А без синхронизации как то стремно. Один байт туда или сюда (мало ли, всякие случаи бывают) и все, пропали данные. А нельзя фифу чистить сигналом например startofpacket или за такт-два до него, ну или хоть как-то синхронизировать с сигналом начала пакета? Фиг бы с ним что не сначала данные, лишь бы всегда одинаково было. Ато получается один раз синхронизировали, а потом что-нибудь сместилось и данные не те совсем.

И ЕЩЕ РАЗ СПАСИБО!!!

UPD:Стоп!!! Хрен с ним с фифо, пусть там и мусор может быть, а сигнал тап-то почему показывает первый адрес, по которому записывает 0x13392C(0x13352C)??? И почему этот адрес зависит от размера фифо? В дескрипторе же русским по белому: 0х133128 ???
vadimuzzz
Цитата(alexPec @ Jan 11 2011, 15:13) *
Написан параметр lpm_showahead = "OFF"

хм, странно. может она не сбрасывается? давайте все ее входные/выходные сигналы в сигналтап, включая aclr. интересно глянуть на нее во время транзакции
alexPec
Цитата(vadimuzzz @ Jan 11 2011, 12:22) *
хм, странно. может она не сбрасывается? давайте все ее входные/выходные сигналы в сигналтап, включая aclr. интересно глянуть на нее во время транзакции

А там два арбитратора фифо, один фифо1. От кого сигналы брать? На все у меня памяти не хватит. И aclr там нигде нет. Видел только rdreset_n, wrreset_n.Смотрел в пресинтезе.
vadimuzzz
Цитата(alexPec @ Jan 11 2011, 17:27) *
А там два арбитратора фифо, один фифо1. От кого сигналы брать? На все у меня памяти не хватит. И aclr там нигде нет. Видел только rdreset_n, wrreset_n.Смотрел в пресинтезе.

да нет, возьмите сигналы именно мегафункции фифо, нафиг арбитраторы
alexPec
Цитата(vadimuzzz @ Jan 11 2011, 16:06) *
да нет, возьмите сигналы именно мегафункции фифо, нафиг арбитраторы

Вывел все что относится к фифо. Но че-то не похоже что в нем проблемы. На второй картинке видно что данные с него на вход дма попадают через несколько тактов (пайплайн думаю). Потом время от входа в фифо до попадания в дма постепенно увеличивается (фифо заполняется). А вот адрес начальный- 0х13352С (512 слов фифо) -беда.
Может конечно такое быть: Фифо при конфигурировании считается заполненной, как только запускаем транзакцию - мусор вываливается сразу, потом ждем правильных данных. Как только появляются правильные данные (по сигналу valid) они не задерживаясь проходят в память, но уже с адреса на размер фифо больше и соответственно транзакция заканчивается раньше чем данные перестают поступать. Оставшиеся данные заполняют фифо и до запуска следующей транзакции. Как запускается - старые данные фифы вываливаются сразу, в начало области памяти дма, потом ждем новых, как появляются - дописываются в конец области памяти дма.
Все таки беда то тогда в синхронизации получается. Вот бы как-то фифу сбросить перед открытием транзакции. Не подскажете?

UPD:О! такой вариант: данные то сразу валятся, даже когда инициализируется процессор,вся система, а транзакций дма нет. Поэтому фифа и заполняется под завязку. И как только открываем транзакцию - сначала вываливается то что накопилось.

Надо синхронизировать однозначно! Но как?
vadimuzzz
Цитата(alexPec @ Jan 11 2011, 22:30) *
Надо синхронизировать однозначно! Но как?

вывести PIO и управлять фифой снаружи (мультиплексор на клок, например). но сначала надо разобраться - выставьте триггер в сигналтапе на сигнал m_write_address=правильный_начальный_адрес, посмотреть, в какой момент он его проскакивает
alexPec
Цитата(vadimuzzz @ Jan 11 2011, 20:29) *
вывести PIO и управлять фифой снаружи (мультиплексор на клок, например). но сначала надо разобраться - выставьте триггер в сигналтапе на сигнал m_write_address=правильный_начальный_адрес, посмотреть, в какой момент он его проскакивает

Посмотрел, вот картинки,первая - при клоке сигналтапа 80 М, вторая чтоб побольше увидеть - 20М. Похоже как я и думал. сигнал valid от источника неактивен (4-я строка сверху), а как только открываешь транзакцию, самую первую, (похоже в мемент времени 0) начинается перекачка данных причем с правильного адреса, и перекачивается 1024 байта (размер фифо). Потом дма ждет пока все остальные данные подойдут, а они подходят когда сигнал valid появляется. И эти данные (правильные) пишутся уже с адреса 0х13352С.

А как бы поизящней синхронизацию сделать, посоветуйте. Мысль такая, покритикуйте.

После транзакции отрубить клок фифы, сбросить фифо, а включение клока сделать аппаратно, за например 2 такта до сигнала Valid. Все бы ничего, но как фифо сбросить? Че-то думал-думал - не обойтись без такого сброса похоже. Можно ли выцепить из сопца сигнал что фифа пустая? Тогда можно транзакцию скажем на 2 байта (или 100) больше делать чем реально данных придет а потом клокать ее после транзакции пока сигнал "пусто" не исчезнет. Тогда даже при рассинхронизации через несколько десятков транзакций снова синхронизируется. Неохота фифу из сопца вытаскивать, можно ли обойтись как-нбудь малой кровью? Или это через Ж и можно красиво сделать как-то?

UPD:Похоже в мегафункции lpm_fifo_dc есть нужный сигнал - aclr. Если я правильно понял, это он и сбрасывает фифо? А можно ли его из dc-fifo который в сопце вытащить наружу? Вот тогда бы все красиво получилось!
vadimuzzz
пока инфы маловато..
вытащите сигналы модуля fifo_1_dual_clock_fifo в сигналтап, особо интересуют
aclr, rdempty, wrreq, wrfull, wrusedw
насчет синхронизации - надо сначала разобраться. мне непонятно, с какого перепугу фифо заполнена (предположительно)
к началу транзакции. aso_out0_valid_from_the_ADC_DMA - какую функцию несет и откуда идет?
alexPec
Цитата(vadimuzzz @ Jan 12 2011, 02:49) *
пока инфы маловато..
вытащите сигналы модуля fifo_1_dual_clock_fifo в сигналтап, особо интересуют
aclr, rdempty, wrreq, wrfull, wrusedw
насчет синхронизации - надо сначала разобраться.

А как их вытащить? Вот все что сигнал тап выдает по маске *fifo_1* design entities (на картинке, там еще data_in[15..0] есть, не влезло, больше ничего). Ставишь post-fitting или pre-synthesis и того меньше сигналов вылазит.

Цитата
aso_out0_valid_from_the_ADC_DMA - какую функцию несет и откуда идет?


aso_out0_valid_from_the_ADC_DMA - признак правильных данных на входе в fifo. Он идет с цифрового автомата (внешнего к сопцу). Там во время обработки валятся данные, но они промежуточные и не нужные, поэтому сигнал aso_out0_valid_from_the_ADC_DMA в это время находится в 0. А когда начинается цикл выгрузки данных из цифрового автомата в память (через дма, уже обработанных, правильных), сигнал aso_out0_valid_from_the_ADC_DMA ставится в 1.

Цитата
с какого перепугу фифо заполнена (предположительно)

Данные на вход фифо валятся независимо от проца, они идут с АЦП, проходят цифровой автомат и попадают в фифо, а дальше в дма. И при старте пока все инициализируется фифо заполняется этими данными, а транзакций нет - пока до них дойдет проходит время >1,5мс (пакеты валятся с периодом 1,5мс), и конец первого блока уже теряется.
vadimuzzz
1. нетлист называется "SignalTap Pre-Synthesis" - как-то так
2. неплохо бы и автомате реализовать backpressure, не считаете? вытянуть сигнал ready или как его там из sgdma и его использовать
alexPec
Цитата(vadimuzzz @ Jan 12 2011, 11:08) *
2. неплохо бы и автомате реализовать backpressure, не считаете? вытянуть сигнал ready или как его там из sgdma и его использовать

А что, тоже вариант. Ready от SGDMA не только на фифо, но и на автомат завести, чтоб он не толкал данные в фифо если дма не спрашивает.

Спасибо, попробую.
alexPec
Все, победил! 08.gif Уважаемый Vadimuzzz! У Вас редкий дар (или опыт) спросить такое, после чего просветвелие наступает, СПАСИБО БОЛЬШОЕ!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.