Apuntes de Verilog
Tema 7. Arquitectura de Ordenadores. Procesador MIPS
3ª Parte: la Unidad de Control
3ª Parte: la Unidad de Control
11 de septiembre 2025
La Control Unit o Unidad de Control en un procesador MIPS es el bloque encargado de dirigir el funcionamiento del procesador, generando las señales necesarias para que los demás módulos (ALU, memoria, Register File, etc.) realicen la operación correcta según la instrucción que se está ejecutando.
Es un circuito que, a partir del opcode y, en algunos casos, de los campos funct de la instrucción, decodifica qué tipo de operación se debe realizar y genera las señales de control adecuadas para coordinar el datapath.
Decodificación de instrucciones
Interpreta el opcode (y funct en instrucciones tipo R) para saber si la instrucción es aritmética, lógica o de carga/almacenamiento.
Generación de señales de control
Produce las señales que gobiernan el datapath, como:
RegWrite → habilita la escritura en el banco de registros.
MemRead / MemWrite → controlan lectura/escritura en la memoria de datos.
ALUOp → envía un código reducido al módulo ALU Decoder para elegir la operación exacta.
Interacción con el módulo ALU Decoder
El módulo principal o Main Decoder envía una señal ALUOp general, y el ALU Decoder (otro bloque más pequeño) afina la operación exacta de la ALU según el campo funct de la instrucción.
Procesador MIPS: Control Unit
La imagen siguiente muestra el código Verilog de los dos módulos simples que forman la Unidad de Control: el Main Decoder y el ALU Decoder. Puedes descargar las fuentes al final de la página.
Para comprobar su correcto funcionamiento, vamos al conectar la Contro Unit con el Program Counter y el Instruction Memory.
La simulación consiste en grabar unas instrucciones de prueba en el Instruction Memory y verificar que la Unidad de Control activa las señales correspondientes, según se va incrementando el PC y el módulo IM va poniendo las instrucciones en el bus.
Unidad de Control. Circuito de prueba
Ejecutamos la simulación y verificamos que efectivamente la Unidad de Control funciona como se espera.
Ya hemos verificado que la Unidad de Control funciona correctamente. Sólo queda conectarla con el Datapath y probar todo el conjunto. Para ello conectamos los módulos datapath y controller dentro de un módulo principal o top module.
Procesador MIPS. Instrucciones I-type
Para que no quede muy extenso, voy a poner a continuación solamente el código Verilog del top module y el testbench.
Todas las fuentes están disponibles para descargar al final de la página.
top module & testbench
La siguiente imagen muestra las instrucciones de prueba que hemos cargado en el módulo Instruction Memory.
Antes de lanzar la simulación en Vivado, veamos un poco de teoría sobre cómo funcionan las instrucciones tipo-I que vamos a ejecutar en el procesador.
En un procesador MIPS, una instrucción I-type es una de las tres principales categorías de instrucciones, junto con R-type y J-type. Las instrucciones I-type se utilizan principalmente para operaciones que involucran inmediatos (valores constantes), cargas y almacenamientos de memoria, y saltos condicionales.
Estructura de una instrucción I-type
Una instrucción I-type tiene el siguiente formato de 32 bits:
| opcode (6 bits) | rs (5 bits) | rt (5 bits) | immediate (16 bits) |
opcode: código de operación que indica qué instrucción se está ejecutando.
rs: registro fuente.
rt: registro destino.
immediate: valor inmediato (constante) o desplazamiento.
Ejemplos de instrucciones tipo-I
1. addi, realiza una suma entre un registro y un valor inmediato (una constante).
addi $t0, $t1, 5
Suma el contenido de $t1 con el valor inmediato 5 y guarda el resultado en $t0.
2. lw, carga una palabra desde Data Memory y la guarda en el Register File; el movimiento de datos es desde la memoria hacia el registro.
lw $t0, 4($t1)
Carga una palabra desde la memoria (dirección [$t1 + 4]) y la guarda en el registro $t0.
3. sw, almacena el contenido de un registro en el módulo Data Memory. En este caso el movimiento de datos es desde el registro hacia la memoria.
sw $rt, offset($rs)
Almacena el contenido del registro $rt en la dirección de memoria [$rs + offset].
Las instrucciones lw (load word) y sw (store word) en MIPS son fundamentales para el acceso a memoria.
¿Cuándo se usan las instrucciones tipo-I?
Cuando necesitamos trabajar con valores constantes.
Para acceder a memoria (cargar o almacenar datos).
Detalles importantes
El offset es un valor inmediato de 16 bits, que puede ser positivo o negativo.
La dirección de memoria debe estar alineada (múltiplo de 4) para evitar errores.
Estas instrucciones se usan comúnmente para acceder a variables en memoria, especialmente en estructuras como arrays o pilas.
Ejecutamos la simulación de un par de instrucciones lw, donde leemos dos datos de Data Memory y los guardamos en el Register File. A continuación ejecutamos dos instrucciones sw para almacenar dos datos del Registro en Data Memory. Luego volvemos a ejecutar tres instrucciones lw para verificar que los datos se han guardado correctamente en la memoria.
Eso es todo por el momento, espero que os haya gustado.
En el Tema 8 veremos cómo añadir nuevas funciones al datapath para ejecutar instrucciones tipo-R.
MIPS32 Single-Cycle Processor, thanks to Mr Moamen Wael for sharing!
Puedes descargar las fuentes, esquema y testbenches aquí abajo.