# SDRAM chip selection

I need to buffer 1.5Gb/s of video data through SDRAM, which works out to be 3Gb/s total in and out combined.

This is my thinking so far:

Write/read burst length is set to max (16 clock cycles), and CL is 3 clock cycles, that means for every 16 clocks, I need at min another 3. So 19% overhead for just CL between bursts.

Changing banks/rows is another 15 clock cycles (RP + WR + RC). The max number of burst writes I can make without changing rows is 64 (according to the Xilinx spartan 6 MCB user guide page 17). This takes 77 clocks (64 writes of 16 bits * 1.19 for CL overhead) and requires an additional 15 clocks for config (or 20%) between rows.

3Gb/s * 1.19 * 1.20 = 4.28 Gb/s.

I'm considering clocking a LPDDR device at 166Mhz, which gives 332Mhz for both clock edges. If I use a device with a 16 bit word length, i get 332Mhz * 16 bit = 5.3 Gb/s, within my spec quite comfortably. Perhaps this device?

My main question is: Am I on the right track here? This is the first time I've had to design a board containing SDRAM, do these numbers look right? Is there any way I can configure the chip to further minimize the overhead? Is there anything else I need to consider? The last thing I want is to select a device, build the board and then discover that my choice is too small/slow for my application.

You can do a little better than this; because burst transfers only use the data paths while in progress, you can overlap bursts with address signal transfers.

So you can get ready to transfer the next burst while the current burst is in progress; likewise you can open the next bank and set RAS for it before the current bank's transfer is done. Start the next actual transfer, then come back to precharge this bank.

It's more complex, and you'd have to read the Spartan-6 MCB docs in case they don't allow this stuff; I was rolling my own controller when I did this.

In any case it sounds like you won't need it, but its nice to know it's there.

A bigger problem is that it will want to stop every 8 us and spend a chunk of time generating a refresh pulse (and precharges around it). I could tell it not to in my own core, (until a convenient break, but no longer than 70 us) and later added a similar hack to the Virtex-5 MIG core for this purpose but I don't think you can control refreshes on Spartan-6. So, if this is a problem, you'll need an elastic buffer somewhere to take up the slack.

• it looks like the Spartan 6 controller allows for auto-refresh to be switched on or off. I also read somewhere that it's intelligent enough to "look ahead" to see if the next transaction is a read on the same row. how this works in practice I'm not too sure, I'll have to do a bit more reading! – stanri Nov 29 '12 at 17:07
• Heh, I still want "Page Mode" back... once upon a time, you could ask for whole page bursts - great for FPGA apps but CPUs didn't use page mode, so it was quietly dropped... – user_1818839 Nov 29 '12 at 17:28

LPDDR is not completely straightforward - there are multiple stages to a simple read or write. For example, rows have to be opened (with an ACTIVE command) before they can be read, but once read, you can read many bytes from them in sequence.

In the datasheet you linked to, if you look at Fig 22, you'll see a read-burst timing diagram, with 4 words of data transmitted consecutively. The transaction takes 5 clock ticks, and must be preceded by an ACTIVE command, and tRCD must elapse before you start reading (another tick+15-22ns depending on speed grade). If you had to do this for every read, you'd not achieve great bandwidth.

However, you can amortise the cost of the ACTIVE command and tRCD if you issue more read commands which go to the same row (Fig 23) you can continue to read two words per clock cycle from the same row.

This is further complicated by the banking arrangement, as you can issue the ACTIVE command to one bank to prepare it, and then (during the tRCD requirement) get on with reading from an already activated bank, thus "hiding" the delay.

In summary, particularly on video applications where you have long streams of consecutive data, you can get very close to using the whole theoretical bandwidth. How close depends on your memory controller and how well you can produce a memory layout which it can use to hide activations etc.