Altifigence Academy

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.

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.

javascript
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.

Lesson files

alu-model.mjs ↓

Tu elección se aplica a este navegador. Puedes cambiarla en el pie de página.