Altifigence Academy

15 / 24 · Lab

Lab: windows that survive pauses

If cycles zero,one,two are paused instead and all inputs are eventually accepted, do window values or count change? What is the total cycle count?

Goal and execution

Generate 3×3 windows from a serial input and verify that pauses preserve their values and order. Create window-lab.mjs, copy the code and run node window-lab.mjs. It needs Node.js and no package. You may manually create and inspect the same file through a supported file workflow in an installed Digital Design Studio. This does not establish execution inside DDS or automatic remote-project creation.

The model pauses accepted input only. It does not implement a complete output-ready protocol, memory bus, padding, dilation or multichannel engine. Entries in stalls identify elapsed cycles; accepted identifies input positions. Separating those counters is the point of the exercise. A pause leaves buffers, windows and the input index unchanged.

Worked expectations

Interpret one through sixteen as width four. The first normal window has acceptedIndex ten and values [1,2,3,5,6,7,9,10,11]. Window indices are [10,11,14,15]. Normal execution takes sixteen cycles. Pausing cycles two, three and twelve takes nineteen cycles and moves the first window to cycle thirteen. Its accepted-input index remains ten. Timing changes; content and ordering do not.

The reported seventeen storage samples comprise eight row-delay slots and nine window slots. JavaScript arrays do not measure synthesized SRAM bytes or area. The unbounded windows log is a verification record, not a finite hardware queue.

Run the original assertions first. Temporarily advance accepted during a pause and confirm that the value comparison fails, then restore the code. Removing row-start clearing while allowing early-column output would mix columns from different rows. Validity and state advancement must be tested together.

To compare with direct convolution, dot each window with the same flattened kernel and fold outputs into spatial order. Hand-check the first window before relying on automatic comparison. Retain configuration, accepted indices and elapsed cycles in your evidence so another run can reproduce the result.

Runnable file

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 lab: a bounded streaming window

Save attachments cnn_window3x3.sv, cnn_conv3x3.sv and tb_cnn_stream.sv together. The synthesizable window generator accepts one row-major 4×4 signed-int8 frame per synchronous active-high reset. It supports one channel, valid 3×3, stride/dilation one and no padding. Advance only when in_valid and in_ready are both high at a rising edge. Hold input data/valid during a pause; a blocked output window also remains stable. Reset before the next frame.

With Icarus Verilog installed, run externally:

sh
iverilog -g2012 -s tb_cnn_stream -o cnn-sim cnn_window3x3.sv cnn_conv3x3.sv tb_cnn_stream.sv
vvp cnn-sim

The self-checking bench compares every window's nine samples and coordinates, row boundaries, input/output pauses, reset with pending output and frame completion. For inputs one through sixteen, coordinates are (0,0),(0,1),(1,0),(1,1). Its final PASS must report frames=6, windows=24, outputs=24, kernels=2 and positive stalled_cycles. Submit your actual log; an unexecuted command is not a pass. Manually inspect files through a supported installed DDS file workflow if available; DDS execution and synthesis require separate evidence.

Change exercise: replace the first input by two, hand-check the first window and inspect a paused-output waveform. Window values/order must survive several cycles of low ready. Removing the registered window stage requires a new backpressure and state-stability argument.

Try it yourself

If cycles zero,one,two are paused instead and all inputs are eventually accepted, do window values or count change? What is the total cycle count?

Read the explanation

The same four windows remain in the same order. Sixteen accepted inputs plus three pauses take nineteen cycles. Accepted indices stay fixed; elapsed arrival times move later.

Lesson files

window-lab.mjs ↓cnn_window3x3.sv ↓cnn_conv3x3.sv ↓tb_cnn_stream.sv ↓

Your choice applies to this browser. Change it any time using the footer.