Bounded firmware playback¶
protocol_emulator.v2.replay.compile_schedule converts a finite output schedule
into ordinary DRIVE, DELAY and HALT instructions. It uses the existing
timing engine and requires no replay hardware. The
UART scenario runner uses this component alongside
external-stimulus regression replay.
from protocol_emulator.v2.replay import OutputEvent, compile_schedule
words = compile_schedule(
[OutputEvent(0, 0, 1), OutputEvent(25, 1, 1), OutputEvent(50, 0, 1)],
end_cycle=74, owner=1,
)
device.load(0, words)
Cycle zero is the first instruction execution edge after START. Each event
specifies output values and enables immediately after its edge. The first
event must explicitly specify cycle zero. The final state remains driven
through end_cycle; HALT releases the outputs on end_cycle + 1. Configure
the same ownership and open-drain masks on the stopped engine before loading
and starting it.
All timestamps must be strictly increasing integer system cycles, within a 32-bit bounded window. One atomic value/enable change per cycle is supported. Fractional spacing, duplicate timestamps, unowned enables, nonzero values for released pins and actively high open-drain outputs are rejected. Long waits are split across 16-bit DELAY instructions without adding waveform cycles. Capacity checking includes every DRIVE, DELAY and the final HALT; an oversized schedule is rejected before generating any firmware. The selected hardware candidate has 64 words; the 128-word option is for feasibility experiments.
Playback reproduces output values and enables relative to the first scheduled execution edge. Capture samples before execution, so a recorded output change appears one sample after the instruction that produced it. Neither these instructions nor synchronized captured inputs recover the asynchronous phase of an external peer. Markers, running flags and input observations are not output schedules.
Python tests compare every output cycle against independent randomized schedules, check capacity boundaries and split long delays. The pin-driven test loads the generated words over host SPI and checks every execution edge, including adjacent events, open-drain release and final HALT. Routed-netlist validation remains required before this capability is accepted.