All projects

smallcore

Hardened 2026

Hardened through the Tiny Tapeout IHP CMOS5L flow at 6x4 tiles with zero DRC, antenna and LVS violations. I have not submitted it for fabrication, and this page does not claim a run on a board.

A small programmable protocol engine in Verilog, in the style of a PIO block. It runs UART, SPI, I2C, SWD and CAN from tiny programs, and I have taken it through a real ASIC flow.

The final chip layout rendered from the GDS, with vertical power stripes, dense magenta and red routing in the middle and blue fill around the edges

The chip

A host writes bytes into a TX FIFO, picks one of the programs in a ROM, and the core runs that program on a handful of pins: UART, SPI, I2C, SWD or CAN. The core has 16-bit instructions with a per-instruction delay, four output pins that are push-pull or open-drain, four input pins, output and input shift registers, and a 16-bit accumulator with optional LFSR feedback. That is eighteen mnemonics in eight opcodes.

The RTL is Verilog-2001. A Python model of the core is the golden reference, and cocotb benches under Verilator run the RTL in lockstep with it.

What's inside the chip

Where it started

It started on paper, with one box: a host byte goes in, a program is loaded, and GPIO comes out. Then three questions, each answered with the least hardware that would do the job.

The first box
Something to hold a program, something to say which instruction runs, and something to turn bytes into bits
Those parts joined up, with a FIFO each way between the host and the pins
The control unit as first drawn
The first five opcode groups. The final instruction set has eighteen mnemonics
The datapath once it had a ROM and RAM, four host registers and the stall points

How I worked on it

Past I2C, every question about the instruction set was an experiment. For SWD, CAN and CRC I came up with a set of candidate instructions, had AI implement them on the golden model, and ran them against the tests and the real protocol programs I already had. Then I read the numbers and decided. Nothing reached the RTL until it was adopted, and I kept the rejected ones with a date and the reason. The articles below are those records:

Verification

The model has 3893 pytest tests, including a sweep of every 16-bit word. The RTL benches run each protocol program at the pins, with the bench acting as the far end of the wire, and several of them were shown to fail under a deliberate mutation before I kept them.

Physical results

All numbers are from the Tiny Tapeout IHP CMOS5L flow at 6x4 tiles, post-route, at a 20 ns clock, worst of the nominal corners. Every hardened row so far has zero routing DRC, Magic DRC, antenna and LVS errors.

Milestone Synthesized cells Routed cells Utilization Setup slack
Protocol engine v2 1894 2403 3.52% +7.20 ns
With a writable 256 by 16 program RAM 23330 31816 55.37% +1.10 ns

The picture at the top of this page is the GDS from that last run, drawn in KLayout with the IHP layer colors. The v2 run still has 26 max-slew violations at the slow corner, on three nets of the ROM’s address decode. The physical results article has every milestone and how each number is measured.

Articles

  1. Choosing a repeat instruction
    Comparing ways to repeat a run of words; REPEAT count, label became opcode 111.
  2. CAN candidates
    Comparing run-test instructions for CAN; SKIP_RUN and SKIP_NORUN were adopted and the others rejected.
  3. CRC baselines
    Can the core as it is compute CAN's CRC-15? No: the state is eight bits wide and the computation needs fifteen.
  4. CRC candidates
    Comparing state architectures against that width wall; the 16-bit accumulator was adopted.
  5. CAN combined
    A whole Classical CAN frame fits in 256 words at 8 clocks a bit; arbitration needs the identifier in the program.
  6. CAN stress test
    A whole CAN node's data path fits, one program per job; the node's judgement does not.
  7. 10BASE-T Ethernet
    An experiment on the frozen core: the transmitter works at 40 MHz with host-side encoding; fixed-timing receivers lose long frames.
  8. Physical results
    Cells, area, utilization and timing from the Tiny Tapeout flow for every RTL milestone.

Source on GitHub