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

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)
  • 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:

(Tablero-monociclo.svg)

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

Licencia

Créditos

Enlaces