SDRAM

From Qi-Hardware
Jump to: navigation, search
SDRAM is a dynamic random access memory (DRAM) that has a synchronous interface. This means that it waits for a clock signal before responding to control inputs and is therefore synchronized with the computer's system bus, unlike the DRAM that has an asynchronous interface which means that it responds as quickly as possible to changes in control inputs.[1]
SDRAM chip on Nanonote board

Contents

[edit] SDRAM operating

The SDRAM is conected to processor by the Data Bus, Adress Bus and Control bus. Data bus is bidirectional, this means that the chip can send or receive information to stored or to be used by the processor. By the adress bus the proccesor can acces to information stored in the chip distributed in 'Blocks' and accesed by Rows and Columns or also, specify the adress where will store new data. Finally, the Control bus carries the Control Signals to the right operation between chip and processor. These signals have the task of establishing the communication protocol between the two sides.

[edit] SDRAM configuration

SDRAM memory is organized how a Cells Matrix, with a Bits number for Rows addressing and other bits number for Column addressing. As mentioned, the memory is distributed in 4 Banks of arrays of 8.192 rows x 512 columns x 16 bits, this corresponds to 67.108.864 bits per bank, or 268.435.456 bits in the four banks (33.554.432 bytes ---> 32MB aprox).
Structure of one SDRAM Block array

A memory cell on SDRAM corresponds to one transistor and one capacitor; the transistor supplied the charge and the capacitor stored the state of each cell. Over time, the charge on the capacitor disappears so, is necessary reload each capacitor periodically, this process is called REFRESH. This process is simplified by an "auto refresh" command[1], which refresh one row in each bank at same time.

[edit] SDRAM Block Diagram

Block Diagram of SDRAM

We can see in the picture the Block Diagram of a SDRAM chip. All blocks and lines will be explain then:

[edit] Signals Description

SIGNAL TYPE Description
CLK Input Clock: CLK is driven by the system clock. All others signals are sampled on the rising edge of CLK. CLK also increments the internal burst counter and controls the output registers.
CKE Input Clock Enable: CKE activates (HIGH) or deactivates (LOW) the CLK signal. Deactivating the clock provides PRECHARGE POWER-DOWN and SELF REFRESH operation (all banks idle), ACTIVE POWER-DOWN (row active in any bank) or CLOCK SUSPEND operation (burst/access in progress). CKE is synchronous except after the device enters power-down and self refresh modes, where CKE becomes asynchronous until after exiting the same mode. The input buffers, including CLK, are disabled during power-down and self refresh modes, providing low standby power. CKE may be tied HIGH.
CS# Input Chip Select: CS# enables (registered LOW) and disables (registered HIGH) the command decoder. All commands are masked when CS# is registered HIGH. CS# provides for external bank selection on systems with multiple banks. CS# is considered part of the command code.
CAS#, RAS#, WE# Input Column Address Strobe - Row Address Strobe - Write Enable: defines the command being entered. Along with CS#.
DQML, DQMH Input Input/Output Mask: DQM is an input mask signal for write accesses and an output enable signal for read accesses. Input data is masked when DQM is sampled HIGH during a WRITE cycle. The output buffers are placed in a High-Z state (two-clock latency) when DQM is sampled HIGH during a READ cycle.
BA0, BA1 Input Bank Address Inputs: BA0 and BA1 define to which bank the ACTIVE, READ, WRITE or PRECHARGE command is being applied.
A0-A12 Input Address Inputs: A0-A12 are sampled during the ACTIVE command (rowaddress A0-A12) and READ/WRITE command (column-address A0-A9, A11 [x4]; A0-A9 [x8]; A0-A8 [x16]; with A10 defining auto precharge) to select one location out of the memory array in the respective bank. A10 is sampled during a PRECHARGE command to determine if all banks are to be precharged (A10 [HIGH]) or bank selected by (A10 [LOW]). The address inputs also provide the op-code during a LOAD MODE REGISTER command.
DQ0-DQ15 Input Data Inputs:Data Bus.

[edit] Blocks Description

  • Control Logic: This block drive the Mode Register and the Bank Control Logic Unit. Basically, this block decodes the Control Signals to the correct operation between the others blocks.
  • Mode Register: This is a programmable register which specify the operation mode of the SDRAM. This definition includes the selection of a burst length, a burst type, a CAS latency, an operating mode and a write burst mode. The mode Register is loaded with the Address bus information during the LOAD MODE REGISTER command. This must be program when all banks are idle, idle, and the controller must wait the specified time before initiating the subsequent operation.
    Mode Register Definition

    ----
    * Burst length: The burst length determines the maximum number of column locations that can be accessed for a given READ or WRITE command.
    * Burst Type: A given burst may be programmed to be either 'sequential' or 'interleaved'. this is referred to as the burst type.
    * CAS latency: The CAS latency is the delay, in clock cycles, between the registration of a READ command and the availability of the first piece of output data.
    * Operating Mode: The normal operating mode is selected by setting M7 and M8 to zero; the other combinations of values for M7 and M8 are reserved for future use and/or test modes. The programmed burst length applies to both READ and WRITE bursts.
    * Write Burst Mode: When M9 = 0, the burst length programmed via M0-M2 applies to both READ and WRITE bursts; when M9 = 1, the programmed burst length applies to READ bursts, but write accesses are single-location (nonburst) accesses.
    * Reserved: Should program M10, M11 and M12= "0, 0, 0" to ensure compatibility with future devices.
  • Address Register: Loads the data present in the Address bus to decoded for access the Banks Memory Arrays.
  • Refresh Counter: Load all possibles row addresses values in the Refresh process.
  • Row-Address Mux: Selects the information from the Refresh Counter or from the Address Register.
  • Row/Column Address Latch/Decoder: These blocks decodes the data in address Register to get the Row or column in the Bank memory.
  • I/O gating - DQM Mask Logic: This block control the data stream(IN-OUT) depending of DQML and DQMH signals.

[edit] SDRAM commands

The SDRAM works with differents operation commands, wich We will explain in the next table:

NAME(FUNCTION) CS# RAS# CAS# WE# DQM ADDR DQs
COMMAND INHIBIT H X X X X X X
NO OPERATION L H H H X X X
ACTIVE(Select bank and activate row) L L H H X Bank/Row X
READ(Select bank and column, and start READ burst) L H L H L/H Bank/Column X
WRITE(Select bank and column, and start WRITE burst) L H L H L/H Bank/Column Valid
BURST TERMINATE L H H L X X Active
PRECHARGE(Deactivate row in bank or banks) L L H L X Code X
AUTO REFRESH(Enter self refresh mode) L L L H X X X
LOAD MODE REGISTER L L L L X Op-Code X
Write Enable/Output Enable - - - - L - Active
Write Inhibit/Output High-Z - - - - H - High-Z
  • COMMAND INHIBIT: The COMMAND INHIBIT function prevents new commands from being executed by the SDRAM. Operations already in progress are not affected.
  • NO OPERATION: The NO OPERATION (NOP) command is used to perform a NOP to an SDRAM which is selected (CS# is LOW). This prevents unwanted commands from being Registered during idle or wait states. Operations already in progress are not affected.
  • ACTIVE: The ACTIVE command is used to open (or activate) a row in a particular bank for a subsequent access. This row remains active (or open) for accesses until a PRECHARGE command is issued to that bank.
  • READ: The READ command is used to initiate a burst read access to an active row. The value on the BA0, BA1 inputs selects the bank, and the address provided on inputs A0-A9 selects the starting column location. The value on input A10 determines whether or not auto precharge is used.
  • WRITE: The WRITE command is used to initiate a burst write access to an active row. The value on the BA0, BA1 inputs selects the bank, and the address provided on inputs A0-A9 selects the starting column location. The value on input A10 determines whether or not auto precharge is used.
  • BURST TERMINATE: The BURST TERMINATE command is used to truncate either fixed-length or full-page bursts.
  • PRECHARGE: The PRECHARGE command is used to deactivate the open row in a particular bank or the open row in all banks.
  • AUTO REFRESH: AUTO REFRESH is used during normal operation of the SDRAM and is analogous to CAS#-BEFORE-RAS# (CBR) REFRESH in conventional DRAMs. This command is nonpersistent, so it must be issued each time a refresh is required. All active banks must be precharged prior to issuing an AUTO REFRESH command.
  • LOAD MODE REGISTER: The mode register is loaded via inputs A0-A11 (A12 should be driven LOW.)

[edit] SDRAM Operations

[edit] Bank/Row Activation

Before any READ or WRITE commands can be issued to a bank within the SDRAM, a row in that bank must be “opened.” This is accomplished via the ACTIVE command. After opening a row a READ or WRITE command may be issued to that row. A subsequent ACTIVE command to a different row in the same bank can only be issued after the previous active row has been “closed” (precharged). A subsequent ACTIVE command to another bank can be issued while the first bank is being accessed, which results in a reduction of total row-access overhead.

Time diagram of a Bank/Row Activating operation

The READ or WRITE command must be issued subject to the tRCD specification. tRCD (MIN) should be divided by the clock period and rounded up to the next whole number to determine the earliest clock edge after the ACTIVE command on which a READ or WRITE command can be entered. For example, a tRCD specification of 20ns with a 125 MHz clock (8ns period) results in 2.5 clocks, rounded to 3.

Time diagram in example with tRCD= 20ns, 125MHz clock




[edit] READ Burst

READ bursts are initiated with a READ command. The starting column and bank addresses are provided with the READ command, and auto precharge is either enabled or disabled for that burst access. If auto precharge is enabled, the row being accessed is precharged at the completion of the burst. For the generic READ commands used in the following illustrations, auto precharge is disabled.

Time diagram of a Read Burst

During READ bursts, the valid data-out element from the starting column address will be available following the CAS latency after the READ command. Each subsequent data-out element will be valid by the next positive clock edge. When a burst is finished, assuming no other commands have been initiated, the DQs will go High-Z. A full-page burst will continue until terminated.

Data from any READ burst may be truncated with a subsequent READ command, and data from a fixed length READ burst may be immediately followed by data from a READ command. In either case, a continuous flow of data can be maintained. The first data element from the new burst follows either the last element of a completed burst or the last desired data element of a longer burst that is being truncated. The new READ command should be issued x cycles before the clock edge at which the last desired data element is valid, where x equals the CAS latency minus one.

Two Burst sequence

[edit] SDRAM on BEN NANONOTE

In this section we will explain some examples of aplications in the Nanonote, where we will include code segments of configuration files to ilustrate How configurate the SDRAM.

[edit] SDRAM Parameters

We need to define parameters like Data Bus width, Number of Banks, number of bits for the ROW and COLUMN Addressing, etc:

/*
 * SDRAM info.
 */

// SDRAM paramters
#define CFG_SDRAM_BW16		        0	/* Data bus width: 0-32bit, 1-16bit */
#define CFG_SDRAM_BANK4		1	/* Banks each chip: 0-2bank, 1-4bank */
#define CFG_SDRAM_ROW		        12	/* Row address: 11 to 13 */
#define CFG_SDRAM_COL		        8	/* Column address: 8 to 12 */
#define CFG_SDRAM_CASL		        2	/* CAS latency: 2 or 3 */

// SDRAM Timings, unit: ns
#define CFG_SDRAM_TRAS		        45	/* RAS# Active Time */
#define CFG_SDRAM_RCD		        20	/* RAS# to CAS# Delay */
#define CFG_SDRAM_TPC		        20	/* RAS# Precharge Time */
#define CFG_SDRAM_TRWL		        7	/* Write Latency Time */
#define CFG_SDRAM_TREF		        7812	/* Refresh period: 8192 refresh cycles/64ms */

Also, we need to define the times parameters for the different operations like Activation of columns and rows, Precharge, write burst or Refresh. This timings are necesaries for the synchronism between the different functions. This code must be included in the board header(board.h)

[edit] SDRAM definition

We have a chip header where we define all periferical devices; in this case, for the SDRAM, we have the following lines:

/* SDRAM Bank Address Configuration Register */
#define EMC_DMAR_BASE_BIT	8
#define EMC_DMAR_BASE_MASK	(0xff << EMC_DMAR_BASE_BIT)
#define EMC_DMAR_MASK_BIT	0
#define EMC_DMAR_MASK_MASK	(0xff << EMC_DMAR_MASK_BIT)

/* Mode Register of SDRAM bank 0 */
#define EMC_SDMR_BM		(1 << 9)        /* Write Burst Mode */
#define EMC_SDMR_OM_BIT		7       /* Operating Mode */
#define EMC_SDMR_OM_MASK	(3 << EMC_SDMR_OM_BIT)
#define EMC_SDMR_OM_NORMAL	(0 << EMC_SDMR_OM_BIT)
#define EMC_SDMR_CAS_BIT	4       /* CAS Latency */
#define EMC_SDMR_CAS_MASK	(7 << EMC_SDMR_CAS_BIT)
#define EMC_SDMR_CAS_1 	(1 << EMC_SDMR_CAS_BIT)
#define EMC_SDMR_CAS_2 	(2 << EMC_SDMR_CAS_BIT)
#define EMC_SDMR_CAS_3 	(3 << EMC_SDMR_CAS_BIT)
#define EMC_SDMR_BT_BIT		3       /* Burst Type */
#define EMC_SDMR_BT_MASK	(1 << EMC_SDMR_BT_BIT)
#define EMC_SDMR_BT_SEQ	(0 << EMC_SDMR_BT_BIT)  /* Sequential */
#define EMC_SDMR_BT_INT	(1 << EMC_SDMR_BT_BIT)  /* Interleave */
#define EMC_SDMR_BL_BIT		0       /* Burst Length */
#define EMC_SDMR_BL_MASK	(7 << EMC_SDMR_BL_BIT)
#define EMC_SDMR_BL_1		(0 << EMC_SDMR_BL_BIT)
#define EMC_SDMR_BL_2		(1 << EMC_SDMR_BL_BIT)
#define EMC_SDMR_BL_4		(2 << EMC_SDMR_BL_BIT)
#define EMC_SDMR_BL_8		(3 << EMC_SDMR_BL_BIT)

#define EMC_SDMR_CAS2_16BIT \
  (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2)
#define EMC_SDMR_CAS2_32BIT \
  (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4)
#define EMC_SDMR_CAS3_16BIT \
  (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2)
#define EMC_SDMR_CAS3_32BIT \
  (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4)

In this code we found two principal definitions: The Bank-Address Configuration Register and The Mode Register. For the first case, we define the BASE BIT which is necessary to the de-codification to the address data to know in which one bank, row and column will be stored the information. For this goal we need too a BASE MASK, with this one we apply a AND operation between the mask and the address obtained to the addressing.

[edit] SDRAM GPIO's

/*
 * D0 ~ D31, A0 ~ A16, DCS#, RAS#, CAS#, CKE#, 
 * RDWE#, CKO#, WE0#, WE1#, WE2#, WE3#
 */
#define __gpio_as_sdram_32bit()			\
do {						\
	REG_GPIO_PXFUNS(0) = 0xffffffff;	\
	REG_GPIO_PXSELC(0) = 0xffffffff;	\
	REG_GPIO_PXFUNS(1) = 0x81f9ffff;	\
	REG_GPIO_PXSELC(1) = 0x81f9ffff;	\
	REG_GPIO_PXFUNS(2) = 0x07000000;	\
	REG_GPIO_PXSELC(2) = 0x07000000;	\
} while (0)

In this section, we define the addresses for the GPIO's available. Basically, we define three pairs of registers to access for the GPIO's, a Function Register (REG_GPIO_PXFUNS) and a Select Register (REG_GPIO_PXSELC). With this pair of registers, we can access to the GPIO's (by the DATA and ADDRESS bus) and know the function (DCS#, RAS#, CAS#, CKE#, RDWE#, CKO#, WE0#, WE1#, WE2#, WE3#) that we will use with this Inputs/Outputs.

[edit] SDRAM on Main file

Now, having the headers already defined, we define the SDRAM operation in the Main file of the aplication program:

static void sdram_init(void)
{
    register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;

    unsigned int cas_latency_sdmr[2] = {
        EMC_SDMR_CAS_2,
        EMC_SDMR_CAS_3,
    };

    unsigned int cas_latency_dmcr[2] = {
        1 << EMC_DMCR_TCL_BIT,  /* CAS latency is 2 */
        2 << EMC_DMCR_TCL_BIT   /* CAS latency is 3 */
    };

    int div[] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 };

    cpu_clk = CFG_CPU_SPEED;
    mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];

    //REG_EMC_BCR = 0;      /* Disable bus release */
    REG_EMC_RTCSR = 0;          /* Disable clock for counting */
    REG_EMC_RTCOR = 0;
    REG_EMC_RTCNT = 0;

    /* Fault DMCR value for mode register setting */
#define SDRAM_ROW0    11
#define SDRAM_COL0     8
#define SDRAM_BANK40   0

    dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) |
        ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) |
        (SDRAM_BANK40 << EMC_DMCR_BA_BIT) |
        (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) |
        EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];

    /* Basic DMCR value */
    dmcr = ((CFG_SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) |
        ((CFG_SDRAM_COL - 8) << EMC_DMCR_CA_BIT) |
        (CFG_SDRAM_BANK4 << EMC_DMCR_BA_BIT) |
        (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) |
        EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];

    /* SDRAM timimg */
    ns = 1000000000 / mem_clk;
    tmp = CFG_SDRAM_TRAS / ns;
    if (tmp < 4)
        tmp = 4;
    if (tmp > 11)
        tmp = 11;
    dmcr |= ((tmp - 4) << EMC_DMCR_TRAS_BIT);
    tmp = CFG_SDRAM_RCD / ns;
    if (tmp > 3)
        tmp = 3;
    dmcr |= (tmp << EMC_DMCR_RCD_BIT);
    tmp = CFG_SDRAM_TPC / ns;
    if (tmp > 7)
        tmp = 7;
    dmcr |= (tmp << EMC_DMCR_TPC_BIT);
    tmp = CFG_SDRAM_TRWL / ns;
    if (tmp > 3)
        tmp = 3;
    dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
    tmp = (CFG_SDRAM_TRAS + CFG_SDRAM_TPC) / ns;
    if (tmp > 14)
        tmp = 14;
    dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);

    /* SDRAM mode value */
    sdmode = EMC_SDMR_BT_SEQ |
        EMC_SDMR_OM_NORMAL |
        EMC_SDMR_BL_4 | cas_latency_sdmr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];

    /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
    REG_EMC_DMCR = dmcr;
    REG8(EMC_SDMR0 | sdmode) = 0;

    /* Wait for precharge, > 200us */
    tmp = (cpu_clk / 1000000) * 1000;
    while (tmp--);

    /* Stage 2. Enable auto-refresh */
    REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;

    tmp = CFG_SDRAM_TREF / ns;
    tmp = tmp / 64 + 1;
    if (tmp > 0xff)
        tmp = 0xff;
    REG_EMC_RTCOR = tmp;
    REG_EMC_RTCNT = 0;
    REG_EMC_RTCSR = EMC_RTCSR_CKS_64;   /* Divisor is 64, CKO/64 */

    /* Wait for number of auto-refresh cycles */
    tmp = (cpu_clk / 1000000) * 1000;
    while (tmp--);

    /* Stage 3. Mode Register Set */
    REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
    REG8(EMC_SDMR0 | sdmode) = 0;

    /* Set back to basic DMCR value */
    REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;

    /* everything is ok now */
}

In this code, we can see the definition of the commands of operation that we already explained, and we can see the differents stages to the correct function of the SDRAM. Also, is defined the Time specifications required for the synchronous operation of SDRAM.

[edit] References

[1] http://en.wikipedia.org/wiki/Synchronous_dynamic_random_access_memory

Personal tools
Namespaces
Variants
Actions
Navigation
interactive
Toolbox
Print/export