implementacin del controlador - dea.unsj.edu.ardea.unsj.edu.ar/sisdig2/capitulo 12.pdf · máquina...

37
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

Upload: vanthuan

Post on 09-Oct-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

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, AD0-AD2, 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:

( ) ( ) ( )( ) ( )1196231

119623110850

EsperarEsperarHOLD

EsperarEsperarCNT

SSSSSS

SSSSSSSSSS

+++•++•=

+++•++•++++=

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 ( )EsperarResetCLR 913127 •++++= SSSS .

Dado que la entrada CLR es activa en bajo, la función debería ser reescrita usando el teorema de De Morgan:

( )EsperarrRestableceCLR 913127 +••••= SSSS

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

( ) EsperarEsperarEsperarEsperarEsperarEsperarHOLDCNT

EsperarEsperarEsperarEsperarEsperarEsperarHOLD

1196321

1196321

•+•+•+•+•+•=

•+•+•+•+•+•=

SSSSSS

SSSSSS

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:

( ) EsperarEsperarEsperarEsperarEsperarEsperarHOLDCNT

EsperarEsperarEsperarEsperarEsperarEsperarHOLD

1196321

1196321

•+•+•+•+•+•=

•+•+•+•+•+•=

SSSSSS

SSSSSS

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:

rRestableceCLR CLR rRestableceCLRCLR mm •=+=

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: ( ) 4IR14 IR15IR14IR15IR14IR15 S++ 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 LD con esta lista de señales. Como otro ejemplo, se pueden combinar

2

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