S11 - myTeachingURJC/Arq-computadores-01 GitHub Wiki
Sesión de Teoría 11: NanoRISC-V Monociclo (I)
- Tiempo: 2h
- Objetivos de la sesión:
- Conocer las etapas en la ejecución de una instrucción
- Entender la ruta de datos
- Funcionamiento de la unidad de control
- Cálculo de la frecuencia máxima de funcionamiento
Contenido
- Introducción
- Procesador monociclo
- Implementación del procesador
- Simulación del funcionamiento
- Conclusiones
- Lecturas del libro de referencia
- Ejercicios
- Autores
- Licencia
- Créditos
- Enlaces
Introducción
Veremos una primera implementación del procesador NanoRisc-V
Procesador monociclo
El NanoRISC-V monociclo ejecuta las instrucciones en un único ciclo de reloj, por lo que tiene un CPI de 1. Todos los cálculos se realizan usando circuitos combinacionales y al llegar el flanco de subida del siguiente ciclo se actualiza el estado del procesador
Modelo de funcionamiento
El funcionamiento se describe utilizando el esquema que ya conocemos del encadenamiento de la parte secuencial con la parte combinacional. Cada vez que llega un flanco de subida del reloj (y comienza un nuevo ciclo) se actualiza el estado del procesador. Ese es el instante en el que la instrucción ha finalizado su ejecución
La parte combinacional es la encargada de calcular el estado siguientes: es decir, calcular cuáles serán los nuevos valores internos del procesador una vez que se ha ejecutado la instrucción
Frecuencia máxima de funcionamiento
La frecuencia máxima de funcionamiento del procesador monociclo viene determinado por la suma de los retardos de la parte secuencial (actualización estado) y de la parte combinacional (calculo del siguiente estado). Lo calculamos con la fórmula que ya conocemos:
El retardo de la parte combinacional viene dado por su camino crítico. Es decir, será el retardo máximo que se tiene al ejecutar las instrucciones. Algunas instrucciones tardarán más y otras menos. El retardo de la parte combinacional lo determina la instrucción más lenta
Estado del procesador
El estado del procesador está determinado por:
- El PC: El contador de programa. Dirección de la instrucción a ejecutar
- Los registros x1-x31
Este estado se actualiza con cada flanco de subida del reloj del sistema. Además, hay un estado externo al procesador: la memoria de datos, que también se actualiza en los flancos de subida, si la instrucción es store
Evolución del estado
Al alimentar el procesador, comienza desde el estado inicial, donde el PC y todos los registros están a cero. Cada vez que llega un flanco de subida de reloj del sistema, el estado se actualiza con los valores calculados por el circuito combinacional
Ejemplo: Programa de test 1
Como ejemplo de la evolución del estado del procesador utilizaremos el ejemplo Test-1 de la sesión anterior:
El programa tiene 3 instrucciones. Cada una de ellas se ejecuta en un ciclo de reloj (al llegar el flanco de subida). En esos flancos el estado se actualiza. El procesador pasa por 3 estados diferentes, contando el estado inicial. Esta evolución se resumen en la siguiente tabla:
Instrucción | Estado actual | Estado siguiente (Ejecución) |
---|---|---|
li t0, 0xc0 |
PC=0, t0=0, t1=0 | PC=4, t0=0xC0, t1=0 |
addi t1,t0,1 |
PC=4, t0=0xC0, t1=0 | PC=8, t0=0xC0, t1=0xC1 |
beq x0,x0,0 |
PC=8, t0=0xC0, t1=0xC1 | PC=8, t0=0xC0, t1=0xC1 |
Y en esta figura se muestra la evolución del estado con el tiempo
El cambio de estado se produce cuando los circuitos combinaciones que calculan el siguiente estado tienen salidas estables
Fases en la ejecución de una instrucción
Para entender el funcionamiento del procesador y poder implementarlo usando circuitos digitales, dividimos la ejecución de las instrucciones en 5 fases independientes
- Fetch (IF): Obtener de la memoria la siguiente instrucción (apuntada por el PC)
- Decode (ID): Decodificación de la instrucción (¿qué instrucción es?), separación de los siguientes campos y lectura de los operandos de los registros
- Ejecución (EX): Realización del cálculo indicado por la instrucción (por medio de la ALU)
- Instrucciones
addi
,add
,sub
,and
,or
: Cálculo de la operación - Instrucción
beq
: Realizar la comparación de los registros - Instrucciones
load/store
: Cálculo de la dirección de memoria (registro + offset)
- Instrucciones
- Acceso a memoria (MEM): Lectura del dato de la memoria (sólo instrucción load)
- WriteBack (WB): Captura del nuevo estado: actualización de los registros, el PC y escritura en la memoria de datos
La fase de acceso a memoria sólo se usa con las instrucciones load. El resto de fases se usan con todas las instrucciones
La parte combinacional que calcula el estado siguiente se divide en sub-circuitos combinacionales, cada uno de los cuales implementa una etapa
En esta figura se muestran ejemplos de lo que ocurre en las ejecuciones de las instrucciones addi t0,x0,0xC0
, ld x1,0x100(x0)
, sd x1,0x108(x0)
y beq x0,x0,0
Implementación del procesador
Los procesadores se implementan a partir de dos circuitos independientes:
- Ruta de datos: Conexión de los elementos que realizan las operaciones. Es el "tablero" de juego por donde los datos se pueen mover
- Control: Genera las señales de control para gobernar la ruta de datos. Hace que los datos se muevan correctamente por la ruta de datos, y que se capturen en los momentos adecuados
Esquema general
El procesador NanoRisc-V tiene en total 3 entradas y 4 salidas, que ya conocemos de la sesión anterior:
El esquema general de su implementación se muestra en esta figura
Las etiquetas amarillas son los pines de Entrada/Salida del procesador. Las etiquetas azules se corresponden con las señales de control. Las etiquetas fucsia son las señales internas de la ruta de datos
La unidad de control genera todas las señales de control (azules) que gobiernan la ruta de datos (y también la señal MemWr que indica si hay escritura en la memoria de datos)
Elementos de la ruta de datos
Los elementos de la ruta de datos son: la Unidad Aritmético-Lógica (ALU), el Contador de programa (PC), el banco de registros, sumador, Multiplexores de 2 a 1, Extensor de signo y separador de campos
Separador de campos
El circuito separador recibe como entrada los 32 bits de la instrucción y saca por las salidas los campos de la instrucción: rd, rs1, rs2 y el valor inmediato (immediately value)
Este circuito realmente no tiene electrónica, sólo cableado. Es así de sencillo porque el formato de las instrucciones está pensado precisamente para que sea así
Extensión de signo
El valor inmediato se usa en todas las instrucciones para sumarlo bien al PC (instrucción de salto) o a otro registro. Ambos son valores de 64 bits con signo. Para realizar la operación hay que extender el signo del valor inmmediato, que es de 12 bits, a 64 bits. Es la misión del circuito de extensión del signo
El circuito se implementa también sin necesidad de electrónica. Sólo hay que clonar el bit de signo (bit 11) 52 veces y concatenarlo con los 12 bits del valor inmediato, para obtener la salida de 64 bits
Banco de registros
El banco de registros contiene los 32 registros de 64 bits del procesador: desde el x0 hasta el x31
Permite realizar tres acciones en paralelo: Lectura del registro fuente 1, lectura del registro fuente 2 y escritura en el registro destino. La lectura de los registros fuentes es combinacional: en cuanto se especifica el número de registro por sus entradas rsx, se obtiene su valor por dx. La escritura en el registro destino es secuencial: se realiza si la entrada write es 1 y llega un flanco de subida por el reloj. En ese caso el dato de 64 bits que llega por data se almacena en el registro cuyo número se ha introducido por rd
Unidad Aritmético-Lógica: ALU
La unidad Aritmético-Lógica (Arithmetic-Logic Unit: ALU) es el circuito que realiza las operaciones con dos operandos. Recibe como entradas los dos operandos, op1 y op2, y un código con la operación a realizar. Según el código, se hace una operación u otra. Por ejemplo una suma (código 0010), una resta (código 0110), etc.
Es un circuito combinacional, por lo que en cuanto hay un cambio en sus entradas, se recalculan todas sus salidas
El código de la operación a realizar es de 4 bits, lo que permite implementar un total de 16 operaciones distintas. Sin embargo, para el NanoRISC-v sólo se han implementado 4: La suma y la resta (operaciones aritméticas) y AND y OR (Operaciones lógicas)
Tiene dos salidas. Una es el resultado de la operación, de 64 bits. La otra es de 1-bit e indica si el resultado es 0. En caso de que la operación haya sido 0, se pone a 1
Esta es la señal que se utiliza para calcular la operación de comparación en la instrucción beq
. Se introduce por op1 y op2 los dos registros fuente, rs1 y rs2, y se realiza una resta. Si el resultado es 0, la señal zero se pone a uno. Mirando la señal zero sabremos si la condición de igualdad se ha cumplido o no
Contador de programa (PC)
El contador de programa es un registro de 64 bits que se actualiza con un nuevo valor con cada flanco de subida del reloj. Contiene la dirección de la instrucción que se está ejecutando actualmente
Por su entrada llega la dirección de la siguiente instrucción a ejecutar, que se capturará al terminar el ciclo actual (al llegar el siguiente flanco de subida del reloj)
Sumador de 64 bits
El sumador de 64-bits es un circuito combinacional para sumar dos operandos. El resultado es un número de 64-bits. No hay acarreo. Se utiliza para actualizar el valor del contador de programa
Multiplexores 2 a 1
Los multiplexores son los componentes que nos permiten seleccionar entre dos datos 64-bits. Por la salida del multiplexor sólo se deja pasar uno de los dos datos: el que está seleccionado. Son unos componentes esenciales, que nos permite ejecutar una decisión en harware (Son el equivalente a las sentencias IF. Si tal señal está activada, entonces devolver un dato, de lo contrario devolver otro)
Las entradas de datos del multiplexor se denominan canales. Tiene dos canales: el 0 y el 1. Hay una tercera entrada denominada señal de selección. Esta es por la que indicamos cuál de los dos canales (0,1) queremos obtener por la salida del multiplexor
La unidad de control
La unidad de control es la que decide qué camino seguirán los datos, qué operación se debe realizar en la ALU y en qué componentes se deben guardar los datos. Todo esto depende de la instrucción a ejecutar
En el NanoRisc-V monociclo la unidad de control se implementa muy fácilmente usando una tabla. Es por tanto un circuito combinacional que activa las señales de control (llamadas micro-órdenes) en función de la instrucción a ejecutar
Señales de control (µórdenes)
Las señales de control se denominan µórdenes (micro-órdenes). En el NanoRISC-V hay en total 6. Tres de ellas actúan sobre tres multiplexores, una indica qué operación debe realizar la ALU y dos son las señales de escritura del banco de registros y de la memoria de datos
En la siguiente tabla se describen las 6 µórdenes y se indica para qué instrucciones se deben activar
µorden | Tipo | Instrucciones | Descripción |
---|---|---|---|
AluSrc | Mux | ld, addi,sd | Fuente del operando 2 de la ALU: registro o valor inmediato |
MemtoReg | Mux | ld | Dato a grabar en registro destino: resultado de la ALU o dato de memoria |
Branch | Mux | beq | Indica que se trata de una instrucción de salto condicional |
RegWrite | Write | Tipo-R, ld, addi | Escritura en el banco de registros |
MemWrite | Write | sd | Escritura en la memoria de datos |
ALUop | ALU | TODAS | Operación a realizar en la ALU |
La decodificación de la operación a realizar en la ALU se hace en dos niveles. A partir del código de operación (opcode) se determina un código de 2 bits (ALUop) según la siguiente tabla:
AluOp | Instrucciones | Descripción |
---|---|---|
00 | ld, sd, addi | Realizar una suma en la Alu |
01 | beq | Realizar una resta en la Alu |
10 | add, sub, and, or (tipo R) | La operación en la Alu viene determinada por funct7 y funct3 |
Implementación
La implementación de esta unidad de control, para el caso del NanoRISC-V monociclo, se realiza mediante una tabla de verdad que asigna el valor de las señales de control en función del opcode de la instrucción
La operación de la ALU se determina en dos niveles. Primero se calcula la señal AluOP de 2 bits, a partir del opcode, y luego se determina la operación final en función de AluOp y de los campos funct7 y funct3
Para implementación completa necesitamos dos tablas:
- Tabla I
Opcode | Inst | AluSrc | MemtoReg | Branch | RegWrite | MemWrite | AluOp |
---|---|---|---|---|---|---|---|
0x03 | ld | 1 | 1 | 0 | 1 | 0 | 00 |
0x13 | addi | 1 | 0 | 0 | 1 | 0 | 00 |
0x23 | sd | 1 | 0 | 0 | 0 | 1 | 00 |
0x63 | beq | 0 | 0 | 1 | 0 | 0 | 01 |
0x33 | Tipo R | 0 | 0 | 0 | 1 | 0 | 10 |
- Tabla II
AluOp | Funct7 | Funct3 | Operación | Código Alu |
---|---|---|---|---|
00 | xxxxxxx | xxx | suma | 0010 |
01 | xxxxxxx | xxx | resta | 0110 |
10 | 0000000 | 000 | Suma | 0010 |
10 | 0100000 | 000 | Resta | 0110 |
10 | 0000000 | 111 | And | 0000 |
10 | 0000000 | 110 | Or | 0001 |
Este es el circuito final de la unidad de control:
Implementación de las Fases
Ahora que ya conocemos todos los componentes necesarios, vamos a analizar todas las Fases y estudiar su implementación
Captura de la instrucción (Fetch)
Esta es la fase en la que obtiene la siguiente instrucción a ejecutar, que se encuentra en la memoria de código (ROM). La dirección está almacenada en el Registro PC. Este registro está conectado directamente con la memoria ROM (a través de los pines de salida del chip)
La memoria tarda un tiempo en leer la instrucción (retardo de lectura). Transcurrido ese tiempo, se tiene la instrucción de manera estable en los pines del chip, listos para ser usados en la siguiente etapa
El retardo total de esta etapa está dado por lo que tarda el registro en capturar el siguiente valor del PC (cuando llega el flanco de subida del reloj del ciclo anterior) y el retardo de la memoria. Transcurrido ese tiempo el valor de la instrucción es estable
Esta fase es exactamente igual para todas las instrucciones
Decodificación
En la fase de la decodificación se parte de que ya existe un valor estable de la instrucción (32 bits) y se analiza para obtener todos sus operandos. Los registros se leen también del banco de registros. La fase termina cuando se tienen valores estables en TODAS las entradas de la ALU, y todo queda listo para realizar los cálculos de la fase de Ejecución
Esta fase tiene dos rutas principales. Por un lado la instrucción llega a la unidad de control y se generan todas las µ-órdenes necesarias para que se ejecute la instrucción. Esta generación tarda un cierto tiempo, dado por el retardo de la unidad de control (el tiempo que tarda desde que llega una instrucción hasta que se generan TODAS las salidas de la unidad)
Por otro lado, la instrucción llega al separador de campos, obteniendo el valor inmediato, los registros fuente rs1, rs2 y el registro destino rd. La instrucción puede que no use esos campos, pero en la decodificación simplemente se sacan de la instrucción y se llevan al siguiente componente. Los registros fuentes se llevan al banco de registros, que transcurrido un cierto tiempo, devolverán un valor estable. Por último, la salida del registro fuente rs2 se pasa por un multiplexor, para que a la ALU le llegue bien este registro o bien el valor inmediato
El retardo de esta fase está dado por el camino más largo (camino crítico). Típicamente será el que pasa por la lectura del banco de registros, que lleva más tiempo que la unidad de control. Pero es algo que hay que analizar según los datos de retardos que tengamos
Al finalizar esta fase, por la entrada de la ALU llegan dos operandos estables, así como el código de la operación a realizar. Esta fase también es igual para TODAS LAS INSTRUCCIONES
Ejecución
En esta fase se realiza el cálculo requerido por la instrucción, a través de la ALU. La fase termina una vez que hay valores estables en sus dos salidas: Result y Zero
El retardo de esta fase depende de la operación realizada en la ALU y, por tanto, depende de la instrucción ejecutada. Unas instrucciones tardarán más, y otras menos. Es algo que habrá que calcular con los datos para obtener el retardo máximo y usarlo para el cálculo de la frecuencia máxima de funcionamiento
Acceso a Memoria
En esta fase se accede a la memoria para la lectura de un dato. Su duración está determinada por el tiempo desde que hay un valor estable en el bus de direcciones (Addr) hasta que la memoria devuelve el dato por DIN
Sólo la instrucción de LOAD realiza una lectura en memoria. En el resto de instrucciones no se usa el dato recibido por din
Actualización del estado (WriteBack)
Esta es la última fase. Es la fase en la que quedan estabilizados los datos para el cálculo del estado siguiente: dirección del PC, valor a escribir en un registro destino o valor a escribir en la memoria
En la mayoría de instrucciones estos datos ya están calculados en las etapas anteriores. Sólo en el caso de la instrucción BEQ se necesitan hacer cálculos adicionales que dependen de la señal Zero. Hasta que no se tiene un resultado estable no se puede calcular el siguiente valor del PC. Este valor típicamente será de PC+4 para todas las instrucciones, pero en el caso de la intrucción BEQ y si zero vale 1, el siguiente valor del PC será PC+Imm
La instrucción de LOAD obtiene el dato a escribir en el registro destino en Din, al final de la etapa de acceso a memoria. En la etapa de writeback este dato debe pasar por un multiplexor para llegar a la entrada data del banco de registros y quedar todo listo para su escritura al finalizar el ciclo
Simulación del funcionamiento
- Tablero de juego:
Conclusiones
La implementación del procesador monociclo nos ha permitido entender el funcionamiento interno. Es una implementación sencilla y que sirve de punto de partida para poder implementar nuestros propios procesadores. Sin embargo tienen el inconveniente de que viola el principio de diseño introducido en el primer capítulo: mejora del rendimiento mediante la mejora del caso más frecuente. Aunque mejoremos los tiempos de las instrucciones más frecuentes, el rendimiento final no mejorará. Sólo se puede aumentar encontrando el caso peor y reduciendo su retardo
En los procesadores modernos se usa la técnica de la segmentación. Como paso previo a entenderla, en la siguiente sesión estudiaremos la implementación multiciclo, en la que las instrucciones necesitan de varios ciclos de reloj para ejecutarse, pero estos ciclos tendrán una frecuencia mayor
Lecturas del libro de referencia
Libro de referencia: "Computer Organization and Design. Hardware/Software interface. Risc-V"
- Apartado 4.3: Building a Datapath (Pag 243-251)
- Apartado 4.4: A simple Implementation Scheme (Pag 251-262)
Ejercicios
Ejercios para practicar y asimilar los conceptos más importantes
Ejercicio 1
En la memoria de instrucciones de un NanoRisc-v monociclo se tiene el siguiente contenido:
Direccion | Instrucción |
---|---|
... | ... |
0x100 | addi x5, x0, 20 |
0x104 | add x5, x5, x6 |
0x108 | beq x5, x7, 4 |
0x10C | beq x0, x0, 0 |
.... | ... |
Tras la ejecución de una instrucción, el estado del procesador es:
- PC = 0x104
- x5 = 20
- x6 = 1
- Resto de registros a 0
Se pide:
- a) Calcula el estado del procesador al llegar el siguiente franco de subida del reloj
- b) Calcula el estado del procesador al llegar otro flanco de subida de reloj tras el del apartado a
- c) Calcula el estado del procesador al llegar otro flanco de subida de reloj tras el del apartado b
Ejercicio 2
En un procesador NanoRisc-V monociclo se ha completado la ejecución de una instrucción y se va a proceder a ejecutar la siguiente: addi x5, x0, 20
. La unidad de control genera las µ-órdenes a partir de estas tablas:
Opcode | Inst | AluSrc | MemtoReg | Branch | RegWrite | MemWrite | AluOp |
---|---|---|---|---|---|---|---|
0x03 | ld | 1 | 1 | 0 | 1 | 0 | 00 |
0x13 | addi | 1 | 0 | 0 | 1 | 0 | 00 |
0x23 | sd | 1 | 0 | 0 | 0 | 1 | 00 |
0x63 | beq | 0 | 0 | 1 | 0 | 0 | 01 |
0x33 | Tipo R | 0 | 0 | 0 | 1 | 0 | 10 |
AluOp | Funct7 | Funct3 | Operación | Código Alu |
---|---|---|---|---|
00 | xxxxxxx | xxx | suma | 0010 |
01 | xxxxxxx | xxx | resta | 0110 |
10 | 0000000 | 000 | Suma | 0010 |
10 | 0100000 | 000 | Resta | 0110 |
10 | 0000000 | 111 | And | 0000 |
10 | 0000000 | 110 | Or | 0001 |
Los retardos introducidos por los componentes de la ruta de datos del procesador son:
Componente | Retardo |
---|---|
Memoria de instrucciones | 400ps |
Sumador | 100ps |
ALU | 120ps |
Memoria de datos | 350ps |
Banco de registros | 200ps |
Se pide
-
a) Calcular el retardo de cada una de las fases: Fetch, decodificación, ejecución, lectura de memoria y escritura de resultados (write-back)
-
b) Calcular el retardo total de la instrucción
Ejercicio 3
Repetir el ejercicio 2, con los mismos datos, pero para las instrucciones:
a) add x5, x5, x6
b) sub x7, x7, x8
c) and x9, x10, x11
Ejercicio 4
Repetir el ejercicio 2, con los mismos datos, pero para las instrucciones:
a) ld x1, 0x100(x2)
b) ld x3, 0(x0)
Ejercicio 5
Repetir el ejercicio 2, con los mismos datos, pero para las instrucciones:
a) sd x1, 0x100(x2)
b) sd x3, 0(x0)
Ejercicio 6
Repetir el ejercicio 2, con los mismos datos, pero para las instrucciones:
a) beq x5, x6, 4
b) beq x0, x0, 0
Ejercicio 7
Con los datos del ejercicio 2 y los cálculos realizados en los ejercicios 2, 3, 4, 5 y 6
Se pide
- a) Completar la siguiente tabla
Instrucción | Tiempo de ejecución |
---|---|
addi x5, x0, 20 |
|
add x5, x5, x6 |
|
ld x1, 0x100(x2) |
|
sd x1, 0x100(x2) |
|
beq x5, x6, 4 |
- b) ¿Cual es la frecuencia máxima de funcionamiento?
Ejercicio 8
En un NanoRisc-V monociclo se tienen los siguientes retardos para los componentes de la ruta de datos:
Componente | Retardo |
---|---|
Memoria de instrucciones | 400ps |
Sumador | 100ps |
Memoria de datos | 350ps |
Banco de registros | 200ps |
La ALU tiene diferentes retardos según la operación realizada:
Operación ALU | Retardo |
---|---|
suma | 120ps |
Resta | 150ps |
AND | 80ps |
OR | 70ps |
Se pide
a) ¿Cuál es la frecuencia máxima de funcionamiento del procesador?
b) ¿Qué mejora de rendimiento se obtiene si le pedimos al ingeniero hardware que reduzca el retardo de la operación de resta de 150ps a 100ps?
Ejercicio 9
En un procesador NanoRisc-V monociclo se tienen los siguientes retardos en sus componentes de la ruta de datos
Componente | Retardo |
---|---|
Memoria de instrucciones | 400ps |
Sumador | 100ps |
ALU | 150ps |
Memoria de datos | 450ps |
Banco de registros | 200ps |
Se pide
a) Calcular la frecuencia máxima de funcionamiento
b) Si ahora tenemos en cuenta los retrasos introducidos por los multiplexores, que son de 5ps y de la escritura del contador de programa (PC) que tarda 20ps... ¿Cuál es la frecuencia máxima de funcionamiento ahora?
Notas para el profesor:
- Título informal de la clase: "El diablo está en los detalles..."
- Vamos a ver los detalles internos de cómo funciona un procesador RiscV monociclo. No es un tema complicado, pero al haber tantos detalles resulta laborioso
Autores
- Katia Leal Algara
- Juan González-Gómez (Obijuan)
Licencia
Créditos
- Muchas gracias a Steven Ho. de la Universidad Berkely, por la publicación del curso: CS61C: RISC-V CPU Datapath, Control Intro [PDF]
Enlaces
- CS61C: RISC-V CPU Datapath, Control Intro [PDF]. By Steven Ho. Berkeley University
- Universidad Rey Juan Carlos de Madrid
- Escuela Técnica Superior de Ingeniería de Telecomunicaciones (URJC)