Monday, May 3, 2010

DDR SDRAM - An walk down the memory lane (3)

Part 1 | prev | next

In this part let us discuss the DDR memory signals. A typical DDR memory has the following pins


Address lines input to memory
The address pins are used to
1. Provide row address
2. Provide column address
3. One pin indicates whether PRECHARGE is applicable to one bank or all banks
4. To carry the opcode during the LOAD MODE REGISTER command.

Bank address input
These have follwing function
1. Select the bank during normal operation
2. To determine whether mode register or extended mode register is selected during LOAD MODE REGISTER command

Clock pins
Clock inout (2 pins : CK and CK#)
The clock is a differential clock. All control signals are sampled on crossing of rising CK edge and falling CK# edge

Clock enable
This input high activates the internal clocks, input buffers and output drivers.

Chip select
This signal is active low in most cases. It acts as an enable for the commands. All commands are masked when this signal is sampled high. *

Control pins
RAS, CAS and WE are the control inputs. These three pins alongwith the CS pin define the command being entered. The DDR data sheets usually specify the definitions of various commands like ACTIVE, PRECHARGE, WRITE, READ etc. as a combination of these signals

Data pins
DQ or data lines
This is usually an 8 bit bus, with either 4 or 8 pins active depending on the data bus width. In 16 bit devices this can be 16 bit wide too. This is a bidirectional bus

DQS or data strobe
A single strobe for every 8 data pins. SO for a 16 bit data bus, 2 bit DQS signal exists. DQS is bi-directional.
Data mask signal
DM is a signal input to memory, with one pin per 8 bits of data. For example, for 16 bit data bus, this signal is 2 bits, one bit corresponding to lower 8 bit of data and the other bit corresponding to higher 8 bit of data. This signal is used as a mask during write operation. If this signal is sampled high, then the data byte is masked.

Wednesday, April 7, 2010

DDR SDRAM - An walk down the memory lane (2)

Part 1 | Part 3

We now look at the various aspects of DDR SDRAM one by one.

Reading or writing data needs to follow a command sequence
The construction of SDRAM is in the form of rows and columns of memory elements. Usually, SDRAMs are divided internally into 2 or 4 'banks' or chunks of memory elements. Hence the way to access data from SDRAM is to specify a bank address, then a row address and the column address.
A specific sequence needs to be carried out when reading from or writing to an SDRAM. JEDEC specifies a set of registers and a set of commands for SDRAM. Separate sets of registers and commands are specified for SDRAM, DDR, DDR2 and DDR3 memories.
Before a row can be accessed inside an SDRAM, an ACTIVE command needs to be issued. This opens a row for data access. It is open for data access till access is closed by a "PRECHARGE" command. Usually, an address line lets you select whether AUTO PRECHARGE is enabled. In case of AUTO PRECHARGE, the access to the row is closed automatically.


Data is read/written on both the edges of the strobe signal
The DDR memory system is a source synchronous interface. This means that the clock signal is transported from the transmitter to the receiver along with the data. This clock is not free running, but only driven during data transfer. The signal is called data strobe or DQS for short. Data is transferred on both the edges of DQS. While defining the specification for DDR, the JEDEC committee decided that the while writing to the memory, the controller must align the DQS to the center of the data eye and while reading from the memory, the memory transmits the DQS edge aligned to the data edge. The design-reuse website has a very nice article on the three most critical decisions regarding the DDR specification from JEDEC.

Reading data in bursts is more efficient
Since an entire row is open for access once activated, and data is prefetched, it is most effeciently read in bursts. The access to SDRAM data always happens in bursts and if one is interested in only 1 or 2 bytes/words, then the rest of the bytes/words are masked using the signal DM or data mask.


Periodic Refresh is required to hold the data
The DDR SDRAM memory controller needs to take care of refreshing the memory every specified time interval by issuing the auto refresh command.

Timing specifications between various commands
Data sheets for SDRAMs usually specify timing requirements for the various operations. For example, minimum time interval between precharge of a row in the same bank  to the activation of another row, or amount of time after which ACTIVE command can be issued after the AUTO-REFRESH command can be issued. Since these timings must be strictly adhered to, to ensure accurate data.

Saturday, April 3, 2010

DDR SDRAM - An walk down the memory lane (1)

 Since PCs were not a household commodity when we were undergraduates, our first introduction to "memory" in the context of a microprocessor based system happened through a typical block diagram in Gaonkar. We just read it as a block essential in the system, and that it does the job of storing data. As I started doing more projects and advanced stuff, the understanding of speed, access times, latencies started coming. Somewhere in that same flow, i learnt about double data rate SDRAMs.

First things first :

So a double data rate (DDR) memory is basically an SDRAM - It is a Synchronous Dynamic Random Access Memory. It is synchronous, means that data reads and writes happen in sync with a clock provided by the system. It is dynamic means the data is stored as charge in capacitors inside integrated circuits. Since capacitors tend to lose charge over a period of time, a periodic refresh is required. It is random access means that one can place any address on the address lines, followed by any other address and the data is accurately accessed and produced on the data lines provided the specified timing relations are adhered to.

In the best case, normal SDRAMs are capable of delivering only one word of data every clock cycle.
DDR is double data rate, which means that for a given clock speed, data can be read/written at twice the rate. 2 words of data can be written/read in a single clock cycle.

For the write mechanism, the controller module provides a clock, (which is not free running) called the DQS and the data is written on the positive as well as the negative edge of DQS. The DQS is called as the strobe in same cases. The write signal needs to be asserted.

For the read operation, the controller issues a read command and after a certain number of clock cycles, (called CAS Latency), the memory puts the data on the data bus. This time, the clock to which the data is synchronised is provided by the memory. The same DQS lines as before are used, but this time, the memory drives those. The DDR memory internally prefetches 2 data words so that it can output data on both edges of the clock.

Part 2 

Friday, April 2, 2010

DDR SDRAM - An walk down the memory lane (Why?)

In any microprocessor based system, fast memory is a requirement to good system performance. Memories have come a long way from the simple SRAM based structures to DDR2 and now DDR3 SDRAMs. From the perspective of a system designer, I have always wanted to explore and summarise the controller requirements, as the memory used migrates from a simple SDRAM to DDR3. This blog series is just an attempt to explore and understand this.
An extensive web search revealed that there are certain resources available abundantly on the web and certain are entirely missing. (I may probably be not searching the right places too :) ). I observed that DDR, DDR2 and DDR3 almost always referred to the PC/Laptop memory DIMM modules in the webworld jargon. Not many people talk about use of these in embedded applications (the HOW part).  There is material available regarding guidance for the PCB design, termination, etc, but the controller design still seems extremely untalked of in the public forums. It could be related to confidential material, design secrets etc, but my attempt here is to only discuss the concepts for the DDR controller design, the issues faced and the possible direction of solutions, The solutions themselves could probably be patents and design secrets!

The series is targeted to anyone new to DDR and DDR module designs. It could act as a refresher to experienced engineers too. As ever, i should mention that my effort is to always learn, so any comments from experienced people reading this series are most welcome.

The way I have structured the series is as follows
Introduction : This covers the very basics of DDR memories, including the data and control signals, overview of physical signal requirements and overview of board design considerations. I do not mean to keep this section exhaustive, as this would mostly be only a compilation of the existing material. I will be putting pointers and the original text is the best read!

Differences between DDR, DDR2 and DDR3: This section will contain the differences between these memories. I plan to keep this section detailed

DDR memory controller design considerations and issues: This section is most likely to contain my own conclusions and explanation after reading up several things.


Part 1
Part 2
Part 3


References

Memory data sheets, application notes and white papers from memory vendors like Micron

Monday, February 1, 2010

The Clockwise/Spiral Rule

I am trying to ramp up on C and C++, and the declarations used to drive me crazy

What do you make of


char *(*fp)( int, float *);

 If you find this tedious and confusing, just like me, then you have some help. It is called Clockwise/Spiral rule.
The following text is reproduced here, as the author, David Anderson permits use of it with the copyright notice


[This was posted to comp.lang.c by its author, David Anderson, on 1994-05-06.]

The ``Clockwise/Spiral Rule''

By David Anderson

There is a technique known as the ``Clockwise/Spiral Rule'' which enables any C programmer to parse in their head any C declaration!
There are three simple steps to follow:
  1. Starting with the unknown element, move in a spiral/clockwise direction; when ecountering the following elements replace them with the corresponding english statements:
    [X] or []
    => Array X size of... or Array undefined size of...
    (type1, type2)
    => function passing type1 and type2 returning...
    *
    => pointer(s) to...

  2. Keep doing this in a spiral/clockwise direction until all tokens have been covered.

  3. Always resolve anything in parenthesis first!

Example #1: Simple declaration

+-------+
                     | +-+   |
                     | ^ |   |
                char *str[10];
                 ^   ^   |   |
                 |   +---+   |
                 +-----------+
Question we ask ourselves: What is str?
``str is an...
  • We move in a spiral clockwise direction starting with `str' and the first character we see is a `[' so, that means we have an array, so...
    ``str is an array 10 of...
  • Continue in a spiral clockwise direction, and the next thing we encounter is the `*' so, that means we have pointers, so...
    ``str is an array 10 of pointers to...
  • Continue in a spiral direction and we see the end of the line (the `;'), so keep going and we get to the type `char', so...
    ``str is an array 10 of pointers to char''
  • We have now ``visited'' every token; therefore we are done!

Example #2: Pointer to Function declaration

+--------------------+
                     | +---+              |
                     | |+-+|              |
                     | |^ ||              |
                char *(*fp)( int, float *);
                 ^   ^ ^  ||              |
                 |   | +--+|              |
                 |   +-----+              |
                 +------------------------+
Question we ask ourselves: What is fp?
``fp is a...
  • Moving in a spiral clockwise direction, the first thing we see is a `)'; therefore, fp is inside parenthesis, so we continue the spiral inside the parenthesis and the next character seen is the `*', so...
    ``fp is a pointer to...
  • We are now out of the parenthesis and continuing in a spiral clockwise direction, we see the `('; therefore, we have a function, so...
    ``fp is a pointer to a function passing an int and a pointer to float returning...
  • Continuing in a spiral fashion, we then see the `*' character, so...
    ``fp is a pointer to a function passing an int and a pointer to float returning a pointer to...
  • Continuing in a spiral fashion we see the `;', but we haven't visited all tokens, so we continue and finally get to the type `char', so...
    ``fp is a pointer to a function passing an int and a pointer to float returning a pointer to a char''

Example #3: The ``Ultimate''

+-----------------------------+
                      |                  +---+      |
                      |  +---+           |+-+|      |
                      |  ^   |           |^ ||      |
                void (*signal(int, void (*fp)(int)))(int);
                 ^    ^      |      ^    ^  ||      |
                 |    +------+      |    +--+|      |
                 |                  +--------+      |
                 +----------------------------------+
Question we ask ourselves: What is `signal'?
Notice that signal is inside parenthesis, so we must resolve this first!
  • Moving in a clockwise direction we see `(' so we have...
    ``signal is a function passing an int and a...
  • Hmmm, we can use this same rule on `fp', so... What is fp? fp is also inside parenthesis so continuing we see an `*', so...
    fp is a pointer to...
  • Continue in a spiral clockwise direction and we get to `(', so...
    ``fp is a pointer to a function passing int returning...''
  • Now we continue out of the function parenthesis and we see void, so...
    ``fp is a pointer to a function passing int returning nothing (void)''
  • We have finished with fp so let's catch up with `signal', we now have...
    ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning...
  • We are still inside parenthesis so the next character seen is a `*', so...
    ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to...
  • We have now resolved the items within parenthesis, so continuing clockwise, we then see another `(', so...
    ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning...
  • Finally we continue and the only thing left is the word `void', so the final complete definition for signal is:
    ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning nothing (void)''
The same rule is applied for const and volatile. For Example:
const char *chptr;
  • Now, what is chptr??
    ``chptr is a pointer to a char constant''
How about this one:
char * const chptr;
  • Now, what is chptr??
    ``chptr is a constant pointer to char''
Finally:
volatile char * const chptr;
  • Now, what is chptr??
    ``chptr is a constant pointer to a char volatile.''
Practice this rule with the examples found in K&R II on page 122.


Copyright © 1993,1994 David Anderson This article may be freely distributed as long as the author's name and this notice are retained.

Thursday, December 17, 2009

Thoughts on verification environment

 My purpose is always to learn. The thoughts I represent below originate from my own thinking. Obviously there is no guarantee of correctness. I would be grateful if you point out to something that is incorrect, as that will definitely enlighten me. Also, any comments that help me as well as other readers to learn are most welcome