OR-1 dataflow CPU sketch

feat: ALLOC_REMOTE reads fref+2 for data-driven ALLOC_SHARED

Task 1 Phase 4a Subcomponent A:

Updated ALLOC_REMOTE handler in emu/pe.py to read fref+2 from frame constants
and conditionally emit ALLOC_SHARED vs ALLOC based on whether parent_act_id
is non-zero.

Implementation details:
- Read fref+0 (target PE), fref+1 (target act_id), and new fref+2 (parent act_id)
- If parent_act (fref+2) is non-zero: emit FrameControlToken with op=ALLOC_SHARED and payload=parent_act
- If parent_act is zero/None: emit op=ALLOC and payload=0 (backwards compatible)
- Frame slots at fref+0, fref+1, fref+2 are assumed to be int values per codegen contract
- No runtime type checking added (consistent with existing ALLOC_REMOTE pattern)

Accepts AC4.1 (data-driven shared allocation) and AC4.2 (no new opcodes).

All 1290 tests pass. Backwards compatibility verified: existing tests with
only fref+0/fref+1 populated default fref+2 to None/0 (falsy), so they
emit op=ALLOC as before.

Orual 617aa7ac a2f3f878

+15 -3
+15 -3
emu/pe.py
··· 260 260 yield self.env.timeout(1) # EMIT cycle 261 261 self._do_emit_new(inst, result, False, token.act_id, frame_id) 262 262 elif inst.opcode == RoutingOp.ALLOC_REMOTE: 263 - # PE-level: read target PE and act_id from frame constants 263 + # PE-level: read target PE, act_id, and optional parent act_id from frame constants 264 + # fref+0: target PE 265 + # fref+1: target act_id 266 + # fref+2: parent act_id (0 = fresh ALLOC, non-zero = ALLOC_SHARED) 264 267 # Total: 4 cycles (dequeue + IFETCH + EXECUTE + EMIT) 265 268 target_pe = self.frames[frame_id][inst.fref] if inst.fref < len(self.frames[frame_id]) else 0 266 269 target_act = self.frames[frame_id][inst.fref + 1] if inst.fref + 1 < len(self.frames[frame_id]) else 0 270 + parent_act = self.frames[frame_id][inst.fref + 2] if inst.fref + 2 < len(self.frames[frame_id]) else 0 271 + 272 + if parent_act: 273 + alloc_op = FrameOp.ALLOC_SHARED 274 + payload = parent_act 275 + else: 276 + alloc_op = FrameOp.ALLOC 277 + payload = 0 278 + 267 279 fct = FrameControlToken( 268 280 target=target_pe, 269 281 act_id=target_act, 270 - op=FrameOp.ALLOC, 271 - payload=0, 282 + op=alloc_op, 283 + payload=payload, 272 284 ) 273 285 self._on_event(Executed( 274 286 time=self.env.now, component=self._component,