Microcódigo
En el diseño de procesadores, el microcódigo (μcode) o microprograma es una técnica que interpone una capa de organización informática entre el hardware de la unidad central de procesamiento (CPU) y la arquitectura del conjunto de instrucciones visible para el programador de una computadora. El microcódigo es una capa de instrucciones a nivel de hardware que implementa instrucciones de código de máquina de nivel superior o secuenciación interna de máquina de estado finito en muchos elementos de procesamiento digital. El microcódigo se usa en unidades de procesamiento central de propósito general, aunque en las CPU de escritorio actuales, es solo una ruta alternativa para los casos que la unidad de control cableada más rápida no puede manejar.
El microcódigo generalmente reside en una memoria especial de alta velocidad y traduce las instrucciones de la máquina, los datos de la máquina de estado u otras entradas en secuencias de operaciones detalladas a nivel de circuito. Separa las instrucciones de la máquina de la electrónica subyacente para que las instrucciones puedan diseñarse y modificarse más libremente. También facilita la creación de instrucciones complejas de varios pasos, al tiempo que reduce la complejidad de los circuitos informáticos. Escribir microcódigo a menudo se denomina microprogramación y el microcódigo en una implementación de procesador particular a veces se denomina microprograma.
Una microcodificación más amplia permite que las microarquitecturas pequeñas y simples emulen arquitecturas más poderosas con una longitud de palabra más amplia, más unidades de ejecución, etc., que es una forma relativamente simple de lograr la compatibilidad de software entre diferentes productos en una familia de procesadores.
Algunos proveedores de hardware, especialmente IBM, utilizan el término microcódigo como sinónimo de firmware. De esa manera, todo el código dentro de un dispositivo se denomina microcódigo, independientemente de que sea un microcódigo o un código de máquina; por ejemplo, se dice que las unidades de disco duro tienen su microcódigo actualizado, aunque normalmente contienen microcódigo y firmware.
Visión general
La capa más baja en la pila de software de una computadora es tradicionalmente instrucciones de código de máquina sin procesar para el procesador. En los procesadores microcodificados, la obtención y decodificación de esas instrucciones y su ejecución pueden realizarse mediante microcódigo. Para evitar confusiones, cada elemento relacionado con un microprograma se diferencia por el prefijo micro: microinstrucción, microensamblador, microprogramador, microarquitectura, etc.
Los procesadores digitales complejos también pueden emplear más de una unidad de control (posiblemente basada en microcódigo) para delegar subtareas que deben realizarse esencialmente de forma asíncrona en paralelo. Por ejemplo, el VAX 9000 tiene una unidad IBox para obtener y decodificar instrucciones, que entrega a una unidad EBox microcodificada para que las ejecute, y el VAX 8800 tiene tanto una IBox microcodificada como una EBox microcodificada.
Un programador de alto nivel, o incluso un programador de lenguaje ensamblador, normalmente no ve ni cambia el microcódigo. A diferencia del código de máquina, que a menudo conserva cierta compatibilidad con versiones anteriores entre los diferentes procesadores de una familia, el microcódigo solo se ejecuta en el circuito electrónico exacto para el que está diseñado, ya que constituye una parte inherente del diseño del procesador en particular.
Diseño
Los ingenieros normalmente escriben el microcódigo durante la fase de diseño de un procesador, almacenándolo en una estructura de memoria de solo lectura (ROM) o matriz lógica programable (PLA), o en una combinación de ambas. Sin embargo, también existen máquinas que tienen algunos o todos los microcódigos almacenados en la memoria estática de acceso aleatorio (SRAM) o en la memoria flash. Esto se denomina tradicionalmente como almacenamiento de control escribible en el contexto de las computadoras, que puede ser memoria de solo lectura o de lectura y escritura. En el último caso, el proceso de inicialización de la CPU carga el microcódigo en el almacén de control desde otro medio de almacenamiento, con la posibilidad de alterar el microcódigo para corregir errores en el conjunto de instrucciones o para implementar nuevas instrucciones de máquina.
Microprogramas
Los microprogramas consisten en una serie de microinstrucciones que controlan la CPU en un nivel muy fundamental de circuitos de hardware. Por ejemplo, una sola microinstrucción horizontal típica podría especificar las siguientes operaciones:
- Conecte el registro 1 al lado A de la ALU
- Conecte el registro 7 al lado B de la ALU
- Configure la ALU para realizar una suma en complemento a dos
- Establecer la entrada de acarreo de la ALU a cero
- Almacene el valor del resultado en el registro 8
- Actualice los códigos de condición de las banderas de estado de ALU (negativo, cero, desbordamiento y acarreo)
- Microsalto a una dirección de microPC determinada para la siguiente microinstrucción
Para controlar simultáneamente todas las funciones del procesador en un ciclo, la microinstrucción suele tener más de 50 bits; por ejemplo, 128 bits en un 360/85 con función de emulador. Los microprogramas están cuidadosamente diseñados y optimizados para la ejecución más rápida posible, ya que un microprograma lento daría como resultado una instrucción de máquina lenta y un rendimiento degradado para los programas de aplicación relacionados que utilizan dichas instrucciones.
Justificación
El microcódigo se desarrolló originalmente como un método más simple para desarrollar la lógica de control de una computadora. Inicialmente, los conjuntos de instrucciones de la CPU estaban cableados. Cada paso necesario para obtener, decodificar y ejecutar las instrucciones de la máquina (incluidos los cálculos, las lecturas y las escrituras de direcciones de operandos) estaba controlado directamente por la lógica combinacional y un circuito de máquina de estado secuencial bastante mínimo. Si bien estos procesadores cableados eran muy eficientes, la necesidad de potentes conjuntos de instrucciones con direccionamiento de varios pasos y operaciones complejas (ver más abajo) dificultaba su diseño y depuración; Las instrucciones altamente codificadas y de longitud variable también pueden contribuir a esto, especialmente cuando se utilizan codificaciones muy irregulares.
El microcódigo simplificó el trabajo al permitir que gran parte del comportamiento del procesador y el modelo de programación se definieran a través de rutinas de microprograma en lugar de circuitos dedicados. Incluso al final del proceso de diseño, el microcódigo se podía cambiar fácilmente, mientras que los diseños de CPU cableados eran muy engorrosos de cambiar. Por lo tanto, esto facilitó enormemente el diseño de la CPU.
Desde la década de 1940 hasta finales de la de 1970, una gran parte de la programación se realizó en lenguaje ensamblador; las instrucciones de alto nivel significan una mayor productividad del programador, por lo que una ventaja importante del microcódigo fue la relativa facilidad con la que se pueden definir poderosas instrucciones de máquina. La última extensión de esto son los diseños de "lenguaje de alto nivel directamente ejecutable", en los que cada declaración de un lenguaje de alto nivel como PL/I se ejecuta completa y directamente mediante microcódigo, sin compilación. El proyecto IBM Future Systems y Data General Fountainhead Processor son ejemplos de esto. Durante la década de 1970, las velocidades de la CPU crecieron más rápidamente que las velocidades de la memoria y se utilizaron numerosas técnicas, como la transferencia de bloques de memoria, la recuperación previa de memoria y las cachés de varios niveles para aliviar esto. Instrucciones de máquina de alto nivel, posibles gracias al microcódigo, ayudó aún más, ya que menos instrucciones de máquina más complejas requieren menos ancho de banda de memoria. Por ejemplo, una operación en una cadena de caracteres se puede realizar como una sola instrucción de máquina, evitando así múltiples búsquedas de instrucciones.
Las arquitecturas con conjuntos de instrucciones implementados por microprogramas complejos incluían IBM System/360 y Digital Equipment Corporation VAX. El enfoque de conjuntos de instrucciones implementados con microcódigos cada vez más complejos se denominó más tarde computadora con conjunto de instrucciones complejas (CISC). Un enfoque alternativo, usado en muchos microprocesadores, es usar una o más matrices lógicas programables (PLA) o memoria de solo lectura (ROM) (en lugar de lógica combinacional) principalmente para la decodificación de instrucciones, y dejar que una máquina de estado simple (sin mucho, o cualquiera, microcódigo) hacen la mayor parte de la secuenciación. La tecnología MOS 6502 es un ejemplo de un microprocesador que utiliza un PLA para la secuenciación y decodificación de instrucciones. El PLA es visible en fotomicrografías del chip, y su funcionamiento puede verse en la simulación a nivel de transistor.
La microprogramación todavía se usa en los diseños modernos de CPU. En algunos casos, después de que se depura el microcódigo en la simulación, las funciones lógicas se sustituyen por el almacén de control. Las funciones lógicas suelen ser más rápidas y menos costosas que la memoria de microprograma equivalente.
Beneficios
Los microprogramas de un procesador operan en una arquitectura más primitiva, totalmente diferente y mucho más orientada al hardware que las instrucciones de ensamblaje visibles para los programadores normales. En coordinación con el hardware, el microcódigo implementa la arquitectura visible para el programador. El hardware subyacente no necesita tener una relación fija con la arquitectura visible. Esto facilita la implementación de una arquitectura de conjunto de instrucciones dada en una amplia variedad de microarquitecturas de hardware subyacentes.
IBM System/360 tiene una arquitectura de 32 bits con 16 registros de propósito general, pero la mayoría de las implementaciones de System/360 utilizan hardware que implementa una microarquitectura subyacente mucho más simple; por ejemplo, System/360 Model 30 tiene rutas de datos de 8 bits a la unidad lógica aritmética (ALU) y la memoria principal e implementó los registros de propósito general en una unidad especial de memoria central de mayor velocidad, y System/360 Model 40 tiene rutas de datos de 8 bits a la ALU y rutas de datos de 16 bits a la memoria principal y también implementó los registros de uso general en una unidad especial de memoria central de mayor velocidad. El Modelo 50 tiene rutas de datos completas de 32 bits e implementa los registros de propósito general en una unidad especial de memoria central de mayor velocidad.El Modelo 65 al Modelo 195 tienen rutas de datos más grandes e implementan los registros de uso general en circuitos de transistores más rápidos. De esta manera, la microprogramación permitió a IBM diseñar muchos modelos System/360 con hardware sustancialmente diferente y abarcando una amplia gama de costos y rendimiento, al tiempo que los hacía compatibles desde el punto de vista arquitectónico. Esto reduce drásticamente la cantidad de programas de software de sistema únicos que se deben escribir para cada modelo.
Digital Equipment Corporation (DEC) utilizó un enfoque similar en su familia de computadoras VAX. Como resultado, diferentes procesadores VAX usan diferentes microarquitecturas, pero la arquitectura visible para el programador no cambia.
La microprogramación también reduce el costo de los cambios de campo para corregir defectos (errores) en el procesador; un error a menudo se puede corregir reemplazando una parte del microprograma en lugar de realizar cambios en la lógica y el cableado del hardware.
Historia
En 1947, el diseño del MIT Whirlwind introdujo el concepto de un almacén de control como una forma de simplificar el diseño de la computadora e ir más allá de los métodos ad hoc. El almacén de control es una matriz de diodos: una red bidimensional, donde una dimensión acepta "pulsos de tiempo de control" del reloj interno de la CPU, y la otra se conecta a señales de control en puertas y otros circuitos. Un "distribuidor de pulsos" toma los pulsos generados por el reloj de la CPU y los divide en ocho pulsos de tiempo separados, cada uno de los cuales activa una fila diferente de la red. Cuando se activa la fila, activa las señales de control conectadas a ella.
Descrito de otra manera, las señales transmitidas por el almacén de control se reproducen de manera muy similar a una pianola. Es decir, están controlados por una secuencia de palabras muy anchas construidas con bits y se reproducen secuencialmente. En una tienda de control, sin embargo, la canción es corta y se repite continuamente.
En 1951, Maurice Wilkes mejoró este concepto al agregar la ejecución condicional, un concepto similar a un condicional en software de computadora. Su implementación inicial consistió en un par de matrices: la primera generaba señales a la manera del almacén de control Whirlwind, mientras que la segunda matriz seleccionaba qué fila de señales (la palabra de instrucción del microprograma, por así decirlo) invocar en el siguiente ciclo. Los condicionales se implementaron al proporcionar una forma en que una sola línea en el almacén de control podía elegir entre alternativas en la segunda matriz. Esto hizo que las señales de control estuvieran condicionadas a la señal interna detectada. Wilkes acuñó el término microprogramación para describir esta función y distinguirla de un simple almacén de control.
Ejemplos
- Se dice que el EMIDEC 1100 utiliza un almacén de control cableado que consiste en cables ensartados a través de núcleos de ferrita, conocidos como "los cordones".
- La mayoría de los modelos de la serie IBM System/360 están microprogramados:
- El Modelo 25 es único entre los modelos System/360 en el uso de los 16 K bytes superiores de almacenamiento central para mantener el almacenamiento de control para el microprograma. El 2025 utiliza una microarquitectura de 16 bits con siete palabras de control (o microinstrucciones). Después del mantenimiento del sistema o al cambiar el modo operativo, el microcódigo se carga desde el lector de tarjetas, la cinta u otro dispositivo. La emulación IBM 1410 para este modelo se carga de esta manera.
- El Modelo 30 utiliza una microarquitectura de 8 bits con solo unos pocos registros de hardware; todo lo que vio el programador es emulado por el microprograma. El microcódigo para este modelo también se encuentra en tarjetas perforadas especiales, que se almacenan dentro de la máquina en un lector dedicado por tarjeta, llamado unidades "CROS" (Capacitor Read-Only Storage). Se agrega otra unidad CROS para máquinas pedidas con emulación 1401/1440/1460 y para máquinas pedidas con emulación 1620.
- El Modelo 40 usa palabras de control de 56 bits. La caja 2040 implementa tanto el procesador principal System/360 como el canal múltiplex (el procesador de E/S). Este modelo utiliza lectores dedicados TROS similares a las unidades CROS, pero con una captación inductiva (Transformer Read-only Store).
- El Modelo 50 tiene dos rutas de datos internas que funcionan en paralelo: una ruta de datos de 32 bits utilizada para operaciones aritméticas y una ruta de datos de 8 bits utilizada en algunas operaciones lógicas. El almacén de control utiliza microinstrucciones de 90 bits.
- El modelo 85 tiene búsqueda de instrucciones (unidad I) y ejecución (unidad E) separadas para proporcionar un alto rendimiento. La unidad I está controlada por hardware. La unidad E está microprogramada; las palabras de control tienen 108 bits de ancho en un 360/85 básico y más ancho si se instala una función de emulador.
- El NCR 315 está microprogramado con núcleos de ferrita cableados a mano (una ROM) pulsados por un secuenciador con ejecución condicional. Los cables enrutados a través de los núcleos están habilitados para varios datos y elementos lógicos en el procesador.
- Los procesadores PDP-11 de Digital Equipment Corporation, con la excepción del PDP-11/20, están microprogramados.
- La mayoría de las minicomputadoras Data General Eclipse están microprogramadas. La tarea de escribir el microcódigo para el Eclipse MV/8000 se detalla en el libro ganador del Premio Pulitzer titulado The Soul of a New Machine.
- Muchos sistemas de Burroughs están microprogramados:
- El "microprocesador" B700 ejecuta códigos de operación de nivel de aplicación utilizando secuencias de microinstrucciones de 16 bits almacenadas en la memoria principal; cada uno de estos es una operación de carga de registro o se asigna a una sola instrucción de "nanocódigo" de 56 bits almacenada en la memoria de solo lectura. Esto permite que un hardware comparativamente simple actúe como un controlador periférico de mainframe o se empaquete como una computadora independiente.
- El B1700 se implementa con hardware radicalmente diferente, incluida la memoria principal direccionable por bits, pero tiene una organización similar de varias capas. El sistema operativo precarga el intérprete para cualquier idioma que se requiera. Estos intérpretes presentan diferentes máquinas virtuales para COBOL, Fortran, etc.
- Equipos producidos con microdatos en los que el microcódigo es accesible al usuario; esto permite la creación de instrucciones de nivel de ensamblador personalizadas. El diseño del sistema operativo Reality de Microdata hace un uso extensivo de esta capacidad.
- La estación de trabajo Xerox Alto usaba un diseño microcodificado pero, a diferencia de muchas computadoras, el motor de microcódigo no está oculto para el programador en un diseño en capas. Las aplicaciones aprovechan esto para acelerar el rendimiento.
- Se describe que IBM System/38 tiene un microcódigo tanto horizontal como vertical. En la práctica, el procesador implementa una arquitectura de conjunto de instrucciones denominada Interfaz Microprogramada Interna (IMPI) utilizando un formato de microcódigo horizontal. La denominada capa de microcódigo vertical implementa el conjunto de instrucciones de interfaz de máquina independiente del hardware del System/38 en términos de instrucciones IMPI. Antes de la instrucción de la línea de procesadores IBM RS64, los primeros sistemas IBM AS/400 usaban la misma arquitectura.
- El coprocesador de realidad (RCP) de Nintendo 64, que sirve como unidad de procesamiento de gráficos y procesador de audio de la consola, utiliza microcódigo; es posible implementar nuevos efectos o ajustar el procesador para lograr el resultado deseado. Algunos ejemplos notables de microcódigo RCP personalizado incluyen gráficos de alta resolución, motores de partículas y distancias de dibujo ilimitadas que se encuentran en Indiana Jones and the Infernal Machine de Factor 5, Star Wars: Rogue Squadron y Star Wars: Battle for Naboo; y la reproducción de video de movimiento completo que se encuentra en Resident Evil 2 de Angel Studios.
- Las unidades vectoriales VU0 y VU1 de Sony PlayStation 2 son microprogramables; de hecho, solo se puede acceder a VU1 a través de un microcódigo durante las primeras generaciones del SDK.
- MicroCore Labs MCL86, MCL51 y MCL65 son ejemplos de implementaciones de microsecuenciadores "verticales" altamente codificadas de Intel 8086/8088, 8051 y MOS 6502.
- El sistema informático Digital Scientific Corp. Meta 4 Series 16 era un sistema microprogramable de usuario disponible por primera vez en 1970. El microcódigo tenía un estilo principalmente vertical con microinstrucciones de 32 bits. Las instrucciones se almacenaron en placas de programa reemplazables con una cuadrícula de posiciones de bits. Uno (1) bits estaban representados por pequeños cuadrados de metal que eran detectados por amplificadores, cero (0) bits por la ausencia de los cuadrados. El sistema se puede configurar con hasta 4K palabras de 16 bits de microstore. Uno de los productos de Digital Scientific fue un emulador para IBM 1130.
- El MCP-1600 es un microprocesador fabricado por Western Digital desde finales de la década de 1970 hasta principios de la de 1980 que se utiliza para implementar tres arquitecturas informáticas diferentes en microcódigo: Pascal MicroEngine, WD16 y DEC LSI-11, un PDP-11 de costo reducido..
- Los procesadores x86 anteriores están completamente microcodificados; comenzando con el Intel 80486, las instrucciones menos complicadas se implementan directamente en el hardware. Los procesadores x86 implementaron microcódigo parcheable (parche por BIOS o sistema operativo) desde la microarquitectura Intel P6 y la microarquitectura AMD K7.
- Algunas tarjetas de video, controladores de interfaz de red inalámbrica implementaron microcódigo parcheable (parche por sistema operativo).
Implementación
Cada microinstrucción en un microprograma proporciona los bits que controlan los elementos funcionales que componen internamente una CPU. La ventaja sobre una CPU cableada es que el control interno de la CPU se convierte en una forma especializada de un programa de computadora. Microcode transforma así un desafío de diseño electrónico complejo (el control de una CPU) en un desafío de programación menos complejo. Para aprovechar esto, una CPU se divide en varias partes:
- Una unidad I puede decodificar instrucciones en hardware y determinar la dirección del microcódigo para procesar la instrucción en paralelo con la unidad E.
- Un microsecuenciador recoge la siguiente palabra del almacén de control. Un secuenciador es principalmente un contador, pero generalmente también tiene alguna forma de saltar a una parte diferente del almacén de control dependiendo de algunos datos, generalmente datos del registro de instrucciones y siempre alguna parte del almacén de control. El secuenciador más simple es solo un registro cargado desde unos pocos bits del almacén de control.
- Un conjunto de registros es una memoria rápida que contiene los datos de la unidad central de procesamiento. Puede incluir el contador del programa y el puntero de la pila, y también puede incluir otros registros que no son fácilmente accesibles para el programador de la aplicación. A menudo, el conjunto de registros es un archivo de registro de tres puertos; es decir, se pueden leer dos registros y escribir un tercero al mismo tiempo.
- Una unidad aritmética y lógica realiza cálculos, generalmente suma, negación lógica, desplazamiento a la derecha y AND lógico. A menudo también realiza otras funciones.
También puede haber un registro de direcciones de memoria y un registro de datos de memoria, utilizados para acceder al almacenamiento principal de la computadora. Juntos, estos elementos forman una "unidad de ejecución". La mayoría de las CPU modernas tienen varias unidades de ejecución. Incluso las computadoras simples suelen tener una unidad para leer y escribir en la memoria y otra para ejecutar el código de usuario. Estos elementos a menudo se pueden unir como un solo chip. Este chip viene en un ancho fijo que formaría una "rebanada" a través de la unidad de ejecución. Estos se conocen como chips de "rebanada de bits". La familia AMD Am2900 es uno de los ejemplos más conocidos de elementos de división de bits. Las partes de las unidades de ejecución y las unidades de ejecución completas están interconectadas por un haz de cables llamado bus.
Los programadores desarrollan microprogramas utilizando herramientas de software básicas. Un microensamblador permite a un programador definir simbólicamente la tabla de bits. Debido a su estrecha relación con la arquitectura subyacente, "el microcódigo tiene varias propiedades que dificultan su generación mediante un compilador". Un programa simulador está destinado a ejecutar los bits de la misma manera que la electrónica y permite mucha más libertad para depurar el microprograma. Una vez finalizado el microprograma y probado exhaustivamente, a veces se utiliza como entrada para un programa de computadora que construye la lógica para producir los mismos datos.Este programa es similar a los que se utilizan para optimizar una matriz lógica programable. Incluso sin una lógica totalmente óptima, la lógica optimizada heurísticamente puede reducir enormemente la cantidad de transistores del número necesario para un almacén de control de memoria de solo lectura (ROM). Esto reduce el costo de producción y la electricidad utilizada por una CPU.
El microcódigo se puede caracterizar como horizontal o vertical, refiriéndose principalmente a si cada microinstrucción controla los elementos de la CPU con poca o ninguna decodificación (microcódigo horizontal) o requiere una decodificación extensa mediante lógica combinatoria antes de hacerlo (microcódigo vertical). En consecuencia, cada microinstrucción horizontal es más ancha (contiene más bits) y ocupa más espacio de almacenamiento que una microinstrucción vertical.
Microcódigo horizontal
"El microcódigo horizontal tiene varias microoperaciones discretas que se combinan en una sola microinstrucción para una operación simultánea". El microcódigo horizontal suele estar contenido en un almacén de control bastante amplio; no es raro que cada palabra tenga 108 bits o más. En cada tic de un reloj secuenciador, se lee, decodifica y utiliza una palabra de microcódigo para controlar los elementos funcionales que componen la CPU.
En una implementación típica, una palabra de microprograma horizontal comprende grupos de bits bastante definidos. Por ejemplo, un arreglo simple podría ser:
Registrar fuente A | Registrar fuente B | Registro de destino | Operación de unidades aritméticas y lógicas | tipo de salto | Dirección de salto |
Para que este tipo de micromáquina implemente una instrucción JUMP con la dirección que sigue al código de operación, el microcódigo puede requerir dos tics de reloj. El ingeniero que lo diseñó escribiría el código fuente del microensamblador con un aspecto similar a este:
# Cualquier línea que comience con un signo de número es un comentario # Esto es solo una etiqueta, la forma ordinaria en que los ensambladores representan simbólicamente una # dirección de memoria. InstrucciónJUMP: # Para prepararse para la siguiente instrucción, el microcódigo de decodificación de instrucción ya # ha movido el contador del programa al registro de dirección de memoria. Esta instrucción extrae # la dirección de destino de la instrucción de salto de la palabra de memoria que sigue al # código de operación de salto, copiando del registro de datos de memoria al registro de dirección de memoria. # Esto le da al sistema de memoria dos tics de reloj para obtener la próxima # instrucción en el registro de datos de memoria para que la utilice la decodificación de instrucciones. # La instrucción del secuenciador "siguiente" significa simplemente agregar 1 a la dirección de la palabra de control. MDR, NONE, MAR, COPY, NEXT, NONE # Esto coloca la dirección de la siguiente instrucción en la PC. # Esto le da al sistema de memoria un tic de reloj para finalizar la búsqueda iniciada en la # microinstrucción anterior. # La instrucción del secuenciador es para saltar al inicio de la decodificación de la instrucción. MAR, 1, PC, ADD, JMP, InstructionDecode # No se muestra la decodificación de la instrucción, porque suele ser un lío, muy particular # al procesador exacto que se está emulando. Incluso este ejemplo está simplificado. # Muchas CPU tienen varias formas de calcular la dirección, en lugar de simplemente obtenerla # de la palabra que sigue al código de operación. Por lo tanto, en lugar de una sola instrucción de salto #, esas CPU tienen una familia de instrucciones de salto relacionadas.
Para cada marca, es común encontrar que solo se utilizan algunas partes de la CPU, y los grupos restantes de bits en la microinstrucción no tienen operaciones. Con un diseño cuidadoso de hardware y microcódigo, esta propiedad se puede explotar para paralelizar operaciones que usan diferentes áreas de la CPU; por ejemplo, en el caso anterior, la ALU no se requiere durante el primer tic, por lo que podría usarse para completar una instrucción aritmética anterior.
Microcódigo vertical
En el microcódigo vertical, cada microinstrucción está codificada significativamente, es decir, los campos de bits generalmente pasan por una lógica combinatoria intermedia que, a su vez, genera las señales de control y secuenciación para los elementos internos de la CPU (ALU, registros, etc.). Esto contrasta con el microcódigo horizontal, en el que los campos de bits producen directamente las señales de control y secuenciación o solo se codifican mínimamente. En consecuencia, el microcódigo vertical requiere longitudes de instrucción más pequeñas y menos almacenamiento, pero requiere más tiempo para decodificar, lo que resulta en un reloj de CPU más lento.
Algunos microcódigos verticales son solo el lenguaje ensamblador de una computadora convencional simple que emula una computadora más compleja. Algunos procesadores, como los procesadores DEC Alpha y los microprocesadores CMOS en los mainframes System/390 y z/Architecture posteriores de IBM, usan código de máquina y se ejecutan en un modo especial que les da acceso a instrucciones especiales, registros especiales y otros recursos de hardware que no están disponibles para código de máquina regular, para implementar algunas instrucciones y otras funciones, como recorridos de tablas de páginas en procesadores Alpha. Esto se llama PALcode en los procesadores Alpha y millicode en los procesadores de mainframe de IBM.
Otra forma de microcódigo vertical tiene dos campos:
Selección de campo | Valor de campo |
La selección de campo selecciona qué parte de la CPU será controlada por esta palabra del almacén de control. El valor del campo controla esa parte de la CPU. Con este tipo de microcódigo, un diseñador elige explícitamente hacer una CPU más lenta para ahorrar dinero al reducir los bits no utilizados en el almacén de control; sin embargo, la complejidad reducida puede aumentar la frecuencia de reloj de la CPU, lo que disminuye el efecto de un mayor número de ciclos por instrucción.
A medida que los transistores se abarataron, el microcódigo horizontal llegó a dominar el diseño de las CPU que usaban microcódigo, y el microcódigo vertical se usó con menos frecuencia.
Cuando se utilizan tanto el microcódigo vertical como el horizontal, el microcódigo horizontal puede denominarse nanocódigo o picocódigo.
Almacén de control grabable
Algunas computadoras fueron construidas usando microcódigos grabables. En este diseño, en lugar de almacenar el microcódigo en la ROM o en la lógica cableada, el microcódigo se almacena en una RAM llamada almacén de control grabable o WCS. Tal computadora a veces se denomina computadora con conjunto de instrucciones grabables (WISC).
Muchas computadoras prototipo experimentales usan almacenes de control grabables; también hay máquinas comerciales que usan microcódigo de escritura, como Burroughs Small Systems, las primeras estaciones de trabajo Xerox, la familia DEC VAX 8800 (Nautilus), las máquinas Symbolics L y G, varias IBM System/360 y System/370 implementaciones, algunas máquinas DEC PDP-10 y el Data General Eclipse MV/8000.
Muchas más máquinas ofrecen almacenes de control escribibles programables por el usuario como una opción, incluidas las minicomputadoras de la serie HP 2100, DEC PDP-11/60 y Varian Data Machines V-70. El IBM System/370 incluye una función llamada Carga de microprograma inicial (IML o IMPL) que se puede invocar desde la consola, como parte del reinicio de encendido (POR) o desde otro procesador en un complejo multiprocesador estrechamente acoplado.
Algunas máquinas comerciales, por ejemplo, IBM 360/85, tienen un almacenamiento de solo lectura y un almacén de control de escritura para microcódigo.
WCS ofrece varias ventajas, incluida la facilidad de parchear el microprograma y, para ciertas generaciones de hardware, un acceso más rápido que el que pueden proporcionar las ROM. El WCS programable por el usuario le permite optimizar la máquina para fines específicos.
Comenzando con el Pentium Pro en 1995, varias CPU x86 tienen Intel Microcode grabable. Esto, por ejemplo, ha permitido corregir errores en los microcódigos Intel Core 2 e Intel Xeon al parchear sus microprogramas, en lugar de requerir que se reemplacen todos los chips. Un segundo ejemplo destacado es el conjunto de parches de microcódigo que Intel ofreció para algunas de sus arquitecturas de procesador de hasta 10 años de antigüedad, en un intento por contrarrestar las vulnerabilidades de seguridad descubiertas en sus diseños, Spectre y Meltdown, que se hicieron públicos al principio. de 2018. Linux, FreeBSD, Microsoft Windows o el BIOS de la placa base pueden instalar una actualización de microcódigo.
Comparación con VLIW y RISC
La tendencia de diseño hacia procesadores altamente microcodificados con instrucciones complejas comenzó a principios de la década de 1960 y continuó hasta aproximadamente mediados de la década de 1980. En ese momento, la filosofía de diseño de RISC comenzó a ser más prominente.
Una CPU que usa microcódigo generalmente toma varios ciclos de reloj para ejecutar una sola instrucción, un ciclo de reloj para cada paso en el microprograma para esa instrucción. Algunos procesadores CISC incluyen instrucciones que pueden tardar mucho tiempo en ejecutarse. Tales variaciones interfieren tanto con la latencia de interrupción como, lo que es mucho más importante en los sistemas modernos, con la canalización.
Al diseñar un nuevo procesador, un RISC de control cableado tiene las siguientes ventajas sobre CISC microcodificado:
- La programación se ha alejado en gran medida del nivel de ensamblaje, por lo que ya no vale la pena proporcionar instrucciones complejas por razones de productividad.
- Los conjuntos de instrucciones más simples permiten la ejecución directa por hardware, evitando la penalización de rendimiento de la ejecución microcodificada.
- El análisis muestra que las instrucciones complejas rara vez se utilizan, por lo que los recursos de la máquina dedicados a ellas se desperdician en gran medida.
- Los recursos de la máquina dedicados a las instrucciones complejas que se utilizan con poca frecuencia se utilizan mejor para acelerar la ejecución de instrucciones más sencillas y de uso común.
- Las instrucciones microcodificadas complejas pueden requerir muchos ciclos de reloj que varían y son difíciles de canalizar para aumentar el rendimiento.
También hay contrapuntos:
- Las instrucciones complejas en implementaciones fuertemente microcodificadas pueden no requerir muchos recursos adicionales de la máquina, excepto el espacio del microcódigo. Por ejemplo, la misma ALU se usa a menudo para calcular una dirección efectiva y calcular el resultado de los operandos, por ejemplo, el Z80 original, 8086 y otros.
- Los compiladores modernos utilizan con frecuencia las instrucciones más simples que no son RISC (es decir, que involucran operandos directos de memoria). Incluso las operaciones aritméticas inmediatas a la pila (es decir, el resultado de la memoria) se emplean comúnmente. Aunque tales operaciones de memoria, a menudo con codificaciones de longitud variable, son más difíciles de canalizar, aún es completamente factible hacerlo, claramente ejemplificado por el i486, AMD K5, Cyrix 6x86, Motorola 68040, etc.
- Las instrucciones que no son RISC inherentemente realizan más trabajo por instrucción (en promedio) y normalmente también están altamente codificadas, por lo que permiten un tamaño general más pequeño del mismo programa y, por lo tanto, un mejor uso de las memorias caché limitadas.
Muchos procesadores RISC y VLIW están diseñados para ejecutar todas las instrucciones (siempre que estén en la memoria caché) en un solo ciclo. Esto es muy similar a la forma en que las CPU con microcódigo ejecutan una microinstrucción por ciclo. Los procesadores VLIW tienen instrucciones que se comportan de manera similar al microcódigo horizontal muy ancho, aunque normalmente sin un control tan detallado sobre el hardware como lo proporciona el microcódigo. Las instrucciones RISC a veces son similares al microcódigo vertical estrecho.
El microcódigo ha sido popular en procesadores específicos de aplicaciones, como procesadores de red, microcontroladores, procesadores de señales digitales, controladores de canal, controladores de disco, controladores de interfaz de red, unidades de procesamiento de gráficos y en otro hardware.
Microoperaciones
Las implementaciones modernas de CISC, como la familia x86, decodifican instrucciones en microoperaciones amortiguadas dinámicamente ("μops") con una codificación de instrucciones similar a RISC o microcódigo tradicional. Una unidad de decodificación de instrucciones cableada emite directamente μops para instrucciones x86 comunes, pero recurre a una ROM de microcódigo más tradicional que contiene μops para instrucciones más complejas o de uso poco frecuente.
Por ejemplo, un x86 podría buscar μops de microcódigo para manejar operaciones complejas de varios pasos, como instrucciones de bucle o cadena, funciones trascendentales de unidades de coma flotante o valores inusuales como números anormales e instrucciones de propósito especial como CPUID.
Contenido relacionado
Exokernel
Familia de arquitectura ARM
DALnet