SuperMUSR Bridge (adc120-bridge-v2)
Software running on the SuperMUSR DAQ box (ADC120 digitizer, Xilinx Zynq UltraScale+, Ubuntu 24.04 ARM64 rootfs) that bridges the FPGA firmware with the rest of the acquisition pipeline: it reads waveforms via DMA, builds the Flatbuffer messages, publishes them to ZMQ and Kafka, and exposes a control and housekeeping channel over ZMQ.
Package name on the NI Packages portal:
supermusr-bridge.
What it does
- Acquisition. A dedicated thread (
acquisition_thread) waits for a waveform to be ready, reads the DMA, lays out the samples per channel (8 xdgtz.pre + dgtz.post, 1 sample = 1 ns at 1 GS/s) and pushes the frame to an internal queue. - Processing. A dedicated thread (
processing_thread) drains the queue, optionally applies zero suppression channel by channel, serializes the frame via Flatbuffer (DigitizerAnalogTraceMessagev2) and fans the same buffer out to every registered push service. - Push services. The same serialized buffer is sent to:
- ZMQ waveforms (
zmq, portzmq.streaming_port) - ZMQ events (
zmq_data, portzmq.streaming_events_port) - Kafka waveforms (
kafka, topickafka.topic) - Kafka events (
kafka_events, topickafka_events.topic)
- ZMQ waveforms (
- Control / Housekeeping. A ZMQ server on
zmq.control_portexecutes commands (start_acquisition,stop_acquisition,configure_dgtz,get_hk,get_waveforms, …) and serves every*.*parameter registered inadc120_brdige.cppthroughparams.add_param(...). - Software zero suppression (from
9.5.10.0): per-channel gate with threshold + hysteresis, samples outside the gate forced to 0. The frame size does not change; combined with Kafka-side compression (compression.type=lz4|zstd) the compression ratio goes up by orders of magnitude. Parameters underzs.*, counters underzs.probes.*(bytes in/out/serializer, windows per event, 1 s throughput). Full details in the release notes. - Software signal emulator (from
9.5.11.0): generates realistic SiPM- scintillator frames (validated against SuperMUSR run2 Module1) so the
full pipeline (ZS, serializer, ZMQ, Kafka) can be exercised without beam.
Two modes:
overwrite(real DMA/trigger/status packet, samples overwritten) andreplace(self-paced viaswemu.frame_rate, fake status packet, works even withhardware.enabled=false). Lives alongside the FPGA emulator (dgtz.emu.*), parameters underswemu.*.
- scintillator frames (validated against SuperMUSR run2 Module1) so the
full pipeline (ZS, serializer, ZMQ, Kafka) can be exercised without beam.
Two modes:
- ZMQ waveform throttle (from
9.5.12.0):zmq.frame_rate_limitcaps the rate of waveforms forwarded to the ZMQ streaming socket without touching Kafka. Useful for GUI slow-monitor during full-rate acquisition.
Supported hardware
- DAQ board: ADC120 (SuperMUSR digitizer), 8 ADC channels, 12 bit, 1 GS/s.
- SoC: Xilinx Zynq UltraScale+ (
xczu*). - Target OS: Ubuntu 24.04 ARM64 (
nibuntu-arm-64-24-04-isis), sysrootsupermusr-root-fs. - Base board: up to 2 SuperMUSR staves, HV, LVDS sync, LEMO, I2C.
Intended to run as a service on the DAQ box, usually started as
sudo chrt --fifo 99 ./zmq_adc120 /ni/config/default.cfg so it gets
SCHED_FIFO priority (see the note at the top of adchal.cpp).
Repository layout
| Path | Contents |
|---|---|
zmq_adc120/src/ | C++17 sources: adc120_brdige.cpp (main + parameter registration), adchal.cpp/h (HAL, acquisition, processing, ZS, swemu), zero_suppression.h (ZS algorithm), signal_emulator.cpp/h + pulse_template.inc (software emulator), flatbufferserializers.cpp/h, kafkaproducer.cpp/h, zmqstreamerserver.cpp/h, processing.cpp/h (CPU-side processing: spectra, deconvolution), … |
zmq_adc120/src/schemas/ | Generated Flatbuffer headers, pulled from the supermusr-flat-buffers package |
zmq_adc120/src/lib_userspace_dma_driver/ | Xilinx DMA userspace driver |
zmq_adc120/Release/ | Output of the Eclipse CDT headless build |
zmq_adc120/Debug/ | Debug build, same layout |
.ni/nipkg.yml | Package descriptor for the supermusr-bridge NI Package |
.ni/pippolina.yml | Release policy consumed by pippolina |
.gitlab-ci.yml, .gitlab-ci/release.yml | Build + release pipeline |
compile-cicd.sh | Build job script (pulls deps, runs Eclipse headless) |
CHANGELOG.md | Release history |
default.cfg | Sample configuration |
Build
Local (aarch64 cross-compile)
Prerequisites:
aarch64-linux-gnu-g++cross toolchain- Eclipse CDT headless (the
zmq_adc120project) - Ubuntu 24.04 ARM sysroot in
/sharedVolume/sysroot-24(hard-coded inRelease/src/subdir.mk) flatbuffersheaders available (-I$(HOME)/projects/flatbuffers/includeor/sharedVolume/flatbuffers/include)- Flatbuffer schema headers from the
supermusr-flat-bufferspackage inzmq_adc120/src/schemas/
Build:
./compile-cicd.sh
# -> zmq_adc120/Release/zmq_adc120The script pulls the sysroot and the flatbuffers package from the internal
catalog (still via nirelease for now), copies the Flatbuffer headers into
src/schemas/ and runs Eclipse CDT headless against zmq_adc120/Release.
GitLab pipeline (build + release)
Any protected tag triggers:
pippolina-pre-pipeline— waits for the pippolina lock (the release orchestrator, 24 h timeout).build_eclipse— imageregistry.lanni/apps/eclipse-2021-09-cpp-arm-aarch-18, runs./compile-cicd.sh, produceszmq_adc120.tar.gz(which containszmq_adc120/Release/zmq_adc120).release—cicd-catalogs/ni-release-catalog/ni-release-genericcomponent, reads.ni/nipkg.ymland publishes the tar.gz on NI Packages under thesupermusr-bridgepackage slug. It also creates the GitLab release, with the description built from theCHANGELOG.mddiff between the previous tag and the current one.
Tag format: date-4-dot (YYYY.M.D.N, e.g. 2026.10.22.1). Any tag
containing -STAGING lands on the staging channel of the portal.
Tags are protected (rule 202* for Maintainers only) so the protected
NIPKG_CICD_TOKEN variable is exposed to the release job.
Runtime configuration
- JSON file read at startup (
default.cfgor the one passed asargv[1]), loaded intocfg_classbyconfiguration.cpp. Holds ZMQ ports, Kafka brokers, channel map, hardware enable flag, stave version, ... - Runtime parameters over the ZMQ control port, one command per parameter.
Everything is registered in
adc120_brdige.cppviaparams.add_param(...).
Main namespaces:
| Namespace | Scope |
|---|---|
dgtz.* | Trigger, pre/post, polarity, FPGA emulator, HW probes |
mp.* | Multiphoton: gain, offset, thresholds, spectrum |
trg.*, in.* | External trigger, input offset, channel map |
stave.*, BIAS.* | Stave control and HV bias |
base.* | LEMO, sync, LVDS, base-board T0 source |
sw_process.* | Software processing (spectra, deconvolution, filters) |
zs.* | Software zero suppression (from 9.5.10.0) |
swemu.* | Software signal emulator (from 9.5.11.0) |
zmq.* | ZMQ waveform throttle (from 9.5.12.0) |
system.* | sw version, SN, IP, system metrics |
Probes (*.probes.*) are read-only and are also aggregated in the JSON
returned by the get_hk command, under data.probes.*.
SuperMUSR Bridge
Bridge software for the SuperMUSR ADC120 DAQ box (Zynq UltraScale+, Ubuntu 24 ARM64): reads waveforms via DMA, applies optional software zero suppression, serializes to Flatbuffer and streams them to ZMQ and Kafka. Includes a ZMQ control server, housekeeping and a software signal emulator for pipeline testing without beam.
License:
You may also like
DAQ121
High-performance, fully integrated digitizer developed by Nuclear Instruments for advanced SiPM-based muon detection systems.
R5560SE MCA Firmware
MCA firmware for Open Hardware digitizers with real-time energy acquisition and spectrum generation.
DT5560 MCA Firmware
Default MCA FPGA firmware of the DT5560 digitizer.
I-Spector uC firmware PSD
I-Spector PSD microcontroller firmware: web/USB update file and recovery firmware.
Trending Products
DT5571
High-performance waveform digitizer featuring 14-bit resolution and a 200 MS/s sampling rate on a single analog input.
DAQ141
High-performance, fully integrated digitizer developed by Nuclear Instruments for advanced SiPM-based muon detection systems
DAQ141-6
High-performance, 6-channel waveform digitizer developed by Nuclear Instruments for demanding scientific and industrial data acquisition.
