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 表示空的級,而非數值零。有效的零結果仍然代表一筆交易。
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');| 邊緣 | 接受的輸入 | 交付的輸出 |
|---|---|---|
| 0 | tag0:1+2 | 無 |
| 1 | tag1:250+10 | 無 |
| 2 | tag2:100+0 | tag0:y9 |
| 3 | tag3:255+255 | tag1: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,而非使用實際邊緣編號。
✓ 已學習