Altera_Forum
Honored Contributor
15 years agoAvalon-MM master and cache
Hi,
I have designed a fifo controller for a sopc system based on Nios II -f with data cache. It is used to read data from FIFO to SRAM and consists of a avalon-MM slave interface and a master interface. The avalon-MM slave interface is used to config 4 registers: status, control, base address, length of transfer. The HDL design is all right, and the following program is a simple test for it: Step1, define a buffer and initialize it with a constant value. Step2, Config and start FIFO controller to read data from FIFO to buffer defined in step 1; Step3, Check the data. As the FIFO controller will write data directly to SRAM rather than cache, the Nios II processor is expected to write/read data directly to/from SRAM too. That's why address is bypassed through setting bit-31. The program runs ok as the data are exactly that in FIFO in step 3. Now the problem is that: Problem 1. Without alt_dcache_flush(fifo_data, sizeof(fifo_data)) in step 1, the first 4 words are 0x56789abc, which is the initial value, and the other data are right. I think alt_dcache_flush() should not matter as the initialization is done with cache bypassed? Problem 2. if alt_u32 fifo_data[64] is defined as global or static, the problem 1 disappears. I am sure that stack is sufficient. I think there is nothing to do with whether fifo_data[] is global or local? I am sure the problems have something to do with cache, but can't explain. Hope somebody can give me some clues. Thanks very much! int main() { alt_u32 i; alt_u32 fifo_data[64]; volatile alt_u32 *fifo_data_uncached; alt_u32 fifo_status, fifo_ctrl, fifo_base, fifo_length; alt_printf("The program is testing fifo controller.\r\n"); /* 1. Initialize buffer. * 1) As FIFO_CTRL has no data cache, it always access memory directly. * 2) Nios II processor should also access memory directly so that * the data is consistent with FIFO_CTRL. * 3) Call alt_remap_uncached() to remap a region of memory for * un-cached access, or set the 31-th bit of address to make a * direct access. */ fifo_data_uncached = (alt_u32 *)((alt_u32)fifo_data | (1<<31)); for(i=0;i<sizeof(fifo_data)/4;i++){ fifo_data_uncached = 0x56789abc;}
alt_dcache_flush(fifo_data, sizeof(fifo_data));
/* 2. configure fifo controller and then start it.
* 1) there are four registers: status, control, length and base.
* write base register with the address of buffer,
* the length register with the length of transfer,
* and then set the go_bit of control register to start.
* 2) check the done_bit of status register to determine when
* the transfer is completed. */
iowr_fifo_base(fifo_ctrl_0_base, ((alt_u32)fifo_data));
iowr_fifo_length(fifo_ctrl_0_base, sizeof(fifo_data));
iowr_fifo_ctrl(fifo_ctrl_0_base, (1<<go_bit));
while(1){
fifo_status = iord_fifo_status(fifo_ctrl_0_base);
if(fifo_status & (1<<done_bit)) break;
}
/* 3. check the data written by fifo controller. */
for(i=0;i<sizeof(fifo_data)/4;i++){
if(i%16==0) alt_printf("\r\n");
alt_printf("%x ", fifo_data_uncached); } while(1); }