Blog
[every widget runs fn bodies of a t27 spec compiled to wasm; delays in lessons 1 and 26 are the reader's inputs, not device timing] Course 9 teaches the arithmetic an FPGA spends its area on, from the carry chain to a filter: adders, Booth multipliers and the DSP48E1 slice, fixed point, CORDIC, sampling, FIR and CIC filters, the FFT, and a capstone filter computed bit for bit. Five new specs in gHashTag/t27 carry the logic of 26 widgets, with 43 tests and 33 negative controls; the 27th runs the correlator of the existing modem spec.

Course 9 of t27.ai is out: Arithmetic and DSP on the FPGA, from the carry chain to a filter. It has 27 lessons in 9 modules, and each lesson opens a widget you play with: tap the bits of a sum, drag a vector, slide a tone between DFT bins, drop the coefficient bits of a filter. None of the 27 widgets computes anything on its own. Every value on the screen comes from a t27 spec whose fn bodies are compiled to WebAssembly, the same bodies the spec's own tests run.
| Module | Widgets | Spec |
|---|---|---|
| Adding numbers | carry-chain, prefix-adder, csa-tree | specs/fpga/dsp/adders.t27 |
| Multiplying | shift-add, booth-radix4, dsp-fit | specs/fpga/dsp/multipliers.t27 |
| Fixed point | q-format, round-sat, sqnr | fixed_point.t27, signals.t27 |
| Functions in hardware | cordic, cordic-vector, sine-table | specs/fpga/dsp/cordic.t27 |
| Signals and sampling | alias-fold, nco, dft-bin | specs/fpga/dsp/signals.t27 |
| FIR filters | fir-response, fir-design, fir-cost | specs/fpga/dsp/signals.t27 |
| Multirate | decimator, cic-growth, polyphase | specs/fpga/dsp/signals.t27 |
| The FFT | fft-butterfly, bit-reverse, fft-scaling | specs/fpga/dsp/signals.t27 |
| On the bench | barker-corr, fir-fit, fir-on-board | bpsk.t27, signals.t27 |
Each module's three widgets are offered under every lesson of the module, so a lesson opens on its own view and the whole lab is one tap away. The colours and controls are shared; the arithmetic is not shared with anything but the spec.
Five specs were written for the course in gHashTag/t27 (t27#8990): adders, multipliers, fixed_point, cordic and signals, with 43 tests and every vector recomputed in Python first. A few of the things they hold: 127 + 1 makes a carry run 7 bits; a 16-bit Kogge-Stone network needs 4 levels and 49 cells, Brent-Kung 7 levels and 26; radix-4 Booth turns the multiplier 6 into the digits -2, +2, 0, 0, and the spec checks it against a x b for all 65536 pairs of 8-bit numbers; 0.7 has no exact Q1.15 word, the nearest is 22938; CORDIC after 16 steps gives cos 30 degrees as 0.866018; a 4-stage CIC decimating by 8 grows 12 bits. Lesson 25 runs the correlator of the existing modem spec bpsk.t27 instead of writing a second one.
A spec whose tests pass for any body proves nothing, so each one was broken on purpose: 33 negative controls, from a carry computed as an OR to a twiddle exponent missing its stride, and every one turned a test red. Two of them did not on the first run, the CORDIC direction at a zero angle and rounding against truncation in the capstone filter; both got a boundary vector. The sine and the decibel are written once, in signals.t27, because every topic from quantization noise to the FFT needs them; t27c dupes --bodies finds no copy.
Work with me
I work contract and part-time on hardware-AI, FPGA/RTL and ML systems — from specification and open toolchains to reproducible measurements.