10 / 20 · Übung
Praktikum: ein 2×2-Array mit Eingabeversatz
Modellieren Sie Weitergabeverzögerungen um eine Flanke und prüfen Sie jeden Akkumulatorzwischenwert.
Lektionen sind frei lesbar. Schreibe dich ein, um deinen Fortschritt zu speichern.
Gleiche k-Werte zusammentreffen lassen
Speisen Sie A(i,k) am linken Rand an logischer Flanke k+i und B(k,j) am oberen Rand an k+j ein. Registrierte Weitergabe fügt horizontal j und vertikal i Flanken hinzu. Beide Operanden erreichen daher PE(i,j) an k+i+j. Diese gestaffelte Einspeisung ist der Eingabeversatz.
Für A=[[1,2],[3,4]], B=[[5,6],[7,8]] endet das Löschen vor E0. Die Randabläufe lauten:
| Flanke | Linke Zeile 0 | Linke Zeile 1 | Obere Spalte 0 | Obere Spalte 1 |
|---|---|---|---|---|
| E0 | 1(k0) | ungültig | 5(k0) | ungültig |
| E1 | 2(k1) | 3(k0) | 7(k1) | 6(k0) |
| E2 | ungültig | 4(k1) | ungültig | 8(k1) |
| E3 | ungültig | ungültig | ungültig | ungültig |
Speichern Sie Folgendes als schedule-lab.mjs und führen Sie node schedule-lab.mjs aus. Es benötigt keine Pakete und gibt Schedule lab passed aus. Ungültige Tokens sind null; gültige Tokens enthalten value und k. Dieses Modell für einen einzelnen Auftrag lässt job-Tags weg, prüft k aber ausdrücklich.
import assert from 'node:assert/strict';
const A=[[1,2],[3,4]],B=[[5,6],[7,8]],N=2,K=2;
const fresh=()=>({a:null,b:null,acc:0,count:0});
let grid=Array.from({length:N},()=>Array.from({length:N},fresh));
const expected=[[[5,0],[0,0]],[[19,6],[15,0]],
[[19,22],[43,18]],[[19,22],[43,50]]];
const token=(value,k)=>({value,k});
for(let t=0;t<K+2*N-2;t++) {
const next=grid.map(r=>r.map(p=>({...p})));
for(let i=0;i<N;i++) for(let j=0;j<N;j++) {
const ka=t-i,kb=t-j;
const a=j?grid[i][j-1].a:(ka>=0&&ka<K?token(A[i][ka],ka):null);
const b=i?grid[i-1][j].b:(kb>=0&&kb<K?token(B[kb][j],kb):null);
const p=next[i][j];p.a=a;p.b=b;
if(a&&b){assert.equal(a.k,b.k);assert.equal(a.k,p.count);
p.acc+=a.value*b.value;p.count++;}
}
grid=next;
assert.deepEqual(grid.map(r=>r.map(p=>p.acc)),expected[t]);
}
assert.deepEqual(grid.map(r=>r.map(p=>p.count)),[[2,2],[2,2]]);
console.log('Schedule lab passed');Jedes PE liest den alten Zustand und schreibt den Folgezustand. Eine unmittelbare Aktualisierung in der Iteration würde fälschlich Weitergabe über mehrere Stationen innerhalb einer Flanke erlauben.
Nach E0 beträgt nur der Akkumulator von C(0,0) fünf. E1 schließt ihn mit neunzehn ab und beginnt seine Nachbarn mit sechs und fünfzehn. E2 schließt diese mit zweiundzwanzig und dreiundvierzig ab, während das letzte PE erst achtzehn enthält. E3 addiert zweiunddreißig und ergibt fünfzig.
Ändern Sie die Zeileneinspeisung von t−i zu t. Eine Tag-Assertion sollte die Fehlausrichtung erkennen. Abschluss erfordert vier advance-Flanken und jeden Zähler gleich zwei. Initialisierung und serielle Ausgabeübertragung sind ausgeschlossen. Dieses ausführbare Modell bestätigt den definierten Ablauf, ohne RTL- oder DDS-Ausführung zu behaupten.
Tatsächliches RTL: das registrierte 2×2-Gitter
Der Anhang systolic_2x2.sv verbindet vier Instanzen aus signed_mac_pe.sv, begrenzt auf N=K=2. A bewegt sich nach rechts und B nach unten über registrierte Verbindungen mit valid und k-Tags. Die externe Randzufuhr erzeugt den Versatz; die step-Aufgabe der Testbench legt den Ablauf E0..E3 direkt an. Löschen endet vor E0 und es existiert keine zusätzliche Multipliziererpipeline.
Speichern Sie alle drei Anhänge gemeinsam und führen Sie Icarus Verilog aus:
iverilog -g2012 -s tb_systolic_2x2 -o systolic.vvp signed_mac_pe.sv systolic_2x2.sv tb_systolic_2x2.sv
vvp systolic.vvpDie Matrizen nach den Flanken sind [[5,0],[0,0]], [[19,6],[15,0]], [[19,22],[43,18]] und [[19,22],[43,50]]. Done wird erst nach E3 gesetzt. Zwei Pausen ergeben vier advance-Flanken und sechs physische Rechenflanken. Die Prüfungen decken auch [[10,9],[−6,3]], vollständiges Halten des Zustands und Reset mitten im Auftrag ab. Erwarten Sie RTL PASS:.
Ersetzen Sie als RTL-Änderungsübung eine registrierte Operandenverbindung durch einen kombinatorischen Pfad. Sagen Sie den ersten Fehler der Tag-Ausrichtung oder Zwischensumme voraus, vergleichen Sie das Protokoll und stellen Sie das Register wieder her. Die Erweiterung dieses Gitters auf N×N erfordert gemeinsame Neubetrachtung von Verdrahtung, Versatz, Breiten, Tags und Abschluss.
Selbst ausprobieren
Welchen Akkumulator und verbleibenden Term hat PE(1,1) nach E2? Weshalb verändert er sich an E3 trotz ungültiger Randeingaben?
Erklärung lesen
Der Akkumulator beträgt 18 aus 3×6, mit verbleibendem 4×8=32. Diese Operanden befinden sich in internen Weitergaberegistern und treffen an E3 ein; ungültige Ränder leeren das Array nicht sofort.