Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Nios II /e vs Nios II /f (проект Ethernet)
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
billidean
Добрый день всем.
На демоплате BeMicro (Cyclone IV E) делаю проект работы с Ethernet (UDP).
При использовании проца Nios II /f все нормально работает. Но для этого проца нужна лицензия (которой у меня нет crying.gif ).
Попробовал перейти в этом же проекте на Nios II /e, при отправке (из платы) пакетов расчитывается кривая CRC для UDP-заголовка. Для самого тела UDP-пакета можно ставить CRC=0, что я и делаю, а вот для заголовка нужна корректная CRC, иначе прога на ПК вообще не принимает пакет.
Код расчета CRC:
Код
unsigned short checksum(void *b, int len)
{
    unsigned short *buf = b, result;
    unsigned int sum=0;
    for ( sum = 0; len > 1; len -= 2 ) /* Sum all 16b words */
    {
//        printf("*buf = 0x%x\n", *buf);
        sum += *buf++;
    }
    if ( len == 1 )
    /* If any stray bytes, */
    sum += *(unsigned char*)buf;
    /* add to sum */
    sum = (sum >> 16) + (sum & 0xFFFF);
    /* Add the carry */
    sum += (sum >> 16);
    /* (again) */
    result = ~sum;
    /* Take the one's complement */
    return result;
    /* Return 16b value */
}


В чем может быть секрет?? Кэшей никаких не использую, поэтому переход на Экономный проц должен вроде пройти без проблем, кроме замедления работы.
Kuzmi4
2 billidean
Листинг смотрели ? В IDE отладчике сравнивали результаты на выходе для одинаковых пакетов?
billidean
Отладчиком еще не проходился.
Но уже дошел до такого решения. Вечером буду пошагово сравнивать расчет этой CRC для обоих процов.
billidean
Дело получилось не таким простым, как показалось мне сначала.
При отладке двух вариантов Nios/e и Nios/f получилось, что сама функция unsigned short checksum(void *b, int len) проводит все операции правильно, а вот данные по адресам void *b получились кривые в случае Nios/e. Формирование этих данных довольно сложное, и поиски "кривых концов" мне не очень улыбаются, поэтому я пока забил на этот вопрос (Но осадок остался).

З.Ы.: Может у кого есть уже наработанное решение (аля "универсальное") подобной проблемы перехода с Fast на Econom Nios ??
Kuzmi4
считать в плисе ?
vadimuzzz
Цитата(billidean @ Mar 11 2014, 20:52) *
При отладке двух вариантов Nios/e и Nios/f получилось, что сама функция unsigned short checksum(void *b, int len) проводит все операции правильно, а вот данные по адресам void *b получились кривые в случае Nios/e.

фокусы с кэшем?
billidean
Цитата
считать в плисе ?
Вы имеете в виду вынести формирование пакета за пределы НИОСа во внешний модуль ПЛИС, который наберет все нужные данные из НИОСа и сформирует отправной пакет? Это конечно интересно, и не будет зависеть от НИОСа и его типа, НО большая проблема в том, что кристалл забит почти на 90%. Проект компилится несколько часов с несколькими заходами в фиттеровщик.

В настройках НИОСа кэш данных отключен, с ним даже Фаст проц чота глючил при формировании пакетов.

Могу выложить исходники проекта НИОСа, если будет желание в нем покопаться.
Serhiy_UA
Попробуйте создать тестовые примеры, максимально все упростив. Вычисляйте Ниосом только контрольную сумму для одного и того же массива по каждому из вариантов и сравнивайте между собой. Таким способом будет легче найти причину, если причина в этой сумме...
У меня контрольная сумма для UDP вычислялась аппаратно в двух потоках (когда один поток через Ниос передавался, другой аппаратно обсчитывался, и наоборот), что было связано с требованием высокого быстродействия.
billidean
Цитата
Вычисляйте Ниосом только контрольную сумму для одного и того же массива по каждому из вариантов и сравнивайте между собой.
В этом то и загвоздка получилась, работа функции расчета CRC корректная, а вот данные для расчета получились неверные при Эконом. процессоре.
Очень затрудняет процесс отладки то, что при использовании Эконом. НИОСа нельзя ставить брейкпойнты, и приходится через printf() все контролировать, а это та еще песня. При выдачи больших объемов вывод ч/з LTAG может зависнуть (несколько раз на такое натыкался) в то время как программа уже ускокала далеко вперед.
Kuzmi4
2 billidean
Как это нельзя ставить брейкпойнты? Кто вам это сказал ?
Всё можно, только там SW-breakpoint, но в вашем случае это не сыграет какой то важной роли.
billidean
Вроде я такое же читал, что при Эконом.НИОС будут софтовые точки останова. Но когда скомпилил проект к квартусе, затем открыл проект в еклипсе, то сколько бы я не тыкал мышью в разных местах, точки останова не ставились. Может просто глюк был, седня попробую еще раз.
Kuzmi4
2 billidean
У меня в проектах обычно Nios2-e, патроны подавать много мозгов не надо, так отладка всегда работает без вопросов (Q2 v9.0sp2 / Q2 v13.0sp1). Даже когда собираю скриптами, потом импортирую проект в эклипс и в уже импортированном выбираю папки/сорцы и в сорцах ставлю точки останова.

Если не получится выставить брейкпойнты, тогда выкладывайте здесь обрезанный вариант - интересно будет глянуть.
Копейкин
Если код был "оптимизирован", то там точку останова поставить не даст.
Уровень оптимизации одинаков в обоих случаях? И какой?
billidean
настройки BSP в части оптимизации были по умолчанию (о0) в обоих случаях.
Исходники не менял при переходе между процами.
Вечером еще раз попробую погонять, может что прояснится.
billidean
Вобщем все вроде заработало.
Дело было в указании адреса на элемент массива подготовленных данных (пакета), начиная с которого необходимо расчитывать контрольную сумму для IP-заголовка. Этот адрес был сдвинут на один байт правее. Но почему в Фаст.НИОСе при этом производился правильный расчет CRC - это пока загадка.
Golikov A.
потому что фаст наверняка 32 битный, и при сдвиге на 1 - 2 - 3 байта все равно попадает в 0 байт. А этот почему то честно отработал...
billidean
Я тоже так подумал, но вот искать истину пока некогда. Хотя всегда считал, что вне зависимости от типа проца. он всегда 32-хбитный. Надо почитать описание поточнее.
billidean
Посмотрел доку "Implementation Details" на НИОС (n2cpu_nii51015.pdf), не нашел про изменение работы с памятью (32-хбитное обращение или 8-мибитное) для разных версий проца.
Kuzmi4
2 billidean
вставьте в С-код выравнивание, откоментируйте это и забудьте wink.gif
Golikov A.
а шина везде одна и таже?
Потом в дорогом проце считался могла быть железная, а передача 32 битными словами, а в дешевом считалка программная и доступ 8 битный.
В ксалинксе так, дешевый мак считает суммы алгоритмически, а дорогой железом.
alexadmin
Цитата(Golikov A. @ Mar 13 2014, 11:21) *
а шина везде одна и таже?
Потом в дорогом проце считался могла быть железная, а передача 32 битными словами, а в дешевом считалка программная и доступ 8 битный.


Нет, базовая архитектура всех ниосов одинакова.
billidean
Вот моя структура пакета в .h-файле
Код
typedef struct UDP_str
{
    char macDst[6];
    char macSrc[6];
    char type[2];
    char ver_lenIP;
    char all00;
    char len_28plus[2];
    char id_pack[2];
    char fl_4000[2];
    char time_l_80;
    char type_UDP_11;
    char crc16_IPhead[2];
    char ipSrc[4];
    char ipDst[4];
    char portSrc[2];
    char portDst[2];
    char lenUDP_8plus[2];
    char crc16_UDP[2];
    // до этого ... длина равна 42 байта
    char data[UDP_DATA_MAX_SIZE];
} __attribute__((__packed__)) UDP_str;

Вот код в .c-файле
Код
volatile UDP_str udp_send_s __attribute__ ((aligned (1)));
volatile UDP_str udp_take_s __attribute__ ((aligned (1)));

После этого я считаю, что обе структуры выровнено по-байтово и без "дырок" между полями.
Расчет CRC для IP-заголовка должен начинаться с поля ver_lenIP, и просчитывать 20 байт, а я указал (ошибочно), чтобы начинался расчет с поля all00, т.е. сдвинул на один байт вправо. При этом НИОС/Фаст все нормально расчитывал, а вот НИОС/Эконом выдавал кривую CRC, из-за чего я и обнаружил свой косяк в указании начального адреса расчета CRC.
Поэтому и началось обсуждение типов НИОСов и их обращение к памяти.
Golikov A.
тогда битность шины не причем, был бы сдвиг в плюс это можно было бы обосновать выравниванием. А сдвиг в минус, никак не объясним...
billidean
Если шина 32-хбитная, и мы указываем на 2-ой или 3-тий байт ячейки, то эта ячейка будет задействована полностью, начиная с 1-го байта, т.о. будем иметь сдвиг по адресу влево, в сторону уменьшения.
Если посмотреть на шину Авалон, то эта ситуация очень видна, НО в этой шине все (имею в виду побайтовое обращение) разруливается доп.сигналами byteenable.
Serhiy_UA
Цитата(billidean @ Mar 13 2014, 11:29) *
Вот моя структура пакета в .h-файле

У меня структура UDP-пакетов несколько схожая, но отличается служебными словами PACKED, у них тоже была своя роль...
//------------------- UDPFRAME
typedef struct udphdr { //8 bytes
u_short uh_sport PACKED; /*!< \brief Source port */
u_short uh_dport PACKED; /*!< \brief Destination port */
u_short uh_ulen PACKED; /*!< \brief UDP length */
u_short uh_sum PACKED; /*!< \brief UDP checksum */
} UDPHDR;

struct UDPFRAME {
ETHERHDR eth_hdr PACKED; //14 bytes
IPHDR ip_hdr PACKED; //20 bytes
UDPHDR udp_hdr PACKED; // 8 bytes
u_char md[1472] PACKED; // + (22..1476) bytes
};
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.