|
NIOS II, программирование ниос2 на СИ |
|
|
|
Jan 20 2015, 06:52
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Здравствуйте, пишу программу на Си в ниос2 эклипс. Проект был собран в qsys, там имеется ниос2, DDR2, PIO, on-chip memory2 и т.д. Возник вопрос: как на языке Си обратиться например именно к выводу PIO или к шине адреса DDR2? Вставил несколько строк, но не знаю правильно ли сделал ALT_MODULE_CLASS_pio_in (PIO_IN_BASE, data_inp); ALT_MODULE_CLASS_pio_out_on (PIO_OUT_ON_BASE, data_out_on); ALT_MODULE_CLASS_pio_out (PIO_OUT_BASE, data_out); ALT_MODULE_CLASS_onchip_memory2_0 (ONCHIP_MEMORY2_0_BASE, on_chip);
|
|
|
|
|
 |
Ответов
(1 - 99)
|
Jan 20 2015, 07:55
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 20 2015, 09:52)  Здравствуйте, пишу программу на Си в ниос2 эклипс. Проект был собран в qsys, там имеется ниос2, DDR2, PIO, on-chip memory2 и т.д. Возник вопрос: как на языке Си обратиться например именно к выводу PIO или к шине адреса DDR2? Вставил несколько строк, но не знаю правильно ли сделал ALT_MODULE_CLASS_pio_in (PIO_IN_BASE, data_inp); ALT_MODULE_CLASS_pio_out_on (PIO_OUT_ON_BASE, data_out_on); ALT_MODULE_CLASS_pio_out (PIO_OUT_BASE, data_out); ALT_MODULE_CLASS_onchip_memory2_0 (ONCHIP_MEMORY2_0_BASE, on_chip); Смотрите в BSP папку drivers, там есть всё необходимое.
|
|
|
|
|
Jan 20 2015, 08:24
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 20 2015, 10:55)  Смотрите в BSP папку drivers, там есть всё необходимое. Все что есть в папке. Где взять DDR2 и on-chip memory2 ?
Эскизы прикрепленных изображений
|
|
|
|
|
Jan 20 2015, 09:07
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
получается, что я могу работать только с адресами ОЗУ? Адресное пространство вроде задал верно, qsys не ругался. Цитата(doom13 @ Jan 20 2015, 11:36)  Bsp перегенерили после добавления DDR2? Должны драйвера под контроллер DDR2 появиться, для On-Chip memory и не требуются, ну а для GPIO - altera_avalon_gpio_regs.h. altera_avalon_gpio_regs.h получается общем для нескольких PIO? я в qsys сделал несколько PIO (PIO_IN, PIO_OUT, PIO_OUT_ON)
|
|
|
|
|
Jan 20 2015, 09:14
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 20 2015, 12:09)  Да, только там есть параметр BASE, а он для всех GPIO разный. Спасибо, начинаю понимать. Везде в примерах даются строки, например IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, leds), но не объясняются.
|
|
|
|
|
Jan 20 2015, 09:16
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 20 2015, 12:07)  получается, что я могу работать только с адресами ОЗУ? Адресное пространство вроде задал верно, qsys не ругался. Не совсем понял, что Вы этим хотели сказать. Если к Ниосу прикручен DDR2 и On-chip memory, то и тот и тот есть ОЗУ. Для работы с DDR2 можно использовать что-то типа: Код int *ddr2_ptr = (int *) DDR2_START_ADDRESS; или в BSP Editor определяете секции, которые будут ложится в DDR2 (например .heap - тогда при динамическом выделении памяти, она и будет выделяться в DDR2).
|
|
|
|
|
Jan 20 2015, 09:19
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 20 2015, 12:09)  Да, только там есть параметр BASE, а он для всех GPIO разный. В моем случае надо так вводить строки? IOWR_ALTERA_AVALON_PIO_DATA(pio_in, data) IOWR_ALTERA_AVALON_PIO_DATA(pio_out, data) IOWR_ALTERA_AVALON_PIO_DATA(pio_out_on, data) Вместо data вводится свое имя переменной
|
|
|
|
|
Jan 20 2015, 09:22
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 20 2015, 12:16)  Не совсем понял, что Вы этим хотели сказать. Если к Ниосу прикручен DDR2 и On-chip memory, то и тот и тот есть ОЗУ. Для работы с DDR2 можно использовать что-то типа: Код int *ddr2_ptr = (int *) DDR2_START_ADDRESS; или в BSP Editor определяете секции, которые будут ложится в DDR2 (например .heap - тогда при динамическом выделении памяти, она и будет выделяться в DDR2). Имеется внешняя DDR2, также есть On-chip memory, которая необходима для моментов времени, когда происходит чтение из DDR2. В эклипсе для работы с адресами я использую строки, например int addr_on_chip=0x4008000; Правильная ли такая запись?
|
|
|
|
|
Jan 20 2015, 09:26
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 20 2015, 12:19)  В моем случае надо так вводить строки? IOWR_ALTERA_AVALON_PIO_DATA(pio_in, data) IOWR_ALTERA_AVALON_PIO_DATA(pio_out, data) IOWR_ALTERA_AVALON_PIO_DATA(pio_out_on, data)
Вместо data вводится свое имя переменной Да, data - то, что хотите видеть на выходе порта или то, что читаете. Адреса pio_in, pio_out, pio_out_on берёте из system.h.
|
|
|
|
|
Jan 20 2015, 09:36
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(Golikov A. @ Jan 20 2015, 12:24)  нет потому что нужно адрес не int addr_on_chip=0x4008000
а int *addr_on_chip = (int *)0x4008000;
записать туда *addr_on_chip = 10; считать оттуда int Temp = *addr_on_chip;
при условии что 0x4008000 - это адрес в ДДР Спасибо за разъяснение. Цитата(doom13 @ Jan 20 2015, 12:26)  Да, data - то, что хотите видеть на выходе порта или то, что читаете. Адреса pio_in, pio_out, pio_out_on берёте из system.h. Спасибо, теперь все понятно стало
|
|
|
|
|
Jan 20 2015, 09:57
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 20 2015, 12:42)  Нет, не правильная, все действия через указатель. имеете ввиду надо как запись повыше у Golikov A.
Сообщение отредактировал x66 - Jan 20 2015, 09:57
|
|
|
|
|
Jan 20 2015, 10:19
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 20 2015, 12:59)  В процах вообще все делается через обращения в адреса памяти. Потому что в вашем проце вся периферия - это модули которые весят на шине и имеют свой адрес, и все их регистры доступны как данные через этот адрес (группу адресов) Только вот в случае ниоса обращение к регистрам периферии лучще осуществлять с использованием макросов из BSP, чтобы потом не думать, что же оно не работает. Цитата(x66 @ Jan 20 2015, 12:57)  имеете ввиду надо как запись повыше у Golikov A. да, подробный механизм работы с указателем у Golikov A расписан, а пример того, как это делается (указатель на память) приводил выше (сообщение #10), что и было потом расписано с подробностями.0
|
|
|
|
|
Jan 20 2015, 10:26
|
Знающий
   
Группа: Участник
Сообщений: 527
Регистрация: 4-06-14
Из: Санкт-Петербург
Пользователь №: 81 866

|
Цитата Только вот в случае ниоса обращение к регистрам периферии лучще осуществлять с использованием макросов из BSP, чтобы потом не думать, что же оно не работает. Присоединяюсь. Есть там такая тонкость: если общаться с переферийным модулем (в т.ч. самописным) посредством макросов типа IOWR/IORD, то все должно работать нормально, если общаться через сишные пойнтеры, то могут возникнуть проблемы. Сам сталкивался с этим и долго думал, что же не работает. Объявил пойнтеры на начало массива по адресу, выделенному переферийному модулю, но при попытке чтения/записи массива стандартным для С способом получалась ошибка. Проблема была в Nios Data Cache. Когда он включен, адекватно работают только макросы IOWR/IORD. Если его вырубить, то можно использовать стандартные методы С, но если в этом нет необходимости, я тоже советую использовать макросы.
|
|
|
|
|
Jan 20 2015, 10:45
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Когда смотрел примеры, на сайте альтеры нашел файл где была программа с использованием указателей. натыкался на другие примеры там с использованием макросов было. Это меня и сбивало с толку, как я понял это два способа работы с одним и тем же
|
|
|
|
|
Jan 20 2015, 10:53
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 20 2015, 13:45)  Когда смотрел примеры, на сайте альтеры нашел файл где была программа с использованием указателей. натыкался на другие примеры там с использованием макросов было. Это меня и сбивало с толку, как я понял это два способа работы с одним и тем же Сомневаюсь, что Вы могли найти примеры от Alter-ы с использованием указателей для обращения к регистрам периферии, тут всё только через макросы (возможно какой-то очень "особенный" пример для ниоса без кэша, но очень маловероятно). Для работы с памятью (On-Chip, SDRAM, DDR и т.д.) указатели и используются.
|
|
|
|
|
Jan 20 2015, 11:00
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 20 2015, 13:53)  Сомневаюсь, что Вы могли найти примеры от Alter-ы с использованием указателей для обращения к регистрам периферии, тут всё только через макросы (возможно какой-то очень "особенный" пример для ниоса без кэша, но очень маловероятно). Для работы с памятью (On-Chip, SDRAM, DDR и т.д.) указатели и используются. вот код примера int to_hex(char* pkt) { int value[8]; int value1; int q; for (q=0; q <= 7; q++) { value[q] = (pkt[q] > 0x39) ? (pkt[q] - 0x37) : (pkt[q] - 0x30); if (q == 0) value1 = (0 + value[q]); else value1 = ((value[q-1] << 4) + value[q]); } return value1; } int main() { unsigned long *DDR_address; //long is 32 bits. int addr; int datar; int ddr_data_out; char packet[32]; DDR_address = (unsigned long *)0x2000000; //make non-cache iprintf("DDR test installed \n"); while (1) { gets(packet); switch(packet[0]) { case 'B': // write operation addr = to_hex(&packet[1]); datar = to_hex(&packet[9]); DDR_address[addr] = datar; iprintf("Written %08x to address %08x \n", datar, addr); break; case 'C': // Read operation addr = to_hex(&packet[1]); ddr_data_out = DDR_address[addr]; iprintf("Read %08x from address %08x \n", ddr_data_out, addr); break; default: iprintf("Error: Unexpected command. Switch was - %C \n",packet[0]); break; } } return 0; }
|
|
|
|
|
Jan 20 2015, 11:38
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 20 2015, 13:59)  Ну прекратите сбивать человека ну возьмите вы свои макросы и поглядите, все в конце сводиться к volatile записи ну или на худой конец к записи с вызовом слива кеша. Чудес то не бывает, макрос то тоже написан средствами языка С, просто иногда делает больше чем 1 действие.
У ксалинкса можно еще выбрать не кешируемое пространство, куда периферию пихаешь чтобы проблем не было, уверен у ниоса тоже должно что-то такое быть.
Так что все можно и ручками сделать, если по какой-то причине макросы вредят. А такое бывает если у вас запись в 10 портов под кешевой областью, то кешь сливать лучше не после каждой записи а сразу после всех. Ну или наоборот, нюансы бывают... Это Вы прекратите сбивать человека. Если я использую указатель для записи памяти/регистра, то я предполагаю, что после записи значения по данному указателю, необходимое значение попадает по нужному адресу и нет необходимости в выполнении ещё каких-то дополнительных действий. В случае регистров Ниоса этого не происходит, т.е. тут правильно исполтьзовать макросы для работы с регистрами. Макросы не вредят, они и присутствуют в BSP, чтобы их использовать. Код // 1 IOWR(BASE, DATA); Код // 2 unsigned int *base_ptr = (unsigned int *)BASE; *base_ptr = DATA; Первый код будет работать, а второй нет (BASE - адресс какого-либо регистра). Цитата(x66 @ Jan 20 2015, 14:00)  вот код примера Но это и есть использование указателя для обращения к памяти (тут всё ок), речь шла про настройку регистров. Например код для GPIO: Код // 1 unsigned int *gpio_data_ptr; unsigned int *gpio_direction_ptr; gpio_data_ptr = (unsigned int) GPIO_OUT_BASE; gpio_direction_ptr = (unsigned int) (GPIO_OUT_BASE + 1); *gpio_data_ptr = 1; *gpio_direction_ptr = 1; может не работать. А 100% рабочий вариант: Код // 2 IOWR_ALTERA_AVALON_PIO_DATA(GPIO_OUT_BASE, 1); IOWR_ALTERA_AVALON_PIO_DIRECTION(GPIO_OUT_BASE, 1); Подразумевалось что код и 1 и 2 должен выполнить одно и то же, на на деле - нет. Для других процов первый вариант кода будет работать - для Ниоса НЕТ!
|
|
|
|
|
Jan 20 2015, 11:51
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
ох... Цитата Первый код будет работать, а второй нет (BASE - адресс какого-либо регистра). а так? volatile unsigned int *base_ptr = (unsigned int *)BASE; *base_ptr = DATA;
|
|
|
|
|
Jan 20 2015, 12:01
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
раскройте вы макрос и поглядите что в нем, я не спорю что у всех может быть все по своему, но не думаю что альтера себе враг. вот ксалиновский макрос Код XGpio_WriteReg(BASE, XGPIO_DATA_OFFSET, Data); который на самом деле Код #define XGpio_WriteReg(BaseAddress, RegOffset, Data) \ XGpio_Out32((BaseAddress) + (RegOffset), (u32)(Data)) который на самом деле Код #define XGpio_Out32 Xil_Out32 который на самом деле Код #define Xil_Out32(Addr, Value) \ (*(volatile u32 *)((Addr)) = (Value)) то есть эта обычная запись по адресу, но с принудительным указанием того что он valotile Цитата И каким образом volatile тут будет влиять на то, чтоб запись данных шла мимо кэша? Знающие люди советовали другое. я и не утверждаю что valotile на это повлияет и я видел что пишут другие люди. Нету у меня среды альтеры, потому не могу макрос поглядеть, и прошу вас его показать. В ксалинксе периферия вешается в не кешируемую область памяти, неужели ниосы до этого не догадались? Так делают на всех процах. А так как я правды не знаю, то и прошу раскрыть макрос
|
|
|
|
|
Jan 20 2015, 12:24
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 20 2015, 14:58)  С Вашим примером всё понятно, но тут всё немного не так. Альтеровский макрос гарантирует, что запись идёт мимо кэша, т.е. помимо записи по указателю должно быть что-то ещё. Макрос максимум могу посмотреть до __builtin_stwio(void *, unsigned int), а это ни есть запись по указателю. Цитата(krux @ Jan 20 2015, 14:00)  http://www.altera.com/literature/hb/nios2/n2sw_nii52007.pdfдля данных есть такой метод как Bit-31 Cache Bypass для Nios II/f To Golikov A. вот это правильный документ, можете просмотреть, там есть описание того, что использование макросов из BSP позволяет обойти кэш о чём и шла речь. Т.е. это не равнозначно обращению к регистру через указатель.
|
|
|
|
|
Jan 20 2015, 12:28
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
ну пипец ваша альтера  .... этож надо было придумать отдельные инструкции записи мимо кеша. Так за этим еще следить надо чтобы кеш был всегда синхронен с памятью под ним... а вот явно указано Цитата Declaring a C pointer volatile does not make pointer accesses bypass the data cache. The volatile keyword merely prevents the compiler from optimizing out accesses using the pointer. This volatile behavior is different from the methodology for the first-generation Nios processor. что срали они на понятие изменяемый%) и просто оптимизацию отключают и рады)
|
|
|
|
|
Jan 20 2015, 13:12
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата т.е. вся дискуссия была для того, чтобы Вы сказали, что Альтера == дураки? смелое заявление я сказал пипец ваша альтера, дураки ли они не знаю... мне дисскусия была полезна, я теперь знаю что волатаил с альтерой не поможет и что у нее спец команды, и что перифирия в кеше (последние не 100% но косвенно так). А вам не знаю...
|
|
|
|
|
Jan 20 2015, 13:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 20 2015, 16:12)  я сказал пипец ваша альтера, дураки ли они не знаю...
мне дисскусия была полезна, я теперь знаю что волатаил с альтерой не поможет и что у нее спец команды, и что перифирия в кеше (последние не 100% но косвенно так).
А вам не знаю... Хороший подход. Не зная, как оно устроено, Вы утверждали обратное, советовали не вводить человека в заблуждение, потом сказали - "узнал много нового"
|
|
|
|
|
Jan 23 2015, 07:47
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Возник еще такой вопрос: во время переключения DDR2 с чтения на запись и наоборот имеются тайминги, и как их учесть программно, т.е. у меня есть постоянно приходящие данные, которые записываются в DDR2, в нужные моменты времени эти данные считываются из DDR2, и хочу узнать можно ли программно отследить данные в этот маленький момент времени между переключениями ОЗУ.
|
|
|
|
|
Jan 23 2015, 08:50
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 23 2015, 11:39)  Для программы Nios у Вас будет что-то типа memcpy() или цикл, "никаких маленьких моментов времени тут нет". Если хотите разгрузить процессор на время записи/чтения данных - используйте одно из ядер DMA/SgDMA/mSgDMA. я планировал на время чтения из DDR2 производить запись входных данных в on-chip memory. Как я понял программно отследить данные на время таймингов переключения не получится
|
|
|
|
|
Jan 23 2015, 09:02
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 23 2015, 11:54)  Смотрите в направленни описанных ядер, поможет одновременно читать/писать данные и использовать процессор. Проблема DDR2 памяти в том, что она работает либо на чтение либо на запись. Данные приходят постоянно, а чтение происходит по запросу пользователя, т.е. может быть и раз в минуту, час. Объем данных для чтения 1.2 Мбайт. Поэтому сразу если выводить данные, то накопятся входные данные, а их терять нельзя. Решил использовать два on-chip memory и по кусочкам выводить эти 1.2Мбайта данных. Может есть какой то другой способ реализации?
|
|
|
|
|
Jan 23 2015, 11:16
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 23 2015, 12:02)  Проблема DDR2 памяти в том, что она работает либо на чтение либо на запись. Данные приходят постоянно, а чтение происходит по запросу пользователя, т.е. может быть и раз в минуту, час. Объем данных для чтения 1.2 Мбайт. Поэтому сразу если выводить данные, то накопятся входные данные, а их терять нельзя. Решил использовать два on-chip memory и по кусочкам выводить эти 1.2Мбайта данных. Может есть какой то другой способ реализации? Тут ещё про шину avalon почитайте, если два устройства будут стучаться к DDR, она должна будет разрулить время доступа для каждого из устройств.
|
|
|
|
|
Jan 23 2015, 11:59
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Вам FIFO надо.
Данные поступают в FIFO а оттуда в DDR, через какой либо DMA контроллер.
Если данные нужны кому-то еще вы их читаете из ДДР, это приостанавливает DMA контроллер, и данные на время задержек падают в FIFO.
Ничего руками разруливать не надо, потому что проц не долбиться в шину постоянно (хотя может НИОС опять по чудному сделан, но надеюсь что нет). Вот и пока проц делает что-то еще, ДМА сам займет шину и успеет положить еще кусочек. Систему надо строить именно на таком принципе. Кстати ДДР контроллер разьве изначально не 2 портовый?
Вам надо перейти на следующий уровень абстракции, надо забыть про то какая у вас память, это забота контроллера, вы же не собираетесь еще сами следить за тем вовремя ли он подает ревреши, я надеюсь%)... Так же забота контроллера обеспечивать доступ к памяти по нескольким портам, во всяком случае у ксалинкс контроллер точно несколько портовый с арбитражем, наверяка у вас тоже, если это не так, то надо делать свой контроллер - арбитр, но не лезть к памяти напрямую, это дело контроллера памяти.
Обратите внимание что контроллер памяти ДДР - это не что-то собранное из вентилей ПЛИС, а отдельная область, готовый блок, слишком там все по таймингам не просто.
|
|
|
|
|
Jan 26 2015, 10:24
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 26 2015, 12:26)  В целом конечно я не прав. Цитата(Golikov A. @ Jan 26 2015, 12:26)  Все же вопрос частоты. Я как то не подумал что люди могут ставить DDR3 и работать с ним на 60 МГц... (условно все конечно) Для FPGA с которой сейчас работаю характеристики DDR3-контроллера на рисунке (или можете просмотреть cv_52006.pdf). Для FPGA Xiinx - поинтересуйтесь пожалуйста сами. Чтобы не получилось Цитата(Golikov A. @ Jan 20 2015, 15:28)  ну пипец ваша ...
Эскизы прикрепленных изображений
|
|
|
|
|
Jan 28 2015, 06:26
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(Golikov A. @ Jan 23 2015, 14:59)  Вам FIFO надо.
Данные поступают в FIFO а оттуда в DDR, через какой либо DMA контроллер.
Если данные нужны кому-то еще вы их читаете из ДДР, это приостанавливает DMA контроллер, и данные на время задержек падают в FIFO.
Ничего руками разруливать не надо, потому что проц не долбиться в шину постоянно (хотя может НИОС опять по чудному сделан, но надеюсь что нет). Вот и пока проц делает что-то еще, ДМА сам займет шину и успеет положить еще кусочек. Систему надо строить именно на таком принципе. Кстати ДДР контроллер разьве изначально не 2 портовый?
Вам надо перейти на следующий уровень абстракции, надо забыть про то какая у вас память, это забота контроллера, вы же не собираетесь еще сами следить за тем вовремя ли он подает ревреши, я надеюсь%)... Так же забота контроллера обеспечивать доступ к памяти по нескольким портам, во всяком случае у ксалинкс контроллер точно несколько портовый с арбитражем, наверяка у вас тоже, если это не так, то надо делать свой контроллер - арбитр, но не лезть к памяти напрямую, это дело контроллера памяти.
Обратите внимание что контроллер памяти ДДР - это не что-то собранное из вентилей ПЛИС, а отдельная область, готовый блок, слишком там все по таймингам не просто. ФИФО максимум как я понял на 8 кБайт. Требуется считать 1.2 МБайт памяти. Пока будет задержка на переключения ддр2 плюс чтение из ддр2 фифо будет переполнена. Поэтому придется по кусочкам производить чтение. On-chip memory можно сделать двухпортовым, а DDR2 насколько мне известно работает либо на чтение либо на запись.
|
|
|
|
|
Jan 28 2015, 07:08
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 09:59)  Что за данные собираетесь писать, какова скорость потока? На входе приходят данные с АЦП со скоростью 60 мегаслов в секунду (1 слово = 8 бит). На выходе считываются данные со скоростью 2 мегаслова в секунду. Скорости потоков разные плюс надо не потерять входные данные. Объем выводимых данных 1.2 мегабайта.
|
|
|
|
|
Jan 28 2015, 08:09
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 10:26)  А поясните, кто такие "вход" и "выход"? 8-бит АЦП с тактовой 60 МГц, а что такое 8-бит на 2МГц? Какое-то тут противоречие - нельзя писать данные 8*60 Mbit/s, а читать со скоростью 8*2 Mbit/s и не переполнить память? То что я пытаюсь сделать является маленьким блоком большого устройства. Входом условно назвал АЦП. Выходом назвал приемник (пользователь), т.е. устройство которое предоставляет пользователю наглядные данные (скорее всего экран). Приемник не постоянно считывает данные, а только по запросу (т.е. пришел человек к терминалу и нажал кнопку сказав: а выведи ка мне ты последние 1.2 МБайта данных которые пришли с АЦП). Между АЦП и Приемником нужно создать такой проект чтобы он связал их, т.к. у них разные скорости работы. Проблема возникает в том, что из-за разницы скоростей возникает момент, когда необходимо где то сохранить данные от АЦП во время чтения из ОЗУ этих 1.2 МБайта. На рисунке под плис подразумевается процессор NIOS II и другие устройства которые управляют DDR2 и данными.
Эскизы прикрепленных изображений
|
|
|
|
|
Jan 28 2015, 08:31
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(x66 @ Jan 28 2015, 11:09)  Из Ваших пояснений не понятно, каким образом получается скорость чтения 8*2 Мbit/s, есть только желание получить объём данных в 1,2 МБ? Чтение производится готовым блоком, что именно там я не знаю, но оно читает со скоростью 2 Мбайта/с и нужно выводить последние 1.2 МБайта данных
|
|
|
|
|
Jan 28 2015, 08:35
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 11:33)  Т.е. это кусок этой же ПЛИС, который имеет доступ к этой же памяти (DDR2). нет, там уже вроде другая плиска или МП
|
|
|
|
|
Jan 28 2015, 08:58
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 28 2015, 11:35)  нет, там уже вроде другая плиска или МП Что-то мне кажется, что сначала Вам нужно разобраться с чтение/записью DDR2, а там можно будет дальше строить систему. Пока вижу, данные пишутся в DDR с частотой 15 МГц при 32-х разрядной шине DDR2-контроллера (8bit*60MHz = 32bit*15MHz), а читаются из DDR2 с частотой 0.5 MHz (8bit*2MHz = 32bit*0.5MHz). Думаю, DDR2-контроллер потянет. У Вас критична только скорость записи (данные не хотите терять), вот и делайте её приоритетной, а читать будете в свободные от записи моменты (контроллер DDR2 тут сам всё разрулит). Ваш DDR2 контроллер при поступлении новых данных пишет их в память (на максимальной для него скорости), по запросу вычитываете данные. Прочитанные данные, чтобы согласовать скорость с внешним интерфейсом (2 МБ/с) складываете в фифо, а он пусть из него и читает.
|
|
|
|
|
Jan 28 2015, 08:59
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
БЛИН! Ну пипец эта ваша альтера - это так чтобы doom13'а позлить  .. Любую память можно сделать хоть милиард портовой уменьшив скорость записи-чтения. Берете контроллер памяти DDR присоединяете его к DDR. А выход этого контроллера присоединяете к блоку который делает вот что. 0 такт он читает или пишет из первого адреса 1 такт он читает или пишет из второго адреса и так по кругу. Получаете обычную 2 портовую память с равномерным распределением шины. Да вы теряете 50% пропускной способности памяти, но если память изначально может пропустить через себя в несколько раз больше чем вы в нее пихаете - то проблем нет. Именно так вашу систему и надо реализовать, поделите память между 2 потоками одни который в нее пишет, другой который из нее читает. Дальше идет оптимизация, можно писать - читать не по 1 слову, а по нескольку потому что память пишет быстрее чем выходит на режим, допустим делаете запись от 1 до 4 слов, на входе обоих каналов ставите FIFO в N слов, и ничего гарантированно не потеряется. Когда будет такт доступа очередного канала, он из фифо сольет от 1 до 4 слов, в зависимости от того сколько туда напихают. Можно раздать приоритеты, то есть 1 канал сливает всегда все фифо, сколько бы там ни было слов, а 2 канал сливает не больше К слов, а фифо на 1 канале сровняет паузы. Если же скорость записи ДДР меньше скорости поступления + чтения данных, то хоть убейтесь ничего не выйдет, даже на ксалинксе, не то что на альтере - ну это тоже чтобы дума позлить
|
|
|
|
|
Jan 28 2015, 09:03
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 11:58)  Что-то мне кажется, что сначала Вам нужно разобраться с чтение/записью DDR2, а там можно будет дальше строить систему. Пока вижу, данные пишутся в DDR с частотой 15 МГц при 32-х разрядной шине DDR2-контроллера (8bit*60MHz = 32bit*15MHz), а читаются из DDR2 с частотой 0.5 MHz (8bit*2MHz = 32bit*0.5MHz). Думаю, DDR2-контроллер потянет. У Вас критична только скорость записи (данные не хотите терять), вот и делайте её приоритетной, а читать будете в свободные от записи моменты (контроллер DDR2 тут сам всё разрулит). Ваш DDR2 контроллер при поступлении новых данных пишет их в память (на максимальной для него скорости), по запросу вычитываете данные. Прочитанные данные, чтобы согласовать скорость с внешним интерфейсом (2 МБ/с) складываете в фифо, а он пусть из него и читает. на картинке параметры DDR2.
Эскизы прикрепленных изображений
|
|
|
|
|
Jan 28 2015, 09:11
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 28 2015, 11:59)  БЛИН! Ну пипец эта ваша альтера - это так чтобы doom13'а позлить  .. Целых два дня и две ночи Вы не спали - думали, что ответить. Хотелось бы узнать, как там обстоят дела у Xilinx с DDR на логике и железе? Может быть за столь долгий час Вы произвели сравнительный анализ девайсов от обсуждаемых производителей?
|
|
|
|
|
Jan 28 2015, 09:13
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 11:58)  Уточнил кое какую деталь: пользователь нажимает 1 кнопку, тем самым просит зафиксировать 1.2 МБайта данных в DDR2. Нажимает 2 кнопку, просит эти данные считать. Следовательно DDR2 надо разделить на 2 области, т.е. циклически пишем в первую половину, как сработала кнопка 1, сохраняем все данные и пишем во 2 половину памяти DDR2.
|
|
|
|
|
Jan 28 2015, 10:32
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 28 2015, 11:59)  Берете контроллер памяти DDR присоединяете его к DDR. А выход этого контроллера присоединяете к блоку который делает вот что. В Qsys-систему его добавляете и на Avalon-MM вешаете, даёте доступ к контроллеру памяти Nios II, DMA-контроллерам (при необходимости). Пробуете писать/читать данные либо Ниосом либо DMA, должно всё получиться. Цитата(x66 @ Jan 28 2015, 12:13)  Уточнил кое какую деталь: пользователь нажимает 1 кнопку, тем самым просит зафиксировать 1.2 МБайта данных в DDR2. Нажимает 2 кнопку, просит эти данные считать. Следовательно DDR2 надо разделить на 2 области, т.е. циклически пишем в первую половину, как сработала кнопка 1, сохраняем все данные и пишем во 2 половину памяти DDR2. Пробуйте DDR2-контроллер запустить и на максимальной скорости. Цитата(Golikov A. @ Jan 28 2015, 11:59)  Если же скорость записи ДДР меньше скорости поступления + чтения данных, то хоть убейтесь ничего не выйдет, даже на ксалинксе и даже с хардовым контроллером
|
|
|
|
|
Jan 28 2015, 10:37
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 13:17)  В Qsys-систему его добавляете и на Avalon-MM вешаете, даёте доступ к контроллеру памяти Nios II, DMA-контроллерам (при необходимости). Пробуете писать/читать данные либо Ниосом либо DMA, должно всё получиться.
Пробуйте DDR2-контроллер запустить и на максимальной скорости. А что если взять два on-chip memory. Сначала закидываем от АЦП в один on-chip memory, а потом скидываем в DDR2, при этом записывая во второй on-chip memory, и так меняя их
|
|
|
|
|
Jan 28 2015, 10:45
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Уточнил кое какую деталь: пользователь нажимает 1 кнопку, тем самым просит зафиксировать 1.2 МБайта данных в DDR2. Нажимает 2 кнопку, просит эти данные считать. Следовательно DDR2 надо разделить на 2 области, т.е. циклически пишем в первую половину, как сработала кнопка 1, сохраняем все данные и пишем во 2 половину памяти DDR2. У вас процессор еще хоть что-то делает или только данные из памяти в память перекидывает? Просто если так, то все эти коллизии можно решить программно в проце. Вам надо FIFO для входных данных, и пусть процессор его постоянно мониторит, если есть данные складывает их в циклический буфер в DDR. При это просто размещаете буффер в ДДР области памяти и даже не думаете как оно там происходит. По запросу пользователя, переключаете буфер, и начинаете маленькими порциями выдавать данные пользователю из 1 буфера. Так чтобы на выдачу данных тратилось времени не больше чем на заполнения половины буфера входными данными. Таким образом арбитраж у вас сделает процессор, данные не потеряются из - за фифо, доступ к памяти организует контроллер. Мне кажется вы усложняете задачу ФИФО как раз строиться на блочной памяти, только с ним работать удобнее, не надо писать алгоритм циклического буфера, Просто пишите с одного конца и читаете с другого, а порядок следования данных реализуется сам собой кстати никто не мешает каскадировать ФИФО, выход одного подавать на вход другого, и тема самым увеличивать длину, правда там надо маленький автоматик сделать который данные будет прокидывать и учитывать задержку появления данных на число блоков фифо.
|
|
|
|
|
Jan 28 2015, 10:47
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 28 2015, 13:35)  Про контроллеры памяти на ПЛИС вентилях я уже сказал выше, видать надо разжевать. Спартан 6, -2 грейда скорости боле менее сложный блок тянет на частоте около 100 МГц, хорошая ли это частота для DDR3 памяти? По мне так не особо, C железным блоком спартан 6 тянет DDR до 400 МГц это и ответ... Все вопрос частоты. Я приводил характеристики DDR3-контроллера для Altera Cyclone 5, там чётко видна разница между железным блоком и блоком на логике (400 МГц и 300 МГц соответственно, думаю, это не смертельно, во многих задачах оно себя оправдает). О каких 60 МГц говорили Вы - Вам виднее.
|
|
|
|
|
Jan 28 2015, 10:53
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(Golikov A. @ Jan 28 2015, 13:45)  У вас процессор еще хоть что-то делает или только данные из памяти в память перекидывает? Просто если так, то все эти коллизии можно решить программно в проце. Вам надо FIFO для входных данных, и пусть процессор его постоянно мониторит, если есть данные складывает их в циклический буфер в DDR. При это просто размещаете буффер в ДДР области памяти и даже не думаете как оно там происходит.
По запросу пользователя, переключаете буфер, и начинаете маленькими порциями выдавать данные пользователю из 1 буфера. Так чтобы на выдачу данных тратилось времени не больше чем на заполнения половины буфера входными данными.
Таким образом арбитраж у вас сделает процессор, данные не потеряются из - за фифо, доступ к памяти организует контроллер. Мне кажется вы усложняете задачу
ФИФО как раз строиться на блочной памяти, только с ним работать удобнее, не надо писать алгоритм циклического буфера, Просто пишите с одного конца и читаете с другого, а порядок следования данных реализуется сам собой
кстати никто не мешает каскадировать ФИФО, выход одного подавать на вход другого, и тема самым увеличивать длину, правда там надо маленький автоматик сделать который данные будет прокидывать и учитывать задержку появления данных на число блоков фифо. Я программно начал делать так: задал min и max адреса в DDR, для каждой половины. Проверяю условия от пользователя провожу запись в блоки. Когда приходит сигнал от пользователя фиксирую конечный адрес и вычитаю до адреса начала этих 1.2МБ, при этом переключаюсь на вторую половину DDR. А вот при чтении из DDR я планировал данные от АЦП передавать на on-chip memory, и выводить данные пользователю (пока ориентировался примерно на 4кбайт), затем скидывать с on-chip memory в DDR то что накопилось.
|
|
|
|
|
Jan 28 2015, 10:54
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 28 2015, 13:37)  А что если взять два on-chip memory. Сначала закидываем от АЦП в один on-chip memory, а потом скидываем в DDR2, при этом записывая во второй on-chip memory, и так меняя их Вы можете так сделать, использовать RAM либо FIFO (это на ваш выбор), данные в DDR2 перекладывать/считывать Ниосом, но лучше разобраться с DMA (SgDMA/mSgDMA). UP Ниос работает на 100MHz?
|
|
|
|
|
Jan 28 2015, 11:05
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 13:54)  Вы можете так сделать, использовать RAM либо FIFO (это на ваш выбор), данные в DDR2 перекладывать/считывать Ниосом, но лучше разобраться с DMA (SgDMA/mSgDMA). Можете посоветовать литературу по DMA, где толково расписано. Цитата(doom13 @ Jan 28 2015, 13:54)  Вы можете так сделать, использовать RAM либо FIFO (это на ваш выбор), данные в DDR2 перекладывать/считывать Ниосом, но лучше разобраться с DMA (SgDMA/mSgDMA).
UP Ниос работает на 100MHz? Да, на 100
|
|
|
|
|
Jan 28 2015, 11:12
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата О каких 60 МГц говорили Вы - Вам виднее. О сферических в вакууме, естественно Цитата но лучше разобраться с DMA (SgDMA/mSgDMA). ДМА имеет смысл если ядро чем то еще полезным нагружено, в данном же случае, я так понимаю вся нагрузка на ядро проца - это тосовка данных. Более того подозреваю что ядро проца появилось как раз из-за необходимости доступа к ДДР, через имеющийся в ядре интерфейс. В таком раскладе ДМА - лишнее усложнение и нестабильность В атаче если будет интересно программное фифо, вам надо создать 2 буфера длинной в 1.2 мегобайта, и набивать один из входящего потока, как получите сигнал выдать данные, переходите на другой буффер, а первый отдаете пользователю. какой смысл хранить данных больше чем у вас могут попросить? использовать буферы так Код uint8_t DataBuf1[1.2*1024*1024+2]; //буфер для хранения его надо в ДДР пихануть uint8_t DataBuf2[1.2*1024*1024+2]; //буфер для хранения его надо в ДДР пихануть FIFOStr Buffer1; FIFOStr Buffer2;
InitFIFOStr(Buffer1,DataBuf1, sizeof(DataBuf1)); InitFIFOStr(Buffer2,DataBuf2, sizeof(DataBuf2)); дальше пихаете туда данные через AddFIFOData и забираете через GetFIFOData, буфер чиститься сам при забирании данных, но можно и вызвать функцию очистки вам надо только поправить функцию добавления данных, потому что она не дает перезаписывать буфер, возвращая код ошибки при переполнении. А также надо понять что делать если данные запросили, но их в буфере меньше 1.2 МБ, может вам вообще надо сделать 1 буфер, и выдавать всегда его целиком, а писать его по кругу...
Прикрепленные файлы
Code.zip ( 2.04 килобайт )
Кол-во скачиваний: 9
|
|
|
|
|
Jan 28 2015, 11:34
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(Golikov A. @ Jan 28 2015, 14:12)  В атаче если будет интересно программное фифо, вам надо создать 2 буфера длинной в 1.2 мегобайта, и набивать один из входящего потока, как получите сигнал выдать данные, переходите на другой буффер, а первый отдаете пользователю. какой смысл хранить данных больше чем у вас могут попросить? использовать буферы так Код uint8_t DataBuf1[1.2*1024*1024+2]; //буфер для хранения его надо в ДДР пихануть uint8_t DataBuf2[1.2*1024*1024+2]; //буфер для хранения его надо в ДДР пихануть FIFOStr Buffer1; FIFOStr Buffer2;
InitFIFOStr(Buffer1,DataBuf1, sizeof(DataBuf1)); InitFIFOStr(Buffer2,DataBuf2, sizeof(DataBuf2)); Не совсем понял кое что: буффер создается в DDR2 или где? Если в самой плиске, то не совсем понятно, как такого объема создать.
|
|
|
|
|
Jan 28 2015, 11:48
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 28 2015, 14:12)  О сферических в вакууме, естественно  Цитата(Golikov A. @ Jan 28 2015, 11:59)  Ну пипец эта ваша альтера - это так чтобы doom13'а позлить  .. то хоть убейтесь ничего не выйдет, даже на ксалинксе, не то что на альтере - ну это тоже чтобы дума позлить  Цитата(Golikov A. @ Jan 26 2015, 12:26)  В целом конечно я не прав. Все же вопрос частоты. Я как то не подумал что люди могут ставить DDR3 и работать с ним на 60 МГц... (условно все конечно) Цитата(Golikov A. @ Jan 24 2015, 00:48)  смело... Цитата(Golikov A. @ Jan 23 2015, 20:44)  Чего то мне говорит что начиная с ддр2, уже не может, но могу и ошибаться... Цитата(Golikov A. @ Jan 20 2015, 15:28)  ну пипец ваша альтера  .... этож надо было придумать отдельные инструкции записи мимо кеша. Так за этим еще следить надо чтобы кеш был всегда синхронен с памятью под ним... а вот явно указано что срали они на понятие изменяемый%) и просто оптимизацию отключают и рады) Думаю, скоро можно будет менять Ваш статус на "БОЛТУН"
|
|
|
|
|
Jan 28 2015, 11:50
|
Знающий
   
Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515

|
Цитата(Golikov A. @ Jan 28 2015, 14:12)  В атаче если будет интересно программное фифо, вам надо создать 2 буфера длинной в 1.2 мегобайта, и набивать один из входящего потока, как получите сигнал выдать данные, переходите на другой буффер, а первый отдаете пользователю.
какой смысл хранить данных больше чем у вас могут попросить? Осталось только разобраться, как бы ухитриться набивать из входящего потока 60М при частоте процессора 100М и ничего не потерять  . Хотя, если со стороны АЦП поставить упаковщик и аппаратное ФИФО, то, наверное, успеет. А так SgDMA воткнул и всё путём. Правда, надо ещё научиться правильно его сконфигурировать и запрограммировать. Данные могут попросить не самые последние, а какие-нибудь старые, например, такая возможность есть в правильных цифровых осциллографах.
|
|
|
|
|
Jan 28 2015, 12:02
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Timmy @ Jan 28 2015, 14:50)  Осталось только разобраться, как бы ухитриться набивать из входящего потока 60М при частоте процессора 100М и ничего не потерять  . Хотя, если со стороны АЦП поставить упаковщик и аппаратное ФИФО, то, наверное, успеет. А так SgDMA воткнул и всё путём. Правда, надо ещё научиться правильно его сконфигурировать и запрограммировать. Данные могут попросить не самые последние, а какие-нибудь старые, например, такая возможность есть в правильных цифровых осциллографах. Там - 8bit*60M, а шина проца - 32bit*100M, получим - 32bit*15M. Цитата(Timmy @ Jan 28 2015, 14:50)  А так SgDMA воткнул и всё путём. Правда, надо ещё научиться правильно его сконфигурировать и запрограммировать. Лучше тогда mSgDMA, оно новее будет, а в управлении им всё просто. Цитата(x66 @ Jan 28 2015, 14:34)  Не совсем понял кое что: буффер создается в DDR2 или где? Если в самой плиске, то не совсем понятно, как такого объема создать. В DDR2, а она - память Ниоса (Qsys-системы).
|
|
|
|
|
Jan 28 2015, 12:38
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 15:30)  Это видно из рисунка приведённого выше. Проект делается на основе отладочной платы DB4CGX15 Cyclone IV PCIexpress Development Board. Такие параметры взяты из примера для этой платы
|
|
|
|
|
Jan 28 2015, 13:02
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(Golikov A. @ Jan 28 2015, 15:39)  200 МГц Я ошибаюсь или пропускная способность такой памяти порядка 3.2 МБайта в секунду по одному каналу? И даже если там будет 4 чипа, то 15 МБайт не достичь? Как вы получили это значение? Не 3200 МБ/с?
Сообщение отредактировал x66 - Jan 28 2015, 13:16
|
|
|
|
|
Jan 28 2015, 13:22
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 28 2015, 16:02)  Цитата(Golikov A. @ Jan 28 2015, 15:39)  200 МГц Я ошибаюсь или пропускная способность такой памяти порядка 3.2 МБайта в секунду по одному каналу? И даже если там будет 4 чипа, то 15 МБайт не достичь?
Как вы получили это значение? Не 3200 МБ/с? Вот и я думаю, что товарищ ткнул пальцем в небо. Для Вашего случая максимальная скорость записи/чтения данных будет: 8 (ширина шины) * 200 MHz(частота тактирования памяти) * 2 (память DDR2 - работает по двум фронтам) = 3200 Mbit/s = 400 MB/s
|
|
|
|
|
Jan 28 2015, 13:44
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 15:02)  В DDR2, а она - память Ниоса (Qsys-системы). Не совсем понятно как делается
Сообщение отредактировал x66 - Jan 28 2015, 13:54
|
|
|
|
|
Jan 28 2015, 14:02
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(Golikov A. @ Jan 28 2015, 16:54)  нет. Надо просто линкеру указать что у него есть такая память. Ну я все элементы добавил и указал адреса. Сделал несколько проектов в кусис. Кстати, можно ли как-то внося изменения в кусисе применять их и в ниос2 эклипсе не создавая заново проект. А то не удобно каждый раз заново создавать проект
|
|
|
|
|
Jan 28 2015, 14:22
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 28 2015, 17:14)  Этого и не надо делать (заново создавать). Правой кнопкой на project_name_bsp->Nios II->Generate BSP/BSP Editor (если хотите настройки генерации BSP менять). А если я в кусисе переименовал проект, то как можно сделать?
|
|
|
|
|
Jan 28 2015, 14:34
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 28 2015, 16:39)  а... 3.2 Гигабита... Тут я просто обязан был спросить: Вы ошибались, да? Цитата(x66 @ Jan 28 2015, 17:22)  А если я в кусисе переименовал проект, то как можно сделать? Тогда есть варианты, но я бы сделал так: progect_name_bsp->BSP Editor->вылазит окно Nios II BSP Editor Далее в окне Nios II BSP Editor: File->New BSP->Выбираете нужный (новый) SOPC Information File Name->снимаете галку Use default locations->Задаёте название progect_name_bsp->Generate В эклипсе все названия сохранятся, а ссылаться будет на новое железо.
|
|
|
|
|
Jan 28 2015, 14:52
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 28 2015, 17:34)  Если вам будет приятно потешить местечковое самолюбие вы разработчик конечно гораздо лучше чем я. Не собирался тут с Вами ничем меряться, всего лишь указал на Ваше свойство уверенно давать ответы на вопросы в которых Вы некомпетентны. Извините, если это задело Вас. Далее был просто стёб, жаль, что Вы не заценили Цитата(Golikov A. @ Jan 28 2015, 17:34)  Одна идея что DMA контроллер, который работает через туже шину что проц и делит с ним эту шину, будет работать быстрее чем проц отдельного уже говорит о многом. Я не говорил, что это будет быстрее (если читать/писать данные в одну и ту же память), а говорил, что это разгрузит проц и он сможет делать что-то там ещё во время пока DMA переливает данные.
|
|
|
|
|
Jan 28 2015, 15:42
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Из полезного вот что надо сделать надо ниосом в память записать кусок данных считать кусок данных и записать - считать кусок данных попеременно (то есть 4 байта записали, затем 4 байта считали). Этот режим лучше попробовать в нескольких вариантах (16 байт записали, 4 считали, 32 байта записали, 4 считали). Писать и читать надо из разных адресов. Данные для записи надо брать из какой-то valotile переменной. А лучше из внешней периферии потому что надо еще через кеш альтеры пробиться, то есть чтобы компилятор поставил правильные команды.
Для всего этого померить время выполнения, чтобы определить реальную пропускную способность.
при скорости 15 МСлов в секунду и проце 100 МГц, у вас на каждую операцию есть 6 тактов, что-то мне говорит что проц не успеет. Кстати сколько микросхем памяти у проца? то есть реально какой длинны слово оно может записать за такт?
П.С. фраза "что-то мне говорит" означает что я не уверен, но мне так кажется
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|