Institute for Physical AI @ BMI · ferrotherm

Thermodynamic sampling on an FPGA you can buy.

A new class of chip computes by drawing random samples with its own thermal noise. The physics is a century old and belongs to everyone. This page shows you how to build that machine yourself, on a 350 dollar board, in pure Rust, with no vendor toolchain anywhere in the path. Every number here was measured on real silicon.

What you are building

A binary stochastic neuron is a coin whose bias is set by its neighbours.

An ordinary bit is 0 or 1. The unit here is a coin that gets flipped over and over, and the only thing you control is how the coin is weighted. Its neighbours set that weight: the more of them that agree, the more strongly the coin leans one way.

You may have met this unit as a p-bit. That name was coined in 2016 and is now widespread in device physics, but the object is much older and has names in two established fields. We use the literature names on this page and give the full lineage below.

Drag the field below and watch the coin's bias follow it. This one curve, the sigmoid, is the entire computation a thermodynamic chip performs, repeated across hundreds of thousands of cells.

local field

Interactive. The bar is the running fraction of samples that came up +1.

Half the lattice can flip at once

If two neurons are not connected, nothing they do can disturb each other, so they may be updated at the same instant. Colour the grid like a checkerboard and every square of one colour is independent of every other. That is why this computation suits hardware: one sweep is two parallel half sweeps, not thousands of sequential steps.

temperature

Interactive. Lower the temperature and order appears on its own. Nothing here is scripted: the pattern is the sampler settling.

What to call it

One unit, a century of names.

Every name in the table below denotes the same object, and every field writes the same rule. Site i is set to +1 with probability

P(si = +1 | rest)  =  σ( 2β ( Σj Jij sj + hi ) )

which is the sigmoid you dragged above. The differences between the rows are vocabulary and discipline, not mathematics.

NameFieldWhere it comes fromStatus
spinstatistical physics Lenz 1920; Ising, Z. Phys. 31, 253 (1925)academic
Glauber dynamics, heat-bath updatestatistical physics Glauber, J. Math. Phys. 4, 294 (1963)academic
unit, binary unitneural networks Ackley, Hinton & Sejnowski, Cognitive Science 9, 147 (1985) academic
stochastic neuronfinite-temperature Hopfield nets Little 1974; Amit, Gutfreund & Sompolinsky, Phys. Rev. A 32, 1007 (1985)academic
sigmoid unit, unit of a sigmoid belief networkmachine learning Neal, Artificial Intelligence 56, 71 (1992)academic
binary stochastic neuron (BSN)deep learning; spintronics Bengio, Léonard & Courville, arXiv:1308.3432 (2013); Camsari, Sutton & Datta, Appl. Phys. Rev. 6, 011305 (2019) academic
p-bit, probabilistic bitdevice physics Camsari, Faria, Sutton & Datta, arXiv:1610.00377 → Phys. Rev. X 7, 031014 (2017)academic coinage
pbit, thermodynamic sampling unitcompany usage Extropic Corp. (2025)branded
stochastic number, bit streamcomputer arithmetic von Neumann 1956; Gaines, AFIPS SJCC (1967) different concept

Bold names are the ones this project uses. The last row is a false friend, explained below.

How the naming went

Lenz proposed the model in 1920 and his student Ising solved the one dimensional case in 1925, but that model was static: an energy over spins, with no rule for how they change. Roy Glauber supplied the dynamics in 1963, deriving the flip rate from the requirement that the chain settle to thermal equilibrium. His rule and a sigmoid resample are the same rule written two ways.

The unit entered machine learning through the Boltzmann machine, where Ackley, Hinton and Sejnowski called it simply a unit: "a unit is always in one of two states, on or off, and it adopts these states as a probabilistic function of the states of its neighboring units." Their own paper notes the physical parallel: such a system "in contact with a heat bath at a given temperature will eventually reach thermal equilibrium."

By 1992 the operation had its modern name. Neal's section 2.2 is headed "Gibbs sampling for Boltzmann machines," and his equation 5 gives the conditional as σ(x* Σj≠i sj wij), with the note that "the 'sigmoid' function, σ(t), is defined as 1/(1 + exp(−t))." That is the rule this project implements and, word for word, the rule the current hardware papers describe.

The term p-bit was introduced in October 2016 by Camsari, Faria, Sutton and Datta. It is a real academic term, now standard in device physics, and the same group made the identity explicit in 2019: their figure 2 is captioned "p-bit: Binary Stochastic Neuron." The coining paper had already said so, writing that its defining equations "are essentially the same as the defining equations for Boltzmann machines introduced by Hinton and his collaborators." What was new there was the hardware, a three terminal device with gain and input–output isolation, and the use of it for invertible logic. The unit itself was thirty years old and the physics sixty.

Extropic's unhyphenated pbit is company vocabulary layered on that coinage. Their peer-facing paper is the clearer guide to what they built: it does not use the word at all, describing each node as "a single Bernoulli random variable" advanced by "the Gibbs sampling update rule," and noting that Boltzmann machines are "also known as Ising models in physics."

One false friend

Stochastic computing, from von Neumann in 1956 and named by Gaines in 1967, is a different and older idea that the similar name invites you to conflate. There, a number is encoded as the fraction of ones in a long random bit stream, so that a multiply becomes a single AND gate. The randomness is a carrier you average away to recover an ordinary arithmetic answer. Here the randomness is the product: the unit's job is to draw a real sample, so that a network of them performs Markov chain Monte Carlo and visits states at their Boltzmann frequency. One is arithmetic done with probabilities, the other is sampling done by physics.

A footnote for the careful reader: Ackley, Hinton and Sejnowski describe their own sigmoid rule as "a form of the Metropolis algorithm." It is not. Metropolis accepts with min(1, e−ΔE/T); their rule is Glauber's. The slip has been repeated in textbooks ever since.

The board

Alchitry Pt V2.

An Artix-7 XC7A100T in a 484 ball package, with 63,400 six input lookup tables. Each lookup table can hold one neuron. A dual channel USB chip on the board speaks JTAG to the FPGA, which is the only wire you need: identify the chip, load a design, read its state back.

Diagram, not a photograph. Positions are schematic; part numbers and capacities are from the vendor listing and the AMD datasheet.

XC7A100T-2FGG484I

63,400 LUT6 · 126,800 flip flops · 4,860 Kb block RAM · 240 DSP slices. The package on the vendor listing reads FGG84I; the board's own schematic says FGG484.

FT2232H

Two USB channels. Channel A drives JTAG in MPSSE mode: four pins, TCK TDI TDO TMS. This is the entire interface used on this page.

Step by step

From an empty board to a fabric on silicon.

Six steps. Each one prints something you can check. The outputs shown are real, copied from a run against a Pt V2 driven over a network link from the other side of the world.

STEP 0

Install

Two crates, no dependencies beyond the USB transport. The core runs anywhere, including a browser; the silicon layer talks to the board.

cargo add ferrotherm
cargo add ferrotherm-silicon --features flash

STEP 1

Ask the chip what it is

Every FPGA holds a hardwired identity code. Reading it proves the whole path works: USB, the MPSSE engine, the JTAG state machine, and the chip itself.

$ cargo run --features flash --example probe

board: Alchitry Pt V2
IDCODE (JTAG DR):        0x13631093  -> XC7A100T
IDCODE (config port):    0x13631093
cross-check: PASS - two independent paths agree

Read the identity twice, by two unrelated mechanisms. If the packet layer were wrong they would disagree. A value you can predict is the right first thing to measure.

STEP 2

Prove the sampler is a sampler

Before trusting any hardware, check the mathematics against an answer nobody chose. Onsager solved the two dimensional Ising model exactly in 1944. Our sampler must reproduce it.

$ cargo run --release --example onsager

     beta  |M| sampled      M exact   |delta|
     0.50       0.9111       0.9113    0.0002  ok
     0.60       0.9736       0.9736    0.0000  ok
     0.70       0.9902       0.9902    0.0000  ok
verdict: PASS - sampler reproduces the exact 2D Ising solution

Four decimal places against a closed form from 1944. This gate runs before every release.

STEP 3

Build a fabric

Each neuron becomes one lookup table holding a stochastic threshold, placed into a real slice, with its couplings routed through real interconnect. The tool resolves every switch to physical configuration bits.

$ cargo run --release --example bsn_fabric -- $DB/xc7a100t/tilegrid.json ...

placing 8 binary stochastic neurons, one LUT6 each:
  neuron 0: CLBLL_L_X2Y102 site SLICE_X0Y102
  ...
stochastic-threshold LUT (threshold 3): INIT = 0xFFFEFEE8FEE8E880
8/8 truth tables written into frames
couplings routed: 7 (22 PIPs total), failed: 0
bitstream: 11,416 bytes, 26 frames, 398 configuration bits set
verdict: FABRIC EMITTED - every neuron placed, every coupling routed

STEP 4

Load it

Clear the configuration memory, stream the bitstream through the configuration port, release the startup sequencer. The status register tells you what happened at each stage.

$ cargo run --features flash --example config_trace

  at start          STAT=0x5000190C
JPROGRAM (clear configuration memory):
  after 20k clocks  STAT=0x00000000   the fabric is now blank
CFG_IN (stream the payload):
  after payload     STAT=0x601079FC   configured

The top digit of that status word encodes how the chip was configured: 5 after booting from its own flash, 6 after a load over JTAG. Comparing whole status words across different configuration paths will tell you a successful load failed.

STEP 5

Ask the silicon where the bits went

Read the configuration back out of the chip and compare it against a bitstream produced by a different toolchain entirely. This is the only version of the test that means anything: checking a readback against your own writes proves nothing, because a wrong address agrees with itself.

$ cargo run --features flash --example readback

reference: FAR 0x00000000, 25856 payload words (256 frames)
reading 4 frames from FAR 0x00000000...
404/404 words match (100.0%)
verdict: THE DEVICE AGREES

What it costs

Every sample has a price, and the price is mostly not the sample.

A thermodynamic chip is cheap per update and expensive per crossing. Using the published figures for one such design, a single node update costs about seven femtojoules, reading one node out costs the same as 239 updates, and writing one costs about 21,700. The architecture wins where many local updates happen between rare crossings, and loses where they do not.

operationenergyin updates
sample one node7.09 fJ1
read one node out1.692 pJ239
write one node153.6 pJ21,665

Pre silicon circuit simulation figures from the vendor's own appendix (arXiv:2608.01615, Table IV), not measured silicon. ferrotherm carries these as a swappable price list, so any workload can be costed in joules before it is built.

Measured on our side for comparison: the same sampler in a browser tab on a laptop GPU runs at 9.35 billion node updates per second, which puts it between 151 and 905 times the projected per update energy of the dedicated chip depending on the wattage you charge it. Two to three orders of magnitude, not the four often quoted. Both biases are stated: our figure covers the whole platform, theirs excludes input and output entirely.

Status

Roadmap.

Shipped

capabilityevidence
identify the chiptwo independent paths agree
load a design104 KB streamed over JTAG, chip reports configured
read configuration back404/404 words vs a foreign bitstream
place and route a fabric8 neurons, 7 couplings, 22 PIPs, 398 bits
sampler correctnessOnsager to four decimals
throughput, browser GPU9.35e9 node updates per second

In progress

The emitted fabric is combinational today: lookup tables and the wires between them. Two pieces turn it into a running sampler, and both sit on layers already built.

Sequential fabric

A flip flop per neuron to hold state, and a clock to advance it. Needs the AFF and AFFMUX configuration bits plus clock routing through a global buffer.

State readout

CAPTURE latches the flip flops into configuration frames, which the readback path on this page already reads correctly. No input or output pins required.

Next

The rest of the ladder

Alchitry Cu V2 and Au V2, Kria KV260, the M.2 Artix, Alveo U55C and AWS F2. The same fabric compiler, different chip databases.

Scale

Thousands of neurons per die rather than eight, and the energy ledger reported per completed sample rather than per update.