Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Microblaze, виснет при работы со SRAM
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
AVR
Имеется Microblaze из состава ISE 14.4.
К процессору подключена асинхронная SRAM 512 Кбайт, интерфейс - 8ми битный.

Когда я делаю test_sram_8bit - всё отлично. Когда попытка обратиться к 16-ти битам - сразу повисает и код разумеется тем более не работает.

В чем может быть хотя бы отдаленно проблема? Пробовал и с кэшами и без кэш-памяти - результат один: память вроде и работает, а по сути нет.

Память 10 нс (100 МГц), процессор тоже на этой частоте, шина AXI - тоже. Смотрю даташит - вроде контроллер целиком на логике, а значит реально частота еще меньше, ибо делится там у себя на циклы. Не должно быть такой проблемы.

Попробовал добавить xil_printf между записью и чтением - стало работать. Значит надо тайминги корректировать, ибо исполнение кода нужно...

Код
#include <stdio.h>
#include "xparameters.h"

void test_sram_8bit(int off)
{
    int max = 0;
    unsigned char *p = (unsigned char*) XPAR_AXI_EMC_0_S_AXI_MEM0_BASEADDR;
    for(int i = 0; i < 10E9; i++)
    {
//        xil_printf("8bit = %d\n\r", i);
        unsigned int v = (i + off) % 0xFF;
        p[i] = v;
        if(v != p[i])
        {
            max = i;
            break;
        }
    }
    xil_printf("SRAM %d Kbytes (%d bytes)\n\r", max / 1024, max);
}

void test_sram_16bit(int off)
{
    int max = 0;
    unsigned short *p = (unsigned short*) XPAR_AXI_EMC_0_S_AXI_MEM0_BASEADDR;
    for(int i = 0; i < 10E9; i++)
    {
        xil_printf("16bit= %d\n\r", i);
        unsigned short v = (i + off) % 0xFFFF;
        p[i] = v;
        if(v != p[i])
        {
            max = i;
            break;
        }
    }
    xil_printf("SRAM %d Kbytes (%d bytes)\n\r", max / 512, max * 2);
}

int main()
{
    int test = 0;
    while(true)
    {
        xil_printf("test %d\n\r", test++);
        test_sram_8bit(test);
        test_sram_16bit(test);
    }
    return 0;
}


Результат работы (вываливается в последовательный порт, вот что вижу):
Код
test 0
SRAM 512 Kbytes (524288 bytes)
16bit= 0


Тут видно что первый тест с 8-ми битным доступом проходит отлично, а 16-битным виснет намертво при первой же попытке. Соответственно я не могу исполнять свой код из SRAM - виснет на первой же инструкции.

З.Ы.
При подключении DDR2 как внешней памяти - всё было отлично, а ведь это сложнее...
Golikov A.
Нашел темуsm.gif

вас не смущает что в 16 битах и в 8 у вас одинаковое количество записей?
for(int i = 0; i < 10E9; i++)

вы просто за область памяти улетает и естественно за областью запись и чтение не срабатывает. Более того вы можете влететь в область памяти программы, и испортить ее, там самым вызывать зависание, разве нет?
AVR
Цитата(Golikov A. @ Jun 12 2013, 11:31) *
Нашел темуsm.gif

вас не смущает что в 16 битах и в 8 у вас одинаковое количество записей?
for(int i = 0; i < 10E9; i++)

вы просто за область памяти улетает и естественно за областью запись и чтение не срабатывает. Более того вы можете влететь в область памяти программы, и испортить ее, там самым вызывать зависание, разве нет?

Это не ошибка - я пробегаю все адреса которые сохраняют значение. Процессор не зависает при обращении к памяти вне пределов, а виснет именно что при обращении сразу к 16 или 32 битам, причем на первом же обращении.

Я переделал систему с AXI на старое PLB - всё работает идеально - этот же код, те же параметры контроллера памяти, причем и все обращения работают и код/данные из SRAM исполняется. НИКТО не может мне помочь даже на форумах Xilinx.
Golikov A.
чего то я все таки не понимаю
for(int i = 0; i < 10E9; i++)

если идти чарами пройдет 10 в 9 адресов
а если интами_16, то пройдете 2*10 в 9

потом шина акси более хитрая чем ПЛБ, может чего то добавилось что такое не прощает? Чтение понятно не должно вызывать проблем, а вот запись вполне может. Потом может требуется какое то выравнивание? а вы в симуляторе не пробовали запускать, да поглядеть где виснет?
AVR
Цитата(Golikov A. @ Jun 13 2013, 00:36) *
чего то я все таки не понимаю
for(int i = 0; i < 10E9; i++)

если идти чарами пройдет 10 в 9 адресов
а если интами_16, то пройдете 2*10 в 9

потом шина акси более хитрая чем ПЛБ, может чего то добавилось что такое не прощает? Чтение понятно не должно вызывать проблем, а вот запись вполне может. Потом может требуется какое то выравнивание? а вы в симуляторе не пробовали запускать, да поглядеть где виснет?

А как при помощи симулятора понять где виснет именно процессор?

Да я уже всё пробовал, и for(int i = 0; i < 256; i++) и другое. Проблема сложнее чем кажется.

Пока что я решил переходом на PLB, но всё равно хочу знать причину. (а с DDR2 не было проблем)

Выравнивание - мысль хорошая, если бы на 8 битном доступе висло а на 32 работало - я бы так и подумал в первую очередь...
Golikov A.
Вот только что до меня дошло. Что дело не в СРАМе.

У меня тоже виснет или ресетиться микроблайз. Причем я не могу понять причин, один и тот же код, то работает, то не работает. Иногда один и тот же вечером не работает, а с утра работает.

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

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

Если кто скажет как можно понять что происходит, будет здорово.
Corvus
Цитата(Golikov A. @ Jun 25 2013, 14:09) *
Если кто скажет как можно понять что происходит, будет здорово.


Вот зависаний у меня никогда не было. Только программные.
А вот всё остальное - нормальная ситуация. Списываю это на глюки SDK и кривого режима дебага. Это нормально для Xilinx. wink.gif Где-то не скомпилилось после изменения. Рекомендую перед каждой компиляцией делать очистку проекта, а перед запуском дебага переконфигурировать ПЛИС. Несколько снижает процент багов.

Например, есть известная проблема - после ресета инициализация lwip проходит с ошибкой
http://forums.xilinx.com/t5/Embedded-Devel...lem/td-p/118770
на оф. форуме несколько веток и хитрый финт с увеличением стека, правда, помогает не всем. Вот уже месяц бодаюсь с техподдержкой, и пока без результата.

А плату у вас самодельная или готовый кит?
Golikov A.
Вроде бы на первый взгляд я нашел проблему.

У меня оба ДДР сидели на том же клок генераторе что и все остальное.
Сейчас я оба ДДР повесил на свой клок генератор, и через констраин запихал его в нужный модуль. И о чудо! макс частота работы с 104 МГц увеличилось до 146, и все зажужало...

Я так понимаю основная проблема микроблайзов что очень много рулек, которые если случайно или бездумно задеть, все может сломаться.

П.С. Плата своя на основе модуля от http://www.trenz-electronic.de/
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.