Documentos de Académico
Documentos de Profesional
Documentos de Cultura
1 – Introducción a RISC-V
Revise las diapositivas 2 a 7 y el video explicativo (https://youtu.be/Gvs7CfOmayQ). Con base en ello explique:
• Un openISA como RISC-V significa que cualquier estudiante o entusiasta pueda diseñar su propio
microprocesador, montarlo en una FPGA, usar el conjunto de herramientas software creadas por terceros
(como compiladores) y construir una aplicación completa que pueda vender sin pagar licencias a nadie.
¿Es esto cierto? Explique. ¿Qué ventajas tiene RISC-V?
ALU
Register File
• ¿Qué es un opcode?
• Con base en tabla de instrucciones de La Guía Práctica de RISC-V (pg. 44, http://www.riscvbook.com/), cómo
ensamblaría manualmente a mano las instrucciones “andi x5, x7, 0x2FC” y “add x3, x2, x1”.
Preguntas:
• Cargue el simulador en línea https://www.cs.cornell.edu/courses/cs3410/2019sp/riscv/interpreter/
y revise la sección de registros y memoria. ¿Por qué en el simulador las direcciones de memoria
incrementan de 4 en 4?
1
• Según la Tarjeta de Referencia del RISC-V (Página 5 de La Guía Práctica de RISC-V) o la página 44 de la La Guía Práctica
de RISC-V, ¿Cuáles operaciones aritméticas y lógicas puede realizar la ALU?
• ¿El RV32I soporta multiplicaciones y divisiones? Si no, ¿Cómo se pueden soportar estas operaciones en RISC-V?
• Suponga que se quiere almacenar la cadena “HOLA” en la memoria de datos, en la posición 0x00000000, ¿cómo
tendría que escribir dicho valor?
Para entender la extensión con signo, considere el número negativo (-1). En 12 bits, este número se representa en
complemento a dos como 0xFFF = 0B1111 1111 1111 (todos unos), donde el bit más significativo denota el signo. Si el
número (-1) se tuviera que reescribir en 32 bits, basta con replicar el signo (bit más significativo) hasta completar 32 bits.
En el ejemplo, basta con extender este bit de la forma: 0B 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF
Nótese que, en la tabla de instrucciones, todas las instrucciones aritméticas, lógicas y desplazamientos soportan los modos
de direccionamiento por registros e inmediato.
En las instrucciones lógicas hay dos tipos de desplazamiento hacia la derecha, el lógico y el aritmético. La diferencia radica
en la forma como se extiende el signo en el desplazamiento. Por ejemplo, el desplazamiento lógico siempre ingresa un “0”
por la izquierda, mientras que, en el desplazamiento aritmético, se desplaza el bit más significativo garantizando la
preservación del signo:
2
Por ejemplo, suponga que el registro x5 tiene el número decimal -100 (). Un corrimiento a la derecha x5 >> 1, equivale a
dividir por 2, por lo que se esperaría que el resultado fuera -50 (). Esto solamente es posible si se hace un corrimiento
aritmético y no lógico, porque el aritmético preserva el signo.
Preguntas:
• Prueba el desplazamiento lógico y aritmético del ejemplo en el simulador en línea usando el siguiente código.
¿cuánto da x5 y x6 después de las siguientes instrucciones?
addi x5, x0, -100 ; x5 = -100
srli x5, x5, 1 ; x5 = x5 >> 1
• En el código anterior se cargó el valor inicial de los registros x5 y x6 con el número -100 usando una instrucción de
suma, ¿por qué funciona esta instrucción?
• ¿Cómo implementaría la operación x7 = x5*4 - x3/2? Pruebe su resultado en el simulador.
5 – Reflexión
• Comparta con sus compañeros lo que ha aprendido en forma individual y elabore un mapa mental, diagrama, o
imagen que resuma lo que aprendido.
• Formule un problema sencillo con instrucciones aritmeticológicas el cual usted debe solucionar, probar en el
simulador y pasar al equipo de al lado.
• Solucione el reto que el equipo del lado le pasó a su grupo e identifique si hay algún error en su formulación.
Las arquitecturas RISC habitualmente se denominan arquitecturas LOAD/STORE (Carga/Almacenamiento) dado a que
todas las instrucciones, como las realizadas por la ALU, solamente pueden tomar como argumentos valores almacenados
en el Register File (Formato de instrucción R) o números inmediatos (Formato de Instrucción I). En las arquicturas RISC no
se permite operaciones en la ALU con valores almacenados en la memoria.
Por ejemplo, supongamos que en memoria se tienen 3 variables X, Y y Z, ubicadas en las posiciones 0x10, 0x14, 0x18,
respectivamente, y se quiere hacer la operación Z = X+Y. Entonces, para poder implementar este algoritmo, es necesario
cargar (LOAD) las variables X y Y en registros temporales al interior del Register file, por ejemplo, x5 y x6; luego sumar los
registros x5 y x6 y almacenarlos en otro registro, por ejemplo, x7, y el resultado final, se debe almacenar (STORE) de nuevo
en la memoria.
lw x5,0x10(x0) ;Carga la posición de memoria 0x10 en el registro x5
lw x6,0x14(x0) ;Carga la posición de memoria 0x14 en el registro x6
add x7,x5,x6 ;x7 = x5 + x6
sw x7,0x18(x0) ;Almacena en la posición de memoria 0x18 el registro x7
Para verificar el resultado de este programa en el simulador es necesario inicializar la memoria incluyendo estas
instrucciones al inicio:
addi x5,x0,12 ;Carga el registro x5 con el número 12
sw x5,0x10(x0) ;Almacena el número 12 en la posición de memoria 0x10 (variable X)
addi x5,x0,23 ;Carga el registro x5 con el número 23
sw x5,0x14(x0) ;Almacena el número 12 en la posición de memoria 0x14 (variable Y)
3
Preguntas:
• ¿Con qué valor queda la variable Z (posición de memoria 0x18) después de ejecutar el código anterior?
• En el código anterior note que las direcciones se escribieron con un formato del tipo 0x10(x0), es decir, que la
dirección donde se carga o almacena es x0 + 0x10. ¿Qué pasaría si en lugar de usar x0 se hubiera puesto x1, y x1
se hubiera cargado con el número 4?.
• Revise las instrucciones de carga en La Guía Práctica de RISC-V (pg. 4, http://www.riscvbook.com/). ¿Qué diferencia
habrá entre las instrucciones LB, LH, LW?
addi x1,x0,0x9c ;Carga en la posición de memoria 0x14 el número 156 o equivalentemente el -100 en 8 bits
sw x1,0x14(x0) ;La posición de memoria 0x14 =
lb x5,0x10(x0) ;Registro x5 =
lb x6,0x14(x0) ;Registro x6 =
Note que en los anteriores programas siempre se han usado las referencias a la memoria del tipo DirecciónInmediata(x0),
pues esto asume que los datos se cargarán de la posición DirecciónInmediata + x0 = DirecciónInmediata, ya que el registro
x0 siempre vale 0.
Los programadores y/o compiladores explotan esta propiedad del conjunto de Posición de memoria Dato
instrucciones para implementar lo que se denomina direccionamiento indirecto, 0x10 5
donde se usa un registro como puntero a una zona de memoria. Por ejemplo, 0x14 -1
suponga que la memoria está cargada con los siguientes números y se ejecuta el 0x18 2
siguiente programa: 0x1C 3
add x5, x0, x0
addi a4, x0, 0x10
lw x6, 0(a4)
add x5, x5, x6
addi a4, a4, 4
lw x6, 0(a4)
add x5, x5, x6
addi a4, a4, 4
lw x6, 0(a4)
add x5, x5, x6
addi a4, a4, 4
lw x6, 0(a4)
add x5, x5, x6
• ¿Qué ecuación está implementando este programa? ¿Es decir con que valor queda al final el registro x5?
• ¿Qué función cumple el registro a4?
• ¿Qué función cumple las instrucciones addi a4,a4,4?
4
8 – Instrucciones de salto (Branches)
El microprocesador no estaría completo si no tuviera instrucciones para implementar instrucciones de alto nivel como
“if”, ciclos “for”, ciclos “while” y “do…while”. En estos casos se usan instrucciones de salto condicional.
En los siguientes ejemplos se muestra como usar las instrucciones de branches para implementar un “if … else” y un
ciclo “while”, note que en estos casos se usan etiquetas como argumentos inmediatos para los saltos.
Preguntas:
• En el ejemplo del if … else:
o ¿Por qué en el ejemplo del if, si se hace una comparación de igualdad el salto se con la condición contraria,
es decir, con diferente?
o ¿Por qué se pone una instrucción de salto incondicional jal antes de la etiqueta else1?
o ¿Cómo cambiaría el if para que la condición sea (x5 > x6)?
• En el ejemplo del while,
o ¿por qué se usa el registro x6 y se inicia con el número 5?
o ¿En la instrucción bge se puede hacer una comparación con un dato inmediato 5?
o ¿Por qué si la condición del while es (x5 < 5) se usa la instrucción de salto bge?
9 – Reflexión final
• Comparta con sus compañeros lo que ha aprendido en forma individual y elabore un mapa mental, diagrama, o
imagen que resuma lo que aprendido.
• Modifique el programa de la sección 7 para que use un ciclo while.
• En RISC-V, para agregar hardware externo se debe mapear en la memoria. Suponga que la matriz de LEDs de 8x8
que se usó para mostrar la carita en un laboratorio pasado está conectada a dos puertos de 8 bits, mapeados en
la dirección 0x06 (las filas) y 0x08 (las columnas). Escriba el programa que muestra la carita en ensamblador de
RISC-V (aquí no hay que hacer trucos de máscaras ):
for (int r=0;r<8;r++) {
row=1<<r;
col = carita[r];
}
5
Anexos – Códigos para probar en el Ensamblador
Ejemplo Sección 4:
Ejemplo Sección 6:
addi x5,x0,12
sw x5,0x10(x0)
addi x5,x0,23
sw x5,0x14(x0)
lw x5,0x10(x0)
lw x6,0x14(x0)
add x7,x5,x6
sw x7,0x18(x0)
Ejemplo Sección 7:
addi x1,x0,5
sw x1,0x10(x0)
addi x1,x0,-1
sw x1,0x14(x0)
addi x1,x0,2
sw x1,0x18(x0)
addi x1,x0,3
sw x1,0x1C(x0)
6
Ejemplos Sección 8:
If..else:
while: