SDRAM/es

From Qi-Hardware
Jump to: navigation, search
La SDRAM es una memoria dinámica de acceso aleatorio (DRAM por sus siglas en inglés Dynamic Random Access Memory) que tiene una interfáz sincrónica. Esto significa que se espera una señal de reloj antes de responder a las entradas de control y por lo tanto está sincronizada con el bus de sistema, a diferencia de la DRAM que tiene una interfaz asíncrona lo que significa que responde lo antes posible a los cambios en las entradas de control.[1]
Chip SDRAM en la board de un Nanonote

Contents

[edit] Funcionamiento

La SDRAM está conectada al procesador mediante un bus de datos, uno de direcciones y un bus de control. El bus de datos bidireccional, esto significa que el chip puede enviar o Recibir información a ser almacenada o utilizada por el procesador. A través del bus de direcciones el procesador puede acceder a la información almacenada en el chip que está distribuída en "bloques" a los que se accede por filas y columnas, ó también puede mediante ese bus, indicar la dirección donde se almacenarán nuevos datos. Finalmente, el bus de control lleva las señales de los comandos necesarios para la operación correcta entre el chip y el procesador. Estas señales tienen la tarea de establecer el protocolo de comunicación entre las dos partes.

[edit] Configuración

Una SDRAM está organizada como una matriz de celdas, con un número de bits para las direcciones de las filas y otro número de bits para las direcciones de las columnas. La memoria se distribuye en 4 bancos cada uno con una matriz de 8,192 líneas x 512 columnas x 16 bits, lo que corresponde a 67.108.864 de bits por banco, o 268.435.456 bits en los cuatro bancos (33.554.432 octetos ---> de 32MB aprox).
Estructura de un bloque en una SDRAM

Un bit de memoria en la SDRAM corresponde a un transistor y un condensador, el transistor suministra la carga y el condensador almacena el estado de cada bit. Con el tiempo, la carga del condensador desaparece, así que es necesario volver a cargar cada condensador periódicamente, esa tarea se llama REFRESH (Refrescar). Este proceso se simplifica con un comando AUTO REFRESH (auto refrescar)[2], que refresca una fila en cada banco al mismo tiempo.

[edit] Diagrama de bloques de la SDRAM

Diagrama de bloques de memoria SDRAM

Podemos ver en la imagen el diagrama de bloques de un chip de memoria SDRAM. Todos los bloques y las líneas se explican a continuación:

[edit] Descripción de Señales

SEÑAL Tipo Descripción
CLK Entrada Clock (Reloj): La señal CLK es manejada por el reloj del sistema. Todas las demás señales de entrada son muestreadas en el flanco de subida de CLK. Esta señal también incrementa el contador interno de acceso consecutivo (Burst Counter en inglés) y controla los registros de salida.
CKE Entrada Clock Enable (Habilitar Reloj): La señal CKE activa (HIGH) o desactiva (LOW), la señal CLK. Desactivar el reloj implica que se activen las operaciones PRECHARGE (Precarga) y SELF REFRESH (auto refrescar) dejando todos los bancos inactivos; POWER-DOWN (Apagado, con una fila activa en algún banco); ó CLOCK SUSPEND (Suspender Reloj) que suspende cualquier acceso consecutivo o normal que esté en progeso. La señal CKE es sincrónica, salvo cuando el dispositivo entra en modo POWER-DOWN ó SELF REFRESH, donde se convierte en asíncrona hasta después de salir de esos modos. Las líneas de entrada, incluída CLK, se desactivan durante el modo apagado y auto refrescar, proporcionando un bajo consumo de energía en estado de espera. Para estar activida, la señal CKE debe tener un nivel ALTO.
CS# Entrada Chip Select (Seleccionar chip): La señal CS# activa (LOW) y desactiva (HIGH) el decodificador de comandos. Todos los comandos serán ignorados cuando CS# tenga un nivel ALTO. También permite la selección de bancos externos en los sistemas con múltiples bancos. CS# se considera parte del código de comando.
CAS#, RAS#, WE# Entrada Column Address Strobe (Selección de Dirección de Columna) - Row Address Strobe (Selección de Dirección de Fila) - Write Enable (Habilitar Escritura): definen el comando a ejecutrar junto con CS#.
DQML, DQMH Entrada Input/Output Mask (Máscara de Entrada/Salida): DQM es una señal que desactiva la de entrada de datos para los accesos de escritura y la salida de datos para accesos de lectura. Los datos de entrada se ignoran cuando DQM tiene un nivel ALTO durante un ciclo WRITE (Escritura). Las líneas de salida se coloca en un estado de alta impedancia (cons dos ciclos de reloj de retrazo) cuando DQM tiene un nivel ALTO durante un ciclo de LECTURA.
BA0, BA1 Entrada Bank Address Inputs (Entradas de dirección de Banco): BA0 y BA1 definen a qué banco se están enviando los comandos ACTIVE, READ, READ Y PRECHARGE.
A0-A12 Entrada Address Inputs (Entradas de Dirección): Las entradas A0-A12 son leídas durante los comando ACTIVE (dirección-fila A0-A12) y READ/WRITE (dirección-columna A0-A9, A11 [x4]; A0-A9[x8]; A0-A8 [x16]; siendo A10 la entrada que define la precarga automática) para seleccionar una ubicación de la tabla de memoria en el banco respectivo. A10 es leída durante un comando PRECHARGE (Precarga) para determinar si todos los bancos han de ser precargados (A10 [ALTA]) o el banco seleccionado por BA0 y BA1 (A10 [LOW]). Las entradas de dirección también proporcionan el código de operación durante el comando LOAD MODE REGISTER (Cargar el Registro de Modo).
DQ0-DQ15 Entrada Data Inputs (Entradas de Datos): Bus de datos.

[edit] Descripción de Bloques

  • Control Logic (Control Lógico): Este bloque controla el Registro de Modo y la Unidad de Control Lógico de bancos. Básicamente, este bloque decodifica las señales de control para el correcto funcionamiento entre los demás bloques.
  • Mode Register (Registro de Modo): Este es un registro programable que especifica el modo de operación de la SDRAM. Esta definición incluye la selección de la longitud de un acceso consecutivo (ó Burst Lenght en inglés), el tipo de acceso consecutivo (Burst Type), la latencia CAS (Column Address Strobe), el modo de funcionamiento (Operating Mode) y el modo de escritura consecutiva (Write Burst Mode). El registro de modo se carga con la información del bus de direcciones durante el comando LOAD MODE REGISTER (Cargar registro de modo). Este debe ser programado cuando todos los bancos están ianctivos, y el controlador debe esperar el tiempo especificado antes de iniciar la próxima operación.
    Diagrama del Registro de Modo.

    ----
    * Burst length (Longitud de acceso consecutivo): La longitud de acceso consecutivo determina el número máximo de ubicaciones de la columna a las que puede acceder a un comando READ ó WRITE determinado.
    * Burst Type (Tipo de acceso consecutivo): Una acceso consecutivo determinado puede ser programado para ser "secuencial" o "intercalado". Esto se conoce como el tipo de acceso consecutivo.
    * CAS latency (Latencia CAS): La latencia CAS (Column address strobe latency) es el retraso, en ciclos de reloj, entre el registro de un comando de lectura y la disponibilidad de la primera porción de datos.< br> * Operating Mode (Modo de funcionamiento): El modo de funcionamiento normal se selecciona mediante el establecimiento de M7 y M8 a cero, las otras combinaciones de valores para M7 y M8 están reservadas para uso futuro y/o modalidades de prueba. La longitud del acceso consecutivo programada se aplica tanto al comando READ como WRITE.
    * Write Burst Mode (Modo de escritura consecutiva): Cuando M9 = 0, la longitud de acceso consecutivo programada a través de M0-M2 se aplica al comando READ y WRITE, per cuando M9 = 1, la longitud de acceso consecutivo programada se aplica solo al comando READ, y los accesos de escritura son de un solo lugar (nonburst).
    * Reserved (Reservados): Se deben programar M10, M11 y M12 = "0, 0, 0" para garantizar la compatibilidad con los dispositivos futuros.
  • Address Register (Registro de Direcciones): Carga los datos presentes en el bus de direcciones para decodificarlos y acceder a los bancos de memoria.
  • Refresh Counter(Contador de Refresco): Carga todas las direcciones de fila posibles durante el proceso de refresco.
  • Row-Address Mux (Mux Dirección-Fila): Selecciona la información desde el contador de refresco durante el modo AUTO REFRESH, o desde el Registro de direcciones durante los accesos normales.
  • Row/Column Address Latch/Decoder (RETENEDOR/DECODIFICADOR de Dirección Fila/Columna): Estos bloques decodifican los datos del Registro de dirección para obtener la fila o columna en la memoria del Banco.
  • I/O gating - DQM Mask Logic (Máscara DQM de Entrada/Salida): Este bloque controla el flujo de datos (ENTRADA-SALIDA), en función de las eñales DQML y DQMH.

[edit] Comandos SDRAM

La SDRAM funciona con varios comandos de funcionamiento, que se explican en la siguiente tabla:

NOMBRE(FUNCIÓN) CS# RAS# CAS# WE# DQM ADDR DQs
COMMANDO INHIBIT H X X X X X X
NO OPERATION L H H H X X X
ACTIVE(Selecciona el banco y activa la fila) L L H H X Banco/Fila X
READ(Selecciona el banco, la columna, e inicia el acceso consecutivo de lectura) L H L H L/H Banco/Columna X
WRITE(Selecciona el banco, la columna, e incia el acceso consecutivo de escritura) L H L H L/H Banco/Columna Válido
BURST TERMINATE L H H L X X Activo
PRECHARGE(Desactiva la fila en el banco o bancos) L L H L X Código X
AUTO REFRESH(Entra en modo SELF REFRESH) L L L H X X X
LOAD MODE REGISTER L L L L X Op-Code X
Write Enable/Output Enable - - - - L - Activo
Write Inhibit/Output High-Z - - - - H - High-Z
  • INHIBIT (Inhibir): El comando INHIBIT impide que nuevos comandos sea ejecutados por la SDRAM. Las operaciones ya en curso no se ven afectadas.
  • NO OPERATION (No Hacer Nada): Este comando se utiliza para realizar un NOP en una SDRAM que se haya seleccionado (CS# está en nivel LOW). Esto evita que los comandos no deseados que se registran durante la inactividad o estados de espera sean ejecutados. Las operaciones ya en curso no se ven afectados.
  • ACTIVE (Activa): El comando ACTIVE se utiliza para abrir (o activar) una fila de un banco en particular para un acceso posterior. Esta fila se mantiene activa (o abierta) para los accesos hasta que un comando PRECHARGE se entrega a ese banco.
  • READ (Leer): El comando READ se utiliza para iniciar un acceso consecutivo de lectura (Burst Read) a una fila activa. El valor de las entradas BA0 y BA1 selecciona el banco, y la dirección facilitada en las entradas A0-A9 selecciona la ubicación de la columna de inicio para la lectura. El valor de la entrada A10 determina si se utiliza la precarga automática.
  • WRITE (Escribir): El comando escribir es utilizado para iniciar un acceso consecutov de escritura (Burst Write) a una fila activa. El valor de las entradas BA0 y BA1 selecciona el banco, y la dirección facilitada en las entradas A0-A9 selecciona la ubicación de la columna de incio para la escritura. El valor de la A10 de entrada determina si se utiliza la precarga automática.
  • BURST TERMINATE (Terminar el acceso): El comando BURST TERMINATE se utiliza para detener el acceso consecutivo que está en progeso sin importar de qué tipo sea.
  • PRECHARGE (Precargar): El comando de precarga se utiliza para desactivar la fila abierta en un banco en particular o de la fila abierta en todos los bancos.
  • AUTO REFRESH (Auto Refrescar): Auto Refresh se utiliza durante el funcionamiento normal de la SDRAM y es análoga a CAS#-BEFORE-RAS# (CBR) de refresco de las DRAM convencionales. Este comando es no persistente, por lo que debe ser ejecutado cada vez que una actualización sea necesaria. Todos los bancos de activos debe estar precargados antes de usar el comando Auto Refresh.
  • LOAD MODE REGISTER (Cargar Registro de Modo): El Registro de modo se carga a través de las entradas A0-A11 (A12 debe tener nivel LOW).

[edit] Operaciones SDRAM

[edit] Activación de Banco / Fila

Antes de ejecutar cualquier comando de lectura o escritura en un banco de la SDRAM, una fila en dicho banco debe ser "abierta". Esto se logra a través del comando ACTIVE. Después de la apertura de una fila, un comando READ o WRITE puede llevarse a cabo en esa fila. Un comando ACTIVE posterior aplicado a una fila diferente en el mismo banco sólo puede ejecutarse después que la fila activada anteriormente haya sido "cerrada" (precargada). Un comando ACTIVE posterior puede ejecutarse en otro banco mientras el primer banco está siendo accedido, lo que resulta en una reducción del total de sobrecarga de acceso a filas.

Diagrama de tiempo de una Activación de Banco/Fila

El comando READ o WRITE debe estar sujeto a la especificación tRCD. tRCD (MIN) debe ser dividido por el período de reloj y redondeado al número entero inmediatamente mayor, con el fin de determinar el flanco de subida de la señal de reloj más próximo después del comando ACTIVE en el cual se pueda enviar una orden de Escritura o Lectura. Por ejemplo, una especificación de tRCD de 20ns con un reloj de 125 MHz (período de 8ns) da como resultado 2,5 ciclos, así que se redondea a 3.

Diagrama de Tiempo para el ejemplo con tRCD= 20ns y 125MHz




[edit] Lectura consecutiva

Un acceso consecutivo de lectura se inicia con el comando READ. La columna de partida y la dirección del banco se proporcionan con el comando READ, y la precarga automática también es habilitada o deshabilitada junto con la orden. Si se activa la precarga automática, la fila a la que se está accediendo será precargada justo después de terminar la lectura actual. Para los comandos READ que se utilizan en las ilustraciones siguientes, la precarga automática está desactivada.

Diagrama de tiempo de una lectura consecutiva

Durante las lecturas consecutivas, la información de salida válida de la dirección de la columna de inicio estará disponible transcurrida la latencia CAS después del comando READ. Cada uno de los datos posteriores será válido en el siguiente ciclo de reloj. Cuando una lectura consecutiva haya terminado, suponiendo que otros comandos no hayan sido iniciados, las líneas DQs irán a un estado de alta impedancia. En el caso de una lectura de página completa, el acceso consecutivo continuará hasta la temrinación de la página entregando un elemento de dato cada ciclo de reloj.

Los datos de cualquier lectura consecutiva pueden ser interrumpidos con un comando READ posterior, y los datos de una lectura consecutiva de longitud fija puede ser seguida de inmediato por los datos de un comando READ. En cualquier caso, un flujo continuo de datos puede ser mantenido. El primer elemento de datos de una nueva lectura consecutiva puede seguir bien sea el uĺtimo datos de una lectura previa completada, o bien el último dato deseado de una lectura más larga que está siendo interrumpida. El nuevo comando READ debe ejecutarse X número de ciclos antes del flanco ascedente de reloj en el que el último elemento de datos deseado sea válido, donde X es igual a la latencia CAS menos uno.

Secuencia de dos accesos consecutivos


[edit] SDRAM en el Ben NANONOTE

En esta sección se explicarán algunos ejemplos de aplicaciones en el Nanonote, donde se incluyen segmentos de código de los archivos de configuración para ilustrar cómo configurar la SDRAM.

[edit] Parámetros SDRAM

Hay que definir los parámetros como el ancho del bus de datos, número de bancos, número de bits para el direccionamiento de filas y columnas, etc:

  1.  
  2.  /*
  3.   * SDRAM info.
  4.   */
  5.  
  6.  // SDRAM paramters
  7.  #define CFG_SDRAM_BW16		        0	/* Data bus width: 0-32bit, 1-16bit */
  8.  #define CFG_SDRAM_BANK4		1	/* Banks each chip: 0-2bank, 1-4bank */
  9.  #define CFG_SDRAM_ROW		        12	/* Row address: 11 to 13 */
  10.  #define CFG_SDRAM_COL		        8	/* Column address: 8 to 12 */
  11.  #define CFG_SDRAM_CASL		        2	/* CAS latency: 2 or 3 */
  12.  
  13.  // SDRAM Timings, unit: ns
  14.  #define CFG_SDRAM_TRAS		        45	/* RAS# Active Time */
  15.  #define CFG_SDRAM_RCD		        20	/* RAS# to CAS# Delay */
  16.  #define CFG_SDRAM_TPC		        20	/* RAS# Precharge Time */
  17.  #define CFG_SDRAM_TRWL		        7	/* Write Latency Time */
  18.  #define CFG_SDRAM_TREF		        7812	/* Refresh period: 8192 refresh cycles/64ms */

Además, se definieron los parámetros de los tiempos para las distintas operaciones, como la activación de las columnas y filas, precarga, escribir o Actualizar. Estos tiempos son necesarios para la sincronización de las diferentes funciones. Este código debe ser incluido en la cabecera de la board (board.h)

[edit] Definiendo de la SDRAM

Existe un archivo cabecera de un chip, en donde se definen todos los dispositivos periférico, en este caso, para la SDRAM, se tienen las siguientes líneas:

  1.  
  2. /* SDRAM Bank Address Configuration Register */
  3.  #define EMC_DMAR_BASE_BIT	8
  4.  #define EMC_DMAR_BASE_MASK	(0xff << EMC_DMAR_BASE_BIT)
  5.  #define EMC_DMAR_MASK_BIT	0
  6.  #define EMC_DMAR_MASK_MASK	(0xff << EMC_DMAR_MASK_BIT)
  7.  
  8.  /* Mode Register of SDRAM bank 0 */
  9.  #define EMC_SDMR_BM		(1 << 9)        /* Write Burst Mode */
  10.  #define EMC_SDMR_OM_BIT		7       /* Operating Mode */
  11.  #define EMC_SDMR_OM_MASK	(3 << EMC_SDMR_OM_BIT)
  12.  #define EMC_SDMR_OM_NORMAL	(0 << EMC_SDMR_OM_BIT)
  13.  #define EMC_SDMR_CAS_BIT	4       /* CAS Latency */
  14.  #define EMC_SDMR_CAS_MASK	(7 << EMC_SDMR_CAS_BIT)
  15.  #define EMC_SDMR_CAS_1 	(1 << EMC_SDMR_CAS_BIT)
  16.  #define EMC_SDMR_CAS_2 	(2 << EMC_SDMR_CAS_BIT)
  17.  #define EMC_SDMR_CAS_3 	(3 << EMC_SDMR_CAS_BIT)
  18.  #define EMC_SDMR_BT_BIT		3       /* Burst Type */
  19.  #define EMC_SDMR_BT_MASK	(1 << EMC_SDMR_BT_BIT)
  20.  #define EMC_SDMR_BT_SEQ	(0 << EMC_SDMR_BT_BIT)  /* Sequential */
  21.  #define EMC_SDMR_BT_INT	(1 << EMC_SDMR_BT_BIT)  /* Interleave */
  22.  #define EMC_SDMR_BL_BIT		0       /* Burst Length */
  23.  #define EMC_SDMR_BL_MASK	(7 << EMC_SDMR_BL_BIT)
  24.  #define EMC_SDMR_BL_1		(0 << EMC_SDMR_BL_BIT)
  25.  #define EMC_SDMR_BL_2		(1 << EMC_SDMR_BL_BIT)
  26.  #define EMC_SDMR_BL_4		(2 << EMC_SDMR_BL_BIT)
  27.  #define EMC_SDMR_BL_8		(3 << EMC_SDMR_BL_BIT)
  28.  
  29.  #define EMC_SDMR_CAS2_16BIT \
  30.    (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2)
  31.  #define EMC_SDMR_CAS2_32BIT \
  32.    (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4)
  33.  #define EMC_SDMR_CAS3_16BIT \
  34.    (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2)
  35.  #define EMC_SDMR_CAS3_32BIT \
  36.    (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4)

En este código encontramos dos definiciones principales: El Registro de configuración de las direcciones de Bancos y el Registro de modo. Para el primer caso, se define un BASE BIT que es necesario para la decodificación de los datos de direcciones para saber en que banco, fila y columna se almacena la información. Para lograr este objetivo es necesario también una BASE MASK, con esta se aplica una operación AND entre la máscara y la dirección obtenida.

Específicamente se ajustaron los siguientes parámetros, asumiendo que finalmente se use la configuración de las líneas 35 y 36:

PARÁMETRO Valor OPCIÓN Línea
Burst Mode M9 = 1 Single Location Access 9
Operating Mode M8,M7 = 0,0 Standard Operation 12
Cas Latency M6,M5,M4 = 0,1,1 3 ciclos 17 y 36
Burst Type 0 Secuencial 20 y 36
Burst Lenght M2,M1,M0 = 0,1,0 4 datos consecutivos 26 y 36


[edit] SDRAM GPIO's

  1.  
  2.  /*
  3.   * D0 ~ D31, A0 ~ A16, DCS#, RAS#, CAS#, CKE#,
  4.   * RDWE#, CKO#, WE0#, WE1#, WE2#, WE3#
  5.   */
  6.  #define __gpio_as_sdram_32bit () 		\
  7.  do {						\
  8. 	REG_GPIO_PXFUNS (0) = 0xFFFFFFFF; 	\
  9.  	REG_GPIO_PXSELC (0) = 0xFFFFFFFF; 	\
  10.  	REG_GPIO_PXFUNS (1) = 0x81f9ffff; 	\
  11.  	REG_GPIO_PXSELC (1) = 0x81f9ffff; 	\
  12.  	REG_GPIO_PXFUNS (2) = 0x07000000; 	\
  13.  	REG_GPIO_PXSELC (2) = 0x07000000; 	\
  14.  } While (0)

En esta sección, se definen las direcciones para los GPIO (Puertos de E/S de propósito general) disponibles. Básicamente, se definen tres pares de registros de acceso para los GPIO, un Registro de función (REG_GPIO_PXFUNS) y un Registro de Selección (REG_GPIO_PXSELC). Con este par de registros, podemos acceder a la GPIO's (por los buses de datos y direcciones) y conocer la función (DCS#, RAS#, CAS#, CKE#, RDWE#, CKO#, WE0#, WE1#, WE2#, WE3#) que vamos a utilizar con estas entradas/salidas.

[edit] SDRAM en el archivo principal

Ahora, después de las cabeceras ya definidas, se define la operación de SDRAM en el archivo principal del programa:

  1.  
  2.  static void sdram_init(void)
  3.  {
  4.      register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
  5.  
  6.      unsigned int cas_latency_sdmr[2] = {
  7.          EMC_SDMR_CAS_2,
  8.          EMC_SDMR_CAS_3,
  9.      };
  10.  
  11.      unsigned int cas_latency_dmcr[2] = {
  12.          1 << EMC_DMCR_TCL_BIT,  /* CAS latency is 2 */
  13.          2 << EMC_DMCR_TCL_BIT   /* CAS latency is 3 */
  14.      };
  15.  
  16.      int div[] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 };
  17.  
  18.      cpu_clk = CFG_CPU_SPEED;
  19.      mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
  20.  
  21.      //REG_EMC_BCR = 0;      /* Disable bus release */
  22.      REG_EMC_RTCSR = 0;          /* Disable clock for counting */
  23.      REG_EMC_RTCOR = 0;
  24.      REG_EMC_RTCNT = 0;
  25.  
  26.      /* Fault DMCR value for mode register setting */
  27.  #define SDRAM_ROW0    11
  28.  #define SDRAM_COL0     8
  29.  #define SDRAM_BANK40   0
  30.  
  31.      dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) |
  32.          ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) |
  33.          (SDRAM_BANK40 << EMC_DMCR_BA_BIT) |
  34.          (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) |
  35.          EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
  36.  
  37.      /* Basic DMCR value */
  38.      dmcr = ((CFG_SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) |
  39.          ((CFG_SDRAM_COL - 8) << EMC_DMCR_CA_BIT) |
  40.          (CFG_SDRAM_BANK4 << EMC_DMCR_BA_BIT) |
  41.          (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) |
  42.          EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
  43.  
  44.      /* SDRAM timimg */
  45.      ns = 1000000000 / mem_clk;
  46.      tmp = CFG_SDRAM_TRAS / ns;
  47.      if (tmp < 4)
  48.          tmp = 4;
  49.      if (tmp > 11)
  50.          tmp = 11;
  51.      dmcr |= ((tmp - 4) << EMC_DMCR_TRAS_BIT);
  52.      tmp = CFG_SDRAM_RCD / ns;
  53.      if (tmp > 3)
  54.          tmp = 3;
  55.      dmcr |= (tmp << EMC_DMCR_RCD_BIT);
  56.      tmp = CFG_SDRAM_TPC / ns;
  57.      if (tmp > 7)
  58.          tmp = 7;
  59.      dmcr |= (tmp << EMC_DMCR_TPC_BIT);
  60.      tmp = CFG_SDRAM_TRWL / ns;
  61.      if (tmp > 3)
  62.          tmp = 3;
  63.      dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
  64.      tmp = (CFG_SDRAM_TRAS + CFG_SDRAM_TPC) / ns;
  65.      if (tmp > 14)
  66.          tmp = 14;
  67.      dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
  68.  
  69.      /* SDRAM mode value */
  70.      sdmode = EMC_SDMR_BT_SEQ |
  71.          EMC_SDMR_OM_NORMAL |
  72.          EMC_SDMR_BL_4 | cas_latency_sdmr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
  73.  
  74.      /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
  75.      REG_EMC_DMCR = dmcr;
  76.      REG8(EMC_SDMR0 | sdmode) = 0;
  77.  
  78.      /* Wait for precharge, > 200us */
  79.      tmp = (cpu_clk / 1000000) * 1000;
  80.      while (tmp--);
  81.  
  82.      /* Stage 2. Enable auto-refresh */
  83.      REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
  84.  
  85.      tmp = CFG_SDRAM_TREF / ns;
  86.      tmp = tmp / 64 + 1;
  87.      if (tmp > 0xff)
  88.          tmp = 0xff;
  89.      REG_EMC_RTCOR = tmp;
  90.      REG_EMC_RTCNT = 0;
  91.      REG_EMC_RTCSR = EMC_RTCSR_CKS_64;   /* Divisor is 64, CKO/64 */
  92.  
  93.      /* Wait for number of auto-refresh cycles */
  94.      tmp = (cpu_clk / 1000000) * 1000;
  95.      while (tmp--);
  96.  
  97.      /* Stage 3. Mode Register Set */
  98.      REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
  99.      REG8(EMC_SDMR0 | sdmode) = 0;
  100.  
  101.      /* Set back to basic DMCR value */
  102.      REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
  103.  
  104.      /* everything is ok now */
  105.  }

En este código, se definen los comandos de operación que ya se han explicado, y puede verse la etapa de configuración de la SDRAM. Además, se definen las especificaciones de tiempo necesario para el correcto funcionamiento sincrónico de SDRAM. En el siguiente diagrama se resume el proceso de este código.

Diagrama de inicialización de la SDRAM

[edit] Referencias

http://en.wikipedia.org/wiki/Synchronous_dynamic_random_access_memory http://arstechnica.com/paedia/r/ram_guide/ram_guide.part2-4.html#Load

Personal tools
Namespaces
Variants
Actions
Navigation
interactive
Toolbox
Print/export