Project write-up · 2026
A valve on learning.
Keep the old task. Learn the new one. Do it with shifts, a local latch, and a write budget — and say clearly what ran in Python versus what exists in Verilog.
Abstract
Aegis is a control policy for cheap spike-timing learning: a local 8-bit protect latch plus a write budget on power-of-two STDP. The point is not a better floating-point neural net. It is a mechanism that can keep an old class-incremental task while still learning a new one, using only integer arithmetic a small FPGA datapath could run.
On a split-pattern protocol (4 classes, 2 sequential tasks, seed 0), a matched shift-STDP baseline finishes at 46% average because it wipes Task 1. Full Aegis finishes at 85%, with 75% of the old task kept and 95% of the new task learned, at about half the synaptic writes. Those numbers are from an integer Python golden model. Verilog implements the same tick/present policy on a tiny net (co-sim). A KiCad IMU/power carrier is the sensor harness. This is not a chip, and not a live bitstream of the 32-input protocol.
The problem in plain language
Imagine teaching a small on-device network one lesson, then a second lesson, then asking about both. That is continual learning. The usual failure is catastrophic forgetting: lesson two overwrites lesson one.
Cheap spike-timing-dependent plasticity (STDP) is attractive for an FPGA because it is local — if two neurons fire close together, the synapse between them moves a little — and because a power-of-two version needs a shifter, not an exponential. It also forgets. Teach classes 0–1, then classes 2–3, then test both: matched power-of-two STDP hits 92.5% on the new task and 0% on the old.
Software consolidation methods such as EWC (Kirkpatrick et al., 2017) usually want a task identity flag and extra memory of what mattered on the old task. A tiny on-device circuit may not have that oracle. Published FPGA STDP cores typically make the update cheap. They do not decide what not to overwrite. That gap is the project.
The idea
Treat learning like a valve. Wide open, the network is a goldfish: it learns whatever arrived last. Shut, it is stubborn: it keeps the old class and starves the new one. Aegis tries to sit in between, with no task-ID pin.
Each labeled sample ticks an 8-bit protect value P on the neuron that should own that class. High P raises the firing threshold and turns down incoming current, so a weakly overlapping new pattern does not steal the old neuron. If that were the only knob, the network would freeze too hard. A write scheduler spends a limited budget of synapse updates on neurons that are still unlatched and unstable. Latched, stable synapses stay frozen.
How it works
Four integer blocks. No floating point. No task-ID oracle.
-
Power-of-two STDP. If two spikes are close in time, change the synapse a little; closer means a bigger change.
Δw = ±A >> k(Δt)with A+ = 16, A− = 4. This alone learns the latest lesson. -
Protect latch. Labeled samples raise 8-bit
P. Effective threshold isθ + P. Incoming current is scaled by(256 − P) >> 8. STDP freezes whenP ≥ 140or stability ≥ 128. That is the shut valve. -
Dual-timescale LIF. A fast membrane that spikes and a slow one meant to hold context, mixed in UQ8. In this experiment spikes are decided on the fast membrane (
V_fast), so dual-τ does not separate from protect-only. Do not claim the slow membrane from this table. - Energy / write scheduler. A window of 32 ticks. Spikes cost 1, weight updates cost 4, soft budget 512. Over budget, only low-stability, unlatched neurons keep writing. That is the partly-open valve.
Python mtstdp is the source of every accuracy number. Verilog mtstdp_core follows the same tick/present policy (V_fast spike, protect increment, LTD/contrast, scheduler). Tiny-net co-sim: LTP 40→56, LTD 40→36, protect +2. Output winner-take-all is simultaneous in Python and sequential in RTL, so co-sim vectors keep at most one output spike. The 32-input tables remain simulator results, not a bitstream.
The experiment
Class-incremental split-pattern: 4 classes, 2 sequential tasks, seed 0, 40 train / 20 test, 2 epochs, 32 input wires, 16 timesteps, one output neuron per class. After each task the model is tested on every task it has seen. That grid is the R matrix. Forgetting is how much Task 1 drops after Task 2 (Chaudhry-style).
The baseline is not a weaker algorithm. It is the same shift-STDP with latch, dual-τ, and scheduler switched off. Protect-only turns the latch on. Dual-τ adds the slow membrane. Full Aegis adds the write budget.
A second split, synthetic gestures, uses overlapping IMU-like codes. It is a stress test, not live captures from the carrier board.
Result
These rows are Python simulator measurements of the 32-input split-pattern protocol.
| Mode | T1 after T1 | T1 after T2 | T2 after T2 | Forget | Writes |
|---|---|---|---|---|---|
| Baseline STDP | 90% | 0% | 92.5% | 0.90 | 104,311 |
| + Protect / θ | 95% | 100% | 30% | −0.05 | 73,803 |
| + Dual τ | 95% | 100% | 30% | −0.05 | 73,803 |
| Aegis full | 75% | 75% | 95% | 0.00 | 52,059 |
Final average 85% vs 46%, at half the synaptic writes. Read the rows as three students. Baseline learns the new quiz and blanks the old one. Protect-only keeps 100% of Task 1 and only 30% of Task 2 — stubborn. Full Aegis is the partly-open valve: 75% old, 95% new, forget 0.00. Protect-only forgetting is −0.05 because Task 1 rose 95% → 100% after Task 2 (Chaudhry’s peak excludes the last row). Dual-τ is identical to protect-only here; spikes on V_fast do not isolate the slow membrane.
On synthetic gestures, protect-only is stronger (~67.5% final). Full Aegis can over-throttle (~50%). The write budget that helps on split-pattern can starve learning when class codes overlap. That plot belongs in the talk, not in a footnote.
Yosys maps the default 4-neuron / 8-input core to 17,426 generic cells. That is a size sketch for a tiny net, not FPGA utilization of a 64-neuron array, and not ASIC milliwatts.
What was built around the algorithm
Think of three layers. Accuracy lives on the first. The others show the policy is a candidate for hardware, not that it has already run on a board.
-
Python golden model (
python/mtstdp) — integer network, protocol, ablation. Config is the single source of bit widths, leaks, latch, and budget. Runmake experimentto regenerate the table. -
Verilog RTL (
rtl/,tb/) — STDP ALU, LIF slice, protect increment, LTD, scheduler, AXI-Lite weight readback. Icarus tests pass, including tiny-net co-sim. PYNQ-Z2 and Arty A7 pin constraints exist. No bitstream is loaded onto hardware. - KiCad carrier — 80 × 50 mm 2-layer board: Digilent PMOD JA, GY-521 IMU, USB 5 V Schottky-ORed with discharge-only LiPo, AP2112K-3.3, 10 mΩ shunt, INA219 @ 0x40. ERC 0, DRC 0. J3 is not a charger. Board current is not chip milliwatts.
Conclusions, takeaways, contribution
The scientific claim is a mechanism, not a leaderboard. On this integer split-pattern run, a local protect latch without a write budget keeps the old task and barely learns the new one. Adding a write budget is what opens the valve far enough to learn Task 2 while still holding most of Task 1, and it does that at about half the synapse writes of matched STDP. Dual-τ did not earn a separate claim on this protocol. Overlapping codes can reverse the ranking: protect-only wins on gestures, so the scheduler is a trade-off, not a free lunch.
Takeaways
- Forgetting is the default of cheap STDP, not a bug in the baseline. The matched shift-STDP control learns the new class-incremental task and drops the old one to 0%. Any “FPGA STDP core” that only accelerates that update will inherit that amnesia.
- Protect without a budget is the stubborn student. Raising θ and cutting gain is enough to keep Task 1. It is not enough to keep learning. The interesting operating point is the partly-open valve, not the freeze.
- The accuracy table is Python. Verilog matching on a tiny net is evidence that the policy fits in a datapath. It is not board-level accuracy, not a bitstream, and not milliwatts of a die.
- The board is a harness. PMOD, IMU, USB/LiPo, 3.3 V, current sense. Useful as a system story. Not the learning chip, and J3 is discharge-only.
Contribution
The contribution is a local, integer continual-learning policy for power-of-two STDP — protect latch plus write scheduler, no task-ID oracle — measured in a golden model, with RTL that closes the same loop on a tiny net, and a DRC-clean IMU/power carrier for the eventual sensor path. Relative to software consolidation, it refuses extra Fisher memory and a task flag. Relative to FPGA STDP literature, it treats “what not to overwrite” as the design problem, not the multiply. The honest scope is a 4-class / 2-task mechanism demo plus co-sim and PCB, not a deployed on-device learner.
Reproduce
python3 -m pip install -r requirements.txt
make pytest && make sim && make experiment
github.com/krishharma/aegis-mtstdp · Briefing · Markdown: docs/WRITEUP.md