OR-1 dataflow CPU sketch
OR1 Monitor (monitor/)#
Last verified: 2026-03-07
Purpose#
Interactive simulation monitor for OR1 dataflow CPU programs. Provides a threaded simulation backend with a command/result protocol, exposed through both a CLI REPL and a web UI with real-time graph visualization and execution overlay.
Contracts#
- Exposes:
SimulationBackend(threaded controller), command types (LoadCmd,StepTickCmd,StepEventCmd,RunUntilCmd,InjectCmd,SendCmd,ResetCmd,StopCmd), result types (GraphLoaded,StepResult,ErrorResult),StateSnapshot,capture(system) - Guarantees: Backend owns SimPy environment in a dedicated daemon thread. Commands are sent via
queue.Queueand processed sequentially. Results include full state snapshots and event lists. Invalid programs returnErrorResultwithout crashing the backend. Reset tears down state cleanly. - Expects: Valid dfasm source for
LoadCmd. Running backend thread (start()called beforesend_command()).
Command/Result Protocol#
Commands are frozen dataclasses sent to the backend thread via queue:
LoadCmd(source)->GraphLoaded(ir_graph, snapshot)orErrorResultStepTickCmd()->StepResult(all events at current sim time)StepEventCmd()->StepResult(exactly oneenv.step())RunUntilCmd(until)->StepResult(batched events up to target time)InjectCmd(token)->StepResult(direct inject, no backpressure)SendCmd(token)->StepResult(viastore.put(), respects backpressure)ResetCmd(reload)->StepResultorGraphLoaded(ifreload=True)StopCmd()-> terminates backend thread
Dependencies#
- Uses:
cm_inst(MemOp, Port, Instruction, FrameSlotValue),tokens(Token types),sm_mod(Presence),emu/(events, types, network),asm/(run_pipeline, codegen, ir),dfgraph/categories(opcode categorisation for graph JSON) - Used by: CLI entry point (
python -m monitor), test suite - Boundary:
cm_inst,tokens,sm_mod,emu/, andasm/must NEVER import frommonitor/
Key Decisions#
- Threaded backend: SimPy is not async-safe, so the simulation runs in a dedicated thread with queue-based IPC. The FastAPI server bridges async/sync via
asyncio.to_thread(). - Frozen command/result types: All protocol types are frozen dataclasses for thread safety and predictability.
- Event callback wiring: Backend uses
dataclasses.replace()to injecton_eventinto PEConfig/SMConfig duringLoadCmd, avoiding mutation of user-provided configs. - StateSnapshot as frozen copy:
capture()reads live PE/SM state and produces frozen dataclasses suitable for serialization, ensuring no aliasing with mutable simulation state. - REPL uses
cmd.Cmd: Standard library module, no external deps for CLI mode.
Invariants#
- Backend thread processes exactly one command at a time (sequential dispatch)
StepResult.finished == Truewhenenv.peek() == inf(no more events)StepResult.eventscontains only events from the most recent command executionStateSnapshotis always captured after the step completesGraphLoaded.snapshotreflects state after seed token injectionResetCmdalways clears_env,_system,_events,_ir_graph; preserves_last_source
Key Files#
__init__.py-- Public API exportsbackend.py--SimulationBackendclass with thread lifecycle and command dispatchcommands.py-- All command and result frozen dataclasses,SimCommandunion typesnapshot.py--StateSnapshot,PESnapshot(frame-based: frames, tag_store mapping act_id → (frame_id, lane) tuples, presence, port_store, match_data all 3D [frame_id][match_slot][lane], lane_count, free_frames),SMSnapshot,SMCellSnapshot,capture()graph_json.py-- JSON serialization with execution overlay (extends dfgraph patterns)server.py--create_app(backend)FastAPI factory,ConnectionManager, WebSocket handlerrepl.py--MonitorREPL(cmd.Cmd)interactive CLIformatting.py-- ANSI colour formatting withNO_COLOURflag for testingfrontend/-- TypeScript browser UI (Cytoscape.js, WebSocket client, event log, state inspector)
Gotchas#
- Backend must be
start()ed before anysend_command()call; otherwise commands sit in queue forever SendCmdinternally creates a one-shot SimPy process and steps once; this means it may process other pending events tooRunUntilCmdbatches events per tick internally but returns all events in a singleStepResult- The
formatting.NO_COLOURglobal flag must be set before calling format functions (used by tests to get predictable output) - Frontend requires
npm install && node build.mjsinmonitor/frontend/to producedist/bundle.js