Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20688 Discussions

SDRAM read out of sync

Altera_Forum
Honored Contributor II
1,251 Views

I am testing SDRAM read and write using nios. I wrote a simple function with loops to write to 15 memory locations and read them back.  

 

for(i=min; i<max; i++) { IOWR(SDRAM_BASE,0,i); } 

 

for(i=min; i<max; i++) { pbase=IOWR(SDRAM_BASE,i); printf("%d %d \n",i, pbase); } 

The first few reads return the last value(14) and the rest -1.  

Reading from Mem 0 14 1 14 2 14 3 14 4 14 5 14 6 -1 7 -1 8 -1 9 -1 10 -1 11 -1 12 -1 13 -1 14 -1  

 

I am driving the SDRAM from a PLL(sdram_clk) which is 3 ns leading the system clock(sys_clk) which is driving the other modules. How can I solve this?  

 

I am on DE4 board.  

 

Cheers,
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
492 Views

You are using the IOWR macro to read the values back, it should be IORD. 

 

Is the DRAM used in any way in your bsp? If you have the exception table set at the beginning of the DRAM, writing new values to it may give weird results. 

IIRC there is a memory test example in Eclipse that you can compile and use on your target.
0 Kudos
Altera_Forum
Honored Contributor II
492 Views

Thanks for your reply.  

 

The IORD was actually a typo. Now I got an example circuit and made the read/write working. But I find it interesting that when I write and read in the same loop(the following code) I can read perfectly.  

 

for(i=min; i<max; i++) 

IOWR_32DIRECT(pbase,0,i); 

printf("%d %d \n",i, iord_32direct(pbase,0));  

 

However, when I write in a loop and read in another loop I got some memory locations read wrong. Is there any explanation for this?  

for(i=min; i<max; i++) 

IOWR_32DIRECT(pbase[i],0,i); 

 

printf("Reading from Mem \n"); 

for(j=min; j<max; j++) 

printf("%d %d \n",j, IOWR_32DIRECT(pbase[j],0));  

 

Cheers,
0 Kudos
Altera_Forum
Honored Contributor II
492 Views

What is the contents of your pbase table? You need different addresses for each entry if you want to be sure to read back the same values. Besides The Nios 2 CPU is not capable of doing a non-aligned 32-bit transfer. That means that when you use an address that is not aligned (such as 1,2 or 3) you will in fact always read/write at the aligned address (0 in that case).

0 Kudos
Altera_Forum
Honored Contributor II
492 Views

pbase is a pointer to the DRAM base address and gets incremented every time to the next memory location in the loop.  

 

# define SDRAM_BASE 0x00000000 

 

void test() 

pbase=(alt_u32 *) mem_base; 

 

void main() 

test(SDRAM_BASE, 0, 0x000000ff); //just testing the first ff memory locations 

}
0 Kudos
Altera_Forum
Honored Contributor II
492 Views

Then you need to change how you use the macros. You need to feed them the actual address you want to write to, but when you write pbase you give them the address contents instead. 

try this: 

iowr_32direct(pbase+i,0,i); printf("%d %d \n",i, iord_32direct(pbase+i,0));  

or this: 

iowr_32direct(pbase,i*4,i); printf("%d %d \n",i, iord_32direct(pbase,i*4));  

or even just use pbase without any IORD/IOWR macro if you don't need to bypass the data cache. 

pbase=i; printf("%d %d \n",i, pbase);
0 Kudos
Reply