OR-1 dataflow CPU sketch
at main 147 lines 5.2 kB view raw
1""" 2ALU execution engine for OR1 dataflow CPU. 3 4Pure-function ALU with no state or SimPy dependency. Implements full v0 opcode 5dispatch for arithmetic, logic, and routing operations. 6""" 7 8from cm_inst import ALUOp, ArithOp, LogicOp, RoutingOp 9 10UINT16_MASK = 0xFFFF 11 12 13def to_signed(val: int) -> int: 14 """Interpret a 16-bit unsigned value as signed 2's complement.""" 15 return val - 0x10000 if val & 0x8000 else val 16 17 18def _compare(op_fn, left: int, right: int) -> bool: 19 """Helper for comparison operations with signed semantics. 20 21 Args: 22 op_fn: A comparison function (e.g., lambda a, b: a == b) 23 left: Left operand (interpreted as signed) 24 right: Right operand (interpreted as signed) 25 26 Returns: 27 Boolean result of the comparison 28 """ 29 return op_fn(to_signed(left), to_signed(right)) 30 31 32def execute(op: ALUOp, left: int, right: int | None, const: int | None) -> tuple[int, bool]: 33 """ 34 Execute an ALU operation. 35 36 Returns (result & 0xFFFF, bool_out). 37 All values stored as unsigned 16-bit. Comparisons interpret as signed 2's complement. 38 39 Args: 40 op: ALU operation (ArithOp, LogicOp, or RoutingOp) 41 left: Left operand (always required) 42 right: Right operand (required for dyadic ops) 43 const: Constant field (required for shift ops and CONST op) 44 45 Returns: 46 Tuple of (result, bool_out) where: 47 - result is masked to 16-bit unsigned 48 - bool_out is Python bool for routing decisions 49 """ 50 if isinstance(op, ArithOp): 51 return _execute_arith(op, left, right, const) 52 if isinstance(op, LogicOp): 53 return _execute_logic(op, left, right) 54 if isinstance(op, RoutingOp): 55 return _execute_routing(op, left, right, const) 56 raise ValueError(f"Unknown ALU operation: {op}") 57 58 59def _execute_arith(op: ArithOp, left: int, right: int | None, const: int | None) -> tuple[int, bool]: 60 """Execute arithmetic operations.""" 61 match op: 62 case ArithOp.ADD: 63 result = (left + right) & UINT16_MASK 64 case ArithOp.SUB: 65 result = (left - right) & UINT16_MASK 66 case ArithOp.INC: 67 result = (left + 1) & UINT16_MASK 68 case ArithOp.DEC: 69 result = (left - 1) & UINT16_MASK 70 case ArithOp.SHL: 71 result = (left << const) & UINT16_MASK 72 case ArithOp.SHR: 73 result = (left >> const) & UINT16_MASK 74 case ArithOp.ASR: 75 signed = to_signed(left) 76 result = (signed >> const) & UINT16_MASK 77 case _: 78 raise ValueError(f"Unknown arithmetic op: {op}") 79 return result, False 80 81 82def _execute_logic(op: LogicOp, left: int, right: int | None) -> tuple[int, bool]: 83 """Execute logic operations.""" 84 match op: 85 case LogicOp.AND: 86 return (left & right) & UINT16_MASK, False 87 case LogicOp.OR: 88 return (left | right) & UINT16_MASK, False 89 case LogicOp.XOR: 90 return (left ^ right) & UINT16_MASK, False 91 case LogicOp.NOT: 92 return (~left) & UINT16_MASK, False 93 case LogicOp.EQ: 94 cmp = _compare(lambda a, b: a == b, left, right) 95 return (0x0001 if cmp else 0x0000), cmp 96 case LogicOp.LT: 97 cmp = _compare(lambda a, b: a < b, left, right) 98 return (0x0001 if cmp else 0x0000), cmp 99 case LogicOp.LTE: 100 cmp = _compare(lambda a, b: a <= b, left, right) 101 return (0x0001 if cmp else 0x0000), cmp 102 case LogicOp.GT: 103 cmp = _compare(lambda a, b: a > b, left, right) 104 return (0x0001 if cmp else 0x0000), cmp 105 case LogicOp.GTE: 106 cmp = _compare(lambda a, b: a >= b, left, right) 107 return (0x0001 if cmp else 0x0000), cmp 108 case _: 109 raise ValueError(f"Unknown logic op: {op}") 110 111 112def _execute_routing(op: RoutingOp, left: int, right: int | None, const: int | None) -> tuple[int, bool]: 113 """Execute routing operations.""" 114 match op: 115 case RoutingOp.BREQ | RoutingOp.SWEQ: 116 cmp = _compare(lambda a, b: a == b, left, right) 117 return left, cmp 118 case RoutingOp.BRGT | RoutingOp.SWGT: 119 cmp = _compare(lambda a, b: a > b, left, right) 120 return left, cmp 121 case RoutingOp.BRGE | RoutingOp.SWGE: 122 cmp = _compare(lambda a, b: a >= b, left, right) 123 return left, cmp 124 case RoutingOp.BROF | RoutingOp.SWOF: 125 raw = left + right 126 cmp = raw > UINT16_MASK 127 return left, cmp 128 case RoutingOp.GATE: 129 cmp = right != 0 130 return left, cmp 131 case RoutingOp.PASS: 132 return left, False 133 case RoutingOp.CONST: 134 return const & UINT16_MASK, False 135 case RoutingOp.FREE_FRAME: 136 return 0, False 137 case RoutingOp.EXTRACT_TAG: 138 return 0, False 139 case RoutingOp.ALLOC_REMOTE: 140 return 0, False 141 case RoutingOp.SEL: 142 cmp = left != 0 143 return (right if cmp else left), cmp 144 case RoutingOp.MRGE: 145 return left, False 146 case _: 147 raise ValueError(f"Unknown routing op: {op}")