
An 8-bit SAP-style (Simple-As-Possible) CPU: one shared 8-bit bus, 5 general-purpose registers (A–E), an 8-operation ALU, conditional jumps, and 14 bytes of byte-addressable program/data memory (Von Neumann — program and data share the same address space).
Every instruction executes in up to 4 cycles:
The instruction set covers memory load/store, all 8 ALU operations against the accumulator (register A), 7 conditional jump variants (zero/carry/negative/overflow and their inverses), input/output through the chip's pins, and halt. See the full opcode table in the repository README.
rst_n low for at least 2 clock cycles, then release it.uio_in[0] high (program_mode), then for each byte of the
program, set ui_in to that byte's value and pulse uio_in[1] (program_wr) for one
clock cycle.program_mode low and pulse rst_n again so the program counter returns to 0
before execution starts.uo_out for results written by an OUT instruction, or drive ui_in with the
value an upcoming IN instruction should capture.A minimal example program (LD A, LD B, ADD B, OUT A, HLT) loads two values from
memory, adds them, and outputs the sum. A working, fully-worked example driving these exact
steps through cocotb is in
test/test.py
in this repository, including load/store, conditional jumps, halt, and external I/O.
None required. ui[0:7] and uo[0:7] are general-purpose 8-bit input/output buses driven
by the IN/OUT instructions — connect switches, LEDs, or any other digital I/O you like.
| # | Input | Output | Bidirectional |
|---|---|---|---|
| 0 | external_input[0] | external_output[0] | program_mode |
| 1 | external_input[1] | external_output[1] | program_wr |
| 2 | external_input[2] | external_output[2] | |
| 3 | external_input[3] | external_output[3] | |
| 4 | external_input[4] | external_output[4] | |
| 5 | external_input[5] | external_output[5] | |
| 6 | external_input[6] | external_output[6] | |
| 7 | external_input[7] | external_output[7] |