RISC-V

RISC-V: Instrucciones auipc y lui en la implementación monociclo.

Para hacer compatible los programas desarrollados en Venus en nuestra implementación monociclo del RISC-V, sería muy útil el uso en nuestro RISC-V de instrucciones para cargar direcciones de memoria en registros, como puede ser la (load address) o li (load immediate).

Las instrucciones la y li son realmente pseudoinstrucciones. El compilador crea dos instrucciones para la (auipc + addi) y dos instrucciones para li (lui+addi). En los dos casos se hace uso de una instrucción de tipo U-Format (auipc y lui).

En este post, la idea es mostrar una sugerencia de implementación de estas instrucciones U-Format en nuestro RISC-V monociclo.

Instrucciones U-Format

Si nos fijamos en la estructura de una instrucciones U-Format vemos que tienen un registro destino y un inmediato de 20 bits

Para los otros formatos de instrucciones los inmediatos eran de 12 bits y por tanto no nos permiten cargar valores de 32 bits en los registros. Para resolver esto tenemos las instrucciones de tipo U-Format que permiten hacer escrituras en los 20 bits de mayor peso de los registros. De esta forma combinando instrucciones U-Format e I-Format podemos cargar valores de 32bits ({20bits,12bits}) en los registros (es lo que hace la y li).

La instrucción lui:

La instrucción lui realiza la siguiente operación:

rd={instr[31:12],12’d0}

Se puede implementar como una generación de inmediato y una suma de este inmediato con 32’d0. El resultado de la suma se guarda en el registro rd.

La instrucción auipc:

La instrucción auipc realiza la siguiente operación:

rd={instr[31:12],12’d0} +PC

Se puede implementar mediante la generación de un inmediato y una suma de este inmediato con el PC. El resultado de la suma se guarda en el registro rd.

Sugerencia de Implementación en el RISC-V

En la siguiente imagen sugiero una posible implementación:

En esta implementación lo cambios más importantes están en:

  • Bloque de entrada de la ALU: Antes la ALU podía realizar operaciones entre Registro y Registro o entre Registro e inmediato. Ahora añadimos un multiplexor nuevo que nos permite realizar operaciones entre 0 e Inmediato y PC con Inmediato.
  • Generador de Inmediato: Debemos añadir la opción de generación de inmediatos para instrucciones U-Format. Inmediato={instr[31:12],12’d0}
  • Control:
    • Debemos añadir la señal de control AuipcLui: Esta señal selecciona la fuente de entrada a la ALU. Cuando tenemos una instrucción Auipc entonces la señal AuipcLui=2’d0 para que la ALU opere con el PC; cuando tenemos una instrucción Lui entonces la señal AuipcLui=2’d1 para que la ALU tenga un 0 en una de sus entradas. En las instrucciones I-Format, R-Format, … AuipcLui=2’d2.
    • ALUOp: ALUOp debe indicar a ALU control que la ALU siempre sume cuando tenemos una instrucción U-Format. Para esto podemos aprovechar el mismo ALUOp de las instrucciones sw y lw donde la ALU siempre suma.

One Comment

  • Ramón Aliaga

    Hola,

    Yo había pensado una implementación ligeramente distinta. Las diferencias serían:

    – El multiplexor de AuipcLui tiene solo dos entradas: PC y Read_data_1. Es decir, no está la entrada 32’d0, y la señal AuipcLui es de 1 bit.
    – La ALU implementa una instrucción adicional cuya salida es simplemente la primera entrada sin modificar (result = A). Habría que seleccionar esta instrucción con ALUOp / ALU control para la LUI.

    Como veis, a menudo hay varias soluciones posibles para implementar un circuito, y en principio todas son buenas. Podéis usar cualquiera de ellas, u otras que no se nos hayan ocurrido.

    Un saludo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *