Altifigence Academy

15 / 24 · 實作

實作:能承受暫停的視窗

若改在週期零、一、二暫停,且所有輸入最終都被接受,視窗數值或數量會改變嗎?總週期數是多少?

目標與執行

由序列輸入產生 3×3 視窗,驗證暫停保留其數值與順序。建立 window-lab.mjs,複製程式並執行 node window-lab.mjs。需要 Node.js,不需要套件。可透過已安裝 Digital Design Studio 支援的檔案流程,手動建立與檢視相同檔案。這不證明 DDS 內執行,也不代表自動建立遠端專案。

模型只暫停輸入接受。它未實作完整輸出 ready 協定、記憶體匯流排、填補、膨脹或多通道引擎。stalls 內項目代表經過週期;accepted 代表輸入位置。區分兩種計數器正是練習重點。暫停保持緩衝器、視窗與輸入索引不變。

預期值範例

將一到十六解讀為寬度四。第一個正常視窗的 acceptedIndex 為十,值為 [1,2,3,5,6,7,9,10,11]。視窗索引為 [10,11,14,15]。正常執行需十六週期。暫停週期二、三與十二後,需十九週期,第一個視窗移到週期十三。其已接受輸入索引仍為十。時序改變,內容與順序不變。

回報的十七個儲存樣本,包括八個行延遲槽與九個視窗槽。JavaScript 陣列不量測合成 SRAM 位元組或面積。無上限的 windows 紀錄是驗證紀錄,不是有限硬體佇列。

先執行原斷言。暫時在暫停期間推進 accepted,確認數值比較失敗,再還原。移除列起點清除,且允許早期欄輸出,會混合不同列的欄。有效性與狀態前進必須一起測試。

與直接卷積比較時,將各視窗與相同攤平核心做內積,再依空間順序折回輸出。依賴自動比較前,先手算第一個視窗。在證據中保留配置、已接受索引與經過週期,讓其他執行可重現結果。

可執行檔案

javascript
import assert from 'node:assert/strict';
// Two row delays plus three horizontal shift registers: valid 3x3, one channel.
export function streamWindows(pixels, width, stalls = new Set()) {
  const previous = Array(width).fill(0), older = Array(width).fill(0);
  const window = Array.from({length: 3}, () => Array(3).fill(0));
  const windows = []; let accepted = 0, cycles = 0;
  while (accepted < pixels.length) {
    if (stalls.has(cycles++)) continue;
    const row = Math.floor(accepted / width), col = accepted % width;
    if (col === 0) window.forEach(r => r.fill(0));
    const current = pixels[accepted];
    [older[col], previous[col], current].forEach((v, r) => {window[r].shift(); window[r].push(v);});
    older[col] = previous[col]; previous[col] = current;
    if (row >= 2 && col >= 2) windows.push({acceptedIndex: accepted, cycle: cycles - 1, values: window.flat()});
    accepted++;
  }
  return {windows, accepted, cycles, storageSamples: 2 * width + 9};
}
const pixels = Array.from({length: 16}, (_, i) => i + 1);
const normal = streamWindows(pixels, 4);
const paused = streamWindows(pixels, 4, new Set([2, 3, 12]));
assert.deepEqual(normal.windows.map(w => w.acceptedIndex), [10, 11, 14, 15]);
assert.deepEqual(normal.windows[0].values, [1, 2, 3, 5, 6, 7, 9, 10, 11]);
assert.deepEqual(paused.windows.map(w => w.values), normal.windows.map(w => w.values));
assert.equal(paused.cycles, 19);
console.log(JSON.stringify({normal, paused}));

RTL 實作:有限的串流視窗

將附件 cnn_window3x3.sv、cnn_conv3x3.sv、tb_cnn_stream.sv 一起儲存。可合成視窗生成器每次同步高有效重設,可接受一個列優先 4×4 signed-int8 影格。支援單通道、無填補有效 3×3、步幅與膨脹一。只在上升緣 in_valid 與 in_ready 皆高時前進。暫停期間保持輸入 data 與 valid;阻塞的輸出視窗也保持穩定。下一影格前重設。

安裝 Icarus Verilog 後,在外部執行:

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

自我檢查測試平台比較各視窗九個樣本與座標、列邊界、輸入輸出暫停、有待處理輸出時的重設,以及影格完成。輸入一到十六時,座標為 (0,0),(0,1),(1,0),(1,1)。最後 PASS 必須回報 frames=6、windows=24、outputs=24、kernels=2,以及正的 stalled_cycles。提交實際紀錄;未執行命令不能算通過。若有可用的已安裝 DDS 檔案流程,手動檢視檔案;DDS 執行與合成需要另外的證據。

變更練習:第一個輸入改為二,手算第一視窗,並檢視暫停輸出波形。低 ready 持續多週期時,視窗數值與順序必須保留。移除暫存器視窗級,需要新的背壓與狀態穩定性論證。

自己試試看

若改在週期零、一、二暫停,且所有輸入最終都被接受,視窗數值或數量會改變嗎?總週期數是多少?

查看解說

相同四個視窗維持相同順序。十六個被接受輸入加上三次暫停,共十九週期。接受索引不變;經過時間的到達時機延後。

Lesson files

window-lab.mjs ↓cnn_window3x3.sv ↓cnn_conv3x3.sv ↓tb_cnn_stream.sv ↓

此選擇適用於本瀏覽器,隨時可從頁尾變更。