
riscv-5i
482 of 482 RISCOF tests, 1972 LUTs at 10 MHz
A 5-stage pipelined RISC-V core in SystemVerilog, checked against the RISCOF compliance suite, running on a Zynq-7000 and taken through a Sky130 layout.
I build digital and analog hardware: CPUs, small ASIC-flow designs, PCBs and the firmware that runs on them. Here's some of it.

482 of 482 RISCOF tests, 1972 LUTs at 10 MHz
A 5-stage pipelined RISC-V core in SystemVerilog, checked against the RISCOF compliance suite, running on a Zynq-7000 and taken through a Sky130 layout.

16-bit core, 18 mnemonics, five protocols
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.

STM32G474, three FDCAN, Rust core, Tauri app
CAN bus tooling: a desktop app, a scriptable CLI, and the firmware and board for an isolated CAN FD adapter, all on one Rust backend.

Gain of about 1000, three electrodes, RC low-pass
An op-amp front end on a breadboard that pulls the heartbeat out of three skin electrodes, with an RC low-pass for mains noise and an LTspice model to match.

1.5625 MHz mic clock, about 16 kHz PCM
A driver that gets the PDM microphones on Infineon's CY8CKIT-062S2-AI kit working under Zephyr, using the vendor's low-level library instead of ModusToolbox.

2 layers, 46 parts, 10-bit R-2R DAC
A two-layer Arduino Uno shield with an IMU, an OLED, buttons, pots, audio jacks and a 10-bit R-2R DAC, routed in KiCad from an instructor's template, plus a 5-bit breadboard DAC I measured on a scope.

2 layers, 46 parts, 10-bit R-2R DAC
A two-layer Arduino Uno shield with an IMU, an OLED, buttons, pots, audio jacks and a 10-bit R-2R DAC, routed in KiCad from an instructor's template, plus a 5-bit breadboard DAC I measured on a scope.

STM32F401, TB6612FNG, MPU6050, ESP-01
A self-balancing robot board that never came up. I hand-soldered it, debugged it over SWD, and traced the problem to the microcontroller's 3.3 V supply, though I never confirmed the cause.

STM32G474, three FDCAN, Rust core, Tauri app
CAN bus tooling: a desktop app, a scriptable CLI, and the firmware and board for an isolated CAN FD adapter, all on one Rust backend.

MAX 10 FPGA, Quartus 25.1, labs 1 to 4
Four lab sessions of Verilog on a DE10-Lite, from multiplexers and seven-segment decoders through adders, latches and counters, ending with a HELLO ticker running on the board.

Two layers, I2C sensors, microSD logging
A two-layer Arduino Uno shield for a weather balloon payload that logs acceleration, pressure, temperature and humidity to a microSD card, redesigned around parts you can still buy.

Manim, six scenes, 5 minutes, synthetic ECG
A five-minute animated explainer, made in Manim, of why 60 Hz mains hum wrecks an ECG and what a brick-wall low-pass and a moving average each do about it.

16 n-well resistors, 156.25 mV per step
A 5-bit R-2R DAC drawn as a chip layout in Electric VLSI, with the netlist pulled back out of the layout and simulated in LTspice against the ideal ladder across all 32 codes.

1.5625 MHz mic clock, about 16 kHz PCM
A driver that gets the PDM microphones on Infineon's CY8CKIT-062S2-AI kit working under Zephyr, using the vendor's low-level library instead of ModusToolbox.

482 of 482 RISCOF tests, 1972 LUTs at 10 MHz
A 5-stage pipelined RISC-V core in SystemVerilog, checked against the RISCOF compliance suite, running on a Zynq-7000 and taken through a Sky130 layout.

16-bit core, 18 mnemonics, five protocols
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.

Gain of about 1000, three electrodes, RC low-pass
An op-amp front end on a breadboard that pulls the heartbeat out of three skin electrodes, with an RC low-pass for mains noise and an LTspice model to match.

500 Hz, 100 nF, about -150 degrees at the top
An op-amp circuit with a potentiometer that shifts the phase of a 500 Hz sine without changing its amplitude, worked out by hand, simulated in LTspice and measured on a scope at three pot settings.

fc 1.59 kHz, bench within 0.4 dB of the sim
Low-pass, high-pass, second-order, band-pass and twin-T notch filters built from 1k and 10k resistors and 0.1 uF capacitors, each simulated in LTspice and then measured on a scope.

C1 3.3 uF, C2 33 uF, overdamped response
A two-capacitor circuit that behaves like a drug dose spreading into the bloodstream and clearing out, solved by hand, simulated in LTspice and measured on a scope.

Uno, RC522 over SPI, 4-byte card match
A card reader that lights a green LED for the right card and sounds a buzzer for the wrong one, built on an Arduino Uno with an RC522 module, plus a few smaller sensor labs.