|
|
  |
Cyclone3, DDR2 и АЦП, Проблема |
|
|
|
Aug 2 2013, 09:03
|
Частый гость
 
Группа: Свой
Сообщений: 168
Регистрация: 29-04-06
Пользователь №: 16 608

|
Здравствуйте, возникла у меня довольно странная проблема. Есть плата собственного производства, на ней установлены Cyclone3, память DDR2 и АЦП. Задача - по нажатию кнопки в программе на компьютере сохранить данные от АЦП в памяти и затем передать их в компьютер. Это реализовано с использованием прямого доступа к памяти и FIFO. Работает хорошо, но сделано это было в Quartus 9.0 и Nios IDE, т.е. без eclipse. Сейчас использую Quartus 12.1sp1. Открываю старый проект перегенерю систему в SOPC Builder, компелирую в Quartus, компелирую программу в Eclipse, прошиваю - не работает. А точнее всё запускается, програма переходит в нужную подпрограмму и зависает в ожидании окончания DMA. Причём проделал такой эксперимент взял старый старые и новые .sof и .elf и попытался перекомбинировать старое с новым, чтобы понять где ошибка (т.к. базовые адреса в SOPC не менялись я подумал, что так можно делать). Результат - хорошо работает только старые .sof и .elf любые другие комбинации работаю плохо и либо зависают при первом же нажатии на кнопку получения данных или через короткое время.
В чём может быть проблемма? Может какие нибудь особенности нового Quartus или Eclipse и они как-то по другому компилируют?
P.S. Т.е. получается, что на старой прошивке ПЛИС новая программа работает плохо. Т.е. дело в компиляторе программы. Хотя это тоже очень странно ведь программа только инициализирует DMA и запускает приём данных, а далее данные записываются в память минуя процессор. Так почему же он зависает ведь прошивка старая - работающая?
Сообщение отредактировал djhall - Aug 2 2013, 10:03
|
|
|
|
|
Aug 2 2013, 12:37
|

Частый гость
 
Группа: Свой
Сообщений: 129
Регистрация: 28-09-10
Из: Москва
Пользователь №: 59 793

|
Цитата(djhall @ Aug 2 2013, 14:58)  Да, видимо это возможно, но при сборке системы с нуля для 12.1sp1 всё работает ещё хуже. Может быть действительно изменильсь сами компоненты dma, контроллер ddr памяти и clock crossing ... Была похожая проблема после переноса проекта с Q9.1 на Q11 перестал работать контроллер DDR SDRAM. Пляски с бубнами не помогли. Когда надоело шаманить вернулся на Q9.1. Цитата(djhall @ Aug 2 2013, 14:58)  Вообще-то я использую Memory-Mapped интерфейс для получения данных от быстродействующего АЦП. Данные записываются в FIFO и затем DMA считывает их оттуда и распределяет в памяти. Причём DMA и память работают на разных частотах и между ними стоит clock crossing. Странное решение. А процессор и остальная перефирия на каком клоке сидит? Обычно, если АЦП работает на частоте отличной от системы, синхронизация делается через FIFO. При этом не теряется быстродействие всей системы. На вход FIFO обычно проще подключать Streaming, но можно и ММ. SG-DMA при правильном использовании однозначно быстрее, только нужно ли Вам это?
|
|
|
|
|
Aug 4 2013, 09:24
|
Частый гость
 
Группа: Свой
Сообщений: 168
Регистрация: 29-04-06
Пользователь №: 16 608

|
Цитата Странное решение. А процессор и остальная перефирия на каком клоке сидит Процессор, DMA и мой компонент для получения данных от АЦП (вместе с FIFO) работают от одной частоты в 100МГц, DDR2(MT47H64M16HR) работает от 133.333МГц в режиме Half-rate, т.е. локальная шина имет размер 64бита и частоту 66,7МГц. Clock-crossing передаёт данные между 100 и 66,7Мгц. Возможно это и не лучшая конфигурация и если кто-то сможет предложить лучше с удовольствием попробую. А пока решил поэкспериментировать. Запустил DDR2 от 200МГц в режиме Half-rate, т.е. теперь локальная шина имет размер 64бита и частоту 100МГц и от неё тактируются все остальные компоненты. Clock-crossing выбросил. С помощью SignalTap выяснил, что зависание происходит из-за переполнения FIFO, причём переполнение происходит не сразу, а постепенно и видимо в моменты когда доступ к памяти перехватывает конкурирующее устройство(видимо процессор). Ну то есть скорости хватает впритык и малейшая пауза в чтении данных из FIFO в конечном счёте приводит переполнению. В SignalTap также видно, что чтение из моего компонента с FIFO с помощью DMA происходит прерывисто - один такт чтение далее один такт простой и следующий такт опять чтение. В чём может быть причина такого чтения ведь мой компонент поддерживает чтение по каждому такту?
|
|
|
|
|
Aug 6 2013, 18:56
|
Частый гость
 
Группа: Свой
Сообщений: 168
Регистрация: 29-04-06
Пользователь №: 16 608

|
Цитата 1) арбитраж доступа к DDR памяти. Попробуйте проставьте вручную своему компоненту максимальный приоритет Аритраж уже выставлен в пользу моего компонента. И в принципе изменяя приоритеты для разных мастеров на шине можно добиться нормальной работы. Но как-то это не надёжно я попробовал на разных компьютерах одни и теже настройки для системы и после компиляции одна прошивка заработала, а другая нет (хотя может я какие-то настроики в Quartus не учёл). Цитата 2) для чтения/записи каждый такт ваш компонент должен уметь burst На счёт burst, то это потребует довольно серьёзной переделки компонента, чего не хотелось бы. Может быть попробовать увеличить размерность шины до 64 бит? Правильно ли я понимаю арбитраж? Например, если мастер1 читает данные из слэйва и в это время мастер2 тоже хочет получить доступ к этому же слэйву, то он его обязательно получит и отношение времён доступа к слэйву для мастера1 и мастера2 будет равно соотношению чисел арбитража выставленных в SOPC builder для этих мастеров.
|
|
|
|
|
Aug 7 2013, 08:40
|

Частый гость
 
Группа: Свой
Сообщений: 129
Регистрация: 28-09-10
Из: Москва
Пользователь №: 59 793

|
Цитата(djhall @ Aug 4 2013, 13:24)  моего компонента с FIFO с помощью DMA происходит прерывисто - один такт чтение далее один такт простой и следующий такт опять чтение. В чём может быть причина такого чтения ведь мой компонент поддерживает чтение по каждому такту? Этот DMA компонент так и работает - читает во внутренний буфер 1 такт, потом записывает -2 такт. У DMA read и write на разных шинах? Если мне не изменяет склероз, обычный DMA с burst не работает. Сложно советовать нe имея перед глазами всей структуры проекта, но варианты такие: 1.SG-DMA 2. перенос DMA и FIFO в клоковый домен памяти. А лучше и то и другое и увеличить кеш процессора и длину FIFO.
|
|
|
|
|
Aug 9 2013, 05:30
|
Частый гость
 
Группа: Свой
Сообщений: 168
Регистрация: 29-04-06
Пользователь №: 16 608

|
Цитата Этот DMA компонент так и работает - читает во внутренний буфер 1 такт, потом записывает -2 такт. Давным давно отлаживал систему с DMA и лично видел, что запись была по каждому фронту. Правда это было очень давно. В DMA есть FIFO поэтому она должна (а точнее я хочу, чтобы DMA так делала) читать несколько циклов и потом записывать несколько циклов. Конечно если чтение и запись идут в одну и туже память то без разделения по времени ни чего не получится, а вот если чтение идёт из переферийного устройства, а запись в память, то казалось бы нет необходимости разделения по времени и запись может идти по каждому такту. Надо поэкспериментировать, но у меня остаётся надежда заставить DMA работать по каждому такту. Цитата У DMA read и write на разных шинах? Не совсем понял вопрос. DMA read и DMA write это отдельные мастеры и соответственно разные шины. Они оба подключены к контроллеру DDR памяти и некоторым другим компонентам в системе, а к моему компоненту получения данных от АЦП подключен только DMA read. Цитата 1.SG-DMA Всегда недолюбливал SG DMA. Надо наверное с ним хорошенько разобраться. SG DMA содержит четыре мастера, т.е. два дополнительных мастера для дискрипторов. Если всё это подключить к контроллеру DDR памяти то минимум к нему будет подключено шесть мастеров и плюс мои собственные. Мне почему-то кажется что это очень плохо для производительности и для разводки по кристалу. Видимо шины для дискрипторов лучше подключать к внутренней памяти ПЛИС. Но как же мне передать большой объём данных ведь в дискрипторе поле для длинны передачи всего 16 бит, т.е. 65536 байт? Увеличивать количество дескрипторов? Так до какой степени, в ПЛИС же память не слишком большая? Цитата 2. перенос DMA и FIFO в клоковый домен памяти. Уже сделано.
|
|
|
|
|
Aug 9 2013, 18:02
|
Профессионал
    
Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596

|
если говорить про SGDMA то суть в следующем: под дескрипторы берется onchip_ram прикидываете сколько дескрипторов поместиться в вашей onchip_ram делаете uncached_malloc() столько раз, сколько у вас есть дескрипторов Составляете связанный список из дескрипторов, собираете дескрипторы в цепочку alt_avalon_sgdma_construct_stream_to_mem_desc() запускаете SGDMA.
при этом начинает заполнятся первый кусок памяти, выделенный через uncached_malloc(). сразу после - второй, и т.д. DMA-операция продолжается до тех пор, пока всё выделенное пространство не быдет записано. После записи каждого куска выделенной памяти можно настроить выдачу прерывания. После этого нужно "перезарядить" DMA при помощи alt_avalon_sgdma_construct_stream_to_mem_desc(), и снова стартануть.
Другой вариант, - при формировании цепочки дескрипторов их можно "закольцевать", и запустить DMA, при этом DMA-запись не будет останавливаться вообще никогда. Тут важно успевать что-то делать с данными пока они не будут перезаписаны следующкей порцией приходящих данных.
зы. за одну операцию запуска можно передать гораздо больше чем 64k
--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
|
|
|
|
|
Aug 12 2013, 06:08
|
Частый гость
 
Группа: Свой
Сообщений: 168
Регистрация: 29-04-06
Пользователь №: 16 608

|
Цитата Лучше разработать IP контроллера дескрипторов для SG-DMA Гениально!!! Так и сделаю. Спасибо. Жаль не я это придумал.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|