A domain-specific language and runtime for spiking neural networks.
Write networks in .spk files. Run them in Python. Compile them to C for production.
spikeling/
├── __main__.py # Entry point
├── compiler/
│ └── compiler.py # .spk parser + C code generator
├── runtime/
│ └── runtime.py # Python runtime: LIF neurons, STDP, spike dispatch
├── stdlib/
│ └── neurons.spk # Standard neuron type presets
└── examples/
└── sound_localizer.spk # Binaural sound localizer demo
# my_network.spk
neuron LeftMic threshold=110 leak=5 type=LIF
neuron RightMic threshold=110 leak=5 type=LIF
neuron Motor threshold=80 leak=3 type=LIF
connect LeftMic -> Motor weight=0.8
connect RightMic -> Motor weight=0.8
action LeftMic -> [SOUND_LOCALIZED_LEFT]
action RightMic -> [SOUND_LOCALIZED_RIGHT]
action Motor -> [MOTOR_FIRE]
refractory=400ms
learn=STDP rate=0.01
| Directive | Description |
|---|---|
neuron <name> threshold=<int> leak=<int> [type=LIF] |
Define a neuron |
connect <src> -> <dst> weight=<float> |
Add a weighted synapse |
action <neuron> -> [<COMMAND>] |
Map a spike to a named command |
refractory=<int>ms |
Global refractory period |
learn=STDP rate=<float> |
Enable STDP learning |
| Type | Description |
|---|---|
LIF |
Leaky Integrate-and-Fire — fast, standard |
Izhikevich |
Cortical neuron model — burst firing, adaptation |
AdEx |
Adaptive Exponential — best realism/speed balance |
# Run default example (interactive)
python -m spikeling
# Run your own network
python -m spikeling path/to/my_network.spk
# Compile only, no interactive loop
python -m spikeling path/to/my_network.spk --no-interactive| Key | Action |
|---|---|
a / ← |
Stimulate first neuron |
d / → |
Stimulate second neuron |
q / ESC |
Quit |
Running any .spk file produces two C files next to it:
spikeling_hw.h — structs, constants, function declarations
spikeling_hw.c — neuron table, synapse table, spikeling_tick(), spikeling_stdp_update()
Compile for production:
gcc -O2 -o my_network main.c spikeling_hw.c -lmEach neuron maintains a membrane potential V. Each tick:
- Leak:
V -= leak(potential decays toward rest) - Input drive:
V += stimulus - Threshold check: if
V >= threshold→ fire, resetV = 0 - Refractory: neuron is silent for
refractory_msafter firing
Weights update based on the timing between pre- and post-synaptic spikes:
Δw = rate × exp(-|dt| / 20ms)
dt > 0 (pre before post) → strengthen (LTP)
dt < 0 (pre after post) → weaken (LTD)
Weights are clamped to [0.0, 1.0].
When a neuron fires, it walks all synapses where it is the source and adds weight × 50.0 to each downstream neuron's membrane potential. This can trigger cascade firing.
| Original | Spikeling |
|---|---|
| Random weights, never updated | STDP learning, weights change over time |
| Hash function dressed as a network | Real LIF dynamics with leak and threshold |
Windows-only (msvcrt) |
Cross-platform (Windows + Unix/Mac) |
| Monolithic C files | Modular: DSL → compiler → Python runtime → C output |
leak parsed but ignored |
Leak applied every tick |
| No synapse propagation | Weighted synapses, cascade firing |
-
type=Izhikevichruntime implementation -
type=AdExruntime implementation - Multi-layer network examples
- Audio input driver (mic → spike encoder)
- Spike train visualiser
- Weight persistence (save/load trained networks)