Altifigence Academy

11 / 24 · 実習

実習:2段とバブルを追跡する

更新前の状態から次状態を計算し、出力のタグ、値、エッジを比較します。

同時に更新されるレジスタをモデル化する

2段の関数f(a,b)=3(a+b)のサイクルモデルを作ります。各反復が1つの立ち上がりエッジを表します。最初に更新前のs2を消費します。次に更新前のs1から新しい第2段を計算し、その後両段を更新します。s2を計算する前にs1を更新すると、入力が1つのエッジで2つのレジスタを横断する誤った動作になります。

プロジェクトにpipeline-model.mjsを手動で追加して保存し、Node.jsの端末でnode pipeline-model.mjsを実行します。エッジ0から3で4入力を受け入れ、エッジ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

2番目のトランザクションは和260を保持し、780を12に縮小します。最後のものは1530を250に縮小します。エッジ、タグ、値を明示して比較すると、算術だけでなくタイミングの誤りも検出できます。排出時のバブルは両段を空にし、古い出力の繰り返しを防ぎます。

入力がない場合を調べるには、選んだ受け入れエッジにnullを挿入し、受け入れたトランザクションに対してのみタグを増やします。出力の空きはバブルに追従し、有効なトランザクションのレイテンシは2エッジのままです。このモデルには出力バックプレッシャーがありません。次の章で弾力的な動作を追加します。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 ↓

選択はこのブラウザに適用されます。フッターからいつでも変更できます。