Regístrate | Conectar
El Tamiz Libros Recursos Series Únete 10 Users Online
Skip to content

Computador mágico XXI – Ordenador C16A I: arquitectura de von Neumann




La serie “El computador mágico” está disponible también en forma de libro.

En los últimos capítulos hemos visto cómo hacer lógica combinacional, y hemos llegado al caso concreto de la unidad aritmético-lógica. Luego vimos la lógica secuencial y vimos que no nos gustaba tener que refabricar completamente el circuito cada vez que había que cambiar algo en el algoritmo. Hoy vamos a introducirnos en el mundo del software, mediante la arquitectura de von Neumann, uniendo algunos componentes que ya hemos visto también: los registros, la memoria de acceso aleatorio y una pantalla y un teclado sencillitos.

No obstante, abordar la arquitectura de von Neumann en abstracto es un poco complicado, así que vamos a mostrarlo con un ejemplo, inventándonos un ordenador que siga dicha arquitectura. Me vais a perdonar la pedantería de ponerle nombre a este ordenador: vamos a llamarlo C16A. C de Cedazo, 16 porque es de 16 bits y A porque habrá sucesivas versiones: B y C. El darle nombre no será importante ahora, pero cuando luego veamos las versiones B y C podremos diferenciarlos por su nombre.

Adelanto que este bloque dentro de la serie será duro, probablemente el más duro si no tienes experiencia en programación. Trataremos de hacer un viaje guiado, pero hay cosas que son intrínsecamente complicadas, y esta es una de ellas. Eso no quiere decir que sea imposible, obviamente: vamos a verlo de forma muy simplificada, para que pueda ser entendido, con un poco de esfuerzo, por cualquiera con un mínimo de ganas.

 

 

Como es difícil explicar la arquitectura de von Neumman en abstracto, vamos a hacer primero una explicación cualitativa para rápidamente pasar al ejemplo concreto del C16A.

La arquitectura de von Neumann fue propuesta, lógicamente, por John von Neumann durante la década de los 40 del siglo XX. Naturalmente, como siempre en ciencia, es difícil decir que se la inventó él solo sin ninguna influencia anterior (es importantísima el menos la influencia de Turing, pero también de muchos otros) y sin ningún apoyo de otros científicos (porque trabajaba integrado en un equipo), pero sí parece un hecho aceptado por la comunidad científica que su papel en su definición fue fundamental, y por eso llamamos a esta idea “arquitectura de von Neumann” en su honor.

Al parecer estaban trabajando en el proyecto Manhattan (el de la bomba atómica) y tenían ordenadores rudimentarios (parecidos a lo que nosotros hemos llamado circuitos secuenciales), pero que hacían cálculos complejísimos. El problema era que cada vez que había que cambiar un detalle en esos cálculos, por nimio que fuera, había que reconstruir el circuito (es decir, nada que no hayamos visto ya nosotros mismos). Así que se propusieron diseñar una máquina cuyo algoritmo se pudiera especificar en forma “blanda” en lugar de en forma “dura”. Fue en ese momento cuando nació la distinción entre el hardware y el software (qué bonito juego de palabras entre hard, duro, y soft, blando): hardware es la máquina en sí, el hierro, las puertas lógicas, los cables; y software es el algoritmo que “vive” y se ejecuta en el hardware. Así, cuando hubiera que cambiar el algoritmo, se cambiaría el software de forma sencilla en lugar del hardware, que es complicado. Para ello el hardware, en lugar de hacer operaciones complicadas y sofisticadas, hará solamente operaciones “sencillas”, básicas, en base a lo que le vaya diciendo dicho software.

Podemos resumir entonces la arquitectura de von Neumann en el siguiente esquema (dependiendo de la fuente que usemos, el esquema tendrá ligeras variaciones):

 

Puedes ver dos componentes principales: la CPU (Central Processing Unit, unidad central de proceso) y la Memoria. La CPU se divide a su vez en dos subbloques: la ALU (Arithmetic-Logic Unit, unidad aritmético-lógica) y la CU (Control Unit, unidad de control). La Memoria contiene tanto la Memoria Principal como los bloques de I/O (Input/Output, entrada/salida).

Tres de estos componentes los hemos visto ya: la ALU, la memoria principal y dos ejemplos de entrada y salida. El cuarto, la CU, la veremos en los próximos capítulos.

La gracia de estos bloques que componen la arquitectura de von Neumann no son tanto los bloques en sí, sino lo que intercambian entre ellos. La CU hace, como su nombre indica, de controlador de todos los demás; en la jerga se dice que da “microórdenes”, a través de la línea punteada. ¿En función de qué lo hace? Lo hace en función de la “instrucciones” que vienen de la Memoria Principal (la línea de rayas largas). Para ello tendrá que ir accediendo a determinadas direcciones de la Memoria (sea Memoria Principal o I/O; es la línea de rayas cortas) que provocarán un intercambio de datos con la ALU (línea sólida) y de instrucciones con la CU. Dicha ALU, como sabemos, se encargará de la operaciones aritméticas y lógicas.

Vamos a leerlo de otro modo, por si ayuda a entenderlo: el algoritmo (las instrucciones del programa, el software) vive en la Memoria Principal. Ese algoritmo se va entregando a la CU, que en función de dichas instrucciones va dando “capones” a los demás componentes, como un director de orquesta. Eso causará que los datos viajen desde la Memoria en donde viven (sea Memoria Principal o sea I/O) a la ALU, que operará con ellos y los devolverá a la Memoria (de nuevo, puede ser a la Memoria Principal o a la I/O).

Como sé que es complicado, vamos a leerlo de una tercera forma, un poco más abstracta. La CPU solo sabe hacer operaciones básicas. El software, que está en la Memoria Principal, dice cómo ir operando con los datos, que también están en la Memoria Principal, usando esas operaciones básicas para componer operaciones más complejas. De vez en cuando también habrá intercambio con los bloques de I/O para interactuar con el exterior (sea el usuario u otras máquinas).

A poco que sepas de tecnología informática, esta idea hoy en día no resulta nueva para ti… pero en su momento fue una revolución. Nosotros vamos a aprovechar esa idea para diseñar un ordenador sencillo, el C16A, con la siguiente arquitectura:

Fíjate en los componentes que lo forman:

  • MM es la memoria principal (Main Memory, en inglés), que ya hemos visto.
  • La pantalla y el teclado también los hemos visto.
  • La ALU también la hemos estudiado ya. Por si no la tienes fresca, recuerda que tiene dos entradas A y B (A es la de la izquierda) y una salida. Tiene cuatro operaciones básicas: sumar A+B, decrementar A, poner la salida a 0 y transferir B a la salida.
  • AC es un registro de 16 bits, donde almacenaremos temporalmente la salida de la ALU. AC viene de “acumulador”, porque en él se va acumulando el resultado.
  • CU es la unidad de control que hemos visto antes. Ya la veremos en detalle. Tiene un componente especialmente importante, que es el PC. PC significa contador de programa (del inglés, Program Counter), y es simplemente un registro de 12 bits. Lo que contiene es la posición, dentro de la memoria, de la siguiente instrucción a ejecutar. Ya lo veremos en detalle, no te obsesiones por entenderlo ahora.
  • Los buses A y D son los que ya hemos visto como bus de direcciones (del inglés address) y bus de datos (del inglés data).

Fíjate también en que no hemos dibujado las líneas de control (lo que eran las líneas punteadas en el dibujo de la arquitectura de von Neumann de más arriba). Eso no quiere decir que no estén: están, por supuesto, pero nos las ahorramos para no embarullar el dibujo. Por ejemplo, recordarás que la memoria tenía una entrada de control que decía si era lectura o escritura (la llamábamos R/W’); pues bien, esa señal viene de la CU. Simplemente no la dibujamos para no embarullar el dibujo. Lo mismo aplica a la señal de reloj: todos los registros (incluyendo la memoria y los dispositivos “que se comportan como memoria”, como la pantalla) reciben esa señal de reloj. Y lo mismo para la otra miriada de señales de control, que no dibujamos, pero están.

Antes de seguir, merece la pena que dediquemos unas palabras a eso de los buses, porque aunque ya ha salido la palabra antes, es la primera vez que los vemos en uso. Hasta ahora, todas las entradas y salidas de un componente habían sido líneas sencillas (es posible que esas líneas fueran de más de un cable, como por ejemplo cuando decíamos que por ahí viajaba un carácter codificado en ISO-8859-15, que eran 8 bits). Había un componente X, un componente Y y una línea que iba de X a Y. Pero si tenemos que comunicar muchos componentes entre sí, ese sistema es muy ineficiente. Si tenemos X e Y, solo necesitamos dos líneas: una de X a Y y otra de Y a X. Pero, ¿qué ocurre si tenemos 3 componentes X, Y y Z? Necesitamos 6 líneas: XY, XZ, YX, YX, ZX, ZY. Peor aún… ¿y si tenemos 4 componentes X, Y, Z y T? Ahora ya necesitamos 12 líneas. En el caso general, si tenemos N componentes, necesitaremos Nx(N-1) líneas. Un incordio.

Así que se inventa el concepto de bus. Un bus no es más que una línea única en la que todos pueden escribir y de la que todos pueden leer. En nuestra arquitectura C16A tenemos cinco componentes (CU, ALU, MM, Pantalla y Teclado), y según vayamos avanzando tendremos más. Así que inventamos el bus de datos D y hacemos que todos se conecten al bus. En un momento dado habrá uno que escriba en el bus, y todos los demás leerán, si les interesa (y si no, simplemente lo ignorarán). Al momento siguiente puede que sea otro el que escriba, y otro u otros los que lean. Esta es una solución muy versátil y que escala muy bien: si tenemos más componentes, simplemente los conectamos al bus.

Lo de inventar un bus tampoco es una panacea. Para empezar, hay que coordinar a los componentes entre sí, para que no haya dos o más que estén intentando escribir a la vez. Si lo hicieran, se embarullaría todo. Hay varias soluciones para ello; nosotros hemos optado porque sea la CU la que vaya dado microórdenes a los demás componentes para que solo uno de ellos escriba en un momento dado.[1] Ni que decir tiene que el concepto de bus tiene un problema adicional: sea cual sea el mecanismo de coordinación, no puede haber dos comunicaciones “activas” a la vez entre componentes. Si X quiere decirle algo a Y y Z quiere decirle algo a T no pueden hacerlo a la vez: uno de los dos deberá esperarse a que el otro acabe. El cómo se coordinen para “esperarse”, depende como decimos de la solución por la que optemos: nosotros, recuerdo, hemos dicho que simplemente la CU manda y no va a dejar que eso ocurra.

Pero esto tiene un problema adicional: si hay varios componentes conectados al mismo cable, todos están escribiendo algo en el cable. Ten en cuenta que escribir 0 no es “no escribir nada”. Recuerda lo que son un 0 y un 1 en realidad: 0V y 5V. Si el componente X está escribiendo un 0 (0V) y el componente Y está escribiendo un 1 (5V), tenemos un cortocircuito y probablemente se queme algo. Así que tenemos que evitar eso. Tenemos que inventar el concepto de “no escribir nada”. Es decir, necesitamos circuitos que puedan sacar un 0, un 1 o nada.

Eso es lo que se llama una salida “alta impedancia”. Seguro que lo ves más sencillo si hablamos de un interruptor: puede que lo que el circuito saque hacia el bus sea un 0 (0V) o un 1 (5V) o simplemente abra el interruptor y entonces no saque nada de nada. Estupendo, eso es lo que queremos.

Hay muchas formas de hacer eso. Vamos a ver solo una, para que puedas creerte que es posible, y a partir de ahora volvamos a obviar el tema. Vamos a ver la puerta de transmisión:

Fíjate en que el circuito no tiene alimentación ni masa… digamos que es la señal de control C quien hace ese papel. Cuando C es un 1 (5V), C’ es un 0 (0V). En ese caso, ¿qué ocurre con S y E? Si E es un 1, el transistor de arriba está en corte y no deja pasar nada; pero el transistor de abajo está en saturación, y por lo tanto es casi como un circuito cerrado. Es decir, E y S están conectados a través del transistor de abajo, y por lo tanto S es un 1. Si E es un 0, ocurre justo lo contrario: el transistor de arriba está en saturación y el de abajo en corte, y por lo tanto S vale lo mismo que E: 0. ¿Y si C es un 0 (y por lo tanto C’ son 5V)? En ese caso, siempre que E se mantenga entre 0V y 5V, ambos transistores están en zona de corte, y son simplemente un circuito abierto.

Fíjate entonces: si C es 0, eso es un circuito abierto; si C es 1, la salida es la entrada. Hemos inventado un interruptor controlado por C.[2]

La gracia es que si ahora ponemos eso a la salida de los componentes, justo antes de conectarlos al bus, podemos controlar mediante C si realmente están conectados al bus (escribiendo) o no (solamente leyendo). Y entonces hemos reducido el problema de “escribir en el bus o no” a que C sea un 1 o un 0… algo que ya sabemos hacer.

En el próximo capítulo profundizaremos en el funcionamiento de este ordenador C16A.

 

  1. Hay otras opciones, como por ejemplo que nadie controle el bus y el que quiera transmitir simplemente lo haga, por contienda: el que gane, gana. O que haya prioridades. Y dentro de esas hay muchas variantes. En fin, territorio de los telecos. []
  2. La explicación está muy simplificada, pero es que para extenderla más hay que entender los transistores con más profundidad que la que hemos visto nosotros. Por ejemplo, ocurre que S es E incluso aunque la entrada E no sea digital, sino analógica, porque en ese caso los transistores pueden estar ambos en zona óhmica. []

Sobre el autor:

J ( )

 

Escribe un comentario

Tu dirección de correo no es mostrada. Los campos requeridos están marcados *

Al escribir un comentario aquí nos otorgas el permiso irrevocable de reproducir tus palabras y tu nombre/sitio web como atribución.