3 / 24 · Práctica
Práctica: modelo de referencia de una ALU de ocho bits
Comprueba ADD, SUB, AND, XOR, acarreo y préstamo en un ejecutable independiente.
Las lecciones se pueden leer gratis. Inscríbete para guardar el progreso.
Haz ejecutable el contrato numérico
Esta práctica modela una ALU combinacional con enteros de JavaScript. Los operandos van de 0 a 255 y las operaciones de 0 a 3. La salida y siempre cabe en ocho bits. El indicador representa el acarreo de ADD o el préstamo de SUB y vale cero en las operaciones lógicas. En esta interfaz, el préstamo vale uno cuando a es menor que b. Otras arquitecturas pueden definir los indicadores de resta de forma distinta; nuestro contrato es explícito.
Crea una carpeta local, o crea manualmente un proyecto vacío y añade alu-model.mjs en Digital Design Studio. Guarda el siguiente archivo. En una terminal con Node.js instalado, entra en la carpeta y ejecuta node alu-model.mjs. Editar un archivo en DDS y ejecutar JavaScript son acciones distintas. No se necesita instalar paquetes ni disponer de una función de importación automática.
import assert from 'node:assert/strict';
function alu(a, b, op) {
if (op === 0) {
const wide = a + b;
return { y: wide & 255, flag: Number(wide > 255) };
}
if (op === 1) return { y: (a - b) & 255, flag: Number(a < b) };
if (op === 2) return { y: a & b, flag: 0 };
if (op === 3) return { y: a ^ b, flag: 0 };
throw new RangeError('operation');
}
assert.deepEqual(alu(250, 10, 0), { y: 4, flag: 1 });
assert.deepEqual(alu(3, 5, 1), { y: 254, flag: 1 });
assert.deepEqual(alu(170, 204, 2), { y: 136, flag: 0 });
assert.deepEqual(alu(170, 204, 3), { y: 102, flag: 0 });
let checks = 0;
for (let a = 0; a < 256; a++) {
for (let b = 0; b < 256; b++) {
const add = alu(a, b, 0), sub = alu(a, b, 1);
assert.equal(add.y + 256 * add.flag, a + b);
assert.equal(sub.y - 256 * sub.flag, a - b);
assert.equal(alu(a, b, 2).y | alu(a, b, 3).y, a | b);
checks += 3;
}
}
console.log(`ALU PASS: ${checks} identities`);Para 250+10, y=4 y carry=1 reconstruyen 260. Para 3-5, y=254 y borrow=1 reconstruyen -2. En binario, 170 es 10101010 y 204 es 11001100: AND da 136 y XOR da 102. El bucle visita los 65536 pares de operandos y comprueba tres identidades por par. Una ejecución correcta informa de 196608 comprobaciones.
Usa un método diferente en el modelo de referencia y en el RTL. Si el hardware extrae el acarreo de un sumador de nueve bits, este modelo comprueba el intervalo matemático. Así se reducen los errores de implementación compartidos. Estas comprobaciones no evalúan los valores X/Z de HDL, los tiempos de propagación ni el comportamiento del reloj. Reutiliza los vectores en un simulador al implementar el RTL. Compara siempre los indicadores además de los datos; unos bits modulares correctos pueden ocultar un indicador de límite incorrecto.
Inténtalo tú
Si SUB siempre devuelve flag=0, ¿qué identidad numérica falla? Comprueba a=0, b=1 a mano y restaura la implementación.
Leer la explicación
y vale 255. Con flag=0, y-256×flag vale 255 en vez de -1, así que falla la reconstrucción de la resta. Con borrow=1, 255-256=-1. Comprobar únicamente y no detectaría este error.