Una de las ventajas de diseñar nuestro propio "microprocesador" es que podemos hacerlo con las características que queramos, incluso si estas son muy caprichosas. Por supuesto que entre mayores sean las funcionalidades, es muy probable que la complejidad, el número de circuitos y su costo aumente drásticamente. Lo normal es que el diseño del microprocesador sea en función de la tarea que vaya a realizar. En este proyecto, he buscado que el CPU resultante no sea un elefante blanco, que quepa en unos cuantos protoboards pero que muestre los elementos más representativos de un microprocesador para que cubra una función didáctica (al menos para mí
). Bueno, debo confesar que otro de los propósitos es acabarlo lo más pronto posible
.

Figura 2.1: Configuración propuesta antes del cableado
Partes del CPU
Por muchos años he estado acostumbrado a usar microprocesadores que utilizan en modelo de Von Newman, por lo que no es raro que este proyecto busque diseñar mi CPU con esta estrategia. En las siguientes secciones de este post, me pongo a soñar ( con los pies en la tierra ) sobre las partes que me gustaría que tuviera mi procesador casero y las instrucciones que va a soportar.
El diagrama de bloquesdel CPU sería a grandes rasgos así:
A continuación presento una breve descripción de sus componentes:
Contador de Programa
El contador de programa es un registro que se incrementa con cada instrucción a menos que se ejecute una instrucción de salto. Para el desarrollo de este microprocesador se va utilizar tres contadores de 4 bits que permitirán direccionar 4 KB de memoria.
Al encender el CPU o al aplicar un pulso de reset, este se inicializa a ceros, por lo que la primera dirección de memoria debe ser ocupada por una memoria no volátil como un EPROM en esa localidad de memoria.
Registro de estado de instrucción
Es un registro de 4 bits el cual indica en que estado de la instrucción estamos. Cada instrucción pasa por varios estados en cada ciclo de reloj. Es por eso que muchas de las instrucciones en realidad llevan varios ciclos de reloj en ejecutarse en este y en muchos microprocesadores. Que un microprocesador corra a 1 Mhz, no quiere decir que realice un millón de instrucciones por segundo.
Registro de instrucción
Como se van a manejar instrucciones de múltiples ciclos es necesario guardar la instrucción que se esta ejecutando para decodificar las señales de control necesarias durante todos los ciclos que esta lleven. Tentativamente será de 8 bits.
Registro de Datos
Al igual que el registro de instrucción, el registro de datos guarda el último operando de la instrucción en curso, si es el caso. Obviamente las instrucciones de un solo byte no llenan este registro.
Acumulador
Tener muchos registros puede ayudar aumentar la eficiencia de los programas que se realizan, pues los programas los aprovecharían como variables y así se evitaría en muchos casos el acceso a memoria para leer o modificar sus valores. Además de que el uso del ALU puede ser también directo.
Como el diseño es similar para n acumuladores, tanto solo se va a construir uno de 8 bits; pues uno es suficiente para entender el funcionamiento de este tipo de registros.
Registro Indice
Es un registro de 4 bits que va permitir que las instrucciones de brinco puedan ser "paginadas" por él.
Banderas de Estado
Las banderas de estado son muy útiles pues son las que pueden llevar la lógica de control con los brincos condicionales. Nuestro microprocesador tiene 3: Bandera de cero, Bandera de sobreflujo y bandera de signo.
Unidad Aritmético-Lógica
La unidad aritmético-lógica es el elemento del procesador donde se llevan acabo las operaciones que hacen muy útil al microprocesador. Después de la unidad de control, es la parte más interesante a mi forma de ver. Más adelante le voy a dedicar uno o dos posts tan sólo a esta unidad.
Memoria RAM y ROM
La memoria RAM y ROM sirve para almacenar programas y datos las cuales puedes ser accesibles por medio del contador de programa de 12 bits (4 KB ).
Puertos de entrada y salida
Los puertos de entrada y salida sirven para expandir el sistema con dispositivos periféricos,
Instrucciones
Ya que soñamos un poco al plantear como sería nuestro microprocesador, ahora sigue algo aún más divertido: el decidir que instrucciones va ser capaz de ejecutar nuestra creación. Después de pensar un buen rato, así es como quedo nuestro set de instrucciones:
Instrucciones especiales
| Operador |
Mnemónico |
Operandos |
Ciclos |
Descripción |
00 |
NOP |
0 |
1 |
No operación |
Instrucciones de carga
Sólo tenemos instrucciones para el acumulador y el registro índice. En el caso del registro indice, al ser de 4 bits; sólo los 4 bits menos significativos son los que se cargan.
| Operador |
Mnemónico |
Operandos |
Ciclos |
Descripción |
| 01 |
LD A, # |
1 |
4 |
Carga inmediata al acumulador |
| 02 |
LD IX, # |
1 |
4 |
Carga inmediata al registro indice |
| 03 |
LD A, $ |
1 |
4 |
Carga desde memoria al acumulador |
| 04 |
LD A, IX:$ |
1 |
4 |
Carga desde memoria al acumulador |
| 05 |
LD $, A |
1 |
4 |
Carga desde el acumulador a la memoria |
| 06 |
LD IX:$, A |
1 |
4 |
Carga desde el acumulador a la memoria |
Instrucciones de salto
Se cuenta con dos modos de direccionamiento: Indexado ( sólo página ) y directo ( no extendido sobre la misma página ).
| Operador |
Mnemónico |
Operandos |
Ciclos |
Descripción |
| 07 |
JMP IX:$ |
1 |
4 |
Brinco indexado |
| 08 |
JPC IX:$ |
1 |
4 |
Brinco indexado si la bandera de acarreo es uno |
| 09 |
JPZ IX:$ |
1 |
4 |
Brinco indexado si la bandera de cero es uno |
| 0A |
JPM IX:$ |
1 |
4 |
Brinco indexado si la bandera de signo es uno |
| 0B |
JMP |
1 |
4 |
Brinco directo (en la misma página) |
| 0C |
JPC |
1 |
4 |
Brinco directo (en la misma página) si la bandera de acarreo es uno |
| 0D |
JPZ |
1 |
4 |
Brinco directo (en la misma página) si la bandera de cero es uno |
| 0E |
JPM |
1 |
4 |
Brinco directo (en la misma página)si la bandera de signo es uno |
Instrucciones aritméticas y lógicas
El ALU es un bloque independiente que tiene sus propios operadores, por lo que se facilita enormemente el diseño si hace concordar los bytes de los operadores de las instrucciones de la ALU y del microprocesador; así no es necesaria una decodificación extra. Aqui esta la tabla de las operaciones propuestas:
| Operador |
Operador ALU |
Mnemónico |
Operandos |
Ciclos |
Descripción |
| 40 |
000 |
NOT |
0 |
2 |
Negación del acumulador |
| 41 |
001 |
LROT |
0 |
2 |
Rotación del acumulador a la izquierda |
| 42 |
010 |
RROT |
0 |
2 |
Rotación del acumulador a la izquierda |
| 43 |
011 |
ADD |
1 |
4 |
Suma con el acumulador |
| 44 |
100 |
SUB |
1 |
4 |
Resta con el acumulador |
| 45 |
101 |
AND |
1 |
4 |
AND lógica del acumulador a la izquierda |
| 46 |
110 |
OR |
1 |
4 |
OR lógico con el acumulador |
| 47 |
111 |
XOR |
1 |
4 |
XOR lógico con el acumulador |
Instrucciones de puertos de Entrada y Salida
Como se mencionó arriba, se va a emplear instrucciones especificas para los puertos de entrada y salida para evitar direcciones de memoria para este propósito. Las instrucciones de entrada y salida están basadas en las del viejo Z80.
| Operador |
Mnemónico |
Operandos |
Ciclos |
Descripción |
| 20 |
IN 0 |
0 |
2 |
Entrada del puerto 0 al acumulador |
| 21 |
IN 1 |
0 |
2 |
Entrada del puerto 1 al acumulador |
| 22 |
IN 2 |
0 |
2 |
Entrada del puerto 2 al acumulador |
| 23 |
IN 3 |
0 |
2 |
Entrada del puerto 3 al acumulador |
| 30 |
OUT 0 |
0 |
2 |
Salida del puerto 0 del acumulador |
| 31 |
OUT 1 |
0 |
2 |
Salida del puerto 1 del acumulador |
| 32 |
OUT 2 |
0 |
2 |
Salida del puerto 2 del acumulador |
| 33 |
OUT 3 |
0 |
2 |
Salida del puerto 3 del acumulador |
Para pruebas se va a conectar unos interruptores, unos leds y tal vez un puerto en serie y tal vez en el futuro, una pantalla de video usando un pic como VDG.
Cosas que se quedaron en el tintero (hasta ahora)
Puntero de Pila
El puntero de pila es un registro que apunta una posición de memoria donde se introducen datos. Es muy útil contar con él porque permite implementar el uso de subrutinas e interrupciones de software/hardware. Realmente se echa de menos y es probable que en el futuro lo agregue. Pero por el momento será el gran ausente.
Segmentación de instrucciones
Es una técnica de optimización que permite al ejecutar una instrucción, ir buscando el código de la siguiente o incluso ejecutar simultáneamente varias operaciones. Para una microprocesador de prueba no es necesaria, pero muchos de los microprocesadores modernos la incluyen que se ha vuelto un tema de estudio obligado.
Conectar el contador de programa a la ALU
Esto permitiría instrucciones de brinco y carga más poderosas al poder efectuar sumas y restas relativas a la dirección actual.
Más instrucciones
Las instrucciones iniciales que tiene este microprocesador casero son las mínimas necesarias y las representativas. Agregar más instrucciones no es más difícil de lo que se va a desarrollar en estos posts, pero aunque siempre deseable por el programador, su implementación aumenta el número de circuitos integrados, el costo y las horas de armado y salvo conceptos específicos no creo que se aporten más conocimientos.
Nota importante:
La construcción del microprocesador se está llevando justo ahorita, por lo que toda la información presentada en este post esta incompleta o incorrecta al ser de carácter provisional.