Skip to content

feat(telemetry): add XADC system telemetry (Phase 1)#15

Draft
steve007iii wants to merge 1 commit into
lmesserStep:mainfrom
steve007iii:feat/xadc-telemetry
Draft

feat(telemetry): add XADC system telemetry (Phase 1)#15
steve007iii wants to merge 1 commit into
lmesserStep:mainfrom
steve007iii:feat/xadc-telemetry

Conversation

@steve007iii
Copy link
Copy Markdown

Summary

Adds FPGA system telemetry using the Artix-7 internal XADC primitive. Continuously samples junction temperature and supply voltages (Vccint, Vccaux, Vbram) and exposes them as registered outputs. The XADC OT_OUT (over-temperature) signal is also routed to the user LED so the panel visibly reflects thermal conditions.

⚠️ Submitted as Draft. Code is written against UG480 (Xilinx XADC User Guide) but the bitstream has not been recompiled and tested by the submitter. Looking for early feedback on approach and integration before validating on hardware.

Motivation

The B210mini design currently has no on-FPGA monitoring of:

  • Junction temperature (Tj) — relevant during sustained TX, especially at higher PAs
  • Internal supply voltages — diagnostic value for brown-outs / power-rail issues
  • Over-temperature condition — there is no panic indicator if the chip approaches thermal damage

The Artix-7 XADC primitive is free (already in the silicon, costs no LUTs or DSPs) and provides this telemetry natively. Adding it is a clear value-add with minimal cost.

What's in this PR

New module: xadc_telemetry.v

A thin wrapper around the XADC primitive:

  • Configures continuous-sequence mode with internal sensors enabled
  • DCLK divider = 8 (gives 12.5 MHz ADCCLK from the 100 MHz bus_clk)
  • Calibration channels (CAL0/1/3) enabled
  • DRP read state machine cycles through TEMP / VCCINT / VCCAUX / VBRAM after each end-of-sequence pulse
  • 12-bit raw values latched into registered outputs
  • valid pulse marks a fresh full sweep
  • over_temp and alarm[7:0] exposed combinationally

Conversions (per UG480):

  • Temp [°C] = (raw * 503.975 / 4096) - 273.15
  • Voltage [V] = (raw * 3.0) / 4096

Integration in libresdr_b210.v

  • Instantiate the module with bus_clk / bus_rst
  • OR over_temp into the existing LED_USER_R driver:
// Before
assign LED_USER_R = ~REF_LOCKED;

// After
assign LED_USER_R = ~REF_LOCKED | xadc_over_temp;

This means the user LED lights up on either "ref unlocked" (existing behavior) or "FPGA over temperature" (new). The two states aren't distinguishable at the LED, but the failure modes are both "needs attention" and a stuck-on LED post-power-cycle is a useful diagnostic.

The 12-bit values (xadc_temp_raw, xadc_vccint_raw, etc.) are wired up internally but not yet routed to UHD-readable registers. That's intentional — it's "Phase 2" follow-up work that needs hardware testing.

Resource impact (estimated)

Resource Cost
LUTs ~200 (DRP state machine + 4×12-bit registers)
DSPs 0
BRAM 0
FPGA pins 0 (XADC is fully internal)
Synthesis time <1% increase

Phase 2 (separate PR, requires hardware testing)

To make the telemetry visible from the UHD host side:

  1. Add settings register addresses for the 4 raw values in b200_core.v
  2. Wire xadc_temp_raw etc. through the readback path
  3. Either: extend UHD's B200 sensor framework, OR document the readback addresses for users to query directly

This part is deliberately omitted here because it requires:

  • Knowing the exact free addresses in the SR_* register space
  • Verifying the readback timing works at the bus_clk rate
  • Testing on real hardware

I'd rather land Phase 1 cleanly first and then iterate on Phase 2 with feedback.

Testing status

  • Code follows UG480 patterns for XADC instantiation and DRP access
  • Default INIT register values match Xilinx-recommended starting points for continuous mode
  • Module is self-contained — outputs unused at top level get optimized away (Phase 2 will wire them)
  • Bitstream not yet recompiled by submitter — no Vivado available at the moment
  • Hardware validation pending — no sensor data captured yet
  • OT-LED behavior not confirmed under thermal stress — I'd recommend reviewers test by sustained TX at high power and observing the LED

Compatibility

  • No UHD-side changes
  • No port changes to top-level libresdr_b210 module
  • No changes to b200_core.v, radio_legacy.v, or any DSP/comms paths
  • FPGA Version register unchanged (still 16.0)
  • Worst case if XADC config is off: the telemetry values are wrong but nothing else breaks. The XADC primitive is always-on and self-contained.

Notes for reviewers

  • New file xadc_telemetry.v may need to be added to the Vivado project's source list if it's not auto-discovered. One click in Vivado: Add Sources → Add or Create Design Sources → select xadc_telemetry.v.
  • The SIM_DEVICE("7SERIES") parameter on the XADC primitive is set for Artix-7. Other 7-Series families also work with this value.
  • I'm happy to rebase, split into smaller commits, or rework the integration approach based on feedback.

New module xadc_telemetry.v wraps the Artix-7 internal XADC primitive
to continuously sample junction temperature and supply voltages
(Vccint, Vccaux, Vbram). A small DRP read state machine latches the
12-bit raw values into registered outputs after each end-of-sequence
pulse. The XADC OT_OUT and ALM[7:0] signals are exposed combinationally.

Phase 1 integration in libresdr_b210.v:
  - Module instantiated with bus_clk (100 MHz) as DRP clock
  - over_temp signal ORd into LED_USER_R so the user LED also lights
    when junction temperature exceeds the XADC OT threshold (~125 degC
    by default), in addition to the existing ref-unlocked indication.

Future work (Phase 2, separate PR):
  - Wire the latched 12-bit values into the b200_core register read
    path so they are accessible via UHD as mboard sensors.

Resource cost (estimated, pending synthesis):
  - LUTs: ~200 (DRP state machine)
  - DSPs: 0
  - BRAM: 0
  - FPGA pins: 0 (XADC is internal)

Configuration of the XADC primitive:
  - Continuous sequence mode (INIT_41 = 0x2EF0)
  - DCLK divider = 8 -> 12.5 MHz ADCCLK from 100 MHz DRP clock
  - Internal sensors: TEMP, VCCINT, VCCAUX, VBRAM
  - Calibration channels (CAL0/1/3) enabled
  - Default alarm thresholds (~85 degC warning, ~125 degC OT)

References: Xilinx UG480 (XADC User Guide, 7-Series).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant