CharlesCNorton
commited on
Commit
·
7c967c0
1
Parent(s):
53a9715
Remove Python fallbacks, add Extension Roadmap
Browse files- Replace SHL/SHR/MUL/DIV with NotImplementedError in both ref_step() and ThresholdCPU.step()
- Add detailed 11-item Extension Roadmap documenting circuit status and requirements
- README.md +21 -4
- threshold_cpu.py +8 -26
README.md
CHANGED
|
@@ -449,10 +449,27 @@ The interface generalizes to **all** 65,536 8-bit additions once trained—no me
|
|
| 449 |
|
| 450 |
### Extension Roadmap
|
| 451 |
|
| 452 |
-
- **
|
| 453 |
-
|
| 454 |
-
- **
|
| 455 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 456 |
|
| 457 |
---
|
| 458 |
|
|
|
|
| 449 |
|
| 450 |
### Extension Roadmap
|
| 451 |
|
| 452 |
+
1. **8-bit addition (0-255)** — Ripple carry adder using 8 chained full adders. Each full adder is 2 half adders + OR gate, built from XOR (2-layer) and AND (1-layer) threshold gates. Circuit exists and passes all 65,536 input combinations.
|
| 453 |
+
|
| 454 |
+
2. **8-bit subtraction (0-255)** — Two's complement via NOT gates on second operand + carry-in of 1. Reuses adder circuit. Handles negative results as unsigned wrap (200 - 250 = 206). Circuit exists and verified.
|
| 455 |
+
|
| 456 |
+
3. **8-bit multiplication** — Requires array of AND gates for partial products + adder tree to sum them. 8×8 produces 16-bit result; can truncate to low 8 bits or preserve full width. Circuit NOT yet implemented.
|
| 457 |
+
|
| 458 |
+
4. **8-bit division with remainder** — Restoring or non-restoring division via subtract-and-shift. Produces 8-bit quotient + 8-bit remainder. Most complex circuit; ~64 subtractors + muxes. NOT yet implemented.
|
| 459 |
+
|
| 460 |
+
5. **Bitwise AND, OR, XOR, NOT** — 8 parallel single-layer threshold gates per operation. AND: w=[1,1], b=-2. OR: w=[1,1], b=-1. XOR: 2-layer (OR+NAND→AND). All circuits exist and verified.
|
| 461 |
+
|
| 462 |
+
6. **Bit shifts (left, right)** — Hardwired routing, not computation. SHL: bit[i] → bit[i-1], inject 0 at LSB. SHR: bit[i] → bit[i+1], inject 0 at MSB. Can implement as identity gates with shifted wiring. NOT yet implemented.
|
| 463 |
+
|
| 464 |
+
7. **Comparisons (>, <, >=, <=, ==)** — Single-layer threshold gates on 16 inputs (8 bits from A, 8 from B). Learned weights encode lexicographic comparison. All 5 comparators exist and verified on 48 test pairs.
|
| 465 |
+
|
| 466 |
+
8. **Divisibility testing (mod 2-12)** — Powers of 2 (mod 2,4,8): single-layer, check relevant bits. Non-powers (mod 3,5,6,7,9,10,11,12): multi-layer circuits encoding residue classes. All 11 circuits exist and exhaustively verified 0-255.
|
| 467 |
+
|
| 468 |
+
9. **Multi-operand expressions (15 + 27 + 33)** — Accumulator pattern: result = 0; for each operand, result = ADD(result, operand). Router must fire multiple times per input sequence. Requires stateful dispatch or unrolled circuit.
|
| 469 |
+
|
| 470 |
+
10. **Order of operations (5 + 3 × 2 = 11)** — Parse expression into tree, evaluate depth-first. MUL before ADD. Requires either: (a) expression parser producing evaluation order, or (b) learned routing that implicitly respects precedence.
|
| 471 |
+
|
| 472 |
+
11. **Parenthetical expressions ((5 + 3) × 2 = 16)** — Explicit grouping overrides precedence. Parser must recognize parens and build correct tree. Evaluation proceeds innermost-out. Adds complexity to extraction layer.
|
| 473 |
|
| 474 |
---
|
| 475 |
|
threshold_cpu.py
CHANGED
|
@@ -193,22 +193,13 @@ def ref_step(state: CPUState) -> CPUState:
|
|
| 193 |
elif opcode == 0x4:
|
| 194 |
result = a ^ b
|
| 195 |
elif opcode == 0x5:
|
| 196 |
-
|
| 197 |
-
result = (a << 1) & 0xFF
|
| 198 |
elif opcode == 0x6:
|
| 199 |
-
|
| 200 |
-
result = (a >> 1) & 0xFF
|
| 201 |
elif opcode == 0x7:
|
| 202 |
-
|
| 203 |
-
result = full & 0xFF
|
| 204 |
-
carry = 1 if full > 0xFF else 0
|
| 205 |
elif opcode == 0x8:
|
| 206 |
-
|
| 207 |
-
result = 0
|
| 208 |
-
carry = 1
|
| 209 |
-
overflow = 1
|
| 210 |
-
else:
|
| 211 |
-
result = (a // b) & 0xFF
|
| 212 |
elif opcode == 0x9:
|
| 213 |
result, carry, overflow = alu_sub(a, b)
|
| 214 |
write_result = False
|
|
@@ -583,22 +574,13 @@ class ThresholdCPU:
|
|
| 583 |
elif opcode == 0x4:
|
| 584 |
result = self.alu.bitwise_xor(a, b)
|
| 585 |
elif opcode == 0x5:
|
| 586 |
-
|
| 587 |
-
result = (a << 1) & 0xFF
|
| 588 |
elif opcode == 0x6:
|
| 589 |
-
|
| 590 |
-
result = (a >> 1) & 0xFF
|
| 591 |
elif opcode == 0x7:
|
| 592 |
-
|
| 593 |
-
result = full & 0xFF
|
| 594 |
-
carry = 1 if full > 0xFF else 0
|
| 595 |
elif opcode == 0x8:
|
| 596 |
-
|
| 597 |
-
result = 0
|
| 598 |
-
carry = 1
|
| 599 |
-
overflow = 1
|
| 600 |
-
else:
|
| 601 |
-
result = (a // b) & 0xFF
|
| 602 |
elif opcode == 0x9:
|
| 603 |
result, carry, overflow = self.alu.sub(a, b)
|
| 604 |
write_result = False
|
|
|
|
| 193 |
elif opcode == 0x4:
|
| 194 |
result = a ^ b
|
| 195 |
elif opcode == 0x5:
|
| 196 |
+
raise NotImplementedError("SHL: threshold circuit not implemented")
|
|
|
|
| 197 |
elif opcode == 0x6:
|
| 198 |
+
raise NotImplementedError("SHR: threshold circuit not implemented")
|
|
|
|
| 199 |
elif opcode == 0x7:
|
| 200 |
+
raise NotImplementedError("MUL: threshold circuit not implemented")
|
|
|
|
|
|
|
| 201 |
elif opcode == 0x8:
|
| 202 |
+
raise NotImplementedError("DIV: threshold circuit not implemented")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
elif opcode == 0x9:
|
| 204 |
result, carry, overflow = alu_sub(a, b)
|
| 205 |
write_result = False
|
|
|
|
| 574 |
elif opcode == 0x4:
|
| 575 |
result = self.alu.bitwise_xor(a, b)
|
| 576 |
elif opcode == 0x5:
|
| 577 |
+
raise NotImplementedError("SHL: threshold circuit not implemented")
|
|
|
|
| 578 |
elif opcode == 0x6:
|
| 579 |
+
raise NotImplementedError("SHR: threshold circuit not implemented")
|
|
|
|
| 580 |
elif opcode == 0x7:
|
| 581 |
+
raise NotImplementedError("MUL: threshold circuit not implemented")
|
|
|
|
|
|
|
| 582 |
elif opcode == 0x8:
|
| 583 |
+
raise NotImplementedError("DIV: threshold circuit not implemented")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 584 |
elif opcode == 0x9:
|
| 585 |
result, carry, overflow = self.alu.sub(a, b)
|
| 586 |
write_result = False
|