Repository navigation
L1: Practica 1
- Tiempo: 2h
-
Objetivos de la sesión:
- Toma de contacto con el simulador RARS, para el procesador RISC-V
- Ejecutar y depurar los programas "hola mundo"
- Instrucción de suma: addi
Haz click en la imagen para ver el vídeo en Youtube
Haz click en la imagen para ver el vídeo en Youtube
- Introducción
- Trabajando en los laboratorios de la EIF-URJC
- El simulador RARS
- Mi primer programa: Hola mundo
- Los registros de la CPU
- Nuestra primera instrucción en ensamblador: addi
- Conclusiones
- Ejercicios para practicar
- SOLUCIONES
- Notas para el profesorado
- Profesorado
- Licencia
- Enlaces
En esta asignatura vamos a programar los procesadores RISC-V en lenguaje ensamblador, para entender su funcionamiento y su arquitectura. En las prácticas del laboratorio utilizaremos un simulador que ejecutaremos en el PC. Sin embargo, no hay que perder de vista que estamos programando un procesador, a bajo nivel
Esta es la pinta que tiene un RISC-V, sintetizado en una FPGA Libre. Está ejecutando un programa que realiza una cuenta de 8 bits, que se muestra por los LEDs. La placa usada es la Alhambra II

Los detalles de la implementación del RISC-V en la FPGA no son de esta asignatura, pero si tienes curiosidad e interés, puedes encontrar más información en este repositorio: RISC-V-FPGA (Proyecto en construcción). También en esta sesión de la asignatura de Mecatrónica del Grado de Robótica Software: Procesadores en FPGA: RISC-V
La placa Raspberry Pi Pico 2 incluye 2 cores de RISC-V. Es una placa ideal para aprender y utilizarla en sistemas reales. Normalmente se programa en lenguaje C, pero se puede programar también en ensamblador del RISC-V

En esta Bitácora en sucio documenté las pruebas que hice. En cuanto pueda crearé un tutorial sobre ello
La información de este apartado concierne únicamente al estudiantado y al profesorado de la URJC de la Escuela de Ingeniería de Fuenlabrada de la URJC
Las prácticas se realizan en los Laboratorios Linux

Note
La información de este apartado es para el profesorado
La sesión la puedes dar a tu manera, como mejor te venga. Puedes utilizar un ordenador portátil conectado al proyector, o bien puedes usar el ordenador Linux del puesto del profesorado
Yo (Obijuan) normalmente utilizo este ordenador porque me permite exportar mi pantalla en sus ordenadores. De esta formas, las personas estudiantes pueden ver en detalle qué es lo que estoy haciendo, además de verlo proyectado en la pantalla grande
Para exportar la pantalla basta con abrir un terminal y ejecutar este comando en la shell:
share-screen
El ordenador del puesto del profesorado ya está configurado para realizar correctamente la exportación. Sin embargo, si es la primera vez que lo haces, asegúrate de que la sesión que tienes abierta está usando el sistema gráfico X windows (Con wayland hay problemas de momento). Esto lo puedes verificar fácilmente desde tu escritorio accediendo al menú de configuración:

Desde ese menú pincha en la opción System y luego About

Ahora selecciona System details para ver todos los detalles

Verificamos que estamos usando el sistema gráfico de las X windows (x11)

Si tienes las X11 y has ejecutado el script anterior share-screen, todas las personas de sala que estén en los ordenadores podrán ver tu pantalla si se conectan
Para realizar las prácticas deberás entrar con tu usuario y contraseña específicos de este laboratorio (Que es diferente del que usas para acceder a Aula virtual). Si eres de primero y NO tienes la cuenta creada, deberás crearte una. Lo puedes hacer fácilmente desde este enlace: Crear cuenta en los laboratorios Linux
Si llevas más de un año sin usar la cuenta linux, tendrás que renovarla: Renovación de tu cuenta Linux
Entra en tu escritorio linux, introduciendo tu usuario y contraseña.
Para visualizar el escritorio del ordenador del profesorado siguen los siguientes pasos:
- Ejecuta el programa Visor de escritorio:

- Introduce la dirección IP del ordenador del profesora. Sigue estos pasos:
- Pincha en Conectar

- Selecciona el protocolo VNC
- Introduce la dirección IP en la caja que dice Equipos. Esta dirección te la tiene que decir el profesora la primera vez, luego se te quedará guardada y la podrás obtener simplemente pinchando en la flecha que apunta hacia abajo situado a la derecha del cajetín
- Pincha en el botón Conectar en la parte inferior derecha

En esta animación se muestra el proceso:

En la ventana aparecerá el escritorio del profesorado. Podrás ver todo lo que está realizando la persona docente Mi recomendación es que dejes la ventana con el escritorio del profesorado a tu derecha, a tamaño real y que uses la parte izquierda para trabajar. El escritorio remoto es de baja resolución, por estar conectado al proyector. De esta forma verás claramente todos los detalles, y no te perderás nada 🙂

(Pantallazo proporcionado por el estudiante Pablo Gutierrez Tenorío*. ¡Muchas gracias!)
¡¡Ya está todo listo para que puedas seguir la clase!!😎
En esta asignatura trabajaremos con el procesador RISC-V, aprendiendo a programarlo en ensamblador para comprender su arquitectura interna
Los programas los ejecutaremos en el simulador RARS, que es libre y multiplataforma
En los laboratorios ya está todo listo para ejecutar el simulador. Pincha en la parte superior izquierda, teclea rars y clica en el icono de la aplicación

Nos aparecerá una pantalla como la siguiente

¡Listos para empezar a trabajar!
En los laboratorios también lo podemos arrancar desde el terminal de Linux. Abre un terminal y escribe el comando rars:

Las últimas versiones del RARs las puedes descargar desde esta página de github. Los vídeos de este curso se hicieron con la versión 1.1. Sin embargo ya van por la versión 1.6, que es la que instalaremos y utilizaremos nosotros
El RARs está programado en Java, y se ejecuta en la máquina virtual de java, por lo que el archivo ejecutable es el mismo para todas las plataformas: linux, Mac o Windows.
Los pasos para la instalación son:
- Descargar el rars: rars1_6.jar
- Instalar JAVA. Aunque es muy probable que en tu ordenador ya lo tengas instalado
- Arrancar RARs
- Instala Java 11. Desde un terminal ejecuta:
sudo apt install default-jdk
- Dar permisos de ejecución al fichero rars.jar que hemos descargado antes
chmod +x rars1_6.jar
- Arranca el rars desde el terminal:
java -jar rars.jar
Puedes instalar JAVA desde este enlace. Descarga el instalador pinchando en el botón rojo. Se bajará el fichero JavaSetup8u221.exe.
- Haz doble click para ejecutarlo: es el instalador de JAVA.

- Pincha en Instalar. Comienza la instalación

- Al cabo de unos segundos se completará. Pinchamos en Cerrar

- Localiza el archivo descargado con el RARs

- Haz doble click para ejecutarlo

¡Ya lo tienes operativo y listo para funcionar!
¡Comenzamos nuestra aventura!. Primero arrancamos el simulador. Todavía NO lo sabemos manejar, ni sabemos nada del procesador RISC-V, pero vamos a ejecutar nuestro primer programa para comprobar que todo está funcionando, y familiarizarnos un poco con el entorno
Nuestro primer programa se muestra a continuacion:
#-- Programa hola mundo en RISC-V
#-- Esto son comentarios
.data
str: .string "Hola mundo en RISC-V!\n"
.text
main:
la a0, str
li a7, 4
ecall
li a7, 10
ecallLo normal es que NO ENTENDAMOS prácticamente nada. No pasa nada. Para ponerlo en marcha seguimos estos pasos:
-
Paso 1: Descargar el fichero en ensamblador con el programa hola mundo: hola_mundo.s (Pulsar el botón derecho y la opción "Save Link as..."). Los ficheros con programas en ensamblador tienen la extensión
.so.asm -
Paso 2: Abrir el fichero desde el entorno. Usamos la opción File/Open para cargar el fichero hola_mundo.s en el editor del simulador

- Paso 3: Ensamblamos el programa
Esta acción analiza el programa en ensamblador y genera el código máquina. Esto ya lo veremos, pero el código máquina es el verdadero programa que entiende el procesador, y que se almacena en memoria
Para ensamblar pinchamos en la herramienta Assemble. Si todo ha ido bien, y el programa no tiene errores de sintaxis, se nos cambia automáticamente a la pestaña Execute donde podemos ver el contenido de la memoria (aunque por ahora no entendamos nada)

Podemos volver a la pestaña donde estaba nuestro programa original pinchando en Edit. En la consola en la parte inferior nos aparece un mensaje indicando que el ensamblado se ha realizado correctamente:
Assemble: operation completed successfully.
- Paso 4: Ejecutar el programa
Para ejecutar el programa pinchamos en el botón de Run en la parte superior. En la parte inferior nos aparecen dos mensajes, uno que lo ha generado nuestro programa, y otro del simulador indicando que el programa se ha terminado de ejecutar

Sí, efectivamente, este programa Hola mundo saca por pantalla la cadena:
Hola mundo en RISC-V!
¡Hemos ejecutado nuestro primer programa en el procesador RISC-V!
Normalmente, para probar nuestros programas tendremos que ejecutarlos varias veces. Para volver a ejecutarlo borramos la consola inferior (opcional) pulsando el botón Clear. A continuación pinchamos en el botón RESET memory and registers, en la parte superior, y volvemos a ejecutar el programa como en el paso anterior

Todavía no conoces las instrucciones del RISC-V, ni entiendes apenas nada del código del "Hola mundo"... pero... ¿Serías capaz de modificar el programa para que saque por pantalla otra cadena diferente?
Una ventaja de usar el simulador es que podemos ejecutar las instrucciones paso a paso y entender todo lo que está ocurriendo. Para ejecutar paso a paso hacemos lo siguiente:
- Desde el editor (pestaña Edit) pinchamos en el botón de ensamblar (igual que antes)

Se resalta en amarillo la primera instrucción. Será la primera que se ejecute
- Pinchamos en el botón "Run one step at a time", justo a la derecha del botón de ejecutar que ya conocemos. Se ejecuta la instrucción actual y se resalta en amarillo la siguiente. También vemos en la derecha un resaltado en verde: nos indica el registro que se ha modificado

- Seguimos pulsando el botón anterior hasta que el programa termina
En esta animación se muestra el proceso completo de ejecución paso a paso

Todavía sabemos muy poco del RISC-V. No sabemos programar ni entendemos las instrucciones... Ejecuta de nuevo el programa hola mundo, paso a paso, y trata de responder las siguientes preguntas:
- ¿Qué instrucción es la que hace que aparezca el mensaje de texto en la consola?
- ¿Qué instrucción es la que hace que el programa termine?
- ¿Sabes cuál es el código máquina de esta instrucción?
- ¿Cuantos bits tiene esta instrucción?
- ¿Cuántas instrucciones se ejecuten hasta que el programa termina?
- ¿Cuál crees que es la dirección donde está situada la primera instrucción?
El RISC-V que usamos en las prácticas es de 32-bits. En su interior tiene 32 registros de propósito general, de 32-bits. Se numeran desde el 0 al 31 y de forma genérica se denotan por la letra x. Así, el registro x5 es el registro número 5
Los registros se encuentran en la parte derecha del simulador. Podemos ver su número y su valor

El registro x0 es especial. Siempre vale 0 y NO le podemos asignar otro valor. Lo utilizamos para inicializar otros registros a 0, o cuando no queremos alterar otros registros al hacer operaciones de suma

Además, hay un registro especial llamado PC, que se encuentra abajo del todo. Este registro se denomina contador de programa (program counter) y contiene la dirección de la siguiente instrucción a ejecutar
Arrancamos la ejecución del "hola mundo", paso a paso. Antes de ejecutar ninguna instrucción, el PC tiene la dirección de la primera instrucción

Ejecutamos la instrucción (damos un paso). Ahora el PC tiene la dirección de la siguiente instrucción a ejecutar:

Repetimos el proceso hasta llegar a la última instrucción:

Por defecto, los registros los vemos en hexadecimal. Pero lo puedes cambiar a decimal desmarcando la casilla Hexadecimal Value, o bien desde el menú, en la opción Settings/Values displayed in hexadecimal

Vamos a estudiar nuestra primera instrucción del RISC-V: addi. Sirve para asignar a un registro la suma de otro registro con una constante. La sintaxis de la instrucción es:

El valor a sumar puede ser positivo o negativo
Estos son algunos ejemplos de utilización:
- Asignar al registro x3 el valor del registro x2 + 50
addi x3, x2, 50- Asignar al registro x4 el valor de x3 - 5
addi x4, x3, -5- Incrementar el registro x5. Se usa el propio registro x5 como origen y destino
addi x5, x5, 1- Decrementar el registro x5 en dos unidades
addi x5, x5, -2- Assignar el valor 30 al registro x6. Usamos el registro 0 para hacer x6 = x0 + 30 = 30 (porque x0 siempre vale 0)
addi x6, x0, 30Vamos a escribir nuestro primero programa desde 0. Será muy sencillo. Simplemente asignaremos el valor 30 al registro x3 y terminaremos. El programa se muestra a continuación, pero en vez de hacer copy & paste, vamos a escribirlo directamente en el simulador
Se han incluido explicaciones adicionales para entenderlo mejor
#-- Nuestro primer programa escrito desde cero
#-- Esto que sale en verde son COMENTARIOS
#-- y siempre es lo primero que tenemos que hacer
#-- ¡Somos ingenieros! ¡Hay que documentar!
#-- Programa para asignar el valor 30 al registro x3,
#-- y terminar
#-- Esto NO es una instruccion. Lo veremos mas
#-- adelante. Es una Directiva. Se usa para
#-- indicar al ensamblador que lo que va a
#-- continuacion es codigo
.text
#-- Mi primera instruccion
addi x3, x0, 30 #-- x3 = 0 + 30 = 30
#-- Terminar. Estas instrucciones no saben
#-- que significan. Lo veremos mas adelante
#-- Las usamos para terminar el programa y
#-- devolver el control al sistema operativo
li a7, 10
ecallPara comenzar a escribir un programa pinchamos en el icono superior izquierdo: "Create a new file for editing"

Se crea una pestaña nueva con el nombre riscv1.asm, que es el nombre que le da el simulador por defecto a los nuevos programas

¡Ya podemos empezar a escribir nuestro primer programa!

Una vez terminado pinchamos en el icono de grabar. Si no lo tenemos grabado no podremos ejecutarlo

Ahora lo ejecutamos paso a paso y comprobamos que efectivamente al ejecutar la instrucción addi el registro x3 cambia su valor a 30 (0x1e en hexadecimal)

En el siguiente programa inicializamos el registro x5 a 1, y lo incrementamos varias veces, para practicar. La operación de incremento la realizamos con la instrucción addi x5, x5, 1. El programa lo puedes bajar de este enlace: cont3.s
# --- Incrementar el registro x5 varias veces
.text
#-- Inicializar contador
addi x5, x0, 1 #-- x5 = 1
#-- Primer incremento
addi x5, x5, 1
#-- Segundo incremento
addi x5, x5, 1
#-- Tercer incremento
addi x5, x5, 1
#-- Terminar
li a7, 10
ecallEnsambla este programa, ejecútalo paso a paso y comprueba que el registro x5 se incrementa en una unidad cada vez que se ejecuta la instrucción addi x5, x5, 1
En esta animación se muestra su funcionamiento

En el programa anterior hemos utilizado la misma instrucción addi x5, x5, 1 varias veces. En el siguiente programa repetimos esta operación indefinidamente, creando lo que llamamos un bucle infinito: la instrucción se repite hasta que se haga un reset de la placa, o se le quite la alimentación
Los bucles los veremos más adelante (Sesión L7). Se presenta este ejemplo aquí para practicar con el simulador rars, y en las siguientes sesiones aprender a poner puntos de ruptura
- Programa: contador.s
# --- Programa contador
# --- Se implementa un contador en el registro x5
# --- que se ejecuta indefinidamente
# --- El contador se inicializa con el valor 1
.text
#-- Inicializar contador
addi x5, x0, 1 #-- x5 = 1
# -- Repetir indefinidamente las siguientes
# -- instrucciones
bucle:
#-- Incrementar contador
addi x5, x5, 1
#-- Repetir!
j bucleComo este programa NO TERMINA NUNCA, no hemos añadido al final las instrucciones para que termine:
li a7, 10
ecallPero esto es un caso especial. En todos los programas que hagamos tiene que haber SIEMPRE un final usando estas instrucciones. Ahora no entendemos qué es lo que hacen, pero lo sabremos más adelante (Sesión L5). Para las personas más curiosas, su misión es llamar al sistema operativo para indicar que el programa ha terminado
Vamos a comprobar el funcionamiento del programa:
- Ejecuta el programa paso a paso
- Observa cómo el registro x5 se incrementa cada vez
El resultado lo vemos en esta animación:

Configuramos el simulador para ver los registros en decimal, y así entender mejor el contador
Para ver el contador en funcionamiento tenemos otra posibilidad: Ejecutar el programa a baja velocidad, en vez de a paso a paso. Como se trata de un bucle infinito, si le damos al botón de ejecutar, el programa se ejecuta a su máxima velocidad, y el simulador NO REFRESCA los registros. El registro x5 sí que está cambiando, pero el simulador no lo muestra
La mejor alternativa es bajar la velocidad de ejecución desplazando el deslizador de la parte superior derecha, donde pone run speed

Bajamos la velocidad a 2 instrucciones por segundo y ejecutamos el programa. En cualquier momento podemos pinchar en el botón de pausa para volver al modo de ejecución paso a paso. Pinchando en Run continuamos la ejecución, a baja velocidad. Por último, si pinchamos en el botón de Stop, detenemos la ejecución
En esta animación vemos el funcionamiento

Ya sabemos manejar el simulador del RISC-V. Somos capaces de ensamblar un programa, ejecutarlo completamente, ejecutarlo paso a paso o a baja velocidad. El RISC-V que veremos en el laboratorio es de 32-Bits. Esto significa que sus registros internos son de 32-bits. En total tiene 32 registros de 32-bits, que se denominan x0, x1, x2...x31, donde el registro x0 SIEMPRE vale 0. Además dispone del registro PC que contiene la dirección de la instrucción a ejecutar
También hemos aprendido nuestra primera instrucción: addi, que nos permite sumar un registro con un valor constante, y el resultado asignárselo a otro registro. Esta instrucción la utilizamos con los siguientes propósitos:
- Inicializar un registro (Ej. x5=2). Para ello hacemos que el registro fuente sea x0 (Ej. addi x5, x0, 2)
- Incrementar un registro una cantidad (Ej. x5=x5+VALOR). Tanto el registro fuente como el registro destino son el mismo (Ej. addi x5, x5, VALOR)
- Sumar a un registro un valor constante y dejar el resultado en otro registro. Este es el caso más general
En la siguiente sesión aprenderemos más sobre la memoria, e introduciremos nuevas instrucciones que nos permitirán calcular expresiones sencillas
- Instrucciones básicas: Son las que se transforman a código máquina y que ejecuta el procesador

Estas actividades están pensadas para que las hagas por tu cuenta, sin guía del profesor. Queremos que pienses. Habrá muchas cosas que no sepas, o que no entiendas: investiga, lee, prueba, practica
Recuerda: El objetivo es que aprendas. No tienes que entregar nada
Escribe un programa para RISC-V que asigne los siguientes valores a los registros indicados: x3=3, x4=4, x5=5, x6=6, x7=7 y x8=8. Ejecútalo paso a paso y comprueba que funciona correctamente
(Ver solución)
Modifica el programa del contador infinito para que se incremente el registro x5 en dos unidades, en vez de en una. Haz que el contador comience en 0. Ejecútalo paso a paso para comprobar que funciona bien. Como empieza en 0 y se incrementa en 2 unidades cada vez, lo que se debe ver es que x5 toma los valores de los números pares: 0, 2, 4...
¿Cuál es la dirección de la primera instrucción?
(Ver solución)
Escribe un programa para el RISC-V para que el registro x3 tome los valores 0,1,2,3,4,5..., el x4 0,3,6,9,12,15... y el x5 0,5,10,15,20,25.... indefinidamente. Ejecútalo paso a paso para comprobarlo
(Ver solución)
Escribe un programa que ejecute las siguientes acciones:
- Inicializar el registro x6 a 0
- Restarle 1
- Terminar
¿Cuál es el valor hexadecimal del registro x6 al terminar el programa?
(Ver solución)
Ejecuta este código paso a paso. ¿Qué es lo que hace?. No te preocupes por las instrucciones que no conozcas. Intenta deducir el funcionamiento del programa a partir de su ejecución
.text
addi x3, x0, 10
a:
addi x3,x3,-1
bgt x3,x0, a
li a7, 10
ecallEjecuta este código paso a paso. ¿Qué es lo que hace?
.text
addi x5, x0, 5
addi x6, x0, 6
addi x7, x0, 0
a:
beq x5,x0,fin
add x7, x7, x6
addi x5, x5, -1
j a
fin:
li a7, 10
ecallEl siguiente código NO se ensambla correctamente porque tiene errores. Introdúcelo en el simulador y soluciona los problemas para que ensamble correctamente y se pueda ejecutar paso a paso. ¿Qué es lo que hace este programa?
.text
addi x17, x0, 10
addi x12, x0, 8
addii x7, x0, 0
a:
beq x17,x0,fin ;-- Comprueba terminacion
add x7, xx7, x12
addi x17, x17, -1
;-- repetir
j hola
fin:
li a7, 10
ecallLas soluciones a los Ejercicios de las actividades NO guidas de esta sesión las tienes aquí: Soluciones L1
Nuestra recomendación es que intentes hacer los ejercicios por tu cuenta, sin mirar las soluciones. El objetivo es que aprendas, y que pienses. Una vez que tengas un ejercicio resuelto, contrástalo con la solución, para comprobar si lo has hecho bien, y sobre todo, para comprobar si tienes claros todos los conceptos
Ten también en cuenta que ¡¡Hay múltiples soluciones!!. Nosotros te proponemos una solución, pero no es la única. Puede haber muchas más formas de resolver el ejercicio
- Título informal de la clase: "Comienza la aventura..."
- Nos interesa que tengan una visión física, y de bajo nivel, del computador: La cpu es un chip (que se puede tocar). La memoria también. La E/S en los sistemas empotrados es rudimentaria (ejemplo del contador binario en los LEDs)
- Para aprender usaremos un simulador, que nos permite "parar el tiempo" y ejecutar instrucciones paso a paso
- En los sistemas (empotrados) reales el procesador ejecuta millones de instrucciones por segundo. Depurar es un infierno...
- Juan González-Gómez (Obijuan)
- Miguel Ángel de Miguel Paraíso
- Javier Macias del Campo
- Juan Ignacio Pérez
- Katia Leal Algara
- Procesadores RISC-V
- Alhambra II: Tarjeta con FPGA Libre, donde se puede sintentizar un RISC-V
- Raspberry Pi Pico 2: Tarjeta que incluye 2 cores de RISC-V. Ideal para practicar con un RISC-V Real
- Simulador RARs: Simulador de RISC-V utilizado en este curso
L1: El simulador RARs
L2: Calculando expresiones
L3: Práctica 1-3. Variables
L4: Pract 2-1. E/S mapeada
L5: Práctica 2-2: Inst. ecall
L6: Prác 2-3: Cadenas
L7: Práct 3-1: Bucles y saltos
L8: Práct 3-2: Cadenas II
L9: Pract 4-1: Subrut. Nivel-1
L10: Pract 4-2: La pila
L11: Pract 4-3: Recursividad
L12: Pract 5-1. Heap. Listas
L13: RV32I: Resto de instrucciones
L14: Macros
L15: Entrada/Salida a bajo nivel
L16: Multiplicaciones/divisiones. Unit Tests 🚧
L17: Biblioteca stdio: salida a alto nivel 🚧
Los registros de estado y control (CSR)
Interrupciones y excepciones
Borrador
Soluciones a los ejercicios planteados en cada sesión para practicar:
Sesión L1
Sesión L2
Sesión L3
Sesión L4
Sesión L5
Sesión L6
Sesión L7
Sesión L8
Sesión L9
Sesión L10
Sesión L11
Sesión L12
Simulacro examen 1
GISAM. Ordinario. 2019-Dic-11
GISAM. Extra. 2020-Jul-03
GISAM. Ordinario. 2021-Ene-21
GISAM. Ordinario. 2022-Ene-10
GISAM. Extra. 2022-Jun-29
GISAM. Parcial 1. 2022-Oct-26
GISAM. Parcial 2. 2022-Nov-30
GISAM. Parcial 3. 2022-Dic-21
GISAM. Parcial 1. 2023-Oct-09
GISAM. Parcial 2. 2023-Nov-11
GISAM. Parcial 3. 2023-Dic-20
GISAM. Extra. 2024-Jun-17
GISAM. Parcial 1. 2024-Oct-14
GISAM. Parcial 2. 2024-Nov-13
GISAM. Parcial 3. 2024-Dic-16
GISAM. Extra. 2025-Jun-17
GISAM. Parcial 1. 2025-Oct-20
GISAM. Parcial 2. 2025-Nov-19
GISAM. Parcial 3. 2026-Enero-9
GISAM. Parcial 1. 2026-Oct-21
TELECO. Ordinario. 2019-Dic-13
TELECO. Extra. 2020-Jul-07
TELECO. Ordinario. 2021-Ene-21
TELECO. Extra. 2021-Jul-02
TELECO. Ordinario. 2022-Ene-10
TELECO. Extra. 2022-Jun-29
TELECO. Ordinario. 2023-Ene-10
TELECO. Extra. 2023-Jun-29
TELECO. Parcial 1. 2023-Oct-20
TELECO. Parcial 2. 2023-Nov-17
TELECO. Parcial 3. 2023-Dic-22
TELECO. Extra. 2024-Jun-17
TELECO. Parcial 1. 2024-Oct-10
TELECO. Parcial 2. 2024-Nov-21
TELECO. Parcial 3. 2024-Dic-19
TELECO. Extra. 2025-Jun-17
TELECO. Parcial 1. 2025-Oct-10
TELECO. Parcial 2. 2025-Nov-13
TELECO. Parcial 3. 2026-Ene-21
TELECO. Extra. 2026-Jun-25
TELECO. Parcial 1. 2026-Oct-09
Robótica. Ordinario. 2020-Jun-1
Robótica. Extra. 2020-Jul-13
Robótica. Ordinario. 2021-Mayo-20
Robótica. Extra. 2021-Junio-16
Robótica. Parcial 1. 2022-Feb-25
Robótica. Parcial 2. 2022-Abril-1
Robótica. Parcial 3. 2022-Mayo-6
Robótica. Parcial 1. 2023-Feb-27
Robótica. Parcial 2. 2023-Mar-27
Robótica. Parcial 3. 2023-May-08
Robótica. Parcial 1. 2024-Feb-26
Robótica. Parcial 2. 2024-Mar-20
Robótica. Parcial 3. 2024-May-06
Robótica. Extra. 2024-Junio-24
Robótica. Parcial 1. 2025-Feb-25
Robótica. Parcial 2. 2025-Mar-31
Robótica. Parcial 3. 2025-May-19
Robótica. Parcial 1. 2026-Feb-23
Robótica. Parcial 2. 2026-Abr-13
Robótica. Parcial 3. 2026-May-11
Datos. Parcial 1. 2023-Oct-09
Datos. Parcial 2. 2023-Nov-15
Datos. Parcial 3. 2023-Dic-20
Datos. Parcial 1. 2024-Oct-09
Datos. Parcial 2. 2024-Nov-13
Datos. Parcial 3. 2025-Ene-17
Datos. Parcial 1. 2025-Oct-15
Datos. Parcial 2. 2025-Nov-19

