19 / 20 · Esercitazione
Progetto finale: modello di verifica N×N suddiviso in blocchi
Combina N e K arbitrari con riempimento e pause e confronta con un riferimento indipendente.
Le lezioni sono gratuite. Iscriviti per salvare i progressi.
Assembla il modello completo
Il progetto finale accetta A di forma M×K e B di forma K×P su una griglia N×N. Ogni blocco spaziale inizia vuoto, gli operandi di riempimento sono zeri validi e le scritture sono mascherate dalle coordinate. Soltanto un lavoro occupa un blocco e le pause globali fermano il tempo logico. La quantizzazione di uscita rimane una prova separata dopo la somma estesa.
Salva questo codice come capstone-lab.mjs ed esegui node capstone-lab.mjs. Non occorrono pacchetti. Gli ingressi sono piccoli casi interi entro l'intervallo esatto di Number di JavaScript; intervalli maggiori richiedono BigInt e verifiche esplicite delle larghezze. Questo verifica un modello Node aritmetico e di pianificazione, indipendentemente dall'esecuzione RTL o DDS.
import assert from 'node:assert/strict';
function golden(A,B){return A.map(r=>B[0].map((_,j)=>
r.reduce((s,a,k)=>s+a*B[k][j],0)));}
function solve(A,B,N,pauses=new Set()){
const M=A.length,K=A[0].length,P=B[0].length;
assert.ok(N>=1&&Number.isInteger(N)&&K>=1);assert.equal(B.length,K);
assert.ok(A.every(r=>r.length===K)&&B.every(r=>r.length===P));
const C=Array.from({length:M},()=>Array(P).fill(null));
let advances=0,physical=0;
for(let r0=0;r0<M;r0+=N)for(let c0=0;c0<P;c0+=N){
const job=r0*P+c0;
let g=Array.from({length:N},()=>Array.from({length:N},()=>
({a:null,b:null,acc:0,count:0})));
const token=(value,k)=>({value,k,job});let t=0,p=0;
while(t<K+2*N-2){
if(pauses.has(p)){p++;continue;}
const next=g.map(r=>r.map(pe=>({...pe})));
for(let i=0;i<N;i++)for(let j=0;j<N;j++){
const ka=t-i,kb=t-j;
const a=j?g[i][j-1].a:(ka>=0&&ka<K?
token(r0+i<M?A[r0+i][ka]:0,ka):null);
const b=i?g[i-1][j].b:(kb>=0&&kb<K?
token(c0+j<P?B[kb][c0+j]:0,kb):null);
const pe=next[i][j];pe.a=a;pe.b=b;
if(a&&b){assert.equal(a.job,b.job);assert.equal(a.k,b.k);
assert.equal(a.k,pe.count);pe.acc+=a.value*b.value;pe.count++;}}
g=next;t++;p++;
}
for(let i=0;i<N;i++)for(let j=0;j<N;j++){
assert.equal(g[i][j].count,K);
if(r0+i<M&&c0+j<P){assert.equal(C[r0+i][c0+j],null);
C[r0+i][c0+j]=g[i][j].acc;}}
advances+=t;physical+=p;
}
return {C,advances,physical};
}
const A=[[1,2,3],[4,5,6],[7,8,9]],B=[[1,0,2],[0,1,0],[2,0,1]];
for(const N of [1,2,3])assert.deepEqual(
solve(A,B,N,new Set([1,2])).C,golden(A,B));
const run=solve(A,B,2,new Set([1,2]));
assert.deepEqual(run.C,[[7,2,5],[16,5,14],[25,8,23]]);
assert.equal(run.advances,20);assert.equal(run.physical,28);
assert.deepEqual(solve([[2,-1],[0,3]],[[4,5],[-2,1]],2).C,
[[10,9],[-6,3]]);
assert.deepEqual(solve([[-128]],[[-128]],1).C,[[16384]]);
console.log('Capstone lab passed');La funzione golden conosce soltanto l'aritmetica delle matrici. Il risolutore sposta indipendentemente token con tag, verifica i termini ordinati e maschera le scritture. Per N=2, quattro blocchi richiedono venti fronti di avanzamento. Fermare i fronti fisici uno e due in ogni blocco aggiunge otto pause, totalizzando ventotto fronti fisici. Inizializzazione, caricamento della memoria e trasferimento serializzato di uscita sono esclusi.
Consegna il log, una traccia dei k consumati di un blocco, l'analisi delle larghezze con segno e un progetto di wrapper dei risultati valid/ready. Conserva il contratto dei fronti quando traduci in RTL. Parti da N=1,K=1 e 2×2 prima di aumentare le dimensioni. Aggiungi quantizzazione, somme parziali conservate o doppio buffering una cosa alla volta con nuove verifiche esplicite.
Le tre dimensioni della griglia esercitano associazioni diverse: N=1 ripete prodotti scalari senza sfasamento, N=2 esercita quattro blocchi con riempimento e N=3 usa un blocco completo. Tutte devono produrre la stessa matrice matematica. Inizializzare C con null distingue uno zero valido da un'uscita non consegnata e rileva scritture duplicate. Il numero job derivato dal blocco è unico qui; l'RTL reale deve definire larghezza dei tag e politica di riuso. Come estensione, prova M=2,K=3,P=1 con valori attesi calcolati a mano. La griglia interna rimane quadrata mentre la matrice di uscita è rettangolare. Verifica che ogni blocco consumi K completo e sopprima scritture fuori intervallo.
Prova tu
Per l'esempio 3×3 con N=3 e pause ai fronti fisici uno e due, trova i conteggi dei fronti di avanzamento e fisici. Che cosa accade se la misura include un fronte clear precedente?
Leggi la spiegazione
Ci sono sette fronti di avanzamento e nove fronti fisici nell'intervallo di calcolo, incluse due pause. Includere un fronte clear precedente dà dieci; caricamento e trasferimento di uscita rimangono esclusi.