Altifigence Academy

15 / 20 · Esercitazione

Laboratorio: contropressione e reset

Esegui pausa globale, conservazione del risultato e reset di un lavoro interrotto.

Ferma il tempo logico come un'unica unità

Il nostro array didattico usa advance globale. Il pianificatore al confine e tutti i PE si muovono soltanto quando è disponibile il pacchetto del prossimo passo logico. Una corsia pianificata come non valida non richiede un vero operando. Far avanzare soltanto un flusso rompe lo sfasamento. Collegamenti con stalli indipendenti richiedono buffer aggiuntivi e regole di corrispondenza, oltre questa configurazione di base.

L'uscita usa un contratto valid/ready separato. Quando un risultato è pronto, mantieni stabili valid, data e job finché un fronte con valid&&ready lo trasferisce esattamente una volta. Il wrapper semplice non avvia nuovi lavori mentre un vecchio risultato rimane in attesa. La disponibilità del consumatore non deve necessariamente fermare il calcolo quando esiste spazio adeguato per i risultati.

Salva questo codice come stall-lab.mjs ed esegui node stall-lab.mjs. Modella un PE a due termini più un registro risultato, non richiede pacchetti e stampa Stall/reset lab passed.

javascript
import assert from 'node:assert/strict';
let s;
function reset(){s={step:0,acc:0,valid:false,data:0,job:7};}
const pairs=[[-2,3],[4,-5]];
function tick({advance=true,ready=false,rst=false}={}){
 if(rst){reset();return null;}
 if(s.valid){if(!ready)return null;
  const out={data:s.data,job:s.job};s.valid=false;return out;}
 if(advance&&s.step<pairs.length){
  const [a,b]=pairs[s.step];s.acc+=a*b;s.step++;
  if(s.step===pairs.length){s.data=s.acc;s.valid=true;}}
 return null;
}
reset();tick();assert.equal(s.acc,-6);
const held={...s};tick({advance:false});assert.deepEqual(s,held);
tick();assert.equal(s.data,-26);assert.equal(s.valid,true);
const blocked={...s};tick({ready:false});tick({ready:false});
assert.deepEqual(s,blocked);
assert.deepEqual(tick({ready:true}),{data:-26,job:7});
assert.equal(tick({ready:true}),null);
reset();tick();tick({rst:true,advance:false});
assert.deepEqual(s,{step:0,acc:0,valid:false,data:0,job:7});
tick();tick();assert.equal(s.data,-26);
console.log('Stall/reset lab passed');

Interpreta le verifiche

Una pausa mantiene la prima somma −6 e la posizione della pianificazione. Il secondo termine produce −26. Due fronti di uscita bloccati conservano il risultato; un fronte pronto lo trasferisce una sola volta. Il reset durante un lavoro incompleto azzera accumulatore, posizione e stato valid del risultato, quindi il recupero riparte dall'inizio del lavoro.

Aggiungere due pause globali alla pianificazione 2×2 di quattro passi dà quattro fronti di avanzamento e sei fronti fisici. Risultati ed elenchi k consumati devono corrispondere all'esecuzione senza stalli. La formula di completamento logico rimane invariata.

Questo è un riferimento di controllo sincrono. La sincronizzazione del reset fisico e gli attraversamenti tra domini di clock richiedono un progetto separato. Un lavoro interrotto dal reset non deve mai riportare un completamento riuscito; azzera i buffer a monte prima di ripartire. Il successo del modello non attesta l'accettazione dell'RTL, dell'app installata o dell'hardware.

Prova tu

Mantieni valid=1 e ready=0 per tre fronti, poi attiva ready. Quali segnali devono rimanere invariati, quanti trasferimenti avvengono e che cosa accade se arriva reset durante l'attesa?

Leggi la spiegazione

Mantieni data, job e valid. L'attesa trasferisce zero risultati; il fronte ready ne trasferisce uno. Reset scarta lo stato valid in sospeso e non deve consegnare quel lavoro come riuscito. Un'eventuale notifica di annullamento richiede un contratto di stato separato.

Lesson files

stall-lab.mjs ↓

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