🧠 Tier: Standard Undergraduate · AI / Neuromorphic · Intel Loihi · snnTorch
§ 01
Interactive Simulation
Active Neurons
0
/ N
Mean Rate
0.0
Hz
Total Spikes
0
spikes
Sync Index
0.00
—
Mean w (STDP)
0.50
—
Sparsity
0.00
—
Sim Time
0
ms
Playback
Speed
Network Preset
Network Parameters
N neurons50
Input rate (Hz)50
τ_m (ms)20
Threshold V_th (mV)-50
Synaptic weight w0.50
STDP A+ (LTP)0.010
STDP A− (LTD)0.012
Noise σ0.5
T_sim (ms)500
Overlays
§ 02
The Idea, Step by Step
▸ From a quiet brain to spiking silicon
START — THE EVERYDAY PICTURE
An ordinary AI chip is like a classroom where every student shouts a number, all at once, every single second — exhausting and power-hungry. Your brain works the opposite way. Most of its ~86 billion neurons stay silent and only send a tiny electrical "blip" — a spike — when they actually have news to share. That habit is why your brain thinks on roughly 20 watts, less than a dim light bulb. A spiking neural network (SNN) is an AI built to copy it: stay quiet, speak in blips, save energy.
BUILD — ONE NEURON, IN WORDS AND ONE EQUATION
Picture a leaky bucket. Each incoming blip pours a little water in; a small hole lets water leak out between blips. The water level is the neuron's membrane potential $U$. When the level reaches a line called the threshold $\theta$, the neuron fires its own spike and the bucket empties (resets). In its simplest form, each timestep updates $U[t] = \beta\,U[t-1] + w\,X[t]$, and the neuron spikes whenever $U[t] \ge \theta$. Here $\beta$ is how much charge survives the leak: $\beta = 0.9$ means the bucket keeps 90% of its level every step, so old inputs fade and the most recent ones matter most.
DEEPEN — THE PRECISE LIF, LEARNING, AND ENERGY
On real hardware the leak factor comes from the membrane time constant: $\beta = e^{-dt/\tau_m}$, so a larger $\tau_m$ means a slower leak and a longer memory. Add the spike-reset explicitly and you get the chip equation derived in §03: $U[t]=\beta\,U[t-1]+W_{\text{in}}X[t]-S[t-1]\theta$. Learning relies on timing: with STDP, a synapse strengthens when its input spike arrives just before the neuron fires (by an amount $A_+$) and weakens when it arrives just after (by $A_-$). And because a synapse only spends energy when a spike actually travels down it, a network that is 99% silent — high sparsity — can be hundreds of times cheaper to run than a dense conventional network.
TRY IT — THREE EXPERIMENTS IN THE SIM ABOVE
(1) Choose the Synchrony preset, then drag Synaptic weight w from low to high and watch the grid switch from random flickering to coherent waves — strong coupling forces neurons to fire together, and the Sync Index climbs toward 1. (2) Pull Noise σ down toward 0 and watch the Sparsity readout rise as the network falls quiet. (3) Open the STDP Learning tab and nudge A− above A+: the green LTP curve stays shorter than the red LTD curve — the small asymmetry that keeps weights from running away.
STDP is the primary unsupervised learning rule for SNNs. Synaptic weight w changes based on the relative timing of pre- and post-synaptic spikes:
$$\Delta w = \begin{cases}A_+\, e^{-|\Delta t|/\tau_+} & \text{if } \Delta t = t_{\text{post}} - t_{\text{pre}} > 0 \quad \text{(LTP: pre before post)} \\ -A_-\, e^{-|\Delta t|/\tau_-} & \text{if } \Delta t < 0 \quad \text{(LTD: post before pre)}\end{cases}$$
Typical: \(A_+ = 0.01\), \(A_- = 0.012\) (slightly asymmetric for net depression), \(\tau_+ = \tau_- = 20\) ms.
Rate Encoding — stimulus intensity → spike count per time window T:
$$r = \frac{N_{\text{spikes}}}{T} \quad \text{(Hz)} \qquad \text{or for a Poisson neuron:} \quad P(\text{spike in }dt) = r \cdot dt$$
Temporal Encoding — stimulus intensity → time to first spike:
$$t_{\text{first}} = \tau_m \ln\!\left(\frac{I_0}{I_0 - V_{th}/R_m}\right) \quad \text{(time-to-first-spike in LIF)}$$
▸ Symbol Table
Symbol
Meaning
Unit / Range
Context
\(U[t]\)
Membrane potential at discrete timestep t
mV or normalised
LIF on chip
\(\beta\)
Membrane decay factor \(= e^{-dt/\tau_m}\)
[0,1]
snnTorch LIF
\(S[t]\)
Spike output (binary event)
{0,1}
All SNN models
\(\theta\)
Firing threshold
mV or normalised
All SNN
\(W_{\text{in}}\)
Synaptic weight matrix
Learnable
SNN training
\(\Delta t\)
Post-pre spike time difference
ms
STDP
\(A_+, A_-\)
STDP potentiation / depression amplitudes
Δw units
STDP
\(\tau_+, \tau_-\)
STDP time windows
ms
STDP
\(r\)
Firing rate
Hz (spikes/s)
Rate coding
\(t_{\text{first}}\)
Time to first spike
ms
Temporal coding
sparsity
Fraction of neurons silent in a given time bin
[0,1]
Energy efficiency
▸ Step-by-Step Derivation — From Biology to Silicon
STEP 1 — Why Spiking? The Event-Driven Advantage
Biological neurons communicate via sparse, asynchronous spikes, not continuous activations. In a typical cortical neuron, the average firing rate is ~1–10 Hz — meaning the neuron is silent ~99% of the time. This sparsity is the source of the brain's energy efficiency (~20 W for 86 billion neurons). Neuromorphic chips exploit this: computation only occurs when a spike arrives (event-driven). In contrast, conventional ANNs compute every neuron's activation at every timestep regardless of input — no sparsity, no event-driven efficiency.
STEP 2 — Discrete-Time LIF on Chip
The continuous LIF ODE \(\tau_m dV/dt = -(V-V_r)+R_m I\) is discretised with Euler for hardware: \(V[t] = V[t-1] + (dt/\tau_m)(-(V[t-1]-V_r) + R_m I[t])\). On neuromorphic chips, this is further simplified: the decay term \((1-dt/\tau_m)\) becomes the integer β, implemented as a bit-shift in digital hardware. Intel Loihi encodes β as a fixed-point number with 12-bit precision. The threshold θ is a programmable register. The entire LIF update is one multiply-add-compare operation per timestep per neuron.
STEP 3 — Information Encoding: Rate vs Temporal
Rate coding: stimulus intensity is encoded in the number of spikes per unit time. A LIF neuron with constant input I produces firing rate f(I) = 1/T_ISI(I) — the f-I curve. This is robust to noise but slow (requires ~100 ms window for reliable rate estimate). Temporal coding: information is encoded in the precise timing of spikes (e.g., time-to-first-spike, inter-spike intervals, phase relative to oscillation). This is faster (single spike carries information) but requires precise timing, which is sensitive to noise. Both codes coexist in the brain; the relative importance depends on the brain area and stimulus.
STEP 4 — STDP: Hebbian Learning in Spike Time
STDP implements "neurons that fire together, wire together" (Hebb, 1949) at the millisecond level. If a presynaptic spike arrives just before a postsynaptic spike (\(\Delta t > 0\)): the synapse potentiates (LTP) — the pre-synaptic neuron likely contributed to the post-synaptic firing. If post fires before pre (\(\Delta t < 0\)): the synapse depresses (LTD) — the pre-synaptic neuron is not causally related. STDP is implemented in all major neuromorphic chips (Loihi, TrueNorth, SpiNNaker) and enables unsupervised feature learning from spike trains without labelled data.
STEP 5 — Surrogate Gradient Training
The spike function S(U) = Θ(U-θ) is non-differentiable: its gradient is 0 everywhere except at θ, where it is ∞ (a Dirac delta). This makes standard backpropagation impossible. The surrogate gradient method replaces the true gradient with a smooth approximation during the backward pass only: \(\partial S/\partial U \approx \sigma'(U-\theta)\) where σ is a sigmoid or piecewise linear function. The forward pass still uses the hard threshold (producing binary spikes). This allows supervised training of SNNs with gradient descent while preserving the spike-based computation during inference.
STEP 6 — Energy Efficiency Analysis
Energy per synaptic operation (SOP): GPU/TPU execute multiply-accumulate (MAC) ops at ~pJ per op. Neuromorphic chips use accumulate-only (AC) ops for spikes: Intel Loihi 2 ≈ 23 fJ/SOP (50× more efficient than GPU). Total energy = (number of spikes) × (ops per spike) × (energy per op). Since sparsity ~1% of neurons active, effective energy = 0.01 × N_synapses × 23 fJ — compared to GPU: 1.0 × N_synapses × 1000 fJ. Net efficiency gain: ~5000×. This is why neuromorphic AI is critical for edge computing, IoT, wearables, and brain-computer interfaces where power budgets are milliwatts.
STEP 7 — Synchrony and Population Codes
When multiple neurons spike in synchrony (within a ~1–5 ms window), the postsynaptic neuron integrates their combined current efficiently — synchronised inputs are more effective than asynchronous inputs of the same mean rate. Synchrony index S = variance(population mean voltage) / mean(individual neuron voltage variance) measures population synchrony. S → 1: fully synchronised (epilepsy-like). S → 0: asynchronous irregular (normal cortical state). The simulation "Synchrony" preset shows how increasing synaptic coupling drives the network from asynchronous to synchronised firing.
▸ Worked Example — STDP Weight Update Calculation
A presynaptic neuron fires at t_pre = 10 ms, postsynaptic neuron fires at t_post = 13 ms. Parameters: A+ = 0.01, A− = 0.012, τ+ = τ− = 20 ms. Current weight w = 0.5.
If instead t_post = 7 ms (post fires 3 ms BEFORE pre): Δt = −3 ms → LTD: \(\Delta w = -0.012 \times e^{-3/20} = -0.0103\), w_new = 0.4897. The asymmetry (A− > A+) ensures net depression for random timing, preventing runaway potentiation.
▸ Primary References — Section 3
[Maa97]
Maass — Networks of spiking neurons: The third generation, Neural Networks 10(9):1659–1671, 1997.
[BI98]
Bi & Poo — Synaptic modifications in cultured hippocampal neurons (STDP), J. Neurosci. 18:10464, 1998.
[Esh21]
Eshraghian et al. — Training spiking neural networks using lessons from deep learning, arXiv:2109.12894, 2021.
[Dav18]
Davies et al. — Loihi: A neuromorphic manycore processor, IEEE Micro 38(1):82–99, 2018.
[Mer14]
Merolla et al. — A million spiking-neuron integrated circuit (TrueNorth), Science 345:668–673, 2014.
🔬 SimulationWhat does the "Network Activity" tab show, and what is the Synchrony Index?▼
The Network Activity tab animates a population of N LIF neurons as a 2D grid. Each neuron is drawn as a circle whose brightness represents its current membrane potential — dim blue when near rest, bright cyan when near threshold, flashing white/yellow when it fires. Connections between neurons are drawn as faint lines when a spike propagates. The Synchrony Index (SI) is computed each timestep as the variance of the population-averaged voltage divided by the mean of individual voltage variances: SI = Var(mean_V) / mean(Var_V). SI near 0: neurons fire asynchronously (normal cortical state — each neuron has its own rhythm). SI near 1: neurons fire synchronously (epilepsy-like; also seen in gamma oscillations). Drag the "Synaptic weight w" slider up — watch the network transition from asynchronous (random-looking activity) to synchronised (waves of firing sweeping across the grid).
Key takeaway: Network synchrony is controlled by synaptic coupling strength — weak coupling → asynchronous (high sparsity, efficient); strong coupling → synchronous (coherent, but epilepsy risk).
🌍 AppliedWhat are the key neuromorphic chips, and how do they implement LIF neurons in silicon?▼
The major neuromorphic platforms are: Intel Loihi 2 (2021) — 1 million LIF neurons, 120 million synapses, 31 mm² TSMC 4 nm, ~1 mW for typical workloads, programmable STDP on-chip, used for robotics and sparse signal processing. IBM TrueNorth (2014) — 4096 neurosynaptic cores, 256 LIF neurons each (1M total), 4096 spike inputs/outputs per core, consumes 70 mW at full utilisation — 400 billion synaptic operations per second per watt. Intel BrainScaleS-2 (Heidelberg) — analogue mixed-signal, runs 1000× faster than biological real-time. SpiNNaker 2 (Manchester) — digital ARM-core architecture, 10 million neurons. Each chip implements LIF as: voltage register U, threshold register θ, decay coefficient β (bit-shifted multiply), synaptic weight memory, and an output spike bus. One LIF update = 1 clock cycle = ~2 ns on Loihi 2.
Key takeaway: LIF on a neuromorphic chip is a hardware finite-state machine: three registers (U, β, θ) and one comparator — the entire neuron model in 6 transistors-worth of logic.
🧠 ConceptualWhat is the difference between rate coding and temporal coding in SNNs, and which does the brain use?▼
Rate coding represents information in the mean firing frequency over a time window (~50–100 ms). Advantages: robust to noise (averaging), simple to decode (count spikes). Disadvantages: slow, requires long time window, ignores millisecond-scale timing. Used by: primary visual cortex (orientation tuning curves), motor cortex (force encoding). Temporal coding represents information in precise spike times, ISI patterns, or phase relative to ongoing oscillations. Advantages: fast (single spike), high capacity. Disadvantages: sensitive to noise, complex decoder needed. Used by: auditory system (sound localisation via microsecond ITD), place cells (theta phase precession), cerebellar timing. Population coding represents information in the pattern of activity across many neurons simultaneously — combines rate and temporal information. The brain almost certainly uses all three codes in different areas; current SNN research in AI predominantly uses rate coding (easier to train) but temporal coding offers 10-100× efficiency gains if training methods mature.
Key takeaway: Rate, temporal, and population codes are not competing theories — they coexist in different brain areas. Most current SNN chips target rate coding; temporal coding SNNs are an active research frontier.
💡 Non-ObviousWhy does STDP have A− slightly greater than A+, and what happens if A+ > A−?▼
With random input spike trains (no correlation), a synapse experiences roughly equal numbers of LTP (pre before post) and LTD (post before pre) events. If A+ = A−, the random walk of the weight is neutral — weights drift randomly. If A+ > A−, random input causes net potentiation — all weights drift toward their maximum, eliminating selectivity and causing "runaway" potentiation (the network loses its ability to distinguish inputs). Setting A− slightly greater than A+ (by ~10–20%) creates a slight net depressive bias for uncorrelated inputs. Only when pre-post correlations are strong (the presynaptic neuron reliably predicts postsynaptic firing) does LTP win and the weight increase. This makes STDP a correlation detector: it strengthens synapses that carry predictive information and depresses those that do not. This is the biological implementation of Bayesian inference and causal learning — STDP preferentially strengthens "causal" synapses.
Key takeaway: The slight asymmetry A− > A+ makes STDP a causal correlation detector — it selectively potentiates synapses that are predictive of postsynaptic firing while preventing runaway potentiation from random noise.
📐 ComputationalWhy is the surrogate gradient needed for SNN training, and what makes a good surrogate?▼
The spike emission function S(U) = Θ(U−θ) (Heaviside step) has a gradient that is zero everywhere except at U = θ, where it is undefined (technically a Dirac delta). During backpropagation, the chain rule requires \(\partial \mathcal{L}/\partial W = (\partial \mathcal{L}/\partial S)(\partial S/\partial U)(\partial U/\partial W)\). The middle term \(\partial S/\partial U\) is zero almost everywhere, giving zero gradients — the "dead neuron" problem. The surrogate gradient replaces \(\partial S/\partial U\) with a smooth proxy during the backward pass only: the forward pass still uses the hard Heaviside. A good surrogate should: (1) be non-zero near threshold to pass gradients; (2) fall to zero far from threshold (to preserve sparsity); (3) be computationally cheap. Common choices: fast sigmoid ≈ 1/π(1+πU)², piecewise linear ≈ max(0,1−|U|), arctan ≈ 1/π(1+U²). The choice matters: too wide → dense gradients, too narrow → vanishing gradients.
Key takeaway: Surrogate gradient training is the key innovation that made SNN training competitive with ANNs — it "hacks" the backward pass to be differentiable while keeping the forward pass biologically realistic (binary spikes).
🎓 Deep / AdvancedHow does SNN sparsity provide energy efficiency, and what is the theoretical maximum energy advantage?▼
In a standard ANN, every neuron in every layer computes a multiply-accumulate (MAC) operation for every input sample — energy scales as O(N_neurons × N_weights). In an SNN, a synapse only needs to be updated when a presynaptic spike arrives — energy scales as O(N_spikes × N_weights/neuron). Since neurons fire at ~1–5% of their maximum rate (sparsity ~95–99%), SNN energy ≈ sparsity × ANN energy. Theoretical advantage: if sparsity = 1% and energy per accumulate (AC, no multiply needed for binary spikes) = 0.1 × MAC energy, then SNN energy ≈ 0.01 × 0.1 = 0.001 × ANN energy = 1000× advantage. In practice, overhead (routing, memory, control logic) reduces this to 10–100× on current chips. The "multiply" is eliminated because spike weights are summed, not multiplied with activations — this is the key arithmetic simplification. However, SNNs require multiple timesteps per inference (typically 10–100), which partially offsets the per-spike efficiency.
Key takeaway: SNN energy efficiency = sparsity × (AC/MAC energy ratio). Both factors contribute ~10–100×; combined they give 100–10,000× advantage over GPU for sparse, event-driven signals.
🧠 ConceptualWhat prevents SNNs from matching ANN accuracy on standard benchmarks, and what are the current frontiers?▼
Current SNNs typically achieve 80–85% accuracy on ImageNet vs 85–90% for comparable ANNs — a gap of 5–10%. The main challenges are: (1) Temporal credit assignment — errors must be propagated not just across layers (spatial) but also across timesteps (temporal), requiring backpropagation through time (BPTT), which is memory-intensive. (2) Surrogate gradient approximation error — the surrogate introduces gradient noise; optimising the surrogate shape is still an active research area. (3) Multi-timestep inference — SNNs require 10–100 timesteps per inference to accumulate enough spikes, adding latency. (4) Training instability — threshold annealing, batch normalisation for SNNs (tdBN), and weight initialisation remain challenging. Current frontiers: ANN-to-SNN conversion (convert pretrained ANN by mapping activations to firing rates), online learning with STDP+neuromodulation (reward-modulated STDP), and training with exact spike timing (SLAYER, STBP). As of 2025, the SNN-ANN accuracy gap is closing rapidly.
Key takeaway: The SNN accuracy gap is a training problem (surrogate gradients, temporal credit assignment), not a model capacity problem — the LIF network has sufficient capacity; the challenge is optimising it efficiently.
§ 04 Best Resources
snnTorch documentation — snntorch.readthedocs.io — best hands-on SNN tutorial in PyTorch
Eshraghian et al. (2021) — Training SNNs using lessons from deep learning — arXiv:2109.12894
Intel Loihi 2 — intel.com/neuromorphic — hardware specs and use cases
Neuromatch Academy — neuromatch.io — SNN and neural coding tutorials
Norse — norse.github.io — LIF and spiking models in PyTorch
§ 05
Misconceptions & Common Errors
Sub-block A — Conceptual Misconceptions
❌"SNNs are simply ANNs with spiking activations — you can replace ReLU with a Heaviside step function and get an SNN."
✅SNNs differ from ANNs in three fundamental ways: (1) Temporal dimension — SNN neurons have memory (membrane potential U[t] depends on U[t-1]); ANN neurons are memoryless. (2) Binary communication — SNNs communicate discrete spikes (0 or 1); ANNs use continuous real-valued activations. (3) Non-differentiable dynamics — the spike emission is discontinuous; backprop requires surrogate gradients. Simply replacing ReLU with Heaviside gives a network that is non-differentiable (zero gradients everywhere) and has no temporal dynamics — it is neither an SNN nor a functional ANN. A true LIF-SNN requires the recurrent membrane equation, the reset rule, multi-timestep processing, and surrogate gradient training.
📖 Eshraghian et al. (2021) arXiv:2109.12894, §2; Maass (1997)
❌"STDP is equivalent to Hebbian learning — 'neurons that fire together, wire together' means any correlated activity strengthens synapses."
✅STDP is causal, not just correlational. It strengthens a synapse only if the presynaptic neuron fires BEFORE the postsynaptic neuron (within ~20 ms), and depresses it if post fires before pre. Two neurons that fire simultaneously (Δt = 0) undergo both LTP and LTD — the net change is near zero. Simple Hebbian learning (correlation-based) does not distinguish causal order; STDP specifically detects the direction of causality. This makes STDP a temporal credit assignment mechanism: it identifies which presynaptic inputs are actually causing the postsynaptic spike vs which merely co-occur. This causal asymmetry is what allows STDP to learn directional temporal sequences — a property that simple Hebb rules cannot achieve.
📖 Bi & Poo (1998) J. Neurosci. 18:10464; Gerstner et al. — Neuronal Dynamics, Ch. 19
❌"SNNs are always more energy-efficient than ANNs for the same task."
✅SNNs are more efficient for sparse, event-driven inputs (e.g., neuromorphic cameras, tactile sensors, audio). For dense inputs (e.g., images where every pixel carries information), low sparsity eliminates the per-spike efficiency advantage. Additionally, SNNs require multiple timesteps (10–100) per inference to accumulate meaningful spike counts, adding latency and memory overhead. On standard GPU hardware, SNNs are often slower than ANNs because GPU architecture is optimised for dense matrix multiplication, not sparse event processing. The energy advantage is only fully realised on dedicated neuromorphic hardware (Loihi, TrueNorth). On a CPU or GPU, a naive LIF implementation may be 5–10× slower than an equivalent ANN.
📖 Davies et al. (2018) IEEE Micro 38(1); Eshraghian et al. (2021) §7
Sub-block B — Common Implementation Errors
❌Not implementing the reset after a spike in the discrete LIF: U[t] = beta*U[t-1] + W*X[t] — missing the - S[t-1]*theta reset term, causing U to accumulate indefinitely above threshold and fire every timestep.
✅The correct discrete LIF update includes the reset: U[t] = beta*(U[t-1] - S[t-1]*theta) + W*X[t] (subtract-reset) or equivalently U[t] = beta*U[t-1]*(1-S[t-1]) + W*X[t] (zero-reset). Without the reset term, U grows without bound after the first spike, producing a neuron that fires at every single timestep — completely destroying sparsity and biological plausibility. The snnTorch library provides both modes (reset_mechanism='subtract' or 'zero') and handles this correctly; custom implementations must include it explicitly.
🔍 Why students do this: Write the LIF recurrence from the ODE and forget the spike-triggered reset is a separate, discontinuous rule not present in the continuous ODE form.
❌Implementing STDP with a fixed pre/post spike time list, applying weight updates once at the end of the simulation — missing online learning and order-of-magnitude errors from temporal overlap.
✅STDP should be implemented as an online trace-based algorithm. Maintain two trace variables per synapse: a presynaptic trace \(x_{\text{pre}}\) that jumps by 1 at each pre spike and decays as \(dx_{\text{pre}}/dt = -x_{\text{pre}}/\tau_+\); and a postsynaptic trace \(x_{\text{post}}\) that jumps at post spikes and decays with τ−. Weight update: at each post spike, \(\Delta w = A_+ x_{\text{pre}}\); at each pre spike, \(\Delta w = -A_- x_{\text{post}}\). This online algorithm avoids storing full spike histories, handles multiple spike pairs correctly (without double-counting), and matches the biophysical implementation in Loihi. Batch STDP (updating once with stored spike lists) is numerically different and often incorrect for long simulations.
🔍 Why students do this: The Δw formula is defined per spike pair; extending it to many pairs by summing all pairs at the end double-counts contributions from nearby spike pairs.
❌Choosing the same β (decay factor) for all neurons regardless of τ_m when changing timestep dt: beta = 0.9 hardcoded — changes time constant when dt changes.
✅Always compute β from the desired τ_m and the actual dt: beta = Math.exp(-dt/tau_m). If you hardcode β = 0.9 and later change dt from 1 ms to 0.1 ms, the effective τ_m changes from −1/ln(0.9) ≈ 9.5 ms to −0.1/ln(0.9) ≈ 0.95 ms — 10× faster dynamics, completely changing the network's temporal integration properties. This is especially critical when converting between biological time (ms) and discrete timesteps (integer) — always track the conversion factor explicitly. In snnTorch: lif = snn.Leaky(beta=torch.exp(-dt/tau)).
🔍 Why students do this: β = 0.9 is the default value in most SNN tutorials; the connection to τ_m and dt is not always made explicit.
§ 05 References
Eshraghian et al. (2021) — Training SNNs using lessons from deep learning — arXiv:2109.12894
Davies et al. (2018) — Loihi — IEEE Micro 38(1):82–99
Merolla et al. (2014) — TrueNorth — Science 345:668–673