Altifigence Academy

3 / 24 · Prática

Laboratório: modelo de referência de uma ALU de oito bits

Verifique ADD, SUB, AND, XOR, carry e borrow em um executável independente.

Torne o contrato numérico executável

Este laboratório modela uma ALU combinacional usando inteiros de JavaScript. Os operandos variam de 0 a 255, com operações de 0 a 3. A saída y sempre cabe em oito bits. O indicador representa carry de ADD ou borrow de SUB e vale zero nas operações lógicas. Nesta interface, borrow vale um quando a é menor que b. Outras arquiteturas podem definir os indicadores de subtração de outra forma; nosso contrato é explícito.

Crie uma pasta local ou crie manualmente um projeto em branco e adicione alu-model.mjs no Digital Design Studio. Salve o arquivo a seguir. Em um terminal com Node.js instalado, entre na pasta e execute node alu-model.mjs. Editar um arquivo no DDS e executar JavaScript são ações distintas. Não é necessária a instalação de pacotes nem um recurso de importação 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 e carry=1 reconstituem 260. Para 3-5, y=254 e borrow=1 reconstituem -2. O valor 170 em binário é 10101010 e 204 é 11001100: AND produz 136 e XOR produz 102. O laço percorre todos os 65536 pares de operandos e verifica três identidades por par. Uma execução bem-sucedida informa 196608 verificações.

Use no modelo de referência um método diferente daquele usado no RTL. Se o hardware extrai o carry de um somador de nove bits, este modelo verifica a faixa matemática. Isso reduz erros de implementação compartilhados. Essas verificações não avaliam valores X/Z de HDL, temporização de propagação ou comportamento de clock. Reutilize os vetores em um simulador ao implementar o RTL. Compare sempre os indicadores além dos dados; bits modulares corretos podem ocultar um indicador de limite incorreto.

Experimente

Se SUB sempre retornar flag=0, qual identidade numérica falhará? Verifique a=0, b=1 manualmente e restaure a implementação.

Ler a explicação

y vale 255. Com flag=0, y-256×flag vale 255 em vez de -1, portanto a reconstituição da subtração falha. Com borrow=1, 255-256=-1. Verificar apenas y não detectaria esse erro.

Lesson files

alu-model.mjs ↓

Sua escolha vale neste navegador. Altere-a a qualquer momento no rodapé.