Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SOPC модуль - чтение из sdram
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
RHnd
Учу свой переферийный модуль побайтово читать данные из памяти. Задача, вроде, тривиальная, однако где-то я застопорился.
Итак, код выглядит примерно так:
Код
assign master_write=1'b0;
assign master_writedata=32'd0;
assign master_byteenable=4'b1111;

always @(posedge clk) begin
    if (State==FirstState) begin//установка запроса
           master_address<=Addr;
           master_read<=1'b1;
           State<=SecondState;
    end
    else begin //ожидание снятия waitrequest и чтение данных
           if (!master_waitrequest) begin
               master_read<=0;
               Data<=master_readdata[7:0];
               Addr<=Addr+32'd1;
               State<=FirstState;
           end
    end
end


Смотрел сигналтабом, что выставляется на шинах - вроде, все правильно. Выставился адрес, выставился запрос на чтение. Выставился waitrequest. По сбросу waitrequest сбросился и запрос чтения. Но вот данные, выставленные на master_readdata, меня расстраивают. Первый байт читается правильно, а далее читается какой-то совершенно другой байт (каждый раз один и тот же), причем этого второго (как и последующих) байта в памяти по данному адресу и рядом нет (проверял дебагером ниоса). Компонент в сопсе создан, вроде, без ошибок. Адреса, выставляемые по версии сигнал таба, совпадают с адресами из дебагера ниоса. Кеша данных в системе нет, да и все равно первый байт читается верно.
Подскажите, где может быть загвоздка. help.gif
vetal
Цитата
Первый байт читается правильно, а далее читается какой-то совершенно другой байт (каждый раз один и тот же), причем этого второго (как и последующих) байта в памяти по данному адресу и рядом нет (проверял дебагером ниоса).

Для какого адреса вы пытаетесь читать? Для нормальной работы адрес должен быть кратен 4 байтам. Чтобы выровнять нужный массив используйте аттрибут __aligned__(4). В противном случае вам необходимо пересчитывать адрес для получения доступа нужному байту, т.к. byteenable работает внутри слова по нужному адресу.
Postoroniy_V
Цитата(RHnd @ Dec 1 2007, 01:18) *
Учу свой переферийный модуль побайтово читать данные из памяти. Задача, вроде, тривиальная, однако где-то я застопорился.
Итак, код выглядит примерно так:
Код
assign master_write=1'b0;
assign master_writedata=32'd0;
assign master_byteenable=4'b1111;

always @(posedge clk) begin
    if (State==FirstState) begin//установка запроса
           master_address<=Addr;
           master_read<=1'b1;
           State<=SecondState;
    end
    else begin //ожидание снятия waitrequest и чтение данных
           if (!master_waitrequest) begin
               master_read<=0;
               Data<=master_readdata[7:0];
               Addr<=Addr+32'd1;
               State<=FirstState;
           end
    end
end


Смотрел сигналтабом, что выставляется на шинах - вроде, все правильно. Выставился адрес, выставился запрос на чтение. Выставился waitrequest. По сбросу waitrequest сбросился и запрос чтения. Но вот данные, выставленные на master_readdata, меня расстраивают. Первый байт читается правильно, а далее читается какой-то совершенно другой байт (каждый раз один и тот же), причем этого второго (как и последующих) байта в памяти по данному адресу и рядом нет (проверял дебагером ниоса). Компонент в сопсе создан, вроде, без ошибок. Адреса, выставляемые по версии сигнал таба, совпадают с адресами из дебагера ниоса. Кеша данных в системе нет, да и все равно первый байт читается верно.
Подскажите, где может быть загвоздка. help.gif

если хочется по байтно считывать, то варианты такие
1) сделать как предлагает уважаемый vetal
2)считывать в своём модуле данные всё такие побайтно biggrin.gif а не "по 4 байтно" biggrin.gif
ибо по исходнику видно что шину внутрь завели 32-х разрядную.
тоесть второй варинт такой:
- либо автомат сделать который будет считывать по 4 байта и адрес+=4 а не +=1, и уже потом 4 байта раскидывать как нужно
- либо сразу считывать по 8 бит, тоесть шина данных должна быть 8 битсо всеми вытекающими wink.gif
з.ы. автомат в исходное состояние не плохо бы привести сбросом
RHnd
Цитата(vetal @ Nov 30 2007, 19:36) *
Для какого адреса вы пытаетесь читать? Для нормальной работы адрес должен быть кратен 4 байтам. Чтобы выровнять нужный массив используйте аттрибут __aligned__(4).

Не совсем понял, аттрибут __aligned__(4) относится к чему, где именно его использовать? Не получится ли так, что каждый байт информации будет занимать 4 байта памяти?
Цитата(vetal @ Nov 30 2007, 19:36) *
В противном случае вам необходимо пересчитывать адрес для получения доступа нужному байту, т.к. byteenable работает внутри слова по нужному адресу.

Если не затруднит, то можно подробнее, как именно пересчитывать адрес для получения доступа к нужному байту и как это связано с byteenable?

Цитата(Postoroniy_V @ Nov 30 2007, 20:38) *
2)считывать в своём модуле данные всё такие побайтно biggrin.gif а не "по 4 байтно" biggrin.gif
ибо по исходнику видно что шину внутрь завели 32-х разрядную.
тоесть второй варинт такой:
- либо автомат сделать который будет считывать по 4 байта и адрес+=4 а не +=1, и уже потом 4 байта раскидывать как нужно

Да, есть такой вариант. Но не хочется, т.к. количество байт может быть не кратно 4. Хотя, это не особо мешает, но не хочется.
Цитата(Postoroniy_V @ Nov 30 2007, 20:38) *
- либо сразу считывать по 8 бит, тоесть шина данных должна быть 8 битсо всеми вытекающими wink.gif

А как? Мне казалось, что по спецификации шина данных всегда 32 бита. Т.е. можно объявить master_readdata 8-ми битной и все заработает?
Цитата(Postoroniy_V @ Nov 30 2007, 20:38) *
з.ы. автомат в исходное состояние не плохо бы привести сбросом

Не, ну это понятно. smile.gif Тут было опущено для краткости. Там и сам автомат посложнее. smile.gif
vetal
Цитата
Не совсем понял, аттрибут __aligned__(4) относится к чему, где именно его использовать? Не получится ли так, что каждый байт информации будет занимать 4 байта памяти?

Этот атрибут выравнивает указатель на массив. чар сам по себе интом не станет.Так же можно выделить массив интов и присвоить его адрес поинтеру чар(по моему эффект будет аналогичный)
Цитата
Если не затруднит, то можно подробнее, как именно пересчитывать адрес для получения доступа к нужному байту?

Примерно так по адресу 0 слово 0 байт 0, а по адресу 1 слово 0 байт 1.
Т.е. 2 байт по адресу 3 лежит в слове 4 по адресу 1 smile.gif
Проще атрибутом или байтовой шиной не правдали?
Доступ к байтам через 32 разрядную шину может пригодиться только для ускорения обработки, т.к. читается сразу 4 байта вместо 1!(а если в пакетном режиме - так вообще обалдеть можно от скорости)

Цитата
А как? Мне казалось, что по спецификации шина данных всегда 32 бита.

Там написано, что шина данных может быть от 1 до 1024, при этом являясь степенью двойки.
При этом ширина шины должна быть одинаковой для чтения и записи.
Цитата
Т.е. можно объявить master_readdata 8-ми битной и все заработает?

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

PSSSS: Люди!!! Читайте мануалы, там аж 200 мегабайт их :-)
RHnd
Цитата(vetal @ Nov 30 2007, 21:16) *
Этот атрибут выравнивает указатель на массив. чар сам по себе интом не станет.Так же можно выделить массив интов и присвоить его адрес поинтеру чар(по моему эффект будет аналогичный)

Бррр... Но это же к сишному коду относится, разве нет? Если я в модуль как значение Address вместо (alt_u32*)Pointer передам (alt_u8*)Pointer, то разве модулю не один фик?
Цитата(vetal @ Nov 30 2007, 21:16) *
да, так...скорее всего....а может и нет, т.к. на сколько я помню ширина шины мастера должна быть больше или равна максимальной ширине шины слэйва, подключенного к этому мастеру.

Минимальный размер - шина SDRAM, 32 бита.
Цитата(vetal @ Nov 30 2007, 21:16) *
PSSSS: Люди!!! Читайте мануалы, там аж 200 мегабайт их :-)

Читаю... 05.gif
vetal
Цитата
Бррр... Но это же к сишному коду относится, разве нет? Если я в модуль как значение Address вместо (alt_u32*)Pointer передам (alt_u8*)Pointer, то разве модулю не один фик?

Как раз относится. Главное как выделить, а передавать можно любым поинтером.
К примеру у адреса int младшие 2 бита должны быть "00". Если вы с этим интом будете работать через char*, то байты 0-3 будут на своем месте в соответствии в byteenable. А если выделять char без выравнивания, то будет смещение от раза к разу разное и вам придется пересчитывать в железе адреса слов и byteenable чтобы выковырять нужный байт.
Цитата
Минимальный размер - шина SDRAM, 32 бита.

Еще надо учитывать byteenable. Проще провести эксперимент и удостовериться.

Не понимаю вашего рвения читать именно 1 байт, и боязнь 4 сразу - по скорости они будут читаться одинаково!
RHnd
Цитата(vetal @ Nov 30 2007, 22:13) *
Как раз относится. Главное как выделить, а передавать можно любым поинтером.
К примеру у адреса int младшие 2 бита должны быть "00". Если вы с этим интом будете работать через char*, то байты 0-3 будут на своем месте в соответствии в byteenable. А если выделять char без выравнивания, то будет смещение от раза к разу разное и вам придется пересчитывать в железе адреса слов и byteenable чтобы выковырять нужный байт.

Хм. В том примере, который я приводил, адрес передается выровненый, последние два бита 0. Однако, не помогло. Или же я чего-то не понимаю. Надо будет в понедельник проверить, что будет читаться при Adr+=4.

Цитата(vetal @ Nov 30 2007, 22:13) *
Не понимаю вашего рвения читать именно 1 байт, и боязнь 4 сразу - по скорости они будут читаться одинаково!

Да, честно говоря, лень дополнительный автомат распределения 4 байт по одному писать. smile.gif Хотя, думаю, так и сделаю.

PS: А точно проблема именно в адресации? Других вариантов нет?
RHnd
Написал сегодня автомат, читающий 4 байта и поочередно их выдающий, все заработало.
Однако! при написании автомата был замечен странный глюк - при чтении несколько раз подряд по одному и тому же адресу на master_readdata первые два раза выставляются правильные данные, а начиная с третьего запроса на чтение - неправильные. Алгоритм чтения такой же, как и в первом посте - выставляем адрес, master_read, а при снятии master_waitrequest - считываем master_readdata. Вообщем, просто из первого поста увеличение Adr убрать.
С чем может быть такой глюк связан?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.