Altifigence Academy

15 / 24 · 实验

实验:暂停后仍保持正确的窗口

如果改为暂停周期零、一、二,且最终接收全部输入,窗口值或数量会改变吗?总周期数是多少?

目标与执行

从串行输入生成 3×3 窗口,验证暂停保持数值和顺序。创建 window-lab.mjs,复制代码,运行 node window-lab.mjs。需要 Node.js,不需要软件包。也可以通过已安装 Digital Design Studio 支持的文件流程手动创建并检查同一文件。这不证明在 DDS 中执行过,也不表示具备自动远程项目创建。

模型只暂停已接收输入,不实现完整 output-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 有符号 int8 输入。它支持单通道、无填充 3×3、步幅和膨胀率均为一。在上升沿,只有 in_valid 和 in_ready 同时为高时才推进。暂停时保持输入数据/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 ↓

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