AN00170 "Using the SDRAM library"

If you have a simple question and just want an answer.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

When testing with the ISSI part, I assume we need to use the released version of server.xc and not the one modified for Micron - correct?
Well, just the void sdram_init() function actually - the rest should the be same.
Also, can BUF_WORDS be made larger?
Yes - you can make this as big as the SDRAM or your local buffer size (obviously the latter will be smaller!). The Server takes care of spanning rows and banks, although looking at the code if you block too long you may delay a refresh. This again will be large though compared with the size of BUF_WORDS you can define in local RAM - you could write 256KB in about 3.5ms so nothing to worry about here..


LumiCore
Member++
Posts: 21
Joined: Fri Jul 01, 2016 6:36 am

Post by LumiCore »

Hi infiniteimprobability,

Not sure if this is the right place to ask this;

Could the lower 16 of PORT32a (32A0-32A15) of an XU232 on X1 also function as the dq_ah port?
I assumed it could earlier on without digging to deep so I went ahead and made custom hardware for it with an IS42S16400J-7BL. Now getting similar results as PlayingWithWires I ended up in this thread :)

So I could use some guidance for where to tune the timing - if possible at all of course!

Thanks!
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

Not sure if this is the right place to ask this;
It's as good a place as any!
Could the lower 16 of PORT32a (32A0-32A15) of an XU232 on X1 also function as the dq_ah port?
I'm afraid not. The SDRAM controller relies on the buffering inside the port to achieve the performance goals. Otherwise, to run at 62.5MHz with a 62.5MHz core, you would need to issue an I/O instruction every core clock which doesn't give you enough time for load/store data, pointer incrementing, loop overhead etc. By using buffering in the port, you can do a 32b in/out instruction at a rate of 31.25MHz to get the 62.5MHz 16b I/O burst speed offered by the controller.
User avatar
aneves
Experienced Member
Posts: 93
Joined: Wed Sep 16, 2015 2:38 pm

Post by aneves »

Hello fellow feline enthusiasts,

After following the recommendations on this thread and lots of trial and error, I was able to create a test bed that used the Micron sdram chip on our demo board very successfully. I was able to write and read data without errors.

However, I am now trying to use the ISSI chip - the IS45S16160G-7TLA1 - on our demo board and I am seeing some strange results. I can write up to 2,097,188 bytes and read it back with no issue. If I try to do the same with an extra 4 bytes (for a total of 2,097,192 bytes), my test bed results that not all the samples match. Through trial and error I've found that what appears to be happening at this threshold is the sdram addressing is folding back onto itself and overwriting previous addresses.

I've confirmed that the ISSI IS45S16160G-7TLA1 and the Micron 48LC16M16A2 should be configured the same way in regards to the parameters I pass to the sdram_server function (same CAS latency, same row, column, and bank address bits, etc.).

I've tried using the officially released lib_sdram v3.1.0. I also tried to follow your comment:
infiniteimprobability wrote:
When testing with the ISSI part, I assume we need to use the released version of server.xc and not the one modified for Micron - correct?
Well, just the void sdram_init() function actually - the rest should the be same.
Which I interpreted as take the sdram_init function from lib_sdram that you made edits to originally to support Micron and replace the sdram_function in the official v3.1.0 with it. Is that correct?
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

Through trial and error I've found that what appears to be happening at this threshold is the sdram addressing is folding back onto itself and overwriting previous addresses.
Ah - yes. It will do that. When I was making it support larger devices, that was a handy test to see if they physically existed or not.
However, are you saying you're seeing an expected behaviour in this case? Is there a bug that needs to be investigated?
Which I interpreted as take the sdram_init function from lib_sdram that you made edits to originally to support Micron and replace the sdram_function in the official v3.1.0 with it. Is that correct
YEs you're right - sorry. It's a bit clunky. For now this is the route to getting the modified startup code to support the non ISSI parts. Please bear in mind that this was a quick fix and hasn't undergone testing (which would be necessary for an official release). The improved startup matches the datasheet better and we have positive conformation in this thread that it worked so hopefully it meets your requirements.
User avatar
aneves
Experienced Member
Posts: 93
Joined: Wed Sep 16, 2015 2:38 pm

Post by aneves »

infiniteimprobability wrote: Ah - yes. It will do that. When I was making it support larger devices, that was a handy test to see if they physically existed or not.
However, are you saying you're seeing an expected behaviour in this case? Is there a bug that needs to be investigated?
I'm hesitant to say it's a bug because I don't know where the fault lies. Could be our hardware and/or my code and nothing to do with the sdram library. It's just very interesting that there is this boundary of 2,097,188 bytes just before things begin to alias. I'm pretty sure when our prototype used the Micron chip I did not see this problem. I'll test again with the Micron chip just to be sure and post back with more info.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

boundary of 2,097,188 bytes just before things begin to alias
But 2 x 1024 x 1024 = 2,097,152

So surely it wraps at this point, which is 36 bytes before your observed wrapping.

Something doesn't quite add up here as I would expect it to wrap at 2,097,152!?
User avatar
aneves
Experienced Member
Posts: 93
Joined: Wed Sep 16, 2015 2:38 pm

Post by aneves »

infiniteimprobability wrote:
boundary of 2,097,188 bytes just before things begin to alias
But 2 x 1024 x 1024 = 2,097,152

So surely it wraps at this point, which is 36 bytes before your observed wrapping.

Something doesn't quite add up here as I would expect it to wrap at 2,097,152!?
At first I though it was aliasing at the bank boundary, but it looks like it is some where in the middle there. I have run the same test bed with our other prototype board which uses the Micron chip and I'm seeing the same results.

Like I said before, if I write 2,097,188 bytes I can read it back and everything is bit perfect. Adding an extra byte for a buffer size of 2,097,189 byes results in a mismatch of the first byte read back. That first sample is identical to the last sample that was written to sdram.

Armed with this knowledge I can verify very easily that there is some aliasing occurring which is either causing my writing to overwrite samples in sdram or my reading to reference the wrong areas of memory. For reference, I am writing a sine wave of 8-bit samples where one full cycle occupies the entire buffer.

This represents the write buffer and is what I expect to get back after a read operation:
Image

If my write buffer is 4,194,376 bytes (exactly double the magic boundary) my read buffer looks like this:
Image

As you can see, the negative cycle is perfectly mirrored. It looks like during the write operation, the positive half of the wave is getting overwritten with the negative cycle. Then during the read operation, the entire buffer is being read back that way too.

The way my test bed differs from the benchmarks I've seen distributed with the sdram library on github is that the benchmarks are run and memory is allocated in small chunks entirely on the chip. I am sending these large buffers from the PC to the processor over USB and the entire buffer is being written and read separately. Therefore write/read verification that take place on the example benchmarks happen in small chunks. That kind of testing would not catch this kind of issue.

Do you have any ideas on what to look for?
User avatar
aneves
Experienced Member
Posts: 93
Joined: Wed Sep 16, 2015 2:38 pm

Post by aneves »

Hi Guys,

Just checking in to see if anyone had any ideas on how I could proceed debugging this?

Thanks for your help.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

I'm still not sure why this weird number of 36 comes out. What is your word_count size (size of read/write block)?
Just checking in to see if anyone had any ideas on how I could proceed debugging this?
I would print the calculated addresses out - to see that address you desire is actually being output to the 16b port. Then check a small block of reads/writes that passes through the 2,097,188 and 2,097,152 addresses. It doesn't matter that it will break timing - we are checking the calculated port value only. The logic can be found in server.xc:

Code: Select all

 //Work out first and second 16b commands (lower word first) -  ACT followed by WRITE (no precharge)
    unsigned rowcol = row | (bank<<BANK_SHIFT) | bank<<(BANK_SHIFT+16) |  (col << 16);

   ....
    dq_ah @ t<: rowcol;
I haven't had a chance to try this myself yet, so if you want to get ahead, put a print of row, bank and col at that point to see if the values look right.. Post back and I'll happily review.
Post Reply