tangled
alpha
login
or
join now
nonbinary.computer
/
or1-design
0
fork
atom
OR-1 dataflow CPU sketch
0
fork
atom
overview
issues
pulls
pipelines
docs: fix CLAUDE.md inaccuracies from PE frame-based redesign
Orual
1 week ago
5bbf02f7
f8ad84fc
+47
-27
2 changed files
expand all
collapse all
unified
split
CLAUDE.md
monitor
CLAUDE.md
+43
-23
CLAUDE.md
···
50
50
51
51
## Project Structure
52
52
53
53
-
- `cm_inst.py` — Instruction set definitions (Port, MemOp, ALUOp hierarchy, Instruction, FrameDest, OutputStyle, TokenKind)
54
54
-
- `tokens.py` — Token type hierarchy (Token -> CMToken -> DyadToken/MonadToken/PELocalWriteToken/FrameControlToken; SMToken). Imports ISA enums from cm_inst.
53
53
+
- `cm_inst.py` — Instruction set definitions (Port, MemOp, ALUOp hierarchy, Instruction, FrameDest, OutputStyle, TokenKind, FrameOp, FrameSlotValue)
54
54
+
- `tokens.py` — Token type hierarchy (Token -> PEToken -> CMToken -> DyadToken/MonadToken; PEToken -> PELocalWriteToken/FrameControlToken; Token -> SMToken). Imports ISA enums from cm_inst.
55
55
+
- `encoding.py` — Pack/unpack boundary between semantic types and 16-bit hardware words (instruction encoding, flit1 routing words)
55
56
- `sm_mod.py` — Structure Memory cell model (Presence enum, SMCell dataclass with `is_wide` metadata flag)
56
57
- `dfasm.lark` — Lark grammar for dfasm graph assembly language
57
58
- `emu/` — Behavioural emulator package (SimPy-based discrete event simulation)
58
59
- `emu/events.py` — Simulation event types: `SimEvent` union (TokenReceived, Matched, Executed, Emitted, IRAMWritten, FrameSlotWritten, FrameAllocated, FrameFreed, TokenRejected, CellWritten, DeferredRead, DeferredSatisfied, ResultSent) and `EventCallback` type alias
59
59
-
- `emu/types.py` — Config and internal types (PEConfig, SMConfig, DeferredRead, FrameSlotValue). PEConfig/SMConfig accept `on_event: EventCallback | None` for simulation observability.
60
60
+
- `emu/types.py` — Config and internal types (PEConfig, SMConfig, DeferredRead). PEConfig/SMConfig accept `on_event: EventCallback | None` for simulation observability.
60
61
- `emu/alu.py` — Pure-function ALU: `execute(op, left, right, const) -> (result, bool_out)`
61
62
- `emu/pe.py` — ProcessingElement: matching store, IRAM fetch, output routing, event emission via `on_event` callback
62
63
- `emu/sm.py` — StructureMemory: I-structure semantics with deferred reads, event emission via `on_event` callback
···
103
104
- `tests/test_sm_tiers.py` — T0/T1 memory tier and EXEC bootstrap tests
104
105
- `tests/test_exec_bootstrap.py` — EXEC opcode acceptance criteria tests
105
106
- `tests/test_migration_cleanup.py` — Verifies removed types (SysToken, CfgOp, etc.) are absent from codebase
106
106
-
- `tests/test_pe_events.py` — PE event emission tests (TokenReceived, Matched, Executed, Emitted, IRAMWritten)
107
107
+
- `tests/test_pe_events.py` — PE event emission tests (TokenReceived, Matched, Executed, Emitted, IRAMWritten, FrameAllocated, FrameFreed, FrameSlotWritten, TokenRejected)
108
108
+
- `tests/test_pe_frames.py` — Frame-based PE matching, routing, and lifecycle tests
107
109
- `tests/test_sm_events.py` — SM event emission tests (CellWritten, DeferredRead, DeferredSatisfied, ResultSent)
108
108
-
- `tests/test_cycle_timing.py` — Cycle-accurate timing verification tests (PE pipeline stages, SM operation timing, network delivery latency, parallel execution)
110
110
+
- `tests/test_cycle_timing.py` — Cycle-accurate timing verification tests
109
111
- `tests/test_network_events.py` — Network-level event propagation tests
112
112
+
- `tests/test_network_routing.py` — Network routing and connectivity tests
113
113
+
- `tests/test_foundation_types.py` — Foundation type (Instruction, FrameDest, encoding) tests
114
114
+
- `tests/test_encoding.py` — Pack/unpack encoding tests for instructions and flit1 words
115
115
+
- `tests/test_ir_frame_types.py` — IR frame-related type tests
116
116
+
- `tests/test_allocate_frames.py` — Frame layout allocation tests
117
117
+
- `tests/test_codegen_frames.py` — Frame-based code generation tests
118
118
+
- `tests/test_sm_t0_raw.py` — SM T0 raw storage tests
110
119
- `tests/test_backend.py` — SimulationBackend command/result protocol tests
111
120
- `tests/test_snapshot.py` — StateSnapshot capture tests
112
121
- `tests/test_repl.py` — MonitorREPL command tests
···
137
146
138
147
All tokens inherit from `Token(target: int)`. The hierarchy:
139
148
140
140
-
- `CMToken(Token)` -- adds `act_id`, `data` (frozen dataclass, base for data-carrying tokens)
141
141
-
- `DyadToken(CMToken)` -- adds `port: Port`, `gen: int` (dyadic operand requiring match)
142
142
-
- `MonadToken(CMToken)` -- monadic operand (no match required)
143
143
-
- `PELocalWriteToken(CMToken)` -- adds `offset: int`, `values: list[int]` (writes IRAM directly)
144
144
-
- `FrameControlToken(CMToken)` -- frame lifecycle control (no data)
149
149
+
- `PEToken(Token)` -- base for all PE-targeted tokens (used for routing in network.py)
150
150
+
- `CMToken(PEToken)` -- adds `offset: int`, `act_id: int`, `data: int` (frozen dataclass, base for data-carrying tokens)
151
151
+
- `DyadToken(CMToken)` -- adds `port: Port` (dyadic operand requiring match)
152
152
+
- `MonadToken(CMToken)` -- adds `inline: bool` (monadic operand, no match required)
153
153
+
- `PELocalWriteToken(PEToken)` -- adds `act_id`, `region`, `slot`, `data`, `is_dest` (writes frame slots directly)
154
154
+
- `FrameControlToken(PEToken)` -- adds `act_id`, `op: FrameOp`, `payload: int` (frame alloc/free)
145
155
- `SMToken(Token)` -- `addr: int`, `op: MemOp`, `flags`, `data`, `ret: Optional[CMToken]`
146
156
147
157
### Instruction Set (cm_inst.py)
148
158
149
159
- `ALUOp(IntEnum)` base with subclasses: `ArithOp`, `LogicOp`, `RoutingOp`
150
150
-
- `MemOp(IntEnum)` -- read/write/atomic ops; includes WRITE, READ, FREE, CLEAR, EXEC, SET_PAGE, WRITE_IMM for T0 tier control
151
151
-
- `Instruction(op, has_const: bool, fref: int)` -- unified instruction type for both ALU and memory ops, stored in PE IRAM
160
160
+
- `MemOp(IntEnum)` -- read/write/atomic ops (READ, WRITE, EXEC, ALLOC, FREE, EXT, CLEAR, RD_INC, RD_DEC, CMP_SW, RAW_READ, SET_PAGE, WRITE_IMM)
161
161
+
- `Instruction(opcode, output: OutputStyle, has_const, dest_count, wide, fref)` -- unified instruction type for both ALU and memory ops, stored in PE IRAM
152
162
- `FrameDest(target_pe: int, offset: int, act_id: int, port: Port, token_kind: TokenKind)` -- destination address resolved from frame slot
163
163
+
- `FrameSlotValue = int | FrameDest | None` -- type alias for frame slot contents
153
164
- `OutputStyle` enum -- INHERIT, CHANGE_TAG, SINK for output routing decisions
154
154
-
- `TokenKind` enum -- DYADIC, MONADIC for token kind classification
165
165
+
- `TokenKind` enum -- DYADIC, MONADIC, INLINE for token kind classification
166
166
+
- `FrameOp(IntEnum)` -- ALLOC, FREE for frame lifecycle control tokens
155
167
- `is_monadic_alu(op: ALUOp) -> bool` -- canonical source of truth for monadic ALU op classification (used by `emu/pe.py` and `asm/opcodes.py`)
156
168
157
169
### ALU (emu/alu.py)
···
178
190
179
191
**Token Processing Pipeline:**
180
192
- Side paths (FrameControlToken, PELocalWriteToken): 1 cycle
181
181
-
- Dyadic CMToken: 5 cycles (dequeue + MATCH + IFETCH + EXECUTE + EMIT)
193
193
+
- Dyadic CMToken: 5 cycles (dequeue + IFETCH + MATCH + EXECUTE + EMIT)
182
194
- Monadic CMToken: 4 cycles (dequeue + IFETCH + EXECUTE + EMIT)
183
195
184
196
**Matching Logic:**
···
187
199
- If slot occupied: retrieve partner data and port, clear presence bit, fire instruction with both operands
188
200
- Port ordering: partner with Port.L goes to left operand; Port.R to right operand
189
201
190
190
-
**Output Routing** (determined by `Instruction.mode`):
202
202
+
**Output Routing** (determined by `Instruction.output`):
191
203
- `OutputStyle.INHERIT` -- routes to destinations specified in frame slots
192
204
- `OutputStyle.CHANGE_TAG` -- routes with different act_id tag (context switch)
193
205
- `OutputStyle.SINK` -- writes result to frame slot, emits no token
194
206
195
207
**Frame Initialization:**
196
196
-
- PE constructor loads initial_frames from PEConfig (dict or list format)
197
197
-
- Dict format: {frame_id: {slot_idx: int_value}} where int_value is unpacked via unpack_flit1() to FrameDest
208
208
+
- PE constructor loads initial_frames from PEConfig: `dict[int, dict[int, FrameSlotValue] | list[FrameSlotValue]]`
209
209
+
- Dict value format: `{slot_idx: value}` where int values are unpacked via `unpack_flit1()` to FrameDest
210
210
+
- List value format: `[slot0, slot1, ...]` raw values assigned by index
198
211
- Handles both codegen-produced packed integers and test-produced FrameDest objects
199
212
200
213
**Output logging:**
201
214
- `PE.output_log: list` records every token emitted (for testing and tracing)
202
215
203
216
**PELocalWriteToken handling:**
204
204
-
- Writes values directly to IRAM at specified offset (1 cycle)
217
217
+
- Writes data to frame slot at specified region/slot within the act_id's frame (1 cycle)
205
218
206
219
### Structure Memory (emu/sm.py)
207
220
···
244
257
- If `PEConfig.allowed_pe_routes` or `allowed_sm_routes` is set, `build_topology` restricts routes at construction time
245
258
246
259
**System API:**
247
247
-
- `System.inject(token: Token)` -- route token by type: SMToken → target SM, CMToken → target PE (IRAMWriteToken routes to PE automatically as CMToken subclass) (direct append, bypasses FIFO)
260
260
+
- `System.inject(token: Token)` -- route token by type: SMToken → target SM, PEToken → target PE (direct append, bypasses FIFO)
248
261
- `System.send(token: Token)` -- same routing as inject() but yields `env.timeout(1)` for 1-cycle delivery latency then `store.put()` (SimPy generator, respects FIFO backpressure)
249
262
- `System.load(tokens: list[Token])` -- spawns SimPy process that calls send() for each token in order
250
263
251
251
-
**PEConfig extensions (emu/types.py):**
264
264
+
**PEConfig (emu/types.py):**
265
265
+
- `pe_id: int`, `iram: dict[int, Instruction] | None`, `frame_count: int = 8`, `frame_slots: int = 64`, `matchable_offsets: int = 8`
266
266
+
- `initial_frames: Optional[dict[int, list[FrameSlotValue]]]` -- pre-loaded frame data
267
267
+
- `initial_tag_store: Optional[dict[int, int]]` -- pre-loaded act_id -> frame_id mappings
252
268
- `allowed_pe_routes: Optional[set[int]]` -- if set, restrict PE route_table to these PE IDs
253
269
- `allowed_sm_routes: Optional[set[int]]` -- if set, restrict PE sm_routes to these SM IDs
254
254
-
- `on_event: EventCallback | None` -- if set, PE fires `SimEvent` for every token receive, match, execute, emit, and IRAM write
270
270
+
- `on_event: EventCallback | None` -- if set, PE fires `SimEvent` for every token receive, match, execute, emit, frame alloc/free, slot write, and rejection
255
271
256
272
**SMConfig (emu/types.py):**
257
273
- `sm_id: int`, `cell_count: int = 512`, `initial_cells: Optional[dict]`, `tier_boundary: int = 256`
···
265
281
266
282
**Event types:**
267
283
- `TokenReceived(time, component, token)` -- PE/SM received a token
268
268
-
- `Matched(time, component, left, right, ctx, offset)` -- PE matched a dyadic pair
284
284
+
- `Matched(time, component, left, right, act_id, offset, frame_id)` -- PE matched a dyadic pair
269
285
- `Executed(time, component, op, result, bool_out)` -- PE executed an ALU instruction
270
286
- `Emitted(time, component, token)` -- PE emitted an output token
271
287
- `IRAMWritten(time, component, offset, count)` -- PE wrote instructions to IRAM
288
288
+
- `FrameAllocated(time, component, act_id, frame_id)` -- PE allocated a frame
289
289
+
- `FrameFreed(time, component, act_id, frame_id)` -- PE freed a frame
290
290
+
- `FrameSlotWritten(time, component, frame_id, slot, value)` -- PE wrote to a frame slot
291
291
+
- `TokenRejected(time, component, token, reason)` -- PE rejected a token (e.g., act_id not in tag store)
272
292
- `CellWritten(time, component, addr, old_pres, new_pres)` -- SM cell presence changed
273
293
- `DeferredRead(time, component, addr)` -- SM registered a deferred read
274
294
- `DeferredSatisfied(time, component, addr, data)` -- SM satisfied a deferred read
275
295
- `ResultSent(time, component, token)` -- SM sent a result token back
276
296
277
277
-
**Union type:** `SimEvent = TokenReceived | Matched | Executed | Emitted | IRAMWritten | CellWritten | DeferredRead | DeferredSatisfied | ResultSent`
297
297
+
**Union type:** `SimEvent = TokenReceived | Matched | Executed | Emitted | IRAMWritten | FrameAllocated | FrameFreed | FrameSlotWritten | TokenRejected | CellWritten | DeferredRead | DeferredSatisfied | ResultSent`
278
298
279
299
**Callback type:** `EventCallback = Callable[[SimEvent], None]`
280
300
+4
-4
monitor/CLAUDE.md
···
1
1
# OR1 Monitor (monitor/)
2
2
3
3
-
Last verified: 2026-02-26
3
3
+
Last verified: 2026-03-07
4
4
5
5
## Purpose
6
6
···
26
26
27
27
## Dependencies
28
28
29
29
-
- **Uses**: `cm_inst` (MemOp, Port), `tokens` (Token types), `sm_mod` (Presence), `emu/` (events, types, network), `asm/` (run_pipeline, codegen, ir), `dfgraph/categories` (opcode categorisation for graph JSON)
29
29
+
- **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)
30
30
- **Used by**: CLI entry point (`python -m monitor`), test suite
31
31
- **Boundary**: `cm_inst`, `tokens`, `sm_mod`, `emu/`, and `asm/` must NEVER import from `monitor/`
32
32
···
52
52
- `__init__.py` -- Public API exports
53
53
- `backend.py` -- `SimulationBackend` class with thread lifecycle and command dispatch
54
54
- `commands.py` -- All command and result frozen dataclasses, `SimCommand` union type
55
55
-
- `snapshot.py` -- `StateSnapshot`, `PESnapshot`, `SMSnapshot`, `SMCellSnapshot`, `capture()`
55
55
+
- `snapshot.py` -- `StateSnapshot`, `PESnapshot` (frame-based: frames, tag_store, presence, port_store, free_frames), `SMSnapshot`, `SMCellSnapshot`, `capture()`
56
56
- `graph_json.py` -- JSON serialization with execution overlay (extends dfgraph patterns)
57
57
- `server.py` -- `create_app(backend)` FastAPI factory, `ConnectionManager`, WebSocket handler
58
58
- `repl.py` -- `MonitorREPL(cmd.Cmd)` interactive CLI
···
67
67
- The `formatting.NO_COLOUR` global flag must be set before calling format functions (used by tests to get predictable output)
68
68
- Frontend requires `npm install && node build.mjs` in `monitor/frontend/` to produce `dist/bundle.js`
69
69
70
70
-
<!-- freshness: 2026-02-26 -->
70
70
+
<!-- freshness: 2026-03-07 -->