Altifigence Academy

11 / 24 · 实验

实验:追踪两级流水线与气泡

根据旧状态计算下一状态,并比较输出标签、数值和时钟沿。

建立寄存器同时更新的模型

为两级函数 f(a,b)=3(a+b) 建立周期模型。每次迭代代表一个上升沿。首先使用旧 s2 的输出。然后根据旧 s1 计算新的第二级状态,再更新两级。如果在计算 s2 之前就更新 s1,就会错误地让输入在一个时钟沿内跨过两个寄存器。

手动将 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 ↓

你的选择适用于此浏览器,可随时在页脚更改。