Technology
FPGA Feedback Controller
A complete closed-loop feedback control system implemented on a Red Pitaya (Xilinx Zynq) FPGA. Combining lock-in-style signal generation, CIC decimation filtering, and real-time PID control at 125 MHz.
Architecture Overview
The system operates as a closed loop: a multi-tone disturbance is generated by DDS (Direct Digital Synthesis), combined with PID feedback (subtracted), and output through the 14-bit DAC. The signal physically loops back through an SMA cable to the 14-bit ADC, naturally acquiring real-world noise.
After acquisition, a 6-stage CIC decimation filter reduces the 125 MSPS sample rate to 1 MSPS, followed by a scaler that normalizes the 64-bit CIC output back to 14-bit range. The PI controller then processes the error signal and closes the feedback loop.
Signal Generation
Multi-Tone DDS
Three independently configurable sine wave generators using Direct Digital Synthesis with 32-bit phase accumulators and a 1024-entry BRAM lookup table.
Phase increment formula: phase_inc = freq × 2³² / 125e6
CIC Decimation Filter
Specifications
- Stages
- 6
- Decimation Factor
- 125
- Input Rate
- 125 MSPS
- Output Rate
- 1 MSPS
- Internal Width
- 64-bit
- Bit Growth
- 14 + 6×ceil(log₂(125)) = 56 bits
Design Notes
- •6 integrator stages run at the full clock rate (125 MHz)
- •6 comb stages run at the decimated rate (1 MHz)
- •Scaler normalizes CIC gain of 125&sup6; = 3.814 × 10¹²
- •Fixed-point: (din × 302231) >>> 60
PID Controller
A fixed-point PI controller operating in Q16.16 format. The proportional term provides immediate response, while the integrator eliminates steady-state error with anti-windup clamping.
P Term
p_out = (din × kp) >>> 16Direct proportional path with Q16.16 scaling
I Term
integrator += din × ki48-bit accumulator, clamped to ±8191 « 16
Output: 14-bit signed, saturated to ±8192. Integrator resets on rst_n deassertion.
Register Map
All registers are accessible via AXI4-Lite at base address 0x40900000. The Rust backend memory-maps these registers through /dev/mem for real-time web control.
| Offset | Register | Description | Access |
|---|---|---|---|
| 0x00 | Control | [0] Enable [1] RST PID [2] Closed Loop [3] CIC Enable | R/W |
| 0x04 | Kp | Q16.16 proportional gain | R/W |
| 0x08 | Ki | Q16.16 integral gain | R/W |
| 0x0C | Setpoint | 14-bit signed setpoint | R/W |
| 0x10 | Sig Gen 1 | Q16.16 gain for 0.5 Hz tone | R/W |
| 0x14 | Sig Gen 2 | Q16.16 gain for 330 Hz tone | R/W |
| 0x18 | Sig Gen 3 | Q16.16 gain for 1200 Hz tone | R/W |
| 0x20 | MUX CH1 | Output source select (0-5) | R/W |
| 0x24 | MUX CH2 | Output source select (0-5) | R/W |
| 0x100 | Test | Returns 0x12345678 | RO |
Output MUX Selection
Two independent 6-way multiplexers allow routing any internal signal to the oscilloscope channels for monitoring and debugging.
| Value | Source | Description |
|---|---|---|
| 0 | ADC Channel A | Raw 14-bit ADC input |
| 1 | ADC Channel B | Raw 14-bit ADC input |
| 2 | Disturbance | Signal generator output (pre-feedback) |
| 3 | PID Output | Feedback compensation signal |
| 4 | DAC Output | Physical DAC output (disturbance - feedback) |
| 5 | CIC Filtered | Decimated and scaled error signal |
Software Stack
Backend
Rust + Axum HTTP server running on the Zynq ARM Cortex-A9.
- • Memory-mapped I/O via /dev/mem
- • REST API for scope & control
- • Mock mode for development
Frontend
Vue 3 + TypeScript SPA with real-time visualization.
- • uPlot for 16k-sample waveforms
- • 20 FPS scope refresh rate
- • Allan deviation analysis
FPGA
SystemVerilog on Xilinx Zynq-7010/7020 (Red Pitaya).
- • Vivado 2020.1 synthesis
- • cocotb simulation testbench
- • AXI4-Lite register interface