Ready SD card image
One card holds every design on this page: the PYNQ 3.0.1 image for the STEMlab 125-14 (Ubuntu 22.04) from Pynq-Redpitaya-125, with the FPGA bitstreams, their Python drivers and Jupyter notebooks, and the control service that loads a design at power-up added. Write it to a card of 8 GB or more.
Download rpfpga-sd-20261110-6178370.img.zip
SHA-256: 2f9f544b5e712a4b93aec632de055d6b1ad2427a9a8ae805c32e366daa0f3fdb
Check the download with sha256sum rpfpga-sd-20261110-6178370.img.zip.
Write the card
With balenaEtcher (it takes the
file as downloaded), or on Linux: find the card with lsblk (the whole
card, e.g. /dev/sdX, not a partition; everything on that device is
overwritten) and run
unzip -p rpfpga-sd-20261110-6178370.img.zip | sudo dd of=/dev/sdX bs=4M conv=fsync status=progress
First power-up
- Connect Ethernet and power. On the first boot PYNQ enlarges its file system to the whole card.
- The board takes an address from your network's DHCP server and also answers at the fixed 192.168.2.99 (for a direct cable, give your computer an address in 192.168.2.0/24).
- Jupyter:
http://<board>:9090, passwordxilinx; each design has its notebook with a control panel. - SSH:
ssh xilinx@<board>, passwordxilinx: change it withpasswd, add your key withssh-copy-id. - About two minutes after power-up the control service (TCP port 5025) loads
analog_echo; switch designs from the notebooks or with
LOAD.
Calibrate once
Until the board is calibrated (loopback cables and a voltmeter; chapter "Calibration" of the common documentation), voltages use nominal converter constants, which were about 13 % off on our board. The calibration belongs to the board and serves every design.
Before connecting lab equipment
Read the full list ("Connecting to lab equipment" in the common documentation) before connecting laser drivers, piezo or modulator drivers or cryogenic wiring. In short:
- For about two minutes after power-on the FPGA is not configured and the outputs are undefined; then the service loads a design and restores its last settings.
- Loading a design starts an uncalibrated state: a unity passthrough (mult_add, analog_echo), a 10 MHz sine (atomic_clock) or everything off (synth, awg, lockin, feedback, timetagger, ajku, counter, spin, boxcar).
- Outputs reach about ±1.13 V at DC; at 10 MHz a 1 MΩ load sees about twice the set amplitude. Calibration drives the outputs by itself (about ±0.83 V).
- PID controllers (lockin, feedback) move outputs on their own; mult_add, awg, lockin, feedback, spin and boxcar have hardware output limits that can be locked until the FPGA is reloaded; spin also has a duty guard per transmitter for power amplifiers.
- Extension-connector pins are 3.3 V and not 5 V tolerant; never drive a pin that a design uses as an output. timetagger's, counter's and boxcar's inputs on E1 take 3.3 V logic: terminate 5 V TTL detectors in 50 Ω, and keep NIM (negative) pulses off E1 (counter counts them on IN1 and IN2). The SATA connectors are 1.8 V FPGA pins, not SATA ports.
Designs
The board runs one design at a time; switching takes a few seconds. Each design has a reference PDF (its README, recipes, theory, control protocol, registers and test records); the larger ones also have user's and theory manuals.
| Design | Version | What it does |
|---|---|---|
| mult_add | 3.0 | two-input analog computer: weighted sums of 13 functions of the inputs, filters, comparators, clamps, meters |
| analog_echo | 1.0 | gain and offset for both channels |
| atomic_clock | 3.2 | 10 MHz source with programmable phase and phase noise, 1 PPS, phase meter |
| synth | 2.1 | 16 phase-coherent tones per output, ramps and timed sequences |
| awg | 3.0 | function, pulse, noise and arbitrary waveform generator with eight digital outputs |
| lockin | 1.0 | four-demodulator lock-in amplifier with oscillators, PIDs and PLLs |
| feedback | 2.0 | lock box: full-rate PIDs, scan and relock, slow analog I/O, TTL reference |
| timetagger | 2.0 | ten-channel time tagger: picosecond timestamps streamed to the PC, g2, TCSPC, coincidences |
| ajku | 1.0 | two-channel CW I/Q analyser: continuous exact statistics, histograms and spectra, raw captures for noise and quantum-optics analysis |
| counter | 1.0 | gated photon counter: per-point sums, on-board decisions, coincidence clusters, NIM inputs |
| spin | 1.1 | pulsed RF transceiver: pulse programs, echoes averaged on the board, single-shot decisions, a spin and qubit emulator |
| boxcar | 1.0 | pump–probe boxcar averager and segmented scope: gated shots, ΔT/T per delay point, electronic delay scans, averaged traces |
mult_add 3.0
A two-input analog computer.
- Inputs conditioned into X and Y: source IN1, IN2 or a test level; gain −128 … +128 and offset
- Each output a weighted sum of 13 terms: X, Y, |X|, |Y|, X·Y, X/Y, X², Y², min, max, sign(X), sign(Y), constant
- Per output: gain and offset, then an optional full-rate first-order low-pass filter (τ from 11.5 ns to 8796 s)
- Optional Schmitt comparator with independent thresholds and output levels
- Saturation, mute and a final voltage clamp that can be locked until the FPGA is reloaded
- Every sample at 125 MSa/s with a fixed pipeline delay of 456 ns (608 ns with X/Y)
- Built-in meters (mean, RMS, minimum, maximum of IN1, IN2, X, Y, OUT1, OUT2) over 8 µs … 1 s; clip flags and counters
- Measures the board calibration (loopback cables and a voltmeter), used by every design
- Presets: passthrough, inverted, sum/difference, multiplier, squarer, ratio, rectifier, comparator, min/max, quadratic
- Worked lab recipes: multiplier and mixer, filtered lock-in output, laser-power normalization, error-signal conditioning, envelope detector, threshold detection
- Jupyter panel, Python API, command line and TCP commands
Status: version 3.0 passed simulation and build verification (2026-10-05); it has not yet been tested on a board (version 1.0 was).
analog_echo 1.0
Gain and offset for both channels.
- OUTn = gainn · INn + offsetn on each channel, sample by sample at 125 MSa/s
- Gains and offsets in volts at the connectors, through the shared board calibration
- Gain about ±128 in steps of about 0.4 %; offset in steps of about 35 µV
- Range about ±1.13 V in and out (LV jumper; HV inputs ±20 V nominal)
- Fixed delay of 32 ns in the FPGA; gain and offset of a channel change together, in one clock cycle
- Presets: passthrough, inverted, notebook; safe state (0 V) and reset (unity gain)
- Jupyter panel, Python API, command line and TCP commands
Status: checked on the board with a voltmeter (offsets within 0.5 mV, 2026-10-04); it cannot read its inputs, so it has no automated hardware test.
atomic_clock 3.2
A 10 MHz source that simulates the phase of a real clock, from microseconds to a year.
- 10 MHz sine, exactly 2/25 of the sample clock: OUT1 the simulated clock, OUT2 a clean reference
- OUT1's phase: unwrapped, steps of 2−64 cycle, range ±231 cycles; approached smoothly or stepped
- Frequency offset ±10−3 with 6.8·10−19 resolution, integrated exactly; drift and aging
- White phase and frequency noise generated in the FPGA, new every 8 ns sample, optional dither
- Flicker PM, flicker FM, random-walk FM, sinusoidal PM and recorded time-error series, played by the board's service
- Ready settings for 11 real oscillators (crystal, TCXO, OCXO, MEMS, rubidium, caesium, hydrogen maser, GPS-disciplined OCXO) and six faulty clocks for demonstrations
- 1 PPS outputs of the simulated clock and of the reference (3.3 V), optionally on a UTC second
- 10 MHz I/Q phase meter on IN1 and IN2, windows of 200 ns … 1 s; in loopback 29 fs per 10 ms window
- Stability recordings on the board; analysis tools on a PC (Allan and related deviations, three-cornered hat, a live dashboard)
- Amplitudes and offsets in volts at the connectors; presets reference, quadrature, off
- Jupyter panel, Python API, command line and TCP commands
Status: version 3.2 runs on the board; the quick test series passed, and the one-day loopback floor is 1.2·10−13 at 1 s and 2.9·10−17 at 18 h; the long series has not been run yet.
synth 2.1
A 16 + 16 tone phase-coherent synthesizer.
- 16 tones per output, each with its own frequency (0 … 62.5 MHz in 0.44 µHz steps), amplitude and phase
- All phases relative to one zero time shared by both outputs: returning to a frequency restores its phase
- Any set of tones on both outputs changes on one sample
- Linear and shaped (cos², Blackman, minimum-jerk) frequency and amplitude ramps with exact endpoints; chirps
- Timed sequences in the FPGA, repeated by the FPGA; longer ones streamed by the service
- TTL trigger input and marker output (3.3 V)
- Amplitude modulation of each output by IN1 or IN2 in real time
- Clean synthesis: digital spurs below −95 dBc (computed), optional dither
- DAC droop corrected; output response and OUT1–OUT2 skew measured in loopback and corrected
- Input capture, tone measurement and spectra for self-tests in loopback
- Presets: off, 10mhz, quadrature, comb5, schroeder16; Jupyter panel, Python API, TCP commands
Status: version 2.1 passes all 32 loopback checks on the board (2026-10-22); spectrum-analyzer measurements have not been made.
awg 3.0
A two-channel function and arbitrary waveform generator with eight digital outputs.
- Two outputs on one 125 MSa/s time base; phases relative to one zero time; both outputs change on one sample
- Sine, square, pulse, ramp/triangle, PRBS (7–31 bits), DC and tables (Gaussian, Lorentzian, sinc, exponential, your own)
- Rise and fall times adjustable separately from 6.4 ns; edges placed in sub-sample steps (no 8 ns jitter)
- A second generator per output, added to it or used as the modulation source
- Gaussian noise with an adjustable flat bandwidth, 1 Hz … 47.7 MHz
- AM or DSB with FM, PM, PWM, FSK or BPSK, by the second generator, IN1, IN2 or the other output
- Linear, logarithmic, list and profile sweeps with a marker at a chosen frequency
- Bursts of N cycles from a start to a stop phase; gated bursts
- Triggers: two pins timed to 1 ns, four event pins, input thresholds, software, two timers, the other output; delays in 31 ps steps
- Arbitrary waveforms from the board's memory: up to 16 M point pairs at a fractional rate up to 125 MSa/s, smooth, linear or step reconstruction
- Sequences with repeats, waits for a trigger, goto and gapless jumps on events
- I/Q at baseband or upconverted to a carrier, with gain, quadrature and offset corrections
- Eight digital outputs: patterns, binary and Gray counts, PRBS, aligned with the analog outputs
- Two marker outputs (sync, burst or sweep state, sweep marker, start pulse) with adjustable delay
- Hardware voltage limits per output, lockable; optional dither
- Input capture for loopback checks; binary uploads at 8–12 MB/s
- Presets: off, sine, square, pulse, iq, noise, am, sweep, burst; Jupyter panel, Python API, TCP commands
Status: version 3.0 passes all 57 loopback checks on the board (2026-10-24).
lockin 1.0
A four-demodulator lock-in amplifier with oscillators, PID controllers and phase-locked loops.
- Four oscillators, 0 … 62.5 MHz in 0.44 µHz steps, switched phase-continuously or coherently
- Two outputs: sums of the oscillators' sines, an offset, a monitor of any reading, lockable voltage limits
- Four demodulators on IN1, IN2 or IN1 − IN2, at a harmonic (up to 1023) or a sideband m·fA ± fB; sine or square reference
- Low-pass filters of 1 to 8 RC sections (6 … 48 dB/octave), τ from 0.5 µs to 106 s
- X, Y, R, θ, unwrapped phase and dθ/dt in volts at the connectors; phases referred to the OUT1 connector
- Four PIDs to an oscillator's frequency or phase, an output's amplitude or offset: PLLs, amplitude and offset loops, hold, lock detection
- Continuous data stream of X and Y; four-channel capture with triggers; frequency counter
- Auto-phase, PLL set-up, nested sweeps with a resonance fit (f0, Q), input spectra
- Zoom spectrum around the reference, noise density, automatic time constant, Allan deviation
- SR86x-compatible TCP port: programs written for an SR860/SR865 drive it
- Measured: R within 0.02 % of the captured input from 1 kHz to 10 MHz; input noise 84–90 nV/√Hz at 1–10 MHz
- Presets: off, loopback, harmonics, pll; Jupyter panel, Python API, TCP commands
Status: version 1.0 passes all 38 checks on the board (2026-10-27).
feedback 2.0
A lock box built on lockin's core.
- Two fast PIDs at 125 MSa/s from IN1, IN2, IN1 − IN2 or a demodulator's mixer product (Pound–Drever–Hall, dither locks)
- P, I and D with two low-pass sections and output limits; about 232 ns from connector to connector (236 ns measured in loopback)
- Two lock acquisitions: triangle scan, engage at a level, relock after a loss
- Two oscillators and two demodulators from lockin: harmonics, sidebands, 1–8 RC sections, X, Y, R, θ, dθ/dt
- Two outputs: oscillators' sines, offset, fast PIDs and scans, monitor, lockable limits
- Four slow PIDs on readings, the inputs' means or the slow inputs, to oscillators, outputs or slow outputs
- Slow analog outputs AO0–AO3 (0 … 1.8 V nominal) and inputs AI0–AI3 (0 … 7 V nominal), calibrated like the fast ones
- Status pins: locked, scanning, scan direction, PID locked, clipping
- TTL reference input timed to 1 ns: PLL to an external clock, also at N/M of its frequency
- Sync output: an oscillator's square wave with 2 ns edges
- 1 ns capture trigger; data stream, four-channel capture, frequency counter
- PI gains tuned from the measured loop for given phase and gain margins; the closed loop measured
- Sweeps with a resonance fit, spectra; presets off, loopback, harmonics, pll; Jupyter panel, Python API, TCP commands
Status: version 2.0 passes all 66 checks on the board (2026-10-27).
timetagger 2.0
A ten-channel time tagger on the FPGA's carry chains.
- Ten channels: DIO0_P–DIO7_P (3.3 V) and the two SATA S2 pairs (1.8 V differential)
- Tapped delay lines in the carry chain, 160 taps of about 30 ps sampled at 250 MHz; 0.98 ps ticks, 60-bit times
- Self-calibration without wiring (code density on an on-chip ring oscillator), refined from the channels' own hits
- Times referred to the connectors: Vivado's path delays with the bitstream, their scale and each line's polarity offsets measured on the test signal
- Rising, falling or both edges, toggle inputs for narrow pulses, dead time, dividers, offsets
- Eight 1 ns markers on DIO0_N–DIO7_N for gates, line and frame clocks
- Coincidence engine in the FPGA: clusters on any eight channels, 4096 pattern counts, eight masks, virtual channels, a marker gate; beyond the stream's rate (60 Mevents/s tested)
- Conditional filter on channels 1 and 2: an 80 MHz laser sync kept only when a detector fires within 120 ns
- Acquisitions started now, at a given sample or armed on a PPS; hardware duration
- A ring in DDR and a compiled pump: 7 Mevents/s sustained to a PC, bursts of 10 Mevents/s, every loss counted
- Host library (C++ with Python): live g2 correlations, start-stop histograms (TCSPC), coincidences, rates, recordings
- 10 MHz reference on IN2 (I/Q phase meter) or any channel; timestamps in reference time; ADEV, TDEV and MTIE of a tagged clock or PPS
- Self-tests: a phase-stepped test signal into all channels and out on SATA S1; an event generator
- Measured: 15 ps rms per channel on clean external edges (9–12 ps on the internal test signal); two channels' calibrations agree to 6–14 ps rms over the period
- Presets: off, detectors, all, test, generator; Jupyter panel, Python API, TCP commands
- A user's manual with time tagging in quantum labs: g2, TCSPC, HOM, QKD with clock recovery from the photons, clock comparison against a GNSS-disciplined oscillator
Status: version 2.0 passes all 89 checks on the board (2026-10-30).
ajku 1.0
A CW I/Q analyser for two balanced receivers or any pair of simultaneous I/Q voltages.
- Both inputs at 125 MSa/s with all 14 bits kept; every result tied to sample indices, the board calibration and its configuration
- Continuous exact statistics in every 8.4 ms block: integer sums through fourth order (cumulants, excess kurtosis, κ22 without gaps), extrema, rail counts
- Continuous FPGA spectra: 1024-point Hann frames of z = I + iQ through a bit-exact FFT, exact sums per 134 ms epoch; I/Q auto and cross spectra, complex and complementary spectra to 25 MHz in 122 kHz bins, at 100 % duty
- Full-rate 64×64 joint and two 1024-bin marginal histograms, zoom windows set in volts, out-of-window counts; reading never stops acquisition
- Raw captures of paired codes into the board's memory (8 MiB by default, 32 MiB tested), also started at a given sample; an internal counter source for exact digital self-tests
- PPS edges on DIO0_P and the slow inputs AI0–AI3 recorded with every statistics block
- A statistics stream to the PC with every loss, gap and invalid slot counted
- On the PC: the full I/Q spectral matrix with coherence and phase, signed and complementary spectra, converter-skew correction
- Distributions: joint and marginal views, ECDF, Q–Q, tails, Gaussian residuals; third- and fourth-order cumulants with batch-jackknife errors
- Amplitude, power and complex lag correlations with batch errors; an optional exact FIR filter and decimation beside the raw products
- LO-power sweeps fitted with A + B P + C P² from independently measured powers
- Drift monitoring of the statistics stream with threshold rules and follow-up captures; Allan deviations of the statistics and slow inputs
- Saved references with provenance checks, recorded runs, HDF5 export; live Jupyter dashboard, Python API, TCP commands
- Measured on the board: one hour of full analysis with 1,657 captures and 429,551 exact statistics blocks, none lost; FPGA spectra within 0.4 % of PC spectra of captures; control replies p99 141 ms
- A user's manual: operation, continuous-variable quantum optics (coherent, squeezed and non-classical states, Wigner and Husimi distributions, detection topologies) and procedures for characterizing your own receiver chain
Status: version 1.0 passes the digital board qualification, including a one-hour workload without loss (2026-11-03). Optical and analogue performance are characterized by the user on their own receiver chain.
counter 1.0
A gated photon counter: the detection half of pulsed experiments.
- Eight count inputs on DIO0_P–DIO7_P sampled every 1 ns, rising or falling edges, a non-paralyzable dead time of 8 ns … 65 µs and a delay of 0 … 255 ns per channel
- IN1 and IN2 as two more count channels: a discriminator at a threshold in volts with a hysteresis, positive or NIM-like negative pulses, the crossing interpolated to 1 ns, aligned with the pins through the board calibration
- 48-bit totals, never cleared; RATE records whose consecutive differences are exact intervals in every channel
- Shots from TRIG (DIO0_N from a pulse generator, an internal timer or software); up to 1024 points per shot, per NEXT or fixed; sweeps from SEQ, checked for lost or extra TRIGs
- Four gates per shot (delay and width in 1 ns steps up to 4.3 s, half-open), each on a set of channels, optionally inside an external GATE level; a delay step per point for time traces without histograms
- Per-point sums of every gate, the shots, the decisions and n1² in two banks, collected by the board's service into 64-bit totals: hours of averaging without the PC
- Two decisions per shot: a count window on each of two gates, any logic of the two; a level, pulses or an early signal on an output pin about 114 ns after the gate (simulated)
- Two coincidence units of up to four channels: timetagger's clusters (8 … 1023 ns), the 15 exclusive patterns in 48-bit totals, inside G1 or not; the second delays one channel by up to 16 µs to count the accidentals directly
- Per-shot records (point, flags, time, counts) and the patterns in RATE records, streamed to a PC: 2 million records/s without loss to a client on the board
- Outputs on DIO4_N–DIO7_N: decisions, gates, TRIG echoes, a channel's clean echo, coincidence heralds, the rate alarm, patterns (2 ns bits)
- Rate monitors on OUT1/OUT2 in volts for alignment, or test pulses for the analog inputs
- A built-in test emitter on any channel: independent, paired (a delayed copy) or split (antibunched) events, bright or dark per shot from a table of the points, with a decay
- Analysis: NV contrast, Rabi, Ramsey, exponential and Lorentzian fits, two-Poisson thresholds and fidelities, g2(0), Grangier's α, visibility, CHSH
- Presets and recipes: NV Rabi, readout traces and ODMR with awg on a second board, ion and atom state detection, preselection, HBT, heralded g2, Bell
- Measured: coincidence patterns as simulated over 13 million clusters; exact counts of 39 million shots from awg's patterns; decisions 105 ns after the gate's end; a preselection loop through awg in 356 ns; IN1/IN2 aligned with the pins within 0.5 ns
- Jupyter panel (with the gates' timing, count distributions and the coincidence table), Python API, TCP commands
Status: version 1.0 passes its board tests and a session with awg on a second board and an oscilloscope (2026-11-05); no real detector was used.
spin 1.1
A pulsed RF transceiver for teaching pulsed NMR, NQR and ESR, and for qubit readout at an intermediate frequency.
- A pulse program on the board: 1024 instructions of 16 ns … 34 s, four nested loops, four tables indexed by the loop counters, WAITs on a trigger, a timer or software, branches
- TRIG on DIO0_P time-stamped to 1 ns: with re-referencing the RF phase follows each edge (0.28 ns rms against an asynchronous trigger, measured)
- Two transmitters to about 50 MHz: eight phase-coherent frequency registers, phases and amplitudes in volts, envelope shapes (amplitude and phase), linear chirps
- Two real outputs or one I/Q pair for an IQ mixer, with each transmitter's Q gain and phase and DC levels; lockable output limits and a duty guard per transmitter
- Two receivers on IN1, IN2 or IN1 + i IN2, mixed with either transmitter's oscillator: coherent by construction, an order-2 CIC from 8 ns to 131 µs per point, exact 90° receiver phases
- Eight windows started by the program; on-board averaging into two halves that swap without dead time, collected by the service into 64-bit sums; regions per array point and phase-cycle step
- Weighted integration at the full rate (1024 complex weights per receiver, a matched filter): one value in volts and a state per shot, as RESULT records streamed to a PC
- Decisions on the board: a branch on a window's state, on COND A/B or a loop counter's parity, decided to the clock; a window's state on a digital output
- Eight digital outputs: TTL bits, power-amplifier gates with lead and lag, capture and shot markers, states (2 ns steps); AO0–AO3 set by the program (field sweeps)
- A built-in emulator answering the transmitters: one qubit with a dispersive readout, or a spin ensemble with a line drawn per shot; bit-exact with its Python model and within 0.1 % of the Bloch equations
- Templates: FID, Hahn echo and T2, CPMG, NQR spin-locked echo trains, inversion and saturation recovery, nutation, ESR echo-detected field sweeps; Rabi, Ramsey, T1, single-shot readout, active reset, repeat-until-success
- Analysis: spectra with the receiver's droop corrected, phasing, fits of T1, T2, T2*, Rabi and Ramsey, populations, single-shot fidelity
- Measured on the emulator: T2* 8.000 µs (8), T2 by CPMG 40.04 µs (40), T1 10.00 µs (10), Rabi 0.999 MHz (1), readout fidelity 0.987, active reset leaving 0.03 excited
- Presets and recipes: the emulator's experiments, a loopback pulse, an NMR probe with a gated amplifier, ESR through an IQ bridge, qubit readout and active reset
- Jupyter panel (sequence view, experiments with fits, averages, I/Q blobs), Python API, TCP commands, a bit-exact model of the whole core
Status: version 1.1 passes its board tests with OUT1 → IN1 and OUT2 → IN2 (2026-11-08); no probe, bridge, spin sample or qubit was used.
boxcar 1.0
A boxcar averager and segmented scope for pump–probe experiments with amplified and high-repetition lasers.
- Shots from a TTL trigger time-stamped to 1 ns (glitch filter, hold-off), an analog level on IN1 or IN2, the internal timer or software; missed shots counted
- Categories per shot: a chopper's reference with a guard band (shots at its edges invalid) or a pattern the board drives onto a modulator
- Eight gates per shot on IN1 or IN2 (8 ns … 524 µs, from 65 µs before the trigger), exact integrals; D1 and D2 with baseline gates of any width, Q = D1/D2 against a reference detector
- Exact sums per delay point and category (Σx, Σx², ΣD1·D2, pump-on/off pairs), totalled over sweeps by the board's service: ΔT/T with its error per point
- Every shot's gates at up to 2.6 MHz (2.016 MHz measured, no shot missed); SHOT records with the values streamed to a PC
- Eight pulse outputs (2 ns steps, per category, 16 pending pulses each) and four markers: the board as the master, firing pump, probe and modulator
- Electronic delay scans from a 1024-entry table (linear, logarithmic, shuffled) with the gates following the probe; a hold for a PC-driven delay stage
- Averaged traces of IN1 and IN2 per category without dead time (up to 4096 points), single snapshots, every raw segment written to the board's memory
- Boxcar outputs on OUT1 and OUT2: a running average per category (on, off, or their difference) of any value, in volts, within lockable limits
- A test source on OUT1/OUT2 emulating a laser and a sample with a programmed ΔT/T(τ), for a cable loopback
- Measured with awg on a second board as an asynchronous laser: every shot taken to 1.95 MHz, ΔT/T within 4·10−4 of awg's; through the loopback: a 5 % decay over 41 delays within 0.00044; Q removes 20 % shared laser noise to 0.16 %; the gates equal the raw segments' sums exactly
- Presets (amplified laser with a chopper, high-repetition laser with a modulator, master delay scan, delay stage, two signals, scope, loopback demonstrations) and recipes
- Jupyter panel (shot timing, traces with the gates, the pump–probe curve), a live window for a PC, Python API, TCP commands, a bit-exact model of the whole core
Status: version 1.0 passes its board tests with OUT1 → IN1, OUT2 → IN2 and two jumpers (2026-11-09); no laser or detector was used.
Guides
Documents about several designs at once: two or three boards, each running a different design, connected and controlled as one experiment.
Common documentation
The board, its specifications and limits, connecting lab equipment, setting up a board and a build machine, the calibration shared by all designs, the control service and its commands, and the framework for building and adding designs.
Acknowledgements
Everything here stands on two open-source projects by Pau Gómez (dspsandbox), and we are very grateful that he made them freely available.
FPGA Notes for Scientists
A wonderful hands-on introduction to FPGA programming, written for scientists with little or no FPGA experience: simple, working, open-source examples on the Red Pitaya with PYNQ, each adding one new concept, from blinking an LED and simulating a design to an analog echo and DMA transfers. This project grew out of its LED blink and Analog echo tutorials. analog_echo still follows the Analog echo tutorial, and every design here uses its converter interface: the ADC, DAC and clock IP blocks and the board constraints, included under its MIT license. If you want to learn how designs like these are made, start there.
PYNQ for the Red Pitaya STEMlab 125-14
A careful port of the PYNQ framework to the Red Pitaya, with a ready-to-use SD card image, the Vivado board files and a documented build process. It is what lets these designs be loaded and controlled from Python and Jupyter on the board. Our SD card image is its PYNQ 3.0.1 image with the designs added, and the designs are built with its board files.