Altifigence Academy

6 / 20 · Esercitazione

Laboratorio: elemento di elaborazione MAC con segno

Usa un modello autonomo per verificare operandi validi, stalli e azzeramento.

Esegui il contratto di un PE

Salva questo codice come pe-lab.mjs ed esegui node pe-lab.mjs con Node.js. Non usa pacchetti esterni e stampa PE lab passed. Verifica un modello aritmetico e di controllo; non compila SystemVerilog né dimostra l'esecuzione in DDS. Considera il normale lavoro a due termini come W=8, K=2, AW=17, mentre il modello usa interi estesi per il riferimento.

Il PE riceve flag valid separati per A e B. Accumula soltanto quando entrambi sono veri. L'inoltro segue il flag valid di ciascun operando. Una lezione successiva aggiunge tag per garantire che due operandi validi appartengano allo stesso termine di riduzione.

javascript
import assert from 'node:assert/strict';
const pe = {acc:0,a:0,b:0,av:false,bv:false};
function edge({a=0,b=0,av=false,bv=false,
               advance=true,clear=false,reset=false}={}) {
  if (reset || clear) {
    Object.assign(pe,{acc:0,a:0,b:0,av:false,bv:false});
  } else if (advance) {
    if (av && bv) pe.acc += a*b;
    Object.assign(pe,{a,b,av,bv});
  }
  return {...pe};
}
edge({clear:true});
assert.equal(edge({a:-2,b:3,av:true,bv:true}).acc,-6);
const held={...pe};
assert.deepEqual(edge({a:99,b:99,av:true,bv:true,advance:false}),held);
assert.equal(edge({a:4,b:-5,av:true,bv:true}).acc,-26);
assert.equal(edge({a:8,b:8,av:true,bv:false}).acc,-26);
assert.equal(pe.av,true); assert.equal(pe.bv,false);
edge({clear:true,a:100,b:100,av:true,bv:true});
assert.equal(pe.acc,0); assert.equal(pe.av,false);
assert.equal(edge({a:-128,b:-128,av:true,bv:true}).acc,16384);
edge({reset:true,advance:false});
assert.deepEqual(pe,{acc:0,a:0,b:0,av:false,bv:false});
console.log('PE lab passed');

Prevedi e metti alla prova il risultato

La prima coppia produce −6. Una pausa ignora i valori 99 offerti e mantiene tutto lo stato. La successiva coppia valida contribuisce −20, raggiungendo −26. Il token A senza compagno viene inoltrato, ma non contribuisce alcun MAC. Clear prevale sulla coppia valida simultanea; minimo×minimo dà poi 16384. Reset azzera lo stato valid anche quando advance è falso.

Traduci la stessa priorità in always_ff usando segnali product e addend esplicitamente con segno. Quando modelli un array, leggi lo stato precedente e scrivi uno stato successivo separato. Aggiornare gli oggetti PE direttamente può consentire accidentalmente a un token di attraversare più PE durante un solo fronte.

Cambia la condizione di accumulo da AND a OR. L'asserzione sul token senza compagno deve fallire. Prova anche ad applicare advance soltanto all'accumulatore lasciando muovere l'inoltro. Spiega quale contratto protegge ogni asserzione; un messaggio di successo da solo non rappresenta l'intero obiettivo di apprendimento.

Registra gli operandi offerti separatamente da quelli consumati: i valori novantanove durante la pausa sono visibili all'interfaccia ma non vengono mai consumati. Il wrapper deve conservare il termine pianificato successivo finché advance riprende. Le copie dello stato restituite conservano le osservazioni precedenti. Esamina i flag valid di inoltro oltre all'accumulatore quando traduci queste verifiche in un testbench basato sulle forme d'onda.

RTL effettivo: il PE MAC con segno

Salva insieme gli allegati signed_mac_pe.sv, systolic_2x2.sv e tb_systolic_2x2.sv. I primi due file sono RTL sintetizzabile; il testbench è soltanto per simulazione. Il PE estende il segno del proprio prodotto completo a 2W bit fino ad AW prima dell'accumulo. Le verifiche W=8,K=4 usano AW=18 per 65536, −65024 e 64516. I tag k ordinati rifiutano termini non corrispondenti tramite protocol_error.

La priorità è reset, clear, poi advance. Clear termina prima del primo fronte dati. Osserva l'accumulatore aggiornato dopo ogni fronte di salita; i vicini consumano l'inoltro registrato al fronte advance successivo. Una pausa mantiene ogni valore, flag valid, tag e conteggio. Tra gli azzeramenti viene eseguito un lavoro, senza quantizzazione di uscita o integrazione DDS.

Con Icarus Verilog installato, esegui:

bash
iverilog -g2012 -s tb_systolic_2x2 -o systolic.vvp signed_mac_pe.sv systolic_2x2.sv tb_systolic_2x2.sv
vvp systolic.vvp

Attenditi RTL PASS:; gli errori terminano con $fatal. Modifica addend affinché usi l'estensione con zeri e riproduci l'errore del prodotto negativo. Spiega la prima somma progressiva errata, ripristina l'estensione del segno e riesegui. Conserva log Node e HDL separati.

Prova tu

Inserisci una coppia valida (0,7) tra (−2,3) e (4,−5). Qual è la somma e in che cosa uno zero valido differisce da un token non valido?

Leggi la spiegazione

La somma è −26. Uno zero valido consuma comunque un vero termine k e fa avanzare conteggio dei termini e tag. Un token non valido non consuma alcun termine. Per un lavoro a tre termini, aggiorna K, analisi della larghezza e controllo di completamento di conseguenza.

Lesson files

pe-lab.mjs ↓signed_mac_pe.sv ↓systolic_2x2.sv ↓tb_systolic_2x2.sv ↓

La scelta vale per questo browser. Puoi modificarla in qualsiasi momento dal piè di pagina.