Altifigence Academy

23 / 24 · Übung

Abschlussprojekt: kleiner Inferenzpfad und Bericht

Behalten Sie K=9,vier Ausgaben und einen Zusatztakt pro Ausgabe bei, nutzen Sie aber drei PEs. Wie groß sind modellierte Gesamttakte und reine MAC-Platzauslastung?

Ziel und Abnahmekriterien

Behalten Sie model.mjs aus dem vorhergehenden Praktikum, erstellen Sie daneben capstone-lab.mjs und führen Sie node capstone-lab.mjs aus. Verbinden Sie eine Faltungsschicht,Bias,Requantisierung,ReLU und Max-Pooling. Berichten Sie Werte getrennt von Aufwand. Dies ist kein vollständiger Klassifikator oder Trainingskern. Sie können Dateien über einen unterstützten Dateiablauf im installierten Digital Design Studio manuell untersuchen; Ausführung innerhalb von DDS ist nicht belegt.

Schließen Sie ab, wenn direkte Faltung und Fenster-Skalarprodukt-Akkumulatoren übereinstimmen, Zwischen-/Ausgabetestfälle passen und Ihr Bericht Form,MACs,angenommene Takte,Platzauslastung und eindeutige Tensorbytes enthält. Ergänzen Sie einen unabhängig handberechneten Testfall mit geänderter Eingabe. Bewahren Sie Befehl,Dateiversion und Annahmen mit dem Protokoll auf. Untersuchen Sie einen fehlgeschlagenen Vergleich, statt nur seinen Erwartungswert zu ändern.

Durchgerechnete Referenz

Die Eingabe ist 4×4 mit Werten 1 bis 16. Kernel [1,0,−1;1,0,−1;1,0,−1] subtrahiert in jeder Zeile die rechte Probe von der linken. Jede Zeile ergibt −2, also summiert sich jedes Fenster zu −6. Bias acht liefert vier Akkumulatoren gleich zwei. Multiplikator 0.5 und Nullpunkt Null erzeugen Code eins. ReLU erhält ihn und 2×2-Pooling ergibt [1]. Bewahren Sie auch asymmetrische Grenztestfälle auf; gleiche Ausgaben können Reihenfolgefehler verbergen.

Form [M,Ho,Wo] ist [1,2,2]. Zählen Sie 36 MACs einschließlich Termen mit Gewicht Null. Bei zwei PEs mit je einem MAC, die jede Ausgabereduktion teilen, nehmen Sie fünf MAC-Takte plus einen Kombinations-/Schreibtakt pro Ausgabe ohne Überlappung oder Wartezyklen an. Die modellierte Gesamtzahl ist 24 Takte. Reine MAC-Platzauslastung ist 36/(4×5×2)=90%. Dies ist keine gemessene Gerätelatenz.

Eindeutige int8-Tensoren benötigen Eingabe 16, Gewichte 9 und Faltungsausgaben 4 Bytes plus einen Bias mit vier Bytes. Die Poolingausgabe benötigt ein Byte. Tatsächlicher Verkehr kann Nachladen und Teilsummen enthalten. Skalierungen sx=sw=1, sy=2 erklären Multiplikator 0.5.

Die Änderung des Bias auf Null sagt Akkumulator −6, Code −3, aktivierte Null und Poolingnull voraus. Nur die erste Eingabe von eins auf zwei zu ändern ergibt ersten Akkumulator drei, Gleichstand 1.5 auf zwei gerundet, drei verbleibende Ausgaben eins und Poolingergebnis zwei. Testen Sie Änderungen getrennt. Mehr PEs oder Überspringen von Nullgewichten erfordert einen neuen ausdrücklichen Ablauf bei erhaltenen Werten.

Ausführbare Datei

javascript
import assert from 'node:assert/strict';
import {conv2d, im2col, dot, requantize, maxPool2x2} from './model.mjs';
const x = [Array.from({length: 4}, (_, r) => Array.from({length: 4}, (_, c) => r * 4 + c + 1))];
const kernel = [[1, 0, -1], [1, 0, -1], [1, 0, -1]];
const weights = [[kernel]], bias = [8];
const reference = conv2d(x, weights, {bias});
const flattenedWeights = kernel.flat();
const rows = im2col(x, 3, 3);
const accumulators = rows.map(row => dot(row, flattenedWeights) + bias[0]);
assert.deepEqual(accumulators, reference[0].flat());
assert.deepEqual(accumulators, [2, 2, 2, 2]);
const activated = reference[0].map(row => row.map(v => Math.max(0, requantize(v, 0.5))));
const pooled = maxPool2x2(activated);
assert.deepEqual(activated, [[1, 1], [1, 1]]);
assert.deepEqual(pooled, [[1]]);
// Cycle estimate with explicit assumptions: all MAC operands local, no stalls,
// one output at a time, K=9, two single-MAC PEs, no overlap with output write.
const macs = rows.length * flattenedWeights.length;
const peCount = 2, macCyclesPerOutput = Math.ceil(flattenedWeights.length / peCount);
const modelCycles = rows.length * (macCyclesPerOutput + 1);
const usefulSlots = macs, scheduledSlots = rows.length * macCyclesPerOutput * peCount;
assert.equal(macs, 36);
assert.equal(modelCycles, 24);
assert.equal(usefulSlots / scheduledSlots, 0.9);
const report = {shape:[1, 2, 2], accumulators, activated, pooled, macs, peCount,
  modelCycles, macSlotUtilization:usefulSlots / scheduledSlots,
  uniqueInputBytes:16, weightBytes:9, outputBytes:4, biasBytes:4,
  scope:'Software reference and schedule estimate only; no synthesis or DDS run'};
console.log(JSON.stringify(report, null, 2));

RTL-Abschlussprojekt: ganzzahlige Faltung

Die Anhänge cnn_window3x3.sv und cnn_conv3x3.sv verbinden Fenster mit neun vorzeichenbehafteten 8×8-Produkten, einer vorzeichenbehafteten 24-Bit-Summe mit Bias, Division durch zwei mit Rundung zur nächsten Ganzzahl mit geradem Ergebnis bei Gleichstand, int8-Sättigung, ReLU und einem 2×2-Maximum. Die Geometrie entspricht den vorhergehenden Regeln für 4×4, einen Kanal und 3×3 ohne Auffüllung. Eingabe-/Gewichtsskalierungen sind eins, Ausgabeskalierung zwei und alle Nullpunkte Null. Standardkernel ist [1,0,−1;1,0,−1;1,0,−1], Bias acht. Kernelparameter dürfen sich ändern; prüfen Sie die 24-Bit-Summengrenze erneut.

Vergleichen Sie out_acc, out_code und out_activation getrennt mit out_row/out_col und übernommenen Ausgabeübertragungen. Done steigt nach Übernahme des vierten Ergebnisses; pooled ist dann gültig. Sechzehn übernommene Eingaben bedeuten keinen Abschluss. Dieses RTL verwendet neun parallele Produkte und zwei registrierte Stufen anstelle der früheren Schätzung mit zwei PEs und 24 Takten. Frequenz/Leistung benötigen Synthese- oder Gerätenachweise.

Führen Sie die gemeinsame selbstprüfende Testbench aus:

sh
iverilog -g2012 -s tb_cnn_stream -o cnn-sim cnn_window3x3.sv cnn_conv3x3.sv tb_cnn_stream.sv
vvp cnn-sim

Standardakkumulatoren sind zwei, Codes/Aktivierungen eins und die Poolingausgabe eins. Die Prüfungen enthalten Vorzeichengrenzen, Sättigung, positive/negative Gleichstände, einen dichten vorzeichenbehafteten Kernel, Pausen und Reset. Prüfen Sie PASS frames=6 windows=24 outputs=24 kernels=2 in Ihrem tatsächlichen Protokoll. Ändern Sie die erste Eingabe auf zwei: Die erste Summe drei wird zu Code zwei gerundet und das Poolingergebnis wird zwei. Wählen Sie dann einen anderen vorzeichenbehafteten Kernel, berechnen Sie dessen erstes Fenster von Hand, aktualisieren Sie die unabhängige Koeffizientenfunktion und führen Sie jeden Testfall erneut aus. Kopieren Sie keine DUT-Ergebnisse in das Sollmodell.

Selbst ausprobieren

Behalten Sie K=9,vier Ausgaben und einen Zusatztakt pro Ausgabe bei, nutzen Sie aber drei PEs. Wie groß sind modellierte Gesamttakte und reine MAC-Platzauslastung?

Erklärung lesen

Jede Ausgabe benötigt drei MAC-Takte plus einen zusätzlichen, also insgesamt sechzehn. Alle 36 MAC-Plätze sind nützlich, also 100%. Gleiche Frequenz, Versorgung und Kombinationskosten benötigen weiterhin separate Implementierungsnachweise.

Lesson files

cnn_window3x3.sv ↓cnn_conv3x3.sv ↓tb_cnn_stream.sv ↓model.mjs ↓capstone-lab.mjs ↓

Deine Auswahl gilt für diesen Browser. Du kannst sie jederzeit in der Fußzeile ändern.