Tarea 7: Mejora del rendimiento

Tarea 7: Mejora del rendimiento

Información de la Tarea

Estudiante: Andrés Cruz Chipol

Curso: Arquitectura De Computadoras

Fecha de entrega: 16 de abril de 2026


Tarea 7: Mejora del Rendimiento del RISC0, Multiplicador en Hardware

Objetivo


1. Implementación de la forma combinacional

Problemas con el diseño de la tarea anterior

En la tarea anterior se usaba un módulo que implementaba la multiplicación mediante un proceso iterativo que tomaba 32 ciclos de reloj. Esto detenía toda la ejecución del procesador durante ese tiempo cada vez que se llamaba la instrucción MUL. Además, la lógica generaba un atraso muy grande en el flujo, por lo que la placa iCE40 no lograba sincronizarse a los 100 MHz normales y fue necesario usar un divisor de reloj a 25 MHz.

Solución: módulo combinacional

Para el diseño actual se armó un módulo completamente combinacional usando el operador * nativo de Verilog:

module Multiplier_comb(
input clk, run, u, // misma interfaz que Multiplier.v
output stall, // siempre 0 — sin ciclos de espera
input [31:0] x, y,
output [63:0] z);
wire signed [63:0] sp = $signed(x) * $signed(y);
wire [63:0] up = x * y;
assign z = u ? sp : up; // u=1: signed, u=0: unsigned
assign stall = 1'b0; // nunca genera stall
endmodule

Como se mantuvieron los mismos nombres de entradas y salidas, la integración en RISC0.v fue directa; el único cambio notable es que la señal de stall queda anclada siempre a 0:

Multiplier_comb mulUnit (.clk(clk), .run(MUL), .stall(stallM),
.u(~u), .x(B), .y(C1), .z(product));

Al quitar el cuello de botella de los ciclos iterativos, también se eliminó el divisor de reloj de RISC0Top.v y se conectó el procesador directamente a 100 MHz, ajustando los parámetros de la UART a esa frecuencia.


2. Evidencia del Número de Ciclos (Simulación)

Se reutilizó el banco de pruebas que intercepta la escritura al registro de conteo de ciclos:

if (micro.riscx.dmwr && micro.riscx.dmadr == 14'd16300) begin
$display("\n============================================================");
$display(" THROUGHPUT (Ciclos de reloj por iteracion): %d", micro.riscx.dmin);
$display("============================================================\n");
$finish();
end

Resultado de la simulación

============================================================
THROUGHPUT (Ciclos de reloj por iteracion): 66
============================================================

El resultado de 66 ciclos contrasta con los 190 de la Tarea 6. La mejora se explica directamente: cada una de las 5 multiplicaciones pasó de tardar 32 ciclos a resolverse en 1, eliminando 160 ciclos de espera del total.


3. Frecuencia de Reloj — Reporte de Síntesis FPGA

Resultados de nextpnr (apio build)

"fmax": {
"clk$SB_IO_IN_$glb_clk": {
"achieved": 28.655759,
"constraint": 12.0
}
}
"utilization": {
"ICESTORM_LC": { "available": 7680, "used": 6537 },
"ICESTORM_RAM": { "available": 32, "used": 32 }
}

La frecuencia máxima para el circuito sintetizado es 28.65 MHz.

Comparativa de frecuencias

MétricaTarea 6Tarea 7
Frecuencia configurada25 MHz (÷4)100 MHz (directo)
Frecuencia máxima — nextpnr~38 MHz~28.65 MHz
Frecuencia de operación real25 MHz28.65 MHz

4. Comparativa de Rendimientos (Throughput)

Fórmula: Throughput = Frecuencia (Hz) / Ciclos_por_iteración

Tarea 6 (Baseline)

Tarea 7 (Con Multiplicador Combinacional)

Tabla Comparativa Final

MétricaTarea 6 (RISC0 original)Tarea 7 (Multiplicador Combinacional)
Frecuencia de operación25 MHz~28.65 MHz
Ciclos por iteración19066
Throughput (resultados/seg)~131,578~434,090
Mejora vs Tarea 6~3.3×

Conclusión

Al cambiar a la forma combinacional se obtuvo un rendimiento más de tres veces mayor. Los ciclos bajaron de 190 a 66 al eliminar todos los tiempos muertos de la instrucción de multiplicar, y eso a su vez permitió subir ligeramente la frecuencia de operación a ~28.65 MHz. Aunque se alcanzan aproximadamente 434,000 cálculos por segundo, el procesador sigue limitado por su naturaleza secuencial y las dependencias de datos propias del RISC0.