TEC30 ("Tiny Embeddable Controller", formerly miniSPU) is a byte serial
arbitrary precision memory-to-memory softcore CPU in SystemVerilog, plus a native assembler
(astec30) and an SDCC C backend.
Every instruction is a 4-byte memory-to-memory operation. There is no accumulator, no operand register and no register file: operands name page-0 cells (or immediates), and a compiled program is one flat image.
The core is 160 LUTs on a Xilinx Artix-7 (189 with the UART). The ALU and the full core are exhaustively proven equal to behavioural references with SymbiYosys.
| Path | Contents |
|---|---|
rtl/tec30.sv |
The bare core: a Q-bus master with IBUS/DBUS channels |
rtl/tec30_pkg.sv |
The Q-bus contract, variant tags and memory map |
rtl/tec30_reset.sv |
Power-on reset + button sync |
rtl/mem/ |
Memory models: tec30_mem_harvard, tec30_mem_modified |
rtl/periph/ |
Q-bus peripherals (page 0xFF): uart |
rtl/tec30_soc.sv |
The composable system: core + memory model + peripherals |
rtl/boards/ |
Board tops (tec30_x7u) = reset + soc parameter set |
rtl/tec30_ds_*.sv |
Spec-sheet parts (bare / pure / hybrid Harvard) |
sim/ |
Behavioural memory model + Xilinx primitive stubs |
formal/ |
SymbiYosys equivalence proofs and the behavioural reference |
tb/ |
iverilog testbenches |
xdc/ |
Basys 3 pin constraints |
scripts/ |
Vivado TCL and image tools (mkimg.py, splitimg.py) |
compiler/astec30/ |
The native assembler, runtime library and ISA docs |
examples/ |
Firmware for the board (PalMon, hello, UART) |
prebuilt/ |
A frozen PalMon image, so the C board builds without SDCC |
The SDCC port is not in this repository; it is developed separately and
submitted upstream. compiler/astec30 is self-contained.
A variant name is a parameter set on tec30_soc, nothing more:
| Variant | ALU_IMPL |
peripherals |
|---|---|---|
TEC30X7 |
0 (X7) |
none (bare core) |
TEC30X7U |
0 (X7) |
HAS_UART=1 |
TEC30G / TEC30GU |
1 (generic) |
— |
The memory model is the core's one personalization axis: Harvard
(tec30_mem_harvard, code ROM + data RAM in separate arrays) or
modified-Harvard (tec30_mem_modified, one dual-port RAM, so a DBUS write
is fetchable). Peripherals are Q-bus slaves that own a sub-range of page 0xFF
(MMIO); the UART owns 0xFF00-0xFF02. tec30_soc computes the page-0xFF
select once, owns the DBUS handshake, and muxes the slaves.
- ISA 4-byte big-endian instruction:
[31:24]opcode,[23:16]dst,[15:8]src1,[7:0]src2. Opcode bits:[3:0]ALU op,[4]invert,[5]no-writeback,[6]src1 immediate,[7]src2 immediate. Addresses arePAGE:ADDR(16-bit). ALU ops:ADD/SUB, AND, OR, XOR, ASR, LSR, LSL, CSL. - JAL / RET
JALstores the return address as two bytes and jumps; a return is an indirect conditional jump after a force-Z. Calls, returns and comparisons are synthesized in software, not in hardware. - Memory independent IBUS and DBUS Q-bus channels, synchronous 1-cycle
reads.
sim/mem_model.svis the behavioural reference used by the proofs.
Needs Icarus Verilog and
SymbiYosys (sby).
make sim # tb_alu + tb_cpu + tb_board (UART smoke test)
make formal # alu_equiv + cpu_equiv (SymbiYosys)
make sim_ds # pure vs hybrid datasheet equivalence
make sim_c # PalMon (prebuilt image) on the real RTL
make sim_mem # modified-Harvard memory (a DBUS write is fetchable)
make test_astec30 # assembler FSX emitter tests
make synth # synthesis-only of the core (Vivado)
make vivado # bitstream of tec30_x7u
make vivado_c # bitstream of tec30_x7u with the PalMon image baked inprebuilt/ holds a frozen image of examples/palmon.c (PalMon, a serial
monitor), so make sim_c and make vivado_c run without the SDCC toolchain.
Rebuilding the image from source (make image) needs the external SDCC port.
The bitstream itself is not committed: build it with make vivado_c.
make -C compiler/astec30
compiler/astec30/astec30 -f dum -o prog.dum prog.asmcompiler/astec30/asm.md documents the assembly text grammar. sim.py runs a
.dum image in a small interpreter.
I shall defend myself from the slop-hunters in this brief section here. Yes, there's an AGENTS.md in this folder, but I'd like to specify this is not "slop". I designed every bit of hardware logic, specified every compiler optimization, wrote code myself. I used an LLM (specifically DeepSeek) to assist me in filling some gaps and write tests, check VCDs and not much more. I have proof of the lengthy development of this in my github pages site, so check it out if you wanna look at what I do.
CERN Open Hardware Licence Version 2 — Strongly Reciprocal (CERN-OHL-S-2.0). Every source file carries the licence header.