Al igual que la anterior consola portátil de Nintendo, el sistema gira en torno a un gran chip llamado CPU NTR. 'NTR' es la abreviatura de Nitro, el nombre en clave de la Nintendo DS original. Este Sistema en Chip (SoC, del inglés System-on-Chip) es también la continuación de una próspera alianza Nintendo-ARM, que tuvo sus inicios en la Game Boy Advance.
Antes de examinar las nuevas CPU, veamos cómo evolucionó ARM a finales de los años 90, pues ello influyó en la tecnología que acabaría integrando la Nintendo DS.
Los nuevos territorios de ARM
A mediados de los años 90, ARM recibía un creciente flujo de clientes del mercado móvil (antes de que los teléfonos se volvieran 'inteligentes'). Sin embargo, le costaba satisfacer a un sector concreto: la informática de alto rendimiento. El ARM7 era bien acogido por muchos dispositivos móviles, pero no llegaba a convencer ni a Apple (con su línea de PDA 'Newton') ni a Acorn (con su línea RiscPC), que comercializaban software que habría sacado partido de una CPU más rápida. Más allá de la ausencia de una solución de 64 bits (algo que MIPS ya comercializaba), ARM tampoco era capaz de producir una CPU que funcionase a más de 40 MHz. En definitiva, los cuellos de botella empezaban a acumularse.

La 'Digital Personal Workstation' modelo 433au (1997) de DEC, equipada con una CPU Alpha 21164A.
No obstante, durante la comercialización de la línea ARM7, ARM ya había comenzado a trabajar en un sucesor llamado ARM8, el primer intento de entrar en el mercado de alto rendimiento. De manera coincidente, Digital Equipment Corporation (DEC), la empresa estadounidense históricamente reconocida por su línea de máquinas PDP y VAX (los llamados 'miniordenadores') y por el sofisticado sistema operativo VMS, se enfrentaba al problema contrario: le costaba desarrollar una CPU de bajo consumo basada en sus soluciones de alto rendimiento.
Resultó que el modelo de licencias de ARM se convirtió en una oportunidad para DEC, que optó por desarrollar una nueva CPU tomando prestados elementos de ARM (su set de instrucciones y microarquitectura).
Al final, DEC tomó el diseño de datapath de su procesador RISC Alpha y, con la ayuda de ARM, lo fusionó con la microarquitectura de ARM . Esta colaboración dio lugar a la CPU StrongARM, lanzada en 1996 y orientada al sector del alto rendimiento.

Una CPU StrongARM a 233 MHz, parte de la tarjeta de mejora de CPU ofrecida para el Acorn RiscPC.
El StrongARM era una nueva CPU basada en ARM con las siguientes características :
- El set de instrucciones ARMv4. Si quieres saber más al respecto, ya lo analicé anteriormente en el artículo de la Game Boy Advance.
- Hasta 233 MHz de velocidad de reloj, aproximadamente un 583 % más rápido que el chip ARM7 más potente.
- Un pipeline de 5 etapas, un avance respecto al diseño original de 3 etapas.
- Un nuevo sistema de caché que implementa una arquitectura Harvard, con 16 KB asignados a instrucciones y otros 16 KB a datos.
- Este diseño ayudó a paliar los cuellos de botella de memoria (algo de lo que adolecía el modelo de von Neumann/Princeton).
Cabe mencionar que este chip seguía funcionando con una alimentación de 3,3 V, como los chips ARM anteriores. De hecho, el StrongARM requiere tan solo 2 voltios y disipa únicamente 1 vatio . En cambio, el chip Intel Pentium a 200 MHz requiere 3,5 V y disipa hasta 15,5 W .
Como cabía esperar, la repercusión en Acorn y Apple fue tal que ambas empresas lanzaron inmediatamente mejoras de CPU y nuevos modelos Newton, respectivamente, usando la invención de DEC.
Ese mismo año, ARM también lanzó su prometida CPU basada en ARM8, el ARM810. Era comparativamente más lenta y no ofrecía ventajas prácticas sobre el StrongARM. En otras palabras, llegó tarde al mercado y sin méritos suficientes para despertar interés comercial. En consecuencia, ARM centró su atención en mejorar la línea ARM7 para el mercado móvil. Sin embargo, el potencial de la CPU de DEC era tan disruptivo que ARM Holdings absorbió el diseño del StrongARM para producir su siguiente línea de CPU: la ARM9 (que es la que alberga la Nintendo DS).
Puntos de inflexión
Gracias al StrongARM, ARM también consolidó su posición en el mercado de dispositivos portátiles, desplazando por completo a MIPS y SuperH como alternativas viables. A partir de entonces, ARM estaba en camino de convertirse en la arquitectura más adoptada para dispositivos móviles .
Por desgracia para DEC, esta CPU sería su último gran logro antes de ser adquirida por Compaq en 1998. El destino del StrongARM quedaría entonces en manos de Intel, que continuó su desarrollo bajo la nueva línea 'Intel XScale'... hasta que liquidó la división para centrarse en CPU x86 de 'bajo consumo' (es decir, el Intel Atom) . Quince años después, Intel no solo perdió su oportunidad en el mercado móvil, sino que ahora se encuentra compitiendo cara a cara con ARM en el mercado de escritorio.
El SoC debut de Nintendo
El silicio de la Nintendo DS es una interesante confluencia entre tecnología asequible y pionera. Además de los avances ya mencionados, la CPU NTR (el SoC) sigue una arquitectura multiprocesador que alberga dos CPU ARM distintas: la ARM7TDMI y la ARM946E-S. Este diseño se realizó antes de que ARM Holdings lanzase oficialmente soluciones multiprocesador. Por tanto, su funcionamiento puede considerarse un tanto heterodoxo teniendo en cuenta la tecnología actual.
Aunque no es el primer sistema paralelo que analizamos en esta serie, su diseño difiere notablemente del resto. No estamos hablando de la configuración maestro-esclavo experimental que debutó en el Saturn, ni del enfoque de coprocesador del PS1 o la N64. La Nintendo DS incluye dos ordenadores en gran medida independientes que realizan operaciones exclusivas, cada uno con su propio bus dedicado. Esta metodología de diseño se conoce como multiprocesamiento asimétrico, y la resultante dependencia entre CPU condiciona el rendimiento global de la consola.
Veamos ahora las dos CPU.
ARM7TDMI

Estructura y componentes de la parte ARM7.
Empezando por la más conocida de las dos, la ARM7TDMI es la misma CPU de la Game Boy Advance, aunque ahora funciona a ~34 MHz, el doble de su velocidad original. Conserva todas sus características originales (especialmente Thumb).
En cuanto a los cambios: como los ingenieros de Nintendo colocaron el ARM7 junto a la mayoría de los puertos de E/S, esta CPU se encarga de arbitrar y gestionar las operaciones de E/S. De hecho, ningún otro procesador puede conectarse directamente a la E/S. Como puedes ver, este no es el procesador 'principal' que se encarga del sistema, sino el 'subprocesador' que alivia la carga de la CPU principal transfiriendo datos entre los distintos componentes.
ARM946E-S

Estructura y componentes de la parte ARM9.
Esta es la CPU 'principal' de la Nintendo DS: la ARM946E-S. Funciona a ~67 MHz, lo que no llega exactamente a la 'velocidad StrongARM'. Aun así, como parte de la serie ARM9, este núcleo no solo hereda todas las características de la ARM7TDMI y el StrongARM, sino que también incluye algunos añadidos que pueden resultar interesantes :
- La ISA ARMv5TE, una extensión de la ISA ARMv4 anterior y Thumb, con más instrucciones y un multiplicador más rápido.
- Si te fijas en el nombre del núcleo, la letra 'E' significa Enhanced DSP, lo que indica que muchas de estas nuevas instrucciones están relacionadas con aplicaciones de procesamiento de señal.
- El Thumb extendido se denomina a veces Thumb v2. Añade
BLXyBKPT, que facilitan el cambio entre los modos ARM y Thumb, y la depuración, respectivamente.
- Un pipeline de 5 etapas, al igual que las familias StrongARM y ARM8.
- 12 KB de caché L1: a diferencia de la ARM7TDMI, el nuevo núcleo incorpora caché y, al igual que el StrongARM basado en Harvard, asigna 8 KB a instrucciones y 4 KB a datos.
- La caché emplea un mecanismo de write-buffer, que permite actualizar la RAM de forma asíncrona para que la CPU pueda trabajar en otras tareas.
- 48 KB de Tightly-Coupled Memory (TCM): similar a la memoria Scratchpad, aunque aquí se discrimina entre instrucciones (32 KB) y datos (16 KB).
- Un coprocesador CP15 integrado. Actúa como una Memory Protection Unit (MPU), determinando qué rangos de memoria pueden accederse, cachearse o escribirse.
Nintendo también añadió los siguientes componentes en torno al núcleo:
- Una unidad de división y raíz cuadrada para acelerar estas operaciones, ya que el ARM9 por sí solo no es capaz de realizar este tipo de aritmética.
- Un controlador de Acceso Directo a Memoria (DMA, del inglés Direct Memory Access): acelera las transferencias de memoria sin depender de la CPU. Combinado con la caché, la CPU y el DMA pueden trabajar de forma potencialmente simultánea.
- La caché y el DMA pueden ofrecer un gran rendimiento, pero también introducen nuevos problemas, como la integridad y coherencia de datos. Los programadores deben, por tanto, mantener la consistencia de memoria manualmente, por ejemplo, vaciando el write buffer antes de activar el DMA.
Supongo que con un hardware así, es fácil imaginar el verdadero motivo por el que los niños adoraban esta consola, ¿no?
Interconexión
Hasta ahora he descrito cómo operan las dos CPU de forma individual. Pero el sistema solo funciona como un todo si ambas cooperan constantemente. Para lograrlo, ambas CPU se 'hablan' directamente mediante una unidad FIFO dedicada . Este bloque contiene dos colas de 64 bytes (con hasta 16 elementos cada una) para comunicación bidireccional.

Representación de la unidad FIFO.
La unidad FIFO funciona de la siguiente manera: la CPU 'emisora' (la que necesita transmitir un mensaje) coloca un bloque de datos de 32 bits en la cola, y la CPU que actúa como 'receptora' puede entonces extraer ese bloque de la cola y realizar con él las operaciones necesarias.
Cada vez que se escribe un valor en la cola, cualquiera de las dos CPU puede leerlo manualmente (sondeo). Sin embargo, esto implica comprobar repetidamente si hay nuevos valores, lo que puede resultar costoso. Como alternativa, puede activarse una unidad de interrupción para notificar al receptor cada vez que haya un nuevo valor en la cola.
Memoria principal
Al igual que su predecesora, la RAM está distribuida en distintas ubicaciones, lo que permite al sistema priorizar la colocación de los datos según la velocidad de acceso. En resumen, la memoria de uso general disponible es la siguiente :

La arquitectura de memoria de la Nintendo DS.
- 32 KB de Work RAM (WRAM) en un bus de 32 bits: para almacenar datos rápidos compartidos entre el ARM7 y el ARM9.
- Ten en cuenta que solo una CPU puede acceder a ella en cada momento.
- 64 KB de WRAM en un bus de 32 bits: también para datos rápidos, pero accesible únicamente por el ARM7.
- 4 MB de Pseudo-Static RAM (PSRAM) en un bus de 16 bits: un tipo más lento, disponible para ambas CPU y arbitrado por una unidad de interfaz de memoria.
- La PSRAM es una variante de la Dynamic RAM (DRAM) que, por el contrario, realiza sus ciclos de refresco internamente, comportándose así como la SRAM (la alternativa más rápida pero más costosa a la DRAM). Este diseño me recuerda a la 1T-SRAM.
Compatibilidad con versiones anteriores
Aunque la arquitectura de la Nintendo DS supone una ruptura radical con su predecesora, esta consola logró conservar los elementos críticos que permiten la compatibilidad nativa con los juegos de Game Boy Advance.
Para que la DS se transforme en una GBA, la consola incluye un conjunto de rutinas de software que la sitúan en el AGB Compatibility Mode. Al activarse, estas rutinas detienen el ARM9, deshabilitan la mayor parte del hardware nuevo, redirigen los buses, ponen el ARM7 al mando y reducen su velocidad de reloj a 16,78 MHz. Por último, el ARM7 ejecuta la BIOS AGB original, que arranca el cartucho GamePak (igual que una Game Boy Advance original).
El modo AGB también presenta algunas características ausentes en la consola original, como mostrar el juego con márgenes negros (ya que la nueva resolución de pantalla es mayor). Además, dado que la DS tiene dos pantallas, los usuarios pueden elegir en cuál se mostrará el juego de GBA.
Por último, una vez en modo AGB, no hay vuelta atrás. Hay que reiniciar la consola para reactivar el nuevo hardware.
Potencia desaprovechada
Con tantos componentes sofisticados integrados en un único chip asequible, no es ningún misterio que surgieran algunos problemas derivados de la forma en que se vieron obligados a trabajar juntos.
Empecemos por el ARM9: esta CPU funciona al doble de velocidad que el ARM7, pero la mayor parte (si no toda) la E/S corre a cargo del ARM7. Por ello, el ARM9 tiende a sufrir bloqueos excesivos mientras espera que el ARM7 responda a las solicitudes de E/S.
Además, el bus de la PSRAM tiene solo 16 bits de ancho (siguiendo aún el modelo de la EWRAM de la Game Boy Advance) y funciona a la mitad de la velocidad de reloj del ARM9. En consecuencia, cada vez que cualquiera de las CPU necesita leer una palabra de 32 bits de la memoria, la interfaz bloquea la CPU e introduce hasta tres 'ciclos de espera' mientras se reconstruye la palabra completa.
El grado de bloqueo varía considerablemente en función del tipo de transferencia (lectura de instrucciones o datos) y del ancho de transferencia (16 o 32 bits). El peor caso se da durante la lectura no secuencial de datos de 32 bits, donde el ARM9 emplea cinco ciclos por transferencia. Esto mejora cuando los datos son secuenciales: los tiempos de transferencia se reducen a un solo ciclo. Sin embargo, el ARM9 no admite lecturas secuenciales de opcodes, por lo que las lecturas de instrucciones no se benefician de esta mejora. En otras palabras, las penalizaciones son las mismas independientemente de si las instrucciones son adyacentes.
En definitiva, esto significa que en el peor caso, los imponentes 66 MHz del ARM9 se reducen en la práctica a tan solo ~8 MHz. Es decir, si el programa hace un uso pésimo de la caché y la TCM. En situaciones así, me pregunto si Nintendo podría haber mitigado el problema simplemente aumentando la cantidad de RAM interna rápida. También me pregunto si esto no es más que deuda técnica arrastrada en aras de la compatibilidad con versiones anteriores.
En cualquier caso, para un informe detallado, recomiendo consultar los tiempos documentados por Martin Korth .
