From Hamsterworks Wiki!

Jump to: navigation, search

This is the SDRAM chip used on the Terasic DE0-nano FPGA board. All this information is for a -7 speed part that is on the board.

This page will eventually have enough info to implement a memory controller to access this component.


Usable clock speeds

The DE0-nano has a '-7' (7ns) part, limiting the maximum clock is 143MHz. At 100MHz speed or lower it can run with a CAS setting of 2 - the ACT to READ command period must be >= 20ns. Using CAS of 2 gives a performance increase of most 16% when all transactions are single byte reads or writes.

Meeting setup / hold times

The easiest way to meet setup and hold time requirements is to delay the SDRAM clock signal and the clock to the data latches by 3ns. This will give enough time for the output signals to propagate to the SDRAM before the clock rises, and for any data being read from the SDRAM to propagate and become stable before capture.

Perhaps the safest way to generate the SDRAM clock signal is to use a DDR output block, with the DATA A signal held high and the DATA-B signal held low. This ensures that the clock is the desired phase as the other signals.


DRAM is organised in rows. Only one row can be open for reads or writes at a time, and it takes time to 'activate' (open) and 'precharge' (close) the row.

Should you never have to activate a different row the performance is pretty simple - at most one word per clock cycle (excluding the 1% lost to refresh cycles).

Speed Burst 1 Burst 2 Burst 4 Burst 8
100MHz 200 200 200 200
125MHz 250 250 250 250
143MHz 286 286 286 286

If you have to activate and precharge a row for every read command the performance quickly diminishes. With a bust length of 1, it is only a seventh of the peak rate. Here are the numbers where CAS = 3:

Speed Burst 1 Burst 2 Burst 4 Burst 8
100MHz 28.6 50.0 80.0 114.3
125MHz 35.7 62.5 100.0 142.8
143MHz 40.8 72.6 114.4 163.4

Should you use a CAS = 2 the numbers are a little bit better, but this can only be used at 100MHz:

Speed Burst 1 Burst 2 Burst 4 Burst 8
100MHz 33.3 57.1 88.8 123.1


Rather than deal with the states of the CKE, CD, RAS, CAS, WE signals the documentation talks of "commands"

  • DSEL - Deselect
  • NOP - No Operation
  • ACT - Bank activate
  • READ - Read (with or without auto precharge)
  • WRITE - Write (with or without auto precharge)
  • BST - Burst stop
  • PRE - Precharge bank
  • PALL - Precharge all banks
  • REF - Refresh - 8192 refresh commands are required every 64ms
  • SELF - Self refresh. This uses an internal timer to generate refreshes, and uses approximately 1/10th the power of active refreshes.
  • MRS - Mode Register set

Refresh cycle

Every 781ns a refresh cycle must occur, to ensure that 8192 refreshes occur every 64ms. These cycles take at most 67.5ns to complete, but as you have to "round up" to the next higher multiple of clock period gets close to 1% of time is spent performing refreshes.

Depending on the clock speed a different numbers of NOPs are required following the refresh command.

Speed Refresh commands (8 cycles, must not issue another command for at least 67.5ns)
100MHz (10ns) [REF] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP]
125MHz (8ns) [REF] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP]
143MHz (7ns) [REF] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP]

Initialisation process

On powerup the SDRAM is in an unknown state, and the Mode Register needs to be set before operation. The initialisation of the SDRAM takes approx 200us and consists of a powerup phase, a precharge command, 8 refresh cycles and then the actual Load Mode register command. Most of these phases are time dependent rather than requiring a fixed number of cycles.

I'm thinking that I might just design my controller to use the commands required for 143MHz operation. That way I never have to adjust them. The only downside is that it will take upto an extra 86us to initialise - big deal!

Speed Powerup (> 200us) Precharge Refreshes (8 cycles, each commands take 67.5ns to complete) Load Mode register
100MHz (10ns) 20000*[NOP] [PRE] [NOP] [NOP] 8 x ([REF] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP]) [Load Mode] [NOP] [NOP]
125MHz (8ns) 25000*[NOP] [PRE] [NOP] [NOP] 8 x ([REF] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP]) [Load Mode] [NOP] [NOP]
143MHz (7ns) 28600*[NOP] [PRE] [NOP] [NOP] 8 x ([REF] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP] [NOP]) [Load Mode] [NOP] [NOP]

Read cycles

A read consists of opening a row with an [ACT] command, issuing multiple [READ] (or write) commands then a [PRE] command to close off the row. A

The DQM signals control if data will be written to the bus, but is delayed by three cycles (it is registered against the command cycle, not the transfer cycle).

Here's the complete read using a CAS of 3, and burst length of 4.

Cmd DQML & DQMH Data
[NOP] LOW data word 0
[PRE] HIGH data word 1
[NOP] HIGH data word 2
[NOP] HIGH data word 3

Write cycles

Much like a read, a Write consists of opening a row with an [ACT] command, issuing multiple [WRITE] (or read) commands then a [PRE] command to close off the row.

The DQML and DQMH signals can be used to select if the high or low bytes of a word will be written to memory, but it must be asserted high for at least three clocks prior to the WRITE command to prevent data from any prior read appearing on the bus.

Here's the complete write using a CAS of 3, and burst length of 4, updating all four words addressed by the burst.

Cmd DQML and DQMH Data (to SDRAM)
[ACT] High -
[NOP] High -
[NOP] High -
[WRITE] Low data word 0
[NOP] Low data word 1
[NOP] Low data word 2
[NOP] Low data word 3
[PRE] High -
[NOP] High -
[NOP] High -

Memory Controller

I'm designing a memory controller for this chip. Have a look at SDRAM Memory Controller for the design.

Personal tools