Implementacin del Controlador

Anuncio
Implementación del Controlador
Introducción
En éste, el capítulo final, se examinan formas alternativas de implementar la parte de control
de un procesador. En las máquinas reales, la unidad de control frecuentemente es la parte más
compleja del diseño.
Se estudian cuatro organizaciones alternativas de controladores. La primera está basada en las
máquinas de estados finitos clásicas, usando una estructura Moore o Mealy. A este enfoque a
veces se lo denomina de forma desdeñosa control de “lógica aleatoria”, para contrastarlo con
métodos más estructurados basados en ROMs y otras formas de lógica programable. El
método clásico es el único enfoque usado en el Capítulo 11.
El segundo método se denomina estado de tiempo (time state). Este método descompone una
máquina de estados finitos en varias máquinas de estados finitos más simples que se
comunican entre ellas. Es una estrategia para dividir una máquina de estados finitos que esté
bien ajustada a la estructura de los controladores de los procesadores.
El tercer método hace uso de los contadores de salto, que se introdujeron en el Capítulo 10.
Este enfoque usa extensivamente componentes de nivel MSI, tales como contadores,
multiplexores y decodificadores, para implementar el controlador.
El método final, la microprogramación, usa ROMs para codificar próximos estados y señales
de control directamente como bits almacenados en una memoria. Se examinan tres métodos
alternativos de microprogramación: secuenciadores de ramificación, microprogramación
horizontal y microprogramación vertical. Un secuenciador de ramificación codifica dentro
de la ROM múltiples opciones de próximo estado. La microprogramación horizontal dedica
un bit de la ROM para cada salida del controlador. La microprogramación vertical codifica
cuidadosamente las salidas del controlador para reducir el ancho de la palabra de la ROM.
Cualquier enfoque práctico de la microprogramación incluye alguna combinación de estos
métodos.
12.1 Lógica Aleatoria
En esta sección se examinarán las estructuras clásicas de los controladores, basadas en los
métodos estándar para implementar máquinas Moore y Mealy. Esta organización del
controlador a veces de denomina lógica aleatoria debido a que las funciones de próximo
estado y de salida se formulan en términos de compuertas lógicas discretas. Para implementar
estas funciones se podría usar fácilmente lógica programable, tal como PAL/PLA, EPLD,
FPGA o ROM.
En esta sección se examinarán dos implementaciones de control alternativas para el conjunto
de instrucciones y el camino de datos introducidos en el último capítulo. Dado que en el
1
Capítulo 11 estudiamos la implementación Mealy, en la subsección siguiente nos
concentraremos en el enfoque Moore.
Una máquina Mealy frecuentemente es la forma más económica de implementar la máquina
de estados del controlador, pero sus salidas asincrónicas introducen problemas de
temporizado. Se estudiarán las diferencias entre las máquinas Mealy sincrónicas y
asincrónicas y la relación de temporizado entre la afirmación de las señales y su efecto en el
camino de datos. Se verá que no lleva demasiado tiempo convertir una máquina Mealy
asincrónica en su prima sincrónica.
12.1.1 Máquina Moore
La Figura 12.1 muestra el diagrama de estados completo, incluyendo las operaciones de
transferencia de registros, de la implementación de la máquina Moore del procesador de la
Sección 11.3. Requiere más estados que el diagrama Mealy equivalente, pero la diferencia es
pequeña. En particular, se necesita un estado adicional en la secuencia de
restablecer/búsqueda de la instrucción y otro más en la secuencia de salto si es negativo.
La asignación de las operaciones de transferencia de registros a los estados es razonablemente
sencilla. Una sola combinación de operaciones de transferencia de registros en el mismo
estado es sorprendente. Esta es donde la petición de lectura de memoria se usa al mismo
tiempo que se acerroja el bus de datos de memoria en el MBR (ver los estados IF2, LD1 y
AD1). ¿Esto da como resultado el acerrojado de datos no válidos?
2
No, no sucede.
La Figura 12.2 muestra el temporizado detallado de los eventos de la secuencia de los estados
IF1, IF2 e IF3. Cada vez que se hace un lazo (o bucle) en el estado, el MBR captura el valor
actual del bus de memoria. Las primeras veces que se cierra el lazo en el estado, el dato
capturado por el MBR no es válido. Sin embargo, la señal Esperar permanece afirmada hasta
que la memoria pone un dato válido en el bus. Cuando se niega Esperar, el valor acerrojado en
el MBR en la siguiente transición del reloj es válido. Esta es la misma transición de estado
que avanza la máquina de estados a su próximo estado (IF3, LD2 o AD2).
Diagrama en Bloques de la Máquina Moore En la figura 12.3 se muestra el diagrama en
bloques de la máquina Moore.
La máquina requiere 16 estados. Se codifican apretadamente en un registro de estados de 4
bits. La lógica de próximo estado tiene nueve entradas (cuatro bits del estado actual,
Restablecer, Esperar, dos bits del IR y un bit del AC) y cuatro salidas (el próximo estado).
Dado que las señales de control del camino de datos se decodifican del estado, este bloque de
lógica tiene cuatro entradas y 18 salidas.
3
Opciones de Implementación: ROM Versus PAL/PLA Se puede implementar el bloque de
próximo estado y el bloque de la lógica de salida con ROMs o bien con PAL/PLAs. Usando
ROMs, se puede implementar la lógica de próximo estado con una memoria de 512 por 4 bits
y la lógica de salida con una memoria de 16 por 18 bits. Dado que los dispositivos de
memoria simples vienen en anchos que son potencias de 2, se podría implementar la última
función con varias ROMs de 4 u 8 bits de ancho.
Se comienza la implementación del controlador obteniendo la tabla de próximo estado
simbólica. Ésta se muestra en la Figura 12.4. En esta tabla vale la pena observar un par de
cosas. Primero, se puede hacer un uso extensivo de los valores no especificados entre las
líneas de entrada/dirección. Observe que una señal de entrada dada se examina en muy pocos
estados. Por ejemplo, los bits del IR se examinan en el estado OD y el bit de signo de AD se
verifica sólo en el estado BR0.
Segundo, la cantidad de operaciones de transferencia de registros afirmadas en cualquier
estado dado es bastante pequeña. En la Figura 12.4, en cualquier estado no se afirman más de
cuatro operaciones de transferencia de registros. Algunas de las salidas, como aquéllas
asociadas con referencias a memoria, siempre se afirman al mismo tiempo. Se explotará esto
en algunas de las estrategias de implementación del controlador más adelante en este capítulo.
4
Por supuesto, una implementación basada en ROM no puede aprovechar los valores no
especificados. En la lógica de próximo estado se deben programar las 512 palabras de la
ROM, una tarea bastante tediosa. Sin embargo, una ventaja de usar una ROM es que no hay
que preocuparse por hacer una asignación de estados muy cuidadosa.
Si se usa un PAL o PLA, entonces es esencial hacer una buena asignación de estados para
reducir la complejidad de la lógica de próximo estado. Por ejemplo, la asignación de estados
naíf sugerida por la Figura 12.4 (básicamente, una enumeración) produce una implementación
de 21 términos producto.
Esto se compara bastante desfavorablemente con el equivalente a 512 términos producto que
se tienen en el caso de la ROM (un término por cada palabra de la ROM).
La Figura 12.5 muestra las entradas y salidas del algoritmo (de minimización) Espresso para
esta asignación de estados particular. La lógica de próximo estado es bastante compleja. Cada
bit de próximo estado requiere de siete a nueve términos producto para su implementación.
Esto implica que se debería usar un componente PAL con compuertas O con un gran número
de entradas, como la P22V10. Para una implementación basada en PLA, todo lo que se
necesita es un PLA que proporcione sólo 21 términos producto.
5
Una asignación de estados con Nova lo puede hacer aún mejor. Sólo requiere 18 términos
producto.
state IF0:
0000
state ST0:
0101
state IF1:
1011
state ST1:
0110
state IF2:
1111
state AD0:
0111
state IF3:
1101
state AD1:
1000
state OD:
0001
state AD2:
1001
state LD0:
0010
state BR0:
1010
state LD1:
0011
state BR1:
1100
state LD2:
0100
state RES:
1110
6
12.1.2 Máquina Mealy Sincrónica
La organización de una máquina Mealy sincrónica no es muy diferente de la máquina Moore
que se acaba de describir. La clave es unir las funciones Booleanas de próximo estado y de
salida en un único bloque lógico. Para la máquina Mealy, la lógica tiene 9 entradas y 22
salidas (cuatro salidas del estado y 18 salidas de control de microoperaciones).
Las funciones de próximo estado y de salida combinadas tienen algunas consecuencias
interesantes para una implementación basada en ROM. La máquina Moore requirió sólo 2.336
bits de una ROM para su implementación (512 x 4 + 16 x 18). La máquina Mealy necesita
11.264 bits de una ROM (512 x 22). Esto muestra algo de la ineficiencia inherente del
enfoque basado en ROM. Muchos de esos bits de la ROM realmente son valores no
especificados. Por supuesto, las ROMs son muy densas y aún las ROMs grandes no son muy
caras. Se verán métodos más eficientes de usar las ROMs en el tratamiento de la
microprogramación.
Máquinas Mealy Sincrónicas Versus Asincrónicas Una máquina Mealy convencional es
asincrónica. Los cambios de las entradas conducen a cambios en la salida,
independientemente del reloj. Esto puede hacer estragos cuando las salidas son señales que
controlan de forma inmediata el camino de datos. Se debe ser capaz de afirmar las señales de
control de una manera sincrónica y correcta.
El peligro de las señales de control asincrónicas se puede minimizar en cierta medida
seleccionando componentes del camino de datos que tengan controles sincrónicos. Estas
entradas no necesitan estabilizarse hasta un tiempo de establecimiento antes del flanco del
reloj del control.
Sin embargo, todavía hay un problema para controlar las señales que tienen efecto de
inmediato. El remedio más seguro es hacer sincrónica la máquina Mealy. En una máquina
Mealy sincrónica, las salidas cambian sólo cuando cambia el estado y permanecen estables
durante todo el tiempo de estado. Esto se logra colocando registros entre las señales de
entrada, la lógica combinacional que calcula las salidas y las señales de salida. A continuación
se examinan los enfoques para construir máquinas Mealy sincrónicas.
Sincronización de una Máquina Mealy
La Figura 12.6 muestra tres formas posibles de construir una máquina Mealy con salidas
sincronizadas, usando dispositivos disparados por flancos: (a) en la entrada y la salida, (b)
sólo en las entradas y (c) sólo en las salidas. Cada una afecta el temporizado de las señales de
control de una forma ligeramente diferente. En la figura, se supone que la salida debería
afirmarse siempre que se afirma la entrada A.
7
Comencemos con el caso (a), que sincroniza tanto las entradas como las salidas. Suponiendo
que A se afirma en el ciclo 0, la salida sincronizada no se afirmará hasta el ciclo 2. Esto
retarda el cálculo en dos ciclos. Así, si A se afirma en el estado S0, la salida no se afirma hasta
el estado S2. Los diagramas de tiempo y estados de la Figura 12.7 aclaran esto.
Debería darse cuenta que colocar registros sincronizadores tanto en las entradas como en las
salidas es exagerado. Se puede obtener la sincronización deseada colocando flip-flops en un
lado o el otro de la lógica de salida. Consideremos el caso (b): sólo se sincronizan las
entradas.
8
La Figura 12.8 muestra este efecto. Si se afirma A en el ciclo 0, la salida se afirma en el ciclo
siguiente. Alternativamente, se pueden etiquetar las transiciones de estado en el próximo
estado con la entrada sincronizada A’ y la salida.
El caso (c) coloca la lógica de sincronización sólo en las salidas. El diagrama de tiempo es
similar al de la figura 12.8 y se muestra en la figura 12.9.
La señal de salida sincronizada f’ tiene efecto en el estado que sigue a aquél en el que se
afirma primero A.
Sincronización del Diagrama de Estados Mealy de la CPU Simple Para concretar estas
ideas, examinemos una implementación Mealy de la máquina de estados de control del
procesador que se obtuvo en la Sección 11.3. El caso (b), que coloca registros en las entradas,
es la que tiene mayor sentido para sincronizar esta máquina. De las cinco entradas, IR<15:14>
y AC<15> ya están sincronizadas, debido a que son registros del camino de datos activados
por el mismo reloj que la máquina de estados de control. El efecto retardado de las señales de
control no se aplica aquí, no se está colocando un registro adicional en el camino entre el IR y
el AC y el control. Por ejemplo, se puede cargar el IR con una nueva instrucción en un estado
y computar una ramificación multivía basada en el código de operación en el mismísimo
próximo estado.
Restablecer y Esperar son otra cosa. Debido a que estas señales vienen desde el exterior del
procesador, de todos modos es prudente pasarlas por flip-flops sincronizadores. Esto significa
9
que las señales externas Restablecer y Esperar se retardan un ciclo de reloj antes de que
puedan influir en la máquina de estados.
Retardar el restablecimiento un ciclo de reloj tiene poco efecto, debido a que el estado de la
máquina de cualquier forma será el de restablecimiento. Sin embargo, el retardo de un estado
de la señal Esperar sí que afecta el rendimiento. El procesador normalmente hace un lazo de
espera en un estado hasta que hay un cambio en Esperar. Esto significa que la máquina
permanece en ese lazo por un ciclo adicional. Incluso una memoria que responde a una
petición inmediatamente requiere de un ciclo de reloj del procesador antes de que el
procesador pueda reconocer que se completó la operación.
Si se diseña el sistema de memoria para que sea sincrónico con el procesador, se puede evitar
esta pérdida de rendimiento. Dado que el controlador del sistema de memoria está
sincronizado por el mismo reloj del procesador, la señal Esperar ya no necesita ser
sincronizada.
12.2 Estado de Tiempo (Divide y Vencerás)
Los enfoques clásicos para implementar máquinas de estados finitos producen una
implementación monolítica que algunas veces es poco flexible y difícil de cambiar. Un
enfoque alternativo, basado en una estrategia “divide y vencerás”, divide la máquina de
estados en varias máquinas de estado más simples que se comunican entre sí.
12.2.1 División de la Máquina de Estados
Una división común es dividir el controlador en tres máquinas de estados: la máquina de
estados finitos de estado de tiempo, la máquina de estados finitos de estado de instrucción y la
máquina de estados finitos de estado de condición. La máquina de estados finitos de estado de
tiempo determina la fase actual de la interpretación de la instrucción. Estas fases incluyen la
búsqueda, la decodificación y la ejecución de la instrucción.
La máquina de estados finitos de estado de instrucción identifica la instrucción actual que se
está ejecutando, tales como cargar, almacenar, sumar o ramificar. Maneja el proceso de
decodificación de la instrucción.
La máquina de estados finitos de estado de condición representa el estado de la condición
actual del camino de datos. En el procesador de ejemplo, la única condición interesante es el
bit más significativo del AC. Otras posibles condiciones del camino de datos incluyen si la
última operación de la ALU dio como resultado cero, un rebose por encima (overflow) o un
rebose por debajo (underflow).
La división en estas tres clases de máquinas de estados es ventajosa porque normalmente sólo
hay pequeñas diferencias entre las secuencias de control de las distintas instrucciones. Si estas
secuencias están parametrizadas adecuadamente, se puede evitar una secuencia exclusiva para
cada instrucción. Dado que el estado de la instrucción se puede decodificar fácilmente desde
el IR y el estado de condición desde el camino de datos, se puede reducir aún más el número
de estados en la máquina de estados global.
10
12.2.2 Máquinas de Estado de Tiempo para el Procesador de Ejemplo
Se comienza con el diagrama de estados Moore de la Figura 12.1. Para obtener la máquina de
estados finitos de estado de tiempo, se debe buscar el camino que sea el peor caso en el
diagrama de estados clásico. En el procesador de ejemplo, el camino más largo tiene ocho
estados (SUMAR o CARGAR).
Dada esta secuencia de ocho estados, la idea es parametrizar la secuencia básica por las
salidas del estado de instrucción (LD, ST, ADD, BRN) y del estado de condición (el bit más
significativo del AC: AC 0, AC<0). Estas salidas están asociadas con las transiciones en la
máquina de estados finitos de estado de tiempo. Bajo las condiciones apropiadas, la máquina
de estados finitos de estado de tiempo avanzará a su próximo estado.
En la Figura 12.10 se muestra el diagrama de estados finitos de estado de tiempo
parametrizado.
Las máquinas de estados finitos de estado de instrucción y estado de condición se muestran en
la Figura 12.11. La señal Restablecer se maneja con otra máquina de estados que no se
muestra. Cada instrucción, sin importar su tipo, hace la secuencia por los primeros cinco
estados, IF0 a IF3 y OD. Estos se asignan a los estados de tiempo T0 a T4, respectivamente.
Después de esto, las instrucciones siguen caminos de ejecución diferentes. Afortunadamente,
gran parte de esta secuenciación sigue siendo común. Los estados LD0-LD2, ST0, ST1, AD0AD2, y BR0, BR1 se han colapsado en los estados de tiempo T5, T6 y T7. La única salida de la
máquina de estado de tiempo es su estado actual, T0 a T7.
11
La Figura 12.10 también muestra cómo las salidas de las máquinas de estado de instrucción y
estado de condición influencian el secuenciado del próximo estado en la máquina de estados
finitos de estado de tiempo. Por ejemplo, en el estado de tiempo T5, si la instrucción es BRN y
el AC 0, la máquina de estado de tiempo retorna al estado T0. En caso contrario, avanza al
estado T6. Este retorno rápido al comienzo de la máquina de estado de tiempo se denomina
transición de cortocircuito. Aunque podríamos forzar a que todas las instrucciones hagan la
secuencia hasta T7 antes de retornar, esto podría ser menos eficiente debido a que cada
instrucción tendría que requerir tantos ciclos como la instrucción más larga posible.
Como otro ejemplo, consideremos el estado de tiempo T6. Si la instrucción es LD, ST o ADD
y Esperar está afirmada, la máquina permanece en T6. Si la instrucción es BRN o ST con
Esperar negada, la máquina retorna a T0. En caso contrario, avanza a T7.
Generación de Microoperaciones No es difícil generar las salidas de las microoperaciones
desde el estado de tiempo, estado de condición y estado de instrucción. Las diversas
operaciones de transferencia de registros se afirman bajo las siguientes condiciones:
0 → PC: Restablecer
PC + 1 → PC: T0
PC → MAR: T0
MAR → Bus de Direcciones de Memoria: T2 + T6 (LD + ST + ADD)
Bus de Direcciones de Memoria → MBR: T2 + T6 (LD + ADD)
MBR → Bus de Datos de Memoria: T6 ST
MBR → IR: T4
MBR → AC: T7 LD
AC → MBR: T5 ST
AC + MBR → AC: T7 ADD
IR<13:0> → MAR: T5 (LD + ST + ADD)
IR<13:0> → PC: T6 BRN
1 → Leer/ Escribir : T2 + T6 (LD + ADD)
0 → Leer/ Escribir : T6 ST
1 → Petición: T2 + T6 (LD + ST + ADD)
El estado de condición no se usa explícitamente para generar ninguna de las operaciones de
transferencia de registros. Por supuesto, esto no influye en las transiciones de próximo estado
de la máquina de estados finitos de estado de tiempo.
Discusión En general, el enfoque de estado de tiempo puede reducir y simplificar la lógica de
próximo estado, posiblemente a expensas de introducir más flip-flops. La técnica de
cortocircuito hace la lógica de próximo estado algo más compleja, pero permite instrucciones
con un número bajo de ciclos para terminar antes. Esto tiene el efecto de llevar a una
ejecución de programas más rápida.
12.3 Contador de Salto
En la Sección 10.2, se describieron métodos para implementar máquinas de estados finitos
usando un contador como registro de estado. Dicho método se denominó contador de salto. El
12
enfoque usa componentes MSI, tales como contadores sincrónicos, multiplexores y
decodificadores, para implementar la máquina de estados finitos. En esta sección se expande
la descripción, para mostrar cómo se pueden usar los contadores de salto para implementar la
unidad de control de una CPU.
Los contadores de salto caen en dos clases: puros e híbridos. Un contador de salto puro sólo
permite uno de cuatro posibles próximos estados: el estado actual (el contador mantiene el
valor actual), el próximo estado secuencial (el contador cuenta), el estado 0 (se limpia el
contador) o un único estado de “salto” (el contador carga). En un contador de salto puro, el
estado de salto es estrictamente una función del estado actual. Un contador híbrido soporta los
mismos tipos de transiciones, pero permite que el estado de salto sea una función de las
entradas, así como del estado actual.
12.3.1 Contador de Salto Puro
La Figura 12.12 es una vista del diagrama de bloques de un contador de salto puro. El estado
de salto es una función del estado actual, mientras que las entradas limpiar, cargar y contar
dependen del estado actual y de las entradas actuales. Se asume que limpiar tiene precedencia
sobre cargar, la que a su vez tiene precedencia sobre contar. Se pueden implementar los
bloques lógicos de la figura con compuertas lógicas, PALs/PLAs o ROMs. Frecuentemente se
usan ROMs para la lógica del estado de salto.
En la Figura 12.13 se muestra la secuencia de estados restringida del contador de salto puro.
Para sacar máximo provecho del contador que hace las veces de registro de estado, se
deberían asignar los estados en una secuencia de cuenta. Se le debería asignar el estado 0 al
objetivo más frecuente de una transición.
13
Esto usualmente resulta ser demasiado restrictivo para estados que requieren una ramificación
multivía más general, tal como el estado de decodificación de la operación en un diagrama de
estados de un procesador. En los estados con ramificación multivía, un enfoque con contador
de salto puro debe introducir una cantidad de estados adicionales, como se muestra en la
figura 12.14.
La Figura 12.14 (a) muestra el fragmento del diagrama de estados de la decodificación de la
operación de las Figuras 11.23 y 12.1. Para implementar esto como un contador de salto puro,
necesitaríamos el fragmento del diagrama de estados de la Figura 12.14 (b). Se deben
introducir dos nuevos estados de decodificación e incrementar el número total de estados
necesarios para ejecutar una instrucción de carga, almacenamiento o suma. No es demasiado
sorprendente que algún diseñador con iniciativa haya inventado el contador de salto híbrido,
que es más general.
12.3.2 Contador de Salto Híbrido
El contador de salto híbrido soluciona el problema de la ramificación multivía. Simplemente
hace que el estado de salto sea función tanto de las entradas como del estado actual. Esto se
aclara en el diagrama en bloques de la Figura 12.15. Las lógicas del estado de salto, limpiar,
cargar y contar son todas funciones de las entradas y del estado actual.
14
Diagrama de Estados Mealy de la CPU Simple Veamos cómo se implementa el diagrama
de estados Mealy de la figura 11.23 con un contador de salto híbrido. La primera
consideración es cómo asignar los códigos de estado al diagrama de estados. La mayoría de
las transiciones entre estados avanzan hacia adelante o permanecen en el estado actual,
dependiendo del valor de la señal Esperar. Por lo tanto, se puede usar una asignación de
estados en binario natural. Ver la figura 12.16.
Luego, se busca un estado para asignarle el 0. Dado que el estado RES es el objetivo más
frecuente de una transición, es el mejor candidato. Arrancando en 0, simplemente se asignan
los estados en secuencia a medida que se avanza hacia abajo por el diagrama de estados.
La última consideración es identificar los estados de ramificación, aquéllos cuyas transiciones
de próximo estado no se pueden describir simplemente en términos de mantener (permanecer
en el estado actual), contar (avanzar al próximo estado en la secuencia) o restablecer (ir al
estado 0). El único estado así es OD, decodificación de la operación. Afortunadamente,
podemos describir las transiciones de próximo estado en función del estado actual y de los
bits del código de operación del IR. De hecho, dado que esta es la única ramificación multivía
en todo el diagrama de estados, la lógica del estado de salto únicamente es función de los bits
del código de operación del IR.
En la Figura 12.16 se muestra la asignación de estados completa. Se supone que los estados
están numerados desde S0 hasta S13. Para las transiciones al estado RES, la señal CLR del
contador de estados debería afirmarse en los estados S7, S9 (si Esperar también está afirmada),
S12 y S13.
15
La señal LD del contador se afirma sólo en los estados que tienen una ramificación multivía.
En este diagrama de estados, debería afirmarse en el estado S4, el estado OD. La lógica del
estado de salto, determinada por los bits del código de operación del IR, genera el nuevo
estado que hay que cargar en el contador de estados.
Cuándo hay que afirmar la señal CNT es ligeramente más complicado. Las ecuaciones
Booleanas para contar o para mantener (no contar) son:
CNT = (S0 + S5 + S8 + S10 ) + Esperar • (S1 + S3 ) + Esperar • (S 2 + S6 + S9 + S11 )
HOLD = Esperar • (S1 + S3 ) + Esperar • (S 2 + S6 + S9 + S11 )
La ecuación HOLD ( CNT ) es más simple que la ecuación CNT. Se podría ahorrar algo de
lógica implementando HOLD y luego negándola para obtener la señal CNT.
La lógica del estado de salto para S4 (OD) es sencilla. Se puede implementar con una ROM de
4 palabras de 4 bits cuyas entradas de dirección son los dos bits del código de operación del
IR.
Implementación a Nivel Esquemático del Contador de Salto En la Figura 12.17 se
muestra una descripción esquemática del contador de salto.
16
Los componentes principales son: (1) un contador sincrónico (74163) usado como registro de
estado; (2) un decodificador 4 a 16 (74154) para generar las señales usadas para identificar el
estado actual; (3) la lógica del estado de salto implementada con una ROM de 4 palabras de 4
bits, indexada por los dos bits del código de operación del IR; (4) un PAL que implementa la
lógica Booleana para la entrada CNT del contador de estados; y (5) la lógica discreta que
implementa la entrada CLR del contador de estados (también se podría haber implementado
CLR como una salida del PAL de CNT). Dado que LD se afirma sólo en un estado, S4, la
salida del decodificador para ese estado maneja la entrada de carga directamente.
Miremos con un poco más de detalle la lógica de este controlador con contador de salto
híbrido, comenzando con el contenido de la ROM de estado de salto. Para cada patrón de bits
del código de operación, se almacenan en la ROM los bits de próximo estado apropiados.
Dirección Contenido (Estado Simbólico)
00
0101 (LD0)
01
1000 (ST0)
10
1010 (AD0)
11
1101 (BR0)
El diseño del resto de la implementación del contador de salto es razonablemente sencillo,
pero hay una complicación. Ésta es la polaridad negativa de las señales de control de LD y
CLR del contador 74163, al igual que las salidas activas en bajo del decodificador 74154.
17
Primero miremos la señal CLR. En lógica positiva se puede expresar como
CLR = Reset + S7 + S12 + S13 + (S9 • Esperar ) .
Dado que la entrada CLR es activa en bajo, la función debería ser reescrita usando el teorema
de De Morgan:
(
CLR = Restablece r • S7 • S12 • S13 • S9 + Esperar
)
Afortunadamente, el decodificador entrega exactamente estas señales de estado activas en
bajo. Una compuerta AND de cinco entradas y una compuerta OR de dos entradas
implementan la señal CLR .
Algunas veces es más conveniente implementar HOLD (NO CNT) en lugar de CNT. En otras
palabras, el complemento de HOLD es CNT. Se puede implementar HOLD usando un PAL
con polaridad de salida programable y elegir que la salida sea de lógica negativa. La función
del PAL se vuelve
HOLD = S1 • Esperar + S 2 • Esperar + S 3 • Esperar + S 6 • Esperar + S 9 • Esperar + S11 • Esperar
(CNT ) HOLD = S1 • Esperar + S 2 • Esperar + S 3 • Esperar + S 6 • Esperar + S 9 • Esperar + S11 • Esperar
Dado que el decodificador da el estado actual en lógica negativa, es igual de fácil especificar
la función HOLD usando las versiones activas en bajo de las entradas del estado. El PAL se
programa realmente con lo siguiente:
HOLD = S1 • Esperar + S 2 • Esperar + S 3 • Esperar + S 6 • Esperar + S 9 • Esperar + S11 • Esperar
(CNT ) HOLD = S1 • Esperar + S 2 • Esperar + S 3 • Esperar + S 6 • Esperar + S 9 • Esperar + S11 • Esperar
Implementación Alternativa del Contador de Salto Basada en MSI En la subsección
anterior, se implementaron las señales CLR, LD y CNT con lógica discreta o PALs. Se puede
usar otro método, basado en multiplexores, para calcular estas señales.
La figura 12.18 muestra cómo hacer esto para el diagrama de estados de la CPU simple. Se
calcula CLR, LD y CNT usando el estado actual para seleccionar exactamente una entrada de
multiplexor. Por ejemplo, la señal LD se debería afirmar en el estado S4 (OD) y en ningún
otro. Cuando las líneas de selección del multiplexor LD se llevan a 0100 (estado 4), la entrada
E4 se conecta a la salida EOUT. E4 está fijada a un valor alto, mientras que todas las otras
entradas del multiplexor están fijadas a un valor bajo. La salida del multiplexor se afirma
activa en bajo en este caso. Es negada en alto en todos los otros casos.
Las salidas activas en bajo del multiplexor hacen esta implementación algo complicada. Dado
que la entrada LD del contador también es activa en bajo, se mantiene la polaridad correcta.
Una entrada afirmada en lógica positiva en el multiplexor genera una salida afirmada en
lógica negativa, que hace que el contador cargue.
18
Volvamos ahora a las señales CLR y CNT. La señal CLR del multiplexor, CLRm, se debe
combinar en una puerta OR con Restablecer para formar la señal CLR del contador:
CLR = CLRm + Restablecer
Pero dado que la señal de limpiar del contador es activa en bajo, se debe aplicar el teorema de
De Morgan. Ahora se transforma en una función NOR:
CLR = CLR m + Restablece r
CLR = CLR m • Restablece r
En la Figura 12.18 se usó la segunda implementación (AND es lo mismo que OR con entradas
y salidas complementadas). La salida activa en bajo del multiplexor CLR ahora tiene la
polaridad correcta. Combinada con la señal Restablecer global, puede retornar la máquina a
S0.
Retornemos a las entradas al multiplexor CLR. De nuevo, son activas en alto: se tiene que
afirmar en alto una entrada del multiplexor si la señal CLR tiene que tener efecto en el estado
19
asociado. Así, E7, E12 y E13 están fijadas a alto, dado que corresponden a los estados S7, S12, y
S13. Siempre se retorna a S0 desde estos estados. Por otra parte, la transición desde S9 a S0
tiene lugar sólo cuando Esperar ya no está afirmada. Así, la entrada E9 es la señal Esperar , que
es la condición para retornar a S0.
El control de CNT es el más complejo, dado que la salida del multiplexor es activa en bajo,
pero la señal de control del contador es activa en alto. La solución simplemente es “empujar la
burbuja” a las entradas. En este caso, hay que afirmar una entrada en bajo del multiplexor si
se quiere que tenga lugar una cuenta. Dado que la cuenta tiene lugar de forma incondicional
en los estados S0, S5, S8, y S10, entonces E0, E5, E8, y E10 están fijadas a un valor bajo.
En los estados en los que la cuenta es condicional, las entradas del multiplexor están
conectadas al complemento de la condición. Así, S1 y S3 avanzan cuando se afirma Esperar, y
E1 y E3 están conectadas a Esperar . S2, S6 y S11 avanzan cuando se afirma Esperar , entonces E2,
E6, y E11 están conectadas a Esperar.
Generación de las Microoperaciones Las microoperaciones se pueden generar a partir del
estado decodificado y las entradas. Las expresiones lógicas se muestran debajo. Para asegurar
una operación sincrónica apropiada, las entradas Esperar y Restablecer deberían sincronizarse
antes de usarlas para formar estas expresiones.
0 → PC: Restablecer
PC + 1 → PC: S0
PC → MAR: S0
MAR → Bus de Direcciones de Memoria:
Esperar (S1 + S2 + S5 + S6 + S8 + S9 + S11 + S12)
Bus de Datos de Memoria → MBR:
Esperar (S2 + S6 + S11)
MBR → Bus de Datos de Memoria:
Esperar (S8 + S9)
MBR → IR: Esperar S3
MBR → AC: Esperar S7
AC → MBR: IR15 IR14 S4
AC + MBR → AC: Esperar S12
IR<13:0> → MAR:
(IR15 IR14 + IR15 IR14 + IR15 IR14) S 4
IR<13:0> → PC: AC15 S13
1 → Leer/ Escribir :
Esperar (S1 + S2 + S5 + S6 + S11 + S12)
0 → Leer/ Escribir :
Esperar(S8 + S9)
1 → Petición:
Esperar (S1 + S2 + S5 + S6 + S8 + S9 + S11 + S12)
Estas funciones se implementan de manera más fácil con alguna forma de lógica programable.
20
Discusión En el esquemático de la figura 12.18 se usaron varios multiplexores, lo que no
parece ser un gran ahorro en términos de la cantidad de circuitos integrados usados. Sin
embargo, este enfoque particular de la implementación es extraordinariamente flexible. La
regularidad del diseño lo hace fácil de depurar; es fácil rastrear las señales que ocasionan una
transición de estado. Es igual de fácil modificar estas transiciones, simplemente hay que
cambiar las entradas a los multiplexores. El contador de salto es una forma razonable de
organizar máquinas de estados con un número modesto de estados, en el rango de 16 a 32.
En un contador de salto híbrido general, el estado de salto es función del estado actual y de las
entradas. Pero CNT, CLR y LD son funciones de exactamente las mismas señales. ¿Por qué
implementarlas con lógica discreta cuando podrían almacenarse en la ROM de estado de salto
junto con los estados de salto? Simplemente se podría extender el ancho de la ROM en 1 bit
para cada una de las tres señales de salida. Por supuesto, dado que se han agregado cinco
entradas nuevas (Esperar más los cuatro bits del estado actual), adoptar este enfoque
incrementa el número de palabras de la ROM en un factor de 32.
Esta estrategia general de reemplazar lógica externa, como compuertas, multiplexores y
PALs, con unos y ceros en una ROM se denominad microprogramación. Se aprenderá más
sobre este enfoque en las dos subsecciones siguientes.
12.4 Secuenciadores de Ramificación
En una máquina de estados finitos, los próximos estados se computan explícitamente como
funciones de salida de la máquina. Una estrategia simple es colocar los bits que representan el
próximo estado en una ROM direccionada por el estado actual y las entradas. El problema con
este enfoque es que la ROM se duplica en tamaño por cada entrada adicional.
El contador de salto representa un compromiso entre el tamaño de la ROM y los circuitos
externos. En la ROM sólo se colocan los estados de salto. En un contador de salto puro, la
ROM sólo es direccionada por el estado actual. Incluso el enfoque híbrido típicamente
selecciona un pequeño subconjunto de las entradas para que formen parte de las direcciones
de la ROM. Otras salidas de la máquina se forman con lógica que combina el estado
decodificado y las entradas del procesador.
La próxima organización se denomina secuenciador de ramificación. Está entre los dos
extremos de una implementación de máquina de estados clásica basada en ROM y el contador
de salto. Los próximos estados se almacenan en una ROM, pero cada estado está restringido a
tener sólo un número limitado de próximos estados, que siempre es una potencia de 2.
Dado que es raro el caso en el que una máquina de estados finitos necesita ver todas sus
entradas para determinar el próximo estado en cualquier estado dado, sólo se debe examinar
un subconjunto de las entradas (preferentemente pequeño). La idea es usar alguna lógica
externa para seleccionar el subconjunto apropiado de entradas, determinado por el estado
actual de la máquina, para usarlo como parte de las direcciones de la ROM. La palabra de la
ROM en esta dirección contendrá el próximo estado de la máquina. A cambio de una pequeña
cantidad de hardware externo, se puede reducir de forma dramática el tamaño de la ROM.
21
12.4.1 Organización de un Secuenciador de Ramificación
Ejemplo Secuenciador de Ramificación de Cuatro Vías La Figura 12.19
muestra la estructura de un secuenciador de ramificación de cuatro vías (o 22 ) que
implementa un controlador Mealy. Los bits más significativos de la dirección de la ROM
están formados por el estado actual, los bits menos significativos por los valores de las dos
entradas α y β. Por lo tanto, cada estado tiene cuatro posibles próximos estados. Si un estado
dado tiene sólo un próximo estado, se coloca el mismo valor en las cuatro palabras de la ROM
dedicadas a almacenar su próximo estado y las salidas.
Observe que los bits de dirección α y β están manejados por las salidas de los multiplexores.
El estado selecciona entre las entradas el subconjunto de dos entradas particular que
determina el próximo estado de la máquina.
Como ejemplo, considere la máquina de estados Mealy de la CPU simple (Figura 11.23). Las
entradas a la máquina son: la señal Esperar, el bit más significativo del AC y los dos bits del
código de operación del IR. En el estado de decodificación de la operación, OD, se necesitan
examinar sólo los bits del IR para determinar el próximo estado. En el estado que ejecuta la
instrucción BRN, la máquina sólo mira el bit AC<15>. Muchos de los otros estados sólo
necesitan verificar la señal Esperar. Ningún estado necesita acceder a más de dos de las cuatro
entradas posibles.
Generalización del Secuenciador de Ramificación Es posible construir un secuenciador de
ramificación de 2N vías simplemente usando N señales de entrada seleccionadas para formar
parte de la dirección de la ROM. Un secuenciador de ramificación de cuatro vías es una
estructura apropiada para la máquina de estados del procesador de ejemplo, debido a que
ningún estado contiene una ramificación multivía que vaya a más de cuatro próximos estados.
Un diagrama de estados diferente podría requerir un grado de ramificación mayor.
Por supuesto, hay un compromiso entre el grado de ramificación multivía que soporta la
implementación, el tamaño de la ROM y la cantidad de estados en la máquina de estados.
22
Considere una máquina con una única ramificación de 16 vías en su diagrama de estados,
pero muchas ramificaciones de cuatro vías. El secuenciador de ramificación de 16 vías
requiere cuatro selectores de entradas, pero el secuenciador de cuatro vías sólo necesita dos.
Esta máquina podría implementarse de manera más económica reemplazando la ramificación
de 16 vías por varios estados con ramificación de cuatro vías. Lo más probable es que la
ROM para el secuenciador de cuatro vías tenga un tamaño que sea la mitad del que tenga el
secuenciador de 16 vías.
Implementación de la CPU Simple con un Secuenciador de Ramificación
La Figura 12.20 muestra la programación de la ROM del controlador Mealy del procesador.
La dirección está formada por la señal Restablecer, el estado actual (4 bits) y las entradas
condicionales α y β. Incluir Restablecer en la dirección duplica el tamaño de la ROM, pero es
la forma más fácil de implementar la función de reinicio. También se pueden usar métodos
que explícitamente limpien los flip-flops del estado.
Los multiplexores α y β están cableados de manera que IR<15> e IR<14> están conectados a
las entradas seleccionadas por el estado 4 (OD). La señal Esperar está cableada a ambos
multiplexores para las entradas de selección 1, 2, 3, 6, 9 y 11, que son los estados en los que
se necesita examinar esa señal. AC<15> está conectada a la entrada 13 de ambos
multiplexores. En la Figura 12.21 se muestra la configuración de los multiplexores.
23
Se pueden hacer dos observaciones inmediatas sobre la estructura de este controlador.
Primero, relativamente pocos estados usan la capacidad del controlador para soportar
ramificaciones de próximo estado de cuatro vías. Esto no es una sorpresa, dado que sólo el
estado de decodificación de la operación es de más de dos vías. Típicamente la ramificación
más ancha se necesita sólo en el(los) paso(s) de decodificación. Dado que cada entrada de bit
duplica el tamaño de la ROM, esto ilustra cuán poco económico es incluir todas las entradas
en las direcciones de la ROM.
Segundo, hay muchas menos entradas que estados. En este caso, se tienen cuatro entradas
pero (aproximadamente) 16 estados. Dado que la máquina de estados sólo mira tres conjuntos
diferentes de entradas (IR<15>/IR<14>, AC<15> y ESPERAR), parece una exageración usar
multiplexores 16:1 en las señales α y β. Esto nos lleva a la siguiente variación en el
secuenciador de ramificación.
Organización del Secuenciador de Ramificación Horizontal A expensas de algunos
multiplexores adicionales, se puede reemplazar la ROM alta y delgada de la figura 12.19 con
una ROM baja y gorda, como la que se muestra en la Figura 12.22.
24
Hay dos diferencias fundamentales. Primero, los multiplexores se controlan con señales
codificadas que salen de la ROM, en lugar de controlarlos directamente con el estado. Debería
notarse que estas señales codificadas sólo son función del estado, dado que los bits de estado
solos forman la dirección de la ROM. Esto también implica que la implementación de la
Figura 12.22 es una máquina Moore.
Segundo, los cuatro posibles próximos estados se disponen horizontalmente dentro de la
ROM, en lugar de en cuatro palabras secuenciales de menor longitud de la ROM. Si la
máquina de estados tiene un gran número de estados, pero relativamente pocas entradas, los
bits de control de los multiplexores incluidos en la ROM hacen posible usar multiplexores con
menos entradas para controlar la lógica de próximo estado.
Miremos la máquina de estados de la CPU simple como ejemplo de esta organización del
controlador. Usando este enfoque, se pueden reemplazar los multiplexores 16:1 verticales por
multiplexores 2:1. El multiplexor α tiene como entradas IR<15> y AC<15>; la entradas del
multiplexor β son IR<14> y Esperar. Un único bit en la palabra de la ROM controla cada
multiplexor. Cuando la máquina está en el estado OD, los bits de control de los multiplexores
α y β se ponen para seleccionar IR<15> e IR<14>, respectivamente. Los multiplexores
horizontales seleccionan A0 si ambos bits están en 0; A1 si IR<15> = 0, IR<14> = 1; A2 si
IR<15> = 1, IR<14> = 0 y A3 si ambos bits son 1.
Cuando la máquina está en su estado de ejecución para la instrucción BRN, los bits de control
de los multiplexores se disponen para seleccionar AC<15> en el multiplexor α. El bit del
multiplexor β es un valor no especificado, por lo que A0 y A1 deberían contener los mismos
bits de próximo estado, al igual que A2 y A3. Se selecciona A0/A1 si AC<15> = 0; en caso
contrario se selecciona A2/A3.
Un argumento similar explica cómo trabajan los multiplexores cuando el estado necesita
examinar la señal Esperar. En este caso, el multiplexor α es el valor no especificado y el
25
multiplexor β se dispone para seleccionar Esperar. A0 y A2 deberían contener el mismo valor,
al igual que A1 y A3. Si Esperar está afirmada, A1/A3 determinan el próximo estado. En caso
contrario se dispone para el estado especificado por A0/A2.
El esquema de próximo estado horizontal es ventajoso en controladores grandes y complejos
con ramificaciones de muchas vías. Agregar longitud a la palabra de la ROM usualmente
requiere menos bits que incrementar el número de palabras de la ROM. Nuevamente,
consideremos la máquina de estados de la CPU simple. Su controlador tiene 14 salidas de
transferencia de registros. Con los cuatro bits de próximo estado, la ROM contiene 64 por 18
bits o 1152 bits de ROM (se supone que el restablecimiento se maneja con lógica externa). El
método horizontal requiere los mismos 14 bits de control, más cuatro próximos estados de 4
bits, así como dos bits adicionales de control de los multiplexores. Esto da una longitud total
de la palabra de la ROM de 32 bits. Pero dado que la organización horizontal requiere sólo 16
palabras de la ROM, el número total de bits de la ROM es mucho menor: sólo 512 bits. En la
próxima subsección se examinará más de cerca el compromiso entre las organizaciones de
ROM verticales y horizontales.
12.5 Microprogramación
Hasta ahora nos hemos concentrado en métodos alternativos para organizar la lógica de
próximo estado. Ahora podemos tratar diversas formas de organizar las señales de salida que
controlan el camino de datos. Habitualmente pensamos que las señales de control se
implementan con lógica discreta, incluso si la implementación hace uso de PALs o PLAs. La
microprogramación, por otra parte, es un enfoque para implementar el control del procesador,
en el que las señales de control se almacenan dentro de una ROM.
Las dos variaciones principales de la microprogramación son los métodos horizontal y
vertical. En la sección anterior, ya se vieron algunas distinciones entre las organizaciones del
próximo estado horizontal y vertical. En la microprogramación horizontal, hay una salida de
la ROM por cada punto de control del camino de datos. La microprogramación vertical está
basada en la observación de que sólo un subconjunto de esas señales se afirma en un estado
dado. Así, las salidas de control se pueden almacenar en la ROM de forma codificada,
reduciendo efectivamente el ancho de la palabra de la ROM a expensas de alguna lógica de
decodificación externa.
Codificar las señales de control puede limitar las operaciones del camino de datos que pueden
tener lugar en paralelo. Si éste es el caso, se pueden necesitar varias palabras de la ROM para
codificar las mismas operaciones del camino de datos que podrían ser realizadas en una única
palabra de una ROM horizontal.
Por ejemplo, considere el control microprogramado de una máquina con cuatro acumuladores
de propósito general. La mayoría de los formatos de instrucción de las computadoras limitan
el destino de una operación a un único registro. Sabiendo esto, se puede elegir codificar el
destino de una operación de transferencia de registros en 2 bits en lugar de 4. Una lógica que
decodifica estos 2 bits desde el control maneja la línea de selección del registro de destino.
Así, en cualquier instante dado, se selecciona como destino sólo uno de los registros.
26
El arte de hacer la ingeniería de una unidad de control microprogramada es encontrar el
balance correcto entre el paralelismo del enfoque horizontal y la economía de la ROM de una
codificación vertical. Por ejemplo, las líneas de habilitación del registro codificado eliminan
la posibilidad de que cualquier estado cargue dos registros al mismo tiempo, incluso si esto
está soportado por el camino de datos del procesador. Si una instrucción de máquina debe
cargar dos registros, requerirá múltiples estados de control (y palabras de la ROM) para
implementar su ejecución.
Se comienza el estudio con el enfoque horizontal a la microprogramación. Se verá que el
conjunto de instrucciones y el camino de datos típicamente no soportan el paralelismo total
supuesto por el control horizontal, por lo que se examinarán métodos de codificación de la
palabra de la ROM para reducir su tamaño.
12.5.1 Microprogramación Horizontal
La organización horizontal del próximo estado de la Figura 12.22 ofrece el núcleo de un
controlador microprogramado horizontal. Un formato de palabra de control extremadamente
horizontal tendría 1 bit para cada microoperación del camino de datos. Se desarrollará tal
formato para el control de la CPU simple.
El procesador de ejemplo soporta 14 operaciones de transferencia de registros. Estas
operaciones se descomponen aún más en 22 microoperaciones discretas (ordenadas por
destino):
PC → ABUS
IR → ABUS
MBR → ABUS
RBUS → AC
AC → ALU A
MBUS → ALU B
ALU SUMAR
ALU PASAR B
MAR → Bus de Direcciones
MBR → Bus de Datos
ABUS → IR
ABUS → MAR
Bus de Datos → MBR
RBUS → MBR
MBR → MBUS
0 → PC
PC + 1 → PC
ABUS → PC
Leer/ Escribir
Petición
AC → RBUS
Resultado ALU → RBUS
27
Una palabra de ROM muy larga para un secuenciador de ramificación de cuatro vías tendría
los bits de los multiplexores α y β, cuatro próximos estados de 4 bits y 22 bits de las
microoperaciones. Esto da una longitud total de la palabra de la ROM de 40 bits, como se
muestra en la Figura 12.23.
La Figura 12.24 muestra el contenido de la ROM del controlador Moore de la Figura 12.1 (el
secuenciador de ramificación de la Figura 12.22 implementa una máquina Moore). Las
entradas del multiplexor α son Sel0 = Esperar, Sel1 = IR<15> y las entradas de β son Sel0 =
AC<15>, Sel1 = IR<14>. Se supone que el registro de estado se restablece directamente.
Los multiplexores que están en el próximo estado trabajan igual que en la Figura 12.22. Por
ejemplo, consideremos el estado IF1. Se permanece en este estado si Esperar está negada. Si
se afirma Esperar, se avanza al estado IF2. Los controles de los multiplexores α y β se
disponen para examinar Esperar y AC<15>, respectivamente. Así, los bits de próximo estado
0X (A0, A1) se ponen para el código de IF1, 0010. De manera similar, los próximos estados 1X
(A2, A3) se disponen para el código de IF2, 0011.
28
Reducción del Ancho de la Palabra de la ROM Mediante Codificación El enfoque
horizontal ofrece la mayor flexibilidad proveyendo acceso a todos los puntos de control del
camino de datos al mismo tiempo. La desventaja es el ancho de la palabra de la ROM, que
puede exceder unos pocos cientos de bits en los controladores complejos.
Una buena forma de reducir el tamaño de la ROM es codificar sus salidas. Esto no
necesariamente tiene que llevar a una pérdida inherente de paralelismo. Después de todo,
ciertas combinaciones de control pueden no tener sentido lógico (por ejemplo, 0 → PC y PC +
1 → PC son lógicamente exclusivas) o podrían ser descartadas por la estrategia de buses del
camino de datos (por ejemplo, PC → ABUS e IR → ABUS no pueden tener lugar
simultáneamente).
Además, el contenido de la ROM de la Figura 12.24 es muy ralo. En cualquier estado se
afirman muy pocas de las señales de control. Esto significa que para codificarlas, se pueden
agrupar las señales de control en conjuntos mutuamente exclusivos. Se las decodifica fuera de
la ROM con hardware adicional.
Por ejemplo, las tres microoperaciones del PC, 0 → PC, PC + 1 → PC y ABUS → PC, nunca
se afirman en el mismo estado. Por el costo de un decodificador 2 a 4 externo, se puede
ahorrar un bit de la ROM, codificando las señales como sigue:
00 Ningún control del PC
01 0 → PC
10 PC + 1 → PC
11 ABUS → PC
Hay muchas otras estrategias de codificación plausibles para este controlador. MAR → Bus
de Direcciones y Petición siempre se afirman juntas, así como RBUS → AC, MBUS → ALU
B, MBR → MBUS y ALU → RBUS. Si se ha diseñado la ALU para pasar su entrada A
selectivamente, se puede combinar AC → ALU A en el estado LD2 con esta lista de señales.
Como otro ejemplo, se pueden combinar MBR → ABUS y ABUS → IR. Si se toman juntas,
estas codificaciones ahorran seis bits de la ROM.
Se pueden ahorrar bits adicionales de la ROM encontrando señales no relacionadas que nunca
se afirman al mismo tiempo. Estas son buenas candidatas para la codificación. Por ejemplo, se
pueden combinar PC → ABUS, IR → ABUS y Bus de Datos → MBR, codificándolas en dos
bits. Aplicando todas estas codificaciones al mismo tiempo se obtiene la unidad de control
codificada de la Figura 12.25. Las salidas directas de la ROM se han reducido de 22 a 15.
29
A medida que se ponen más señales de control de la ROM en una forma codificada, nos
movemos de un formato muy horizontal a uno que es cada vez más vertical. A continuación
se presenta un enfoque sistemático a la microprogramación vertical.
12.5.2 Microprogramación Vertical
La microprogramación vertical hace un uso mayor de la codificación de la ROM para reducir
el largo de la palabra de control. Para alcanzar este objetivo, comúnmente se usan múltiples
formatos de micropalabras. Por ejemplo, muchos estados no requieren una ramificación de
próximo estado condicional; simplemente avanzan al próximo estado en la secuencia. En
lugar de hacer que cada micropalabra contenga un próximo estado y una lista de
microoperaciones, se puede acortar la palabra de la ROM separando estas dos funciones en
formatos de micropalabra individuales: uno para los “saltos de ramificación” condicionales y
otro para las operaciones de transferencia de registros/microoperaciones.
Acortar la palabra de la ROM no sale gratis. Se pueden necesitar varias palabras de la ROM
en una secuencia para realizar las mismas operaciones que una única micropalabra horizontal.
La combinación de niveles adicionales de decodificación, múltiples accesos a la ROM para
ejecutar una secuencia de operaciones de control y el sacrificio de paralelismo potencial del
enfoque vertical lleva a implementaciones más lentas. El tiempo de ciclo básico de la máquina
se incrementa y el número de ciclos de máquina para ejecutar una instrucción también se
incrementa.
30
A pesar de esta ineficiencia, los diseñadores prefieren el microcódigo vertical debido a que es
muy parecido a codificar en lenguaje ensamblador. Así, el compromiso entre el microcódigo
vertical y horizontal es realmente un asunto de facilidad de implementación versus
rendimiento.
Formato de Microcódigo Vertical para la CPU Simple Desarrollemos ahora un formato de
microcódigo vertical simple para el procesador simple. Se introducirán sólo dos formatos: un
formato de salto de ramificación y un formato de transferencia de registros/operación.
En una micropalabra de salto de ramificación, se incluye un campo para seleccionar una señal
que se tiene que evaluar (Esperar, AC<15>, IR<15>, IR<14>) y el valor contra el que se debe
comprobar (0 ó 1). Si la señal es igual al valor especificado, el resto de la micropalabra
contiene la dirección de la próxima palabra de la ROM que se tiene que buscar. El campo de
selección de la condición puede tener una longitud de 2 bits; el campo de comparación de la
condición puede ser de 1 bit de ancho.
La micropalabra de transferencia de registros/operación contiene tres campos: un registro de
origen, un registro de destino y un campo de operación para indicarle qué hacer a las unidades
funcionales, como la ALU. Para comenzar, organicemos las microoperaciones de acuerdo a
estas categorías:
Orígenes:
PC → ABUS
IR → ABUS
MBR → MBUS
AC → ALU A
MAR → Bus de Direcciones de Memoria
MBR → Bus de Datos de Memoria
MBR → MBUS
AC → RBUS
Resultado ALU → RBUS
Destinos:
RBUS → AC
MBUS → ALU B
MBUS → IR
ABUS → MAR
Bus de Datos de Memoria → MBR
RBUS → MBR
ABUS → PC
Operaciones:
ALU SUMAR
ALU PASAR B
0 → PC
PC + 1 → PC
Leer (Leer, Petición)
Escribir ( Escribir , Petición)
31
Se pueden codificar los nueve orígenes en un campo de 4 bits, los siete destinos en 3 bits y las
seis operaciones también en 3 bits (se han combinado Leer/ Escribir y Petición en el
formato de operación).
Por supuesto que sería conveniente codificar todos los campos en la misma cantidad de bits.
En este momento, se tienen varios orígenes más que destinos. Un examen de cerca del camino
de datos de la Figura 11.26 indica que podemos hacerlo mejor al codificar los destinos. Se
puede asumir que el AC está cableado a la entrada A de la ALU, al igual que el MBUS está
cableado a la entrada B de la ALU. Además, el MBR es el único origen del MBUS, de manera
que se puede eliminar la microoperación MBR → MBUS. Esto nos da siete orígenes y seis
destinos, fácilmente codificados en 3 bits cada uno.
Todavía hay una complicación. En las escrituras a memoria, tales como durante un
almacenamiento, el MAR debe manejar las líneas de dirección de la memoria y el MBR debe
manejar las líneas de datos. Pero tal como está listado arriba, estas dos microoperaciones
ahora son mutuamente excluyentes.
Afortunadamente, hay una solución razonable. Se puede mover la operación MBR → Bus de
Datos de Memoria de los orígenes a los destinos, simplemente pensando en la memoria como
destino, en lugar del MBR como origen. La codificación de los dos formatos puede encajar en
10 bits muy compactos, como se muestra en la Figura 12.26.
En la Figura 12.27 se muestra el contenido de la ROM para el controlador Moore.
32
Restablecer se maneja externamente. El formato simbólico debería ser intuitivamente obvio y
guarda una sorprendente similitud con los programas en lenguaje ensamblador. Los dos
formatos alternativos se denotan con BJ para el salto de ramificación y RT para la
transferencia de registros. El primero está escrito como la condición seguida de la próxima
dirección. Por ejemplo,
BJ Wait = 0, IF0
es una microinstrucción de salto de ramificación que comprueba si la señal Esperar está
negada. Si lo está, la microinstrucción causa que se busque la próxima microinstrucción del
lugar de la ROM con la etiqueta IF0.
El formato RT se escribe como SRC → DST seguido de las operaciones que se realizan en
paralelo con la transferencia de registros. Por ejemplo,
RT PC → MAR, PC + 1 → PC
es una operación de transferencia de registros que se corresponde con las microoperaciones
PC → ABUS, ABUS → MAR y PC + 1 → PC.
Discusión La Figura 12.27 nos conduce a unas pocas observaciones. Primero, no se ha
incluido una operación de ramificación incondicional en el conjunto de instrucciones del
microcódigo. Esto se maneja con dos instrucciones BJ en secuencia, comprobar una condición
33
y su complemento, saltando al mismo lugar en ambos casos. Obviamente, se podría revisar el
formato de microinstrucción para incluir ese tipo de ramificación.
Segundo, es importante que las señales que van al mundo exterior, tales como aquéllas que
conectan el MAR y el MBR a buses externos y aquéllas que manejan las líneas Leer/ Escribir y
Petición, se acerrojen en la salida del controlador. Esto se necesita debido a que las
operaciones RT que afirman estas señales normalmente son seguidas por operaciones BJ que
comprueban la señal Esperar. Para implementar correctamente el protocolo de intercambio
con dispositivos externos, se deben mantener las señales externas hasta que encontremos la
próxima operación RT. Esta tarea se puede hacer con registros simples en las salidas de
control, que se carguen sólo cuando se ejecute una microoperación RT.
El microprograma requiere 31 palabras por 10 bits de ROM, es decir, un total de 310 bits. La
implementación horizontal descrita anteriormente usó una ROM de 16 palabras x 38 bits (16
bits de próximos estados más 22 bits de las microoperaciones), dando una ROM de 608 bits.
El formato vertical es muy eficiente en términos de la cantidad de bits de ROM requeridos
para implementar este controlador en particular. Una buena parte de los ahorros vienen del
formato separado del salto de ramificación. Se lo ha usado solo en los casos que se hace un
bucle en un estado o se salta fuera de la secuencia.
Detalles de Implementación del Controlador con Microcódigo Vertical En la Figura 12.28
se muestra una implementación sencilla del controlador con microprogramación vertical.
El registro de próximo estado se implementa como un contador de microprograma, con CLR,
CNT y LD. Un bloque de lógica condicional determina si se afirma CNT o LD en base al tipo
de microinstrucción y las condiciones que se están comprobando. Mediante decodificadores
externos se hacen corresponder las operaciones de transferencia de registros codificadas con
las microoperaciones soportadas por el camino de datos.
En la figura 12.29 se muestra la lógica del bloque de condición. Los bits del selector de
condición que vienen de la microinstrucción seleccionan una de cuatro señales posibles a
comprobar. La condición seleccionada se compara con el bit especificado. La señal de carga
del µPC se afirma si la microinstrucción actual es un salto de ramificación (tipo 1) y el bit de
condición y de comparación son idénticos. El valor que se va a cargar viene de los 6 bits
menos significativos de la microinstrucción. La señal de cuenta se afirma si el tipo de
instrucción es transferencia de registros (tipo 0) o si el bit de condición es diferente al bit de
comparación.
34
12.5.3 Memoria de Control de Escritura (Writable Control Store)
La memoria de control no necesita estar fija en una ROM. Algunas computadoras hacen
corresponder parte de las direcciones de la memoria de control en RAM, la misma memoria
que los programadores usan para las instrucciones y los datos. Esto tiene la flexibilidad
añadida de que los programadores de lenguaje ensamblador pueden escribir su propio
microcódigo, extendiendo el conjunto de instrucciones “nativo” de la máquina con
instrucciones de propósito especial.
Por supuesto, la mayoría de los programadores no son lo suficientemente sofisticados como
para escribir su propio microcódigo, sin embargo muchas máquinas con conjuntos de
instrucciones complejos todavía proporcionan una memoria de control de escritura. La razón
es simple. Dado que el microprograma de una máquina de estados compleja es en sí mismo
bastante complejo, no es inusual que tenga errores. Si se dispone de una memoria de control
de escritura se hace más fácil revisar el control de la máquina y actualizarlo en el campo. En
el momento del encendido, la máquina ejecuta una secuencia de microprograma de “inicio”
35
(“boot”) desde ROM, que carga el resto del microcódigo en la RAM desde un dispositivo
externo, tal como un disco flexible.
Resumen del Capítulo
En este capítulo se han descrito métodos alternativos para organizar la unidad de control de un
procesador simple. Se comenzó tratando las implementaciones clásicas de las máquinas
Moore y Mealy. Si bien son apropiadas para máquinas de estados finitos simples, estas
implementaciones monolíticas no son de mucha ayuda al estructurar una máquina de estados
compleja.
Como alternativa, se ha examinado el enfoque “divide y vencerás” basado en la
descomposición de las máquina de estados en máquinas de estados de tiempo, instrucción y
condición, el también denominado enfoque estado de tiempo. La mayor parte de las
instrucciones siguen un camino similar por la máquina de estados, y el enfoque de estado de
tiempo captura esta secuencia con la máquina de estado de tiempo. Las microoperaciones se
implementan como funciones Booleanas del estado de tiempo, el estado de instrucción y el
estado de condición.
Luego se vieron los contadores de salto, un método que usa componentes TTL MSI, tales
como contadores, mutiplexores y decodificadores, para implementar las funciones de próximo
estado y salida de la máquina de estados finitos. Esto conduce a una implementación limpia
de la máquina de estados finitos que es fácil de depurar y modificar. Sin embargo, están
limitados a máquinas con una cantidad modesta de estados.
La siguiente organización del controlador fue el secuenciador de ramificación. Este es un
método de disponer la lógica de próximo estado que coloca los próximos estados potenciales
en una ROM. La lógica de selección usa las entradas de la máquina para seleccionar
condicionalmente el próximo estado entre los candidatos posibles.
Finalmente, se examinó la microprogramación, incluyendo sus variedades horizontal y
vertical. La microprogramación evita la implementación con lógica discreta de las funciones
de próximo estado y de salida, implementándolas como una tabla de unos y ceros almacenada
en una memoria. La microprogramación horizontal dedica un bit de la ROM para cada señal
36
de control, y los formatos de microcódigo vertical buscan reducir el tamaño de la ROM
mediante la codificación extensiva. Una implementación de microcódigo vertical típica
soporta múltiples formatos de la micropalabra dentro de la ROM.
Todos estos enfoques son apropiados para hacer la implementación con dispositivos lógicos
programables o ROMs. El diseño basado en ROM tal vez es el más simple, pero se pueden
llegar a construir ROMs de control inmensas si no se es cuidadoso. En su implementación
más naíf, cada señal de entrada posible podría formar parte de la dirección de la ROM! En
parte, las técnicas del contador de salto y del secuenciador de ramificación se desarrollaron
como formas de reducir el tamaño de la ROM, trasladando algo de la secuenciación de
próximo estado condicional a lógica externa. De forma similar, la microprogramación vertical
reduce el tamaño de la ROM de control separando la selección del próximo estado de las
operaciones de transferencia de registros y codificando fuertemente las últimas.
Vale la pena comparar los controladores “cableados” con lógica discreta con el enfoque de la
microprogramación. El control cableado tiende a llevar a implementaciones más rápidas, pero
son más difíciles de modificar. Dichas implementaciones forman la base de las máquinas con
conjuntos de instrucciones simples o “reducidos” (RISC).
Por otra parte, los controladores microprogramados sacan ventaja de la densidad de la
memoria, implementando funciones de control complejas como unos y ceros almacenados en
una ROM. La arquitectura de tales controladores es más general que la de los cableados,
haciendo posible el cambio del conjunto de instrucciones sin tener que cambiar el camino de
datos subyacente. Sin embargo, esta flexibilidad se obtiene a algún costo en el tiempo de ciclo
del procesador, y normalmente se hace un esfuerzo por mantener el tamaño de la ROM tan
pequeño como sea posible. Comparada con el enfoque cableado, la microprogramación
provee una forma razonable de estructurar el diseño y la implementación de un controlador
complejo. Este es el enfoque de implementación preferido para máquinas con conjuntos de
instrucciones complejos, y por lo tanto para los controladores de los procesadores, como la
VAX de Digital Equipment Corporation, el 80x86 de Intel y el 68x00 de Motorola.
Lectura Adicional
Si bien las técnicas de implementación de controladores descritas en este capítulo son una
aplicación natural de los métodos de diseño de sistemas digitales, pocos libros sobre diseño de
sistemas digitales gastan mucho tiempo en ellas. Entre las excepciones se incluyen el libro de
Johnson y Karim Digital Design: A Pragmatic Approach, PWS Engineering, Boston, 1987
(ver el Capítulo 13), y Prosser y Winkel, The Art of Digital Design, 2nd ed., Prentice-Hall,
Englewood Cliffs, NJ, 1987 (ver el Capítulo 10).
Varios libros buenos se enfocan en la microprogramación como técnica de implementación.
Por ejemplo, vea el libro de M. Andrew Principles of Firmware Engineering in
Microprogram Control, Computer Science Press, Woodland Hills, CA, 1980.
37
Descargar