Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Некоректное чтение памяти DMA-компонентом
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Shevnnov
Проблема с одной стороны простая, но природа её не понятна. Тестирую систему, в которой имеется самописный контроллер DMA, которому передается адрес начала данных, длина данных и дается отмашка на работу. И он начинает выкачивать из памяти эти данные. Текст программы генерирующий тестовую последовательность приведен ниже:
Код
    txp.data_len = 64;
    txp.data = malloc(txp.data_len*sizeof(alt_u8));
    for (i = 0; i< txp.data_len; i++)
        if(!i)
            *(txp.data) = 0x10;
        else
            *(txp.data + i) = *(txp.data + i - 1) + 1;
        *(txp.data + txp.data_len) = 0;

Симулирую программу на симуляторе. Работает, но только порядок байт переставлен (в память записывал 0x10111213 считывает dma из памяти 0x13121110). Временная диаграмма приведена ниже:

Работаю с контроллером DDR SDRAM Controller Megafunction

В чем проблема?

Код DMA контроллера ниже
CODE

module x_dma ( clk,
rst,
data_read,
data_readdata,
data_address,
data_waitrequest,
data_chipselect,
data_arbiterlock,

control_chipselect,
control_write,
control_writedata,
control_address,
control_read,
control_readdata,

fifo_write_data,
fifo_write,
fifo_full,
start_transmit,
State_Data,
State_Preamble,
State_SFD,
data_length,
tx_ready);



input clk;
input rst;

output data_read;
input [31:0] data_readdata;
output [31:0] data_address;
output data_chipselect;
output data_arbiterlock;
input data_waitrequest;

input control_chipselect;
input control_write;
input [31:0] control_writedata;
input [3:0] control_address;
input control_read;
output [31:0] control_readdata;

output fifo_write;
output [31:0] fifo_write_data;
input fifo_full;
output start_transmit;
input State_Data;
input State_Preamble;
input State_SFD;
output [10:0] data_length;
input tx_ready;

reg [31:0] control_readdata;
reg [31:0] addr_offset;
reg [10:0] data_length;
reg [31:0] start_address;
reg start_transmit;
wire dma_state;

parameter IDLE = 0,
TRANSMIT = 1;


parameter ADDR_TX_START_ADDRESS = 32'd0,
ADDR_TX_DATA_LENGTH = 32'd1,
ADDR_TX_START_TRANSMIT = 32'd2,
ADDR_TX_STATUS = 32'd3;


always @(posedge clk or negedge rst)
if (!rst)
start_address <= 32'b0;
else
if (control_chipselect & control_write & (control_address == ADDR_TX_START_ADDRESS))
start_address <= control_writedata;

always @(posedge clk or negedge rst)
if (!rst)
start_transmit <= 1'b0;
else
if (control_chipselect & control_write & (control_address == ADDR_TX_START_TRANSMIT))
start_transmit <= control_writedata[0];
else
start_transmit <= 1'b0;

always @(posedge clk or negedge rst)
if (!rst)
data_length <= 32'b0;
else
if (control_chipselect & control_write & (control_address == ADDR_TX_DATA_LENGTH))
data_length <= control_writedata;

always @(posedge clk or negedge rst)
if (!rst)
addr_offset <= 32'd0;
else if (start_transmit)
addr_offset <= 32'd0;
else if (dma_state & (~data_waitrequest))
addr_offset <= addr_offset +32'd4;

always @(posedge clk or negedge rst)
if (!rst)
control_readdata <= 32'b0;
else
if (control_read & control_chipselect)
case(control_address)
ADDR_TX_STATUS: control_readdata <= {31'b0,tx_ready};
default: control_readdata <= 32'hz;
endcase

assign dma_state = (~fifo_full & (State_Data | State_Preamble | State_SFD) & ~(addr_offset == data_length)) ? TRANSMIT : IDLE;
assign data_arbiterlock = dma_state;
assign data_address = start_address + addr_offset;
assign data_read = dma_state;
assign data_chipselect = data_read;
assign fifo_write = dma_state & (~data_waitrequest);
assign fifo_write_data = fifo_write ? data_readdata : 32'bx;

endmodule

vadimuzzz
а в чем вопрос-то? в порядке данных? тогда все правильно, NIOS - little endian
Shevnnov
Ну гут, ладно. Но мне нужно чтобы DMA считывал в порядке big endian (то есть так как я побайтово записываю). Можно ли это софтварно сделать ли нужно на RTL провода перекрещивать?
vadimuzzz
Цитата(Shevnnov @ Nov 3 2010, 01:03) *
Ну гут, ладно. Но мне нужно чтобы DMA считывал в порядке big endian (то есть так как я побайтово записываю). Можно ли это софтварно сделать ли нужно на RTL провода перекрещивать?

ну, если речь о DMA, то "софтварно" смысла не имеет. у ниоса есть какая-то дополнительная инструкция на эту тему, но она здесь лишняя сущность. сделайте лучше перекрещивание, причем управляемое. флажок взвели в контрольном регистре - big endian, сбросили - little endian
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.