Skip to content
Projects

sql-hkr/tiny8 has 1,390 GitHub stars and 42 forks. GitHot measured +3 stars in 24 hours. Last checked 2026-11-08 06:19 UTC. Last push 2026-10-29.

How these counts are measured

A tiny CPU simulator written in Python

Measured star growth

in 24h
+3
in 7 days
Collecting history
in 15 days
Collecting history
in 1 month
Collecting history

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

README.md

Original

Tiny8

PyPI version License Python versions CI codecov

From bare-metal computer architecture to Generative AI — an educational 8-bit AVR RISC CPU simulator with real-time interactive visualization

Tiny8 is a lightweight educational toolkit that bridges bare-metal computer architecture and modern Generative AI. Designed for hands-on learning and experimentation, it guides you through the full stack of computing — from 32 general-purpose registers, ALU operations, stack frames, and C compilation up to executing an iterative reverse-diffusion model synthesizing 28x28 MNIST digits directly on an AVR 8-bit RISC processor. With an interactive Vim-inspired terminal debugger, time-travel reverse execution, and a 32x32 TrueColor memory heatmap, Tiny8 lets you see, step through, and understand computation at every level.

Native 28x28 Generative Diffusion synthesis executing at x5,000 speed in Tiny8 TUI

Real-time generative reverse-diffusion synthesis (MNIST digit 8) executing at x5,000 speed in Tiny8 TUI (HEX mode for weight/LFSR init → PIXEL mode for reverse denoising trajectory)

Features

Modern Textual TUI Debugger & Dashboard

  • Reactive Terminal Dashboard: Real-time panels with gradient heatmap bars, SREG condition timeline, call stack, and memory dump
  • Bottom statusline: High-contrast mode badges (NORMAL, RUNNING, INSERT, COMMAND), file progress, and key hints (h: help)
  • Interactive controls: Step forward/back (n/p), continue (c), toggle breakpoint (b), play/pause (Space), speed control (+/-), TUI application help guide (h / ?), and instruction inspector modal (i)
  • Seamless Vim Editor: Press e anytime to jump into the built-in editor, modify code, and hit :run to debug

Built-in Vim-Style Modal Editor

  • Standalone file creation & editing: Run tiny8 or tiny8 my_prog.c to create and edit files directly inside the terminal
  • Complete Vim modes:
    • NORMAL: h/j/k/l movement, w/b word jump, 0/$ line limits, gg/G bounds, x delete char, dd delete line, yy yank, p paste, u undo, Ctrl+r redo
    • INSERT: Full typing with syntax highlighting, line numbers, and <Esc> to return to normal mode
    • COMMAND (:): :w (save), :w <file>, :q (exit), :wq / :x (save and run), :run (compile/assemble and launch debugger), :e <file> (switch file)

32x32 Heatmap Memory Dump & Diffusion Synthesis

  • 32x32 Heatmap Memory Grid (1024 Bytes): TrueColor gradient heatmap background mapped directly to memory (0x0200..0x05FF VRAM default), rendering 28x28 MNIST handwritten digits directly inside the memory dump with 1:1 pixel aspect ratio.
  • Embedded Generative AI: Iterative reverse-diffusion synthesis generating MNIST digits on Tiny8 AVR CPU (tiny8 examples/diffusion_mnist8.asm).
  • Viridis & Grayscale Palettes: Supports both colorful Viridis heatmap and realistic MNIST Grayscale pixel display modes (toggle with g for gray/viridis and x for hex/pixel).
  • Sample Programs: Native 28x28 diffusion generation (tiny8 examples/diffusion_mnist8.asm) showcasing real-time image synthesis on the 32x32 VRAM heatmap monitor.

Built-in C Compiler & Extensions

  • Compile and run C programs directly: Write C code (.c) and execute on Tiny8 (tiny8 program.c)
  • Enhanced C features: Character literals ('A', '#'), string literals, fixed-size arrays (int arr[4];), for loops, break;, logical && and ||, bit shifts << and >>, function calls, peek()/poke(), and VRAM helpers (vram_set, vram_get, vram_puts, vram_clear)
  • Compile-to-assembly inspection: Generate and inspect clean Tiny8 assembly with -c flag

Optimized AVR Instruction Set

  • Extended SRAM Addressing: LDS Rd, k (Load Direct from SRAM) and STS k, Rr (Store Direct to SRAM) for direct 16-bit address access
  • 16-bit Pointer Pairs: Full support for pointer pairs Z (R31:R30), X (R27:R26), and Y (R29:R28) with LD and ST across the entire 64KB address space

Complete 8-bit Architecture

  • 32 general-purpose registers (R0-R31)
  • 8-bit ALU with arithmetic, logical, and bit manipulation operations
  • Status register (SREG) with 8 condition flags
  • 64KB address space for unified memory and I/O
  • Stack operations with dedicated stack pointer
  • AVR instruction set with 67 instructions compliant with Microchip DS40002198A

Educational Focus

  • Clean, readable Python implementation
  • Comprehensive examples (Fibonacci, bubble sort, factorial, and more)
  • Step-by-step execution traces for debugging
  • Full API documentation and instruction set reference

Quick Start

Installation

pip install tiny8

Your First Program

Create fibonacci.asm:

; Fibonacci Sequence Calculator
; Calculates the 10th Fibonacci number (F(10) = 55)
; F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2)
;
; Results stored in registers:
; R16 and R17 hold the two most recent Fibonacci numbers

    ldi r16, 0          ; F(0) = 0
    ldi r17, 1          ; F(1) = 1
    ldi r18, 9          ; Counter: 9 more iterations to reach F(10)

loop:
    add r16, r17        ; F(n) = F(n-1) + F(n-2)
    mov r19, r16        ; Save result temporarily
    mov r16, r17        ; Shift: previous = current
    mov r17, r19        ; Shift: current = new result
    dec r18             ; Decrement counter
    brne loop           ; Continue if counter != 0

done:
    jmp done            ; Infinite loop at end

Run it:

tiny8 fibonacci.asm            # Interactive Textual debugger
tiny8 examples/factorial.c     # Run C program directly in debugger
tiny8 examples/factorial.c -c  # Print compiled Tiny8 assembly

Python API

from tiny8 import CPU, assemble_file, compile_c

# Run assembly program
asm = assemble_file("fibonacci.asm")
cpu = CPU()
cpu.load_program(asm)
cpu.run(max_steps=1000)
print(f"Result: R17 = {cpu.read_reg(17)}")

# Or compile and run C code directly!
asm_from_c = compile_c("int main() { return 10 + 32; }")

Why Tiny8?

For Students — Write assembly, see immediate results with visual feedback. Understand how each instruction affects CPU state without abstractions.

For Educators — Interactive demonstrations, easy assignment creation, and generate animations for lectures.

For Hobbyists — Rapid algorithm prototyping at the hardware level with minimal overhead and an extensible, readable codebase.

Documentation

Interactive CLI Controls

The terminal debugger provides modern modal navigation and inspection capabilities.

Navigation & Execution Shortcuts

  • n / p — Step forward / backward (+1 / -1)
  • c — Continue run forward until next breakpoint, watchpoint, or program completion
  • C (Shift+C) — Reverse continue run backward until previous breakpoint or watchpoint
  • b — Toggle breakpoint at current PC
  • Space — Play / pause automatic step execution
  • + / - — Increase / decrease playback speed
  • j / k (or J / K) — Scroll memory dump down / up (by 32-byte line or fast 128-byte page)
  • e — Open full-screen Vim Editor for source code
  • r — Reset execution to step 0
  • h / ? — Open TUI application usage & keyboard guide modal
  • i — Inspect specification & status details for the currently selected instruction
  • q — Quit debugger

Tabbed Views (Inspector & Telemetry)

  • Registers & Memory — Gradient heatmap bars for R0..R31 alongside 32x32 memory dump with TrueColor heatmap background (0x0200..0x05FF VRAM)
  • C Variables — Live symbol table tracking C variable names, types, memory addresses, hex/dec values, and update status
  • Call Stack — Dynamic function call backtrace reconstructed from execution calls and returns

Command Bar (press :)

  • :<step> or :goto <step> — Jump directly to step number
  • :b <pc> or :break <pc> — Toggle breakpoint at PC (0x000E or 14)
  • :b <pc> if <expr> — Set conditional breakpoint (e.g. :b 10 if R16 == 42, :b 0x12 if mem[0x60] > 0)
  • :bc or :clear — Clear all breakpoints and conditional breakpoints
  • :watch <expr> or :w <expr> — Add watchpoint on register, memory address, or condition (e.g. :watch R0, :watch mem[0x60])
  • :unwatch [expr] — Remove watchpoint or clear all watchpoints
  • :mark <name> — Create bookmark for current execution state
  • :'<name> or :goto <name> — Jump to bookmarked step
  • :c or :run — Continue execution to next breakpoint
  • :rc or :rev — Reverse continue execution backward
  • :set R<n> <val> — Live modify register value in current state (e.g. :set R16 42)
  • :poke <addr> <val> — Live modify memory value at address (e.g. :poke 0x60 255)
  • :exec <instruction> — Mini REPL: assemble and execute an instruction on the fly (e.g. :exec LDI R17, 88)
  • :mem <addr> or :m <addr> — Jump memory view to address (0x0060)
  • :find <text> — Search forward for instruction
  • :e [file] — Open Vim editor for file
  • :r or :reset — Reset to step 0
  • :h or :help — Show instruction reference modal
  • :q or :quit — Exit tiny8
  • <Esc> — Cancel command bar / close modal dialog

Examples

The examples/ directory contains programs demonstrating key concepts:

Example Description
fibonacci.asm Fibonacci sequence using registers
bubblesort.asm Sorting algorithm with memory visualization
diffusion_mnist8.asm Native 28x28 MNIST digit generation using an iterative reverse diffusion process
find_max.asm Finding maximum value in array
is_prime.asm Prime number checking algorithm
gcd.asm Greatest common divisor (Euclidean algorithm)

Bubble Sort

Sort 32 pseudo-random bytes in ascending order (RAM 0x60..0x7F):

tiny8 examples/bubblesort.asm

Using Python

from tiny8 import CPU, assemble_file

cpu = CPU()
cpu.load_program(assemble_file("examples/bubblesort.asm"))
cpu.run()

print("Sorted:", [cpu.read_ram(i) for i in range(0x60, 0x80)])

CLI Options

Command Syntax

tiny8 [FILE] [OPTIONS]

General Options

Option Description
-v, --version Show version and exit
-e, --edit Launch directly into Vim editor mode
--max-steps N Maximum execution steps (default: until infinite loop or halt)
-c, --compile-only Compile C program and print generated Tiny8 assembly without running

Interactive Controls (Textual TUI)

Key Action
Space Play / Pause auto execution
Shift+Space Reverse playback auto execution
n Step forward (+1 instruction)
p Step backward (-1 instruction, time-travel)
c Continue execution forward to next breakpoint
C (Shift+c) Reverse continue backward to previous breakpoint
b Toggle breakpoint on current instruction
: Open command line prompt (e.g. :goto <step>, :b <pc>, :q)
j / k (or J / K) Scroll memory viewport down / up by 32 bytes (or 128-byte fast page)
g Toggle Grayscale / Viridis color palette
x Toggle Hexadecimal digits (02X) / Graphic Pixel blocks
m Cycle view modes (Viridis+Hex -> Viridis+Pixel -> Grayscale+Pixel -> Grayscale+Hex)
e Launch full-screen Vim-style modal editor
h / ? Open TUI Application Usage & Keyboard Guide
i Open Instruction Reference modal (all 67 instructions)
+ / - Increase / Decrease playback speed
r Reset execution back to step 0
q Quit debugger

Instruction Set Reference

Tiny8's instruction set strictly adheres to the official Microchip AVR® Instruction Set Manual (DS40002198A). All mnemonics are case-insensitive. Registers are specified as R0–R31, and immediates support decimal, hex (0xFF), and binary (0b11111111) notation.

Data Transfer

Instruction Description (DS40002198A) Operation Example
LDI Rd, K Load Immediate Rd ← K (16 ≤ d ≤ 31) ldi r16, 42
MOV Rd, Rr Copy Register Rd ← Rr mov r17, r16
LD Rd, Rr Load Indirect from Data Space Rd ← (Rr) ld r18, r26
ST Rr, Rs Store Indirect to Data Space (Rr) ← Rs st r26, r18
LDS Rd, k Load Direct from Data Space Rd ← (k) lds r16, 0x0200
STS k, Rr Store Direct to Data Space (k) ← Rr sts 0x0200, r16
IN Rd, P Load an I/O Location to Register Rd ← P in r16, 0x3F
OUT P, Rr Store Register to an I/O Location P ← Rr out 0x3F, r16
PUSH Rr Push Register on Stack STACK ← Rr, SP ← SP - 1 push r16
POP Rd Pop Register from Stack SP ← SP + 1, Rd ← STACK pop r16

Arithmetic Operations

Instruction Description (DS40002198A) Operation Flags Example
ADD Rd, Rr Add without Carry Rd ← Rd + Rr H, S, V, N, Z, C add r16, r17
ADC Rd, Rr Add with Carry Rd ← Rd + Rr + C H, S, V, N, Z, C adc r16, r17
ADIW Rd, K Add Immediate to Word Rd+1:Rd ← Rd+1:Rd + K S, V, N, Z, C adiw r24, 1
SUB Rd, Rr Subtract without Carry Rd ← Rd - Rr H, S, V, N, Z, C sub r16, r17
SUBI Rd, K Subtract Immediate Rd ← Rd - K H, S, V, N, Z, C subi r16, 10
SBC Rd, Rr Subtract with Carry Rd ← Rd - Rr - C H, S, V, N, Z, C sbc r16, r17
SBCI Rd, K Subtract Immediate with Carry Rd ← Rd - K - C H, S, V, N, Z, C sbci r16, 5
SBIW Rd, K Subtract Immediate from Word Rd+1:Rd ← Rd+1:Rd - K S, V, N, Z, C sbiw r24, 1
INC Rd Increment Rd ← Rd + 1 S, V, N, Z inc r16
DEC Rd Decrement Rd ← Rd - 1 S, V, N, Z dec r16
MUL Rd, Rr Multiply Unsigned R1:R0 ← Rd × Rr Z, C mul r16, r17
MULS Rd, Rr Multiply Signed R1:R0 ← Rd × Rr (signed) Z, C muls r16, r17
MULSU Rd, Rr Multiply Signed with Unsigned R1:R0 ← Rd × Rr (Rd signed, Rr unsigned) Z, C mulsu r16, r17
NEG Rd Two's Complement Negation Rd ← 0x00 - Rd H, S, V, N, Z, C neg r16

Logical & Bit Operations

Instruction Description (DS40002198A) Operation Flags Example
AND Rd, Rr Logical AND Rd ← Rd · Rr S, V=0, N, Z and r16, r17
ANDI Rd, K Logical AND with Immediate Rd ← Rd · K S, V=0, N, Z andi r16, 0x0F
OR Rd, Rr Logical OR Rd ← Rd ∨ Rr S, V=0, N, Z or r16, r17
ORI Rd, K Logical OR with Immediate Rd ← Rd ∨ K S, V=0, N, Z ori r16, 0x80
EOR Rd, Rr Exclusive OR Rd ← Rd ⊕ Rr S, V=0, N, Z eor r16, r17
COM Rd One's Complement Rd ← 0xFF - Rd S, V=0, N, Z, C=1 com r16
CLR Rd Clear Register (Alias: EOR Rd, Rd) Rd ← Rd ⊕ Rd S=0, V=0, N=0, Z=1 clr r16
SER Rd Set Register (Alias: LDI Rd, 0xFF) Rd ← 0xFF None ser r16
TST Rd Test for Zero or Minus (Alias: AND Rd, Rd) Rd ← Rd · Rd S, V=0, N, Z tst r16
SWAP Rd Swap Nibbles Rd(7..4) ↔ Rd(3..0) None swap r16
SBI P, b Set Bit in I/O Register I/O(P, b) ← 1 None sbi 0x18, 3
CBI P, b Clear Bit in I/O Register I/O(P, b) ← 0 None cbi 0x18, 3

Shifts & Rotates

Instruction Description (DS40002198A) Operation Flags Example
LSL Rd Logical Shift Left (Alias: ADD Rd, Rd) Rd ← Rd ≪ 1 H, S, V, N, Z, C lsl r16
LSR Rd Logical Shift Right 0 → Rd7 … Rd0 → C S, V, N, Z, C lsr r16
ASR Rd Arithmetic Shift Right Rd7 → Rd7 … Rd0 → C S, V, N, Z, C asr r16
ROL Rd Rotate Left through Carry (Alias: ADC Rd, Rd) C ← Rd7 … Rd0 ← C H, S, V, N, Z, C rol r16
ROR Rd Rotate Right through Carry C → Rd7 … Rd0 → C S, V, N, Z, C ror r16

Control Flow & Branches

Instruction Description (DS40002198A) Condition / Target Flags Example
JMP k Jump PC ← k None jmp loop
RJMP k Relative Jump PC ← PC + k + 1 None rjmp -5
CALL k Long Call to Subroutine STACK ← PC + 1, PC ← k None call function
RCALL k Relative Call to Subroutine STACK ← PC + 1, PC ← PC + k + 1 None rcall -10
RET Return from Subroutine PC ← STACK None ret
RETI Return from Interrupt PC ← STACK, I ← 1 I reti
BREQ k Branch if Equal Z = 1 None breq done
BRNE k Branch if Not Equal Z = 0 None brne loop
BRCS k Branch if Carry Set C = 1 None brcs overflow
BRCC k Branch if Carry Clear C = 0 None brcc no_carry
BRLO k Branch if Lower (Unsigned) C = 1 (Alias for BRCS) None brlo lower
BRSH k Branch if Same or Higher (Unsigned) C = 0 (Alias for BRCC) None brsh same_or_higher
BRGE k Branch if Greater or Equal (Signed) S = 0 (N ⊕ V = 0) None brge positive
BRLT k Branch if Less Than (Signed) S = 1 (N ⊕ V = 1) None brlt negative
BRMI k Branch if Minus N = 1 None brmi negative
BRPL k Branch if Plus N = 0 None brpl positive

Compare & Skip Instructions

Instruction Description (DS40002198A) Operation Flags Example
CP Rd, Rr Compare Rd - Rr H, S, V, N, Z, C cp r16, r17
CPI Rd, K Compare with Immediate Rd - K H, S, V, N, Z, C cpi r16, 42
CPSE Rd, Rr Compare Skip if Equal Skip next if Rd = Rr None cpse r16, r17
SBRS Rd, b Skip if Bit in Register is Set Skip next if Rd(b) = 1 None sbrs r16, 7
SBRC Rd, b Skip if Bit in Register is Cleared Skip next if Rd(b) = 0 None sbrc r16, 7
SBIS P, b Skip if Bit in I/O Register is Set Skip next if I/O(P, b) = 1 None sbis 0x16, 3
SBIC P, b Skip if Bit in I/O Register is Cleared Skip next if I/O(P, b) = 0 None sbic 0x16, 3

MCU Control

Instruction Description (DS40002198A) Operation Flags Example
NOP No Operation None None nop
SEI Set Global Interrupt Flag I ← 1 I sei
CLI Clear Global Interrupt Flag I ← 0 I cli

Status Register (SREG) Flags

The 8-bit Status Register (SREG) contains condition flags updated by ALU instructions according to exact formulas defined in DS40002198A:

Bit Flag Name DS40002198A Formula & Meaning
7 I Global Interrupt Enable Set by SEI, cleared by CLI
6 T Bit Copy Storage Bit copy buffer for BST / BLD
5 H Half Carry Flag Carry/borrow between bit 3 and bit 4 (BCD arithmetic)
4 S Sign Bit True algebraic sign test: S = N ⊕ V
3 V Two's Complement Overflow Set when signed arithmetic overflows range [-128, +127]
2 N Negative Flag Set if MSB is 1 (N = R7)
1 Z Zero Flag Set if result is zero (R == 0)
0 C Carry / Borrow Flag Unsigned carry from MSB (R7) or borrow

Flags are used for conditional branching and tracking arithmetic results.

Assembly Syntax Notes

  • Comments: Use ; for line comments
  • Labels: Must end with : (e.g., loop:)
  • Registers: Case-insensitive R0-R31 (r16, R16 equivalent)
  • Immediates: Decimal (42), hex (0x2A), binary (0b00101010)
  • Whitespace: Flexible indentation, spaces/tabs interchangeable

Architecture Overview

CPU Components

  • 32 General-Purpose Registers (R0-R31) — 8-bit working registers
  • Program Counter (PC) — 16-bit, addresses up to 64KB
  • Stack Pointer (SP) — 16-bit, grows downward from high memory
  • Status Register (SREG) — 8 condition flags (I, T, H, S, V, N, Z, C)
  • 64KB Address Space — Unified memory for RAM and I/O

Memory Map

0x0000 - 0x001F    General-Purpose Registers (R0 - R31) / System Reserved
0x0020 - 0x005F    I/O Registers (64 ports: 0x00 - 0x3F via IN/OUT)
0x0060 - 0x01FF    User SRAM (general variables & arrays start at 0x0060)
0x0200 - 0x05FF    32x32 Heatmap VRAM (1,024 bytes, writable visual memory)
0x0600 - 0xFFFF    Extended User SRAM (general data, heap & downward-growing stack)

Testing

pytest                                    # Run all tests
pytest --cov=src/tiny8 --cov-report=html  # With coverage
pytest tests/test_arithmetic.py           # Specific test file

Contributing

Contributions welcome! See CONTRIBUTING.md for guidelines.

Areas for contribution: New instructions, example programs, documentation, visualizations, performance optimizations.

License

MIT License — see LICENSE for details.

Support


Made for learners, educators, and curious minds

Star the repo if you find it useful!

Explore related projects