Altifigence Academy

11 / 24 · 實作

實作:追蹤兩級管線與空泡

由舊狀態計算下一個狀態,並比較輸出標籤、數值與邊緣。

模擬一起更新的暫存器

建立兩級函數 f(a,b)=3(a+b) 的週期模型。每次迭代代表一個上升緣。先消費舊 s2,再由舊 s1 計算新的第二級,最後更新兩級。若先更新 s1 才計算 s2,便會錯誤地讓輸入在同一個邊緣跨越兩個暫存器。

手動將 pipeline-model.mjs 加入專案,儲存後,在 Node.js 終端機執行 node pipeline-model.mjs。在邊緣 0 到 3 接受四筆輸入,再於邊緣 4 與 5 排空。在此永遠 ready 的契約下,所有輸入都會被接受。Null 表示空的級,而非數值零。有效的零結果仍然代表一筆交易。

javascript
import assert from 'node:assert/strict';
const inputs = [[1,2], [250,10], [100,0], [255,255]];
let s1 = null, s2 = null;
const seen = [];
for (let edge = 0; edge < 6; edge++) {
  if (s2 !== null) seen.push({ edge, ...s2 });
  const next2 = s1 === null ? null : {
    tag: s1.tag, y: (s1.sum * 3) % 256
  };
  const next1 = edge < inputs.length ? {
    tag: edge, sum: inputs[edge][0] + inputs[edge][1]
  } : null;
  s1 = next1;
  s2 = next2;
}
assert.deepEqual(seen, [
  { edge: 2, tag: 0, y: 9 },
  { edge: 3, tag: 1, y: 12 },
  { edge: 4, tag: 2, y: 44 },
  { edge: 5, tag: 3, y: 250 }
]);
assert.equal(s1, null);
assert.equal(s2, null);
console.log('PIPELINE PASS: 4 ordered results, latency=2');
邊緣接受的輸入交付的輸出
0tag0:1+2無
1tag1:250+10無
2tag2:100+0tag0:y9
3tag3:255+255tag1:y12
4空泡tag2:y44
5空泡tag3:y250

第二筆交易保留總和 260,再將 780 縮窄為 12。最後一筆將 1530 縮窄為 250。比較明確的邊緣、標籤與數值,既能抓出時序錯誤,也能抓出算術錯誤。排空用的空泡會清除兩級,避免舊輸出重複出現。

若要探索缺少輸入的情況,在選定的接受邊緣插入 null,且只對被接受的交易遞增標籤。輸出間隙會跟隨空泡,而有效交易仍維持兩個邊緣的延遲。此模型沒有輸出背壓。下一章會加入彈性行為。Node 檢查通過,驗證的是這個狀態模型,不代表 HDL 編譯或 DDS 模擬執行通過。

自己試試看

若邊緣 1 沒有輸入,而 B、C、D 在邊緣 2、3、4 被接受,標籤 0 到 3 的交付邊緣各是多少?

查看解說

A 在邊緣 2 傳輸。B、C、D 在邊緣 4、5、6 傳輸。邊緣 3 是輸出空泡。依接受順序配置標籤 0、1、2、3,而非使用實際邊緣編號。

Lesson files

pipeline-model.mjs ↓

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