1 # Xilinx XADC support for 7 Series FPGAs
3 # The 7 Series FPGAs contain an on-chip 12 bit ADC that can probe die
4 # temperature, internal power supply rail voltages as well as external
5 # voltages. The XADC is available both from fabric as well as through the
8 # This code implements access through the JTAG TAP.
10 # https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf
12 # build a 32 bit DRP command for the XADC DR
13 proc xadc_cmd {cmd addr data} {
19 return [expr ($cmds($cmd) << 26) | ($addr << 16) | ($data << 0)]
22 # XADC register addresses
23 # Some addresses (status registers 0-3) have special function when written to.
94 proc xadc_select {tap} {
101 proc xadc_xfer {tap cmd addr data} {
102 set ret [drscan $tap 32 [xadc_cmd $cmd $addr $data]]
107 # XADC register write
108 proc xadc_write {tap addr data} {
109 xadc_xfer $tap WRITE $addr $data
112 # XADC register read, non-pipelined
113 proc xadc_read {tap addr} {
114 xadc_xfer $tap READ $addr 0
115 return [xadc_xfer $tap NOP 0 0]
118 # convert 16 bit register code from ADC measurement on
119 # external voltages (VAUX) to Volt
120 proc xadc_volt {code} {
121 return [expr $code * 1./(1 << 16)]
124 # convert 16 bit temperature measurement to Celsius
125 proc xadc_temp {code} {
126 return [expr $code * 503.975/(1 << 16) - 273.15]
129 # convert 16 bit suppply voltage measurement to Volt
130 proc xadc_sup {code} {
131 return [expr $code * 3./(1 << 16)]
134 # perform a single channel measurement using default settings
135 proc xadc_single {tap ch} {
136 set cfg0 [xadc_read $tap [XADC CFG0]]
137 set cfg1 [xadc_read $tap [XADC CFG1]]
139 xadc_write $tap [XADC CFG0] $cfg0
140 # single channel, disable the sequencer
141 xadc_write $tap [XADC CFG1] 0x3000
142 # leave some time for the conversion
144 set ret [xadc_read $tap [XADC $ch]]
146 xadc_write $tap [XADC CFG0] $cfg0
147 xadc_write $tap [XADC CFG1] $cfg1
151 # measure all internal voltages
152 proc xadc_report {tap} {
154 echo "TEMP [format %.2f [xadc_temp [xadc_single $tap TEMP]]] C"
155 foreach ch [list VCCINT VCCAUX VCCBRAM VPVN VREFP VREFN \
156 VCCPINT VCCPAUX VCCODDR] {
157 echo "$ch [format %.3f [xadc_sup [xadc_single $tap $ch]]] V"