Binary Neural Networks on FPGAs: When a Look-Up Table Becomes the Neuron
Here is a genuinely strange idea: you can build a neural network with no multipliers at all. No floating point, no DSP blocks doing multiply-accumulate, not even integer multiplies. Just XNOR gates and a circuit that counts bits. And on an FPGA the payoff is beautiful, because a single look-up table, the basic atom of the chip, can become a neuron. This is the story of binary neural networks (BNNs), the most FPGA-native corner of AI hardware, and why the match is so good it feels like cheating.
If you have not met the deeper argument that an FPGA is already shaped like a neural network, start there. This post is the sharp, practical edge of it: what happens when you quantize a network all the way down to one bit.
The problem: multiplies are expensive
A neural network layer is, at heart, a lot of multiply-accumulate. Every output neuron computes a weighted sum of its inputs, sum(x[i] * w[i]), then applies an activation. Do that across a whole network and you are doing billions of multiplies. In hardware, a full 32-bit floating-point multiplier is big, power-hungry, and slow compared to plain logic. That is the single biggest cost of running AI on a chip.
The way out is quantization: use fewer bits for the weights and activations. Each bit you drop makes the multiply smaller and cheaper, and shrinks the memory you need to store the weights.
| Precision | Bits | The multiply becomes | Weight storage | Relative cost |
|---|---|---|---|---|
| FP32 | 32 | a floating-point multiplier | 32 bits | ~1000x |
| INT8 | 8 | an integer multiplier | 8 bits | ~64x |
| INT4 | 4 | a small integer multiplier | 4 bits | ~16x |
| Binary | 1 | an XNOR gate | 1 bit | 1x |
(Relative costs are illustrative, but the trend is real and dramatic.) INT8 is the workhorse of practical inference. But keep going, all the way to a single bit, and something magical happens to the arithmetic itself.
The binary trick: multiply becomes XNOR
In a binary network, every weight and every activation is just +1 or -1. We store that in one bit: let a bit value of 1 mean +1, and 0 mean -1.
Now look at what a multiply of two such values does. There are only four cases, and the product is +1 exactly when the two values are the same sign:
| bit a | bit w | a as ±1 | w as ±1 | product | XNOR(a, w) |
|---|---|---|---|---|---|
| 0 | 0 | -1 | -1 | +1 | 1 |
| 0 | 1 | -1 | +1 | -1 | 0 |
| 1 | 0 | +1 | -1 | -1 | 0 |
| 1 | 1 | +1 | +1 | +1 | 1 |
That last column is the punchline: the product is +1 exactly when the bits agree, which is the XNOR of the two bits. A multiply of +/-1 values is a single XNOR gate. One of the cheapest things a chip can do.
So the whole weighted sum collapses:
- Multiply becomes XNOR across the input and weight vectors.
- Accumulate becomes popcount: count how many bits agree. If
Pbits agree out ofN, then the real dot product is2*P - N(each agreement adds +1, each disagreement subtracts 1). - The activation (sign) becomes a threshold: the neuron fires when the dot product is positive, which is just "did the popcount clear a threshold?".
No multipliers. The entire neuron is XNOR gates feeding a bit-counter feeding a comparator. That is exactly the kind of logic an FPGA is built from.
Build one and watch it fire
Talk is cheap; here is a real binary neuron in Verilog. It takes an 8-bit input vector and an 8-bit weight vector, XNORs them, counts the agreements, and fires when the count clears a threshold. Edit the weights or threshold and press Run to see the neuron light up on the waveform:
Follow the signals: agree = ~(x ^ w) is the XNOR, the little loop counts the set bits into popcnt, and y goes high when popcnt >= thresh. That is a complete neuron, and it synthesizes to a handful of gates.
Why FPGAs love this: bit-parallel throughput
Here is where the FPGA wins big. Because each multiply is now a single-bit XNOR, you can pack many of them into one machine word and do them all at once. A 64-bit XNOR followed by a popcount computes 64 multiply-accumulates in essentially one clock, using a tiny slice of logic and almost no power. Widen the word and you scale further. A design that would need a bank of expensive multipliers in INT8 becomes a wall of cheap XNOR gates and popcount trees.
That is why binary inference on an FPGA can hit enormous throughput per watt: you are spending the chip's most abundant, cheapest resource (LUTs and simple logic) instead of its scarcest (DSP multipliers). For always-on, battery-powered, or latency-critical edge tasks, that trade is often exactly what you want.
Taken further: the look-up table IS the neuron
Now for the idea that makes this uniquely an FPGA story. A LUT computes an arbitrary Boolean function of its handful of inputs, whatever truth table you load into it. In a normal design you decide that truth table to implement AND, OR, an adder, and so on. But what if you let training choose the bits?
If the contents of a LUT are learned, the LUT stops being a fixed gate and becomes a tiny, trained function of its inputs: a neuron whose "weights" are the truth-table bits themselves. This is the direction behind research like LUTNet, and the broader family of BNN accelerators (such as Xilinx Research's FINN) that map binarized networks straight onto FPGA fabric. An FPGA has hundreds of thousands of LUTs, so in principle it can hold an entire binary network as pure, reconfigurable logic, no instruction fetch, no separate compute units, the network is the circuit.
The lineage of the core idea goes back to work like BinaryConnect / BinaryNet and XNOR-Net, which showed you can train networks with +/-1 weights and activations and still do useful work. The hardware community noticed immediately, because +/-1 arithmetic is a perfect fit for logic gates.
The catch: accuracy, and the honest middle ground
Binarizing is not free. Squashing every weight and activation to one bit throws away a lot of information, and accuracy drops, sometimes a little, sometimes a lot, depending on the task. A few things soften it:
- Ternary networks add a third value, allowing weights of
-1, 0, +1. The zero lets the network "ignore" inputs and recovers much of the lost accuracy for a small extra cost. - Scaling factors and batch normalization restore some of the dynamic range that pure +/-1 discards.
- Keeping the first and last layers in higher precision is a common, effective compromise.
Where do BNNs actually shine? Small, well-defined, always-on tasks: keyword and wake-word spotting, simple image classification, gesture and anomaly detection, sensor front-ends, anything where "good enough, tiny, and low-power" beats "state of the art." For larger models, INT8 is the pragmatic sweet spot, cheap enough to be fast, precise enough to keep accuracy. That is exactly what the neural micro-kit targets, with an INT8 MAC and activations, and why the fixed-point converter is a handy companion when you are choosing a quantization format.
Try it yourself
The binary neuron above is the whole idea in one runnable module. From there:
- Widen it: make
Nbigger and watch the popcount tree grow. That is bit-parallel MAC. - Chain neurons into a layer, then layers into a tiny network.
- Reach for the verified building blocks: the libfpga library has a
popcountmodule (the heart of the accumulate step) and the INT8 neural micro-kit for when one bit is not enough. - Simulate anything in the playground, no installs.
Binary networks are the clearest demonstration of why FPGAs and neural networks belong together. When the math is +/-1, the multiply is a gate, the accumulate is a bit-count, and the neuron is a look-up table. The chip does not run the network. The chip is the network.
Frequently asked questions
What is a binary neural network (BNN)? A neural network where the weights and activations are constrained to two values, +1 and -1, each stored in a single bit. This turns the usual multiply-accumulate into an XNOR followed by a popcount, which is extremely cheap in hardware.
Why are BNNs a good fit for FPGAs? Because +/-1 multiplies are just XNOR gates and the accumulation is a bit-count, both of which map directly onto the LUTs and simple logic an FPGA has in abundance, instead of the scarce DSP multipliers that INT8 or FP32 inference needs. A 64-bit XNOR plus popcount does 64 multiply-accumulates in about one clock.
How does XNOR replace multiplication? If bit value 1 represents +1 and 0 represents -1, then the product of two such values is +1 exactly when the bits are equal, which is the XNOR of the bits. So a +/-1 multiply is a single XNOR gate.
Do binary neural networks lose accuracy? Yes, quantizing to one bit reduces accuracy compared to INT8 or FP32. Ternary weights, scaling factors, batch normalization, and keeping the first and last layers in higher precision recover much of it. BNNs are best for small, always-on, low-power tasks; INT8 is the usual choice when accuracy matters more.
Should I use binary or INT8 for FPGA inference? Use binary/ternary for tiny, power- and latency-critical edge tasks where a modest accuracy hit is acceptable. Use INT8 for most real models, it is still very hardware-friendly and keeps accuracy close to floating point.