马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
1.1
XADC简介 为了提高系统集成度,Xilinx的7Series FPGA器件内部都集成了一个模数转换器(Analog-to-DigitalConverter),以下简称XADC。该模块具有以下特性: Ø
模拟信号转换为数字信号 Ø
FPGA的温度和电压检测功能 Ø
根据用户设置的参数生成警报 1.2
UG480使用例程根据官方给出的例程,本文档针对温度和电压检测功能,整理出了简要使用方法。 使用官方的ug480.v完成温度电压寄存器的访问,该模块代码如下:
- `timescale 1ns / 1ps
- module ug480 (
- input DCLK, // Clock input for DRP
- input RESET,
- input [3:0] VAUXP, VAUXN, // Auxiliary analog channel inputs
- input VP, VN,// Dedicated and Hardwired Analog Input Pair
-
- output reg [15:0] MEASURED_TEMP, MEASURED_VCCINT,
- output reg [15:0] MEASURED_VCCAUX, MEASURED_VCCBRAM,
- output reg [15:0] MEASURED_AUX0, MEASURED_AUX1,
- output reg [15:0] MEASURED_AUX2, MEASURED_AUX3,
- output wire [7:0] ALM,
- output wire [4:0] CHANNEL,
- output wire OT,
- output wire EOC,
- output wire EOS
- );
- wire busy;
- wire [5:0] channel;
- wire drdy;
- wire eoc;
- wire eos;
- wire i2c_sclk_in;
- wire i2c_sclk_ts;
- wire i2c_sda_in;
- wire i2c_sda_ts;
-
-
- reg [6:0] daddr;
- reg [15:0] di_drp;
- wire [15:0] do_drp;
- wire [15:0] vauxp_active;
- wire [15:0] vauxn_active;
- wire dclk_bufg;
- reg [1:0] den_reg;
- reg [1:0] dwe_reg;
-
- reg [7:0] state = init_read;
- parameter init_read = 8'h00,
- read_waitdrdy = 8'h01,
- write_waitdrdy = 8'h03,
- read_reg00 = 8'h04,
- reg00_waitdrdy = 8'h05,
- read_reg01 = 8'h06,
- reg01_waitdrdy = 8'h07,
- read_reg02 = 8'h08,
- reg02_waitdrdy = 8'h09,
- read_reg06 = 8'h0a,
- reg06_waitdrdy = 8'h0b,
- read_reg10 = 8'h0c,
- reg10_waitdrdy = 8'h0d,
- read_reg11 = 8'h0e,
- reg11_waitdrdy = 8'h0f,
- read_reg12 = 8'h10,
- reg12_waitdrdy = 8'h11,
- read_reg13 = 8'h12,
- reg13_waitdrdy = 8'h13;
-
- BUFG i_bufg (.I(DCLK), .O(dclk_bufg));
- always @(posedge dclk_bufg)
- if (RESET) begin
- state <= init_read;
- den_reg <= 2'h0;
- dwe_reg <= 2'h0;
- di_drp <= 16'h0000;
- end
- else
- case (state)
- init_read : begin
- daddr <= 7'h40;
- den_reg <= 2'h2; // performing read
- if (busy == 0 ) state <= read_waitdrdy;
- end
- read_waitdrdy :
- if (eos ==1) begin
- di_drp <= do_drp & 16'h03_FF; //Clearing AVG bits for Configreg0
- daddr <= 7'h40;
- den_reg <= 2'h2;
- dwe_reg <= 2'h2; // performing write
- state <= write_waitdrdy;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- write_waitdrdy :
- if (drdy ==1) begin
- state <= read_reg00;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- read_reg00 : begin
- daddr <= 7'h00;
- den_reg <= 2'h2; // performing read
- if (eos == 1) state <=reg00_waitdrdy;
- end
- reg00_waitdrdy :
- if (drdy ==1) begin
- MEASURED_TEMP <= do_drp;
- state <=read_reg01;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- read_reg01 : begin
- daddr <= 7'h01;
- den_reg <= 2'h2; // performing read
- state <=reg01_waitdrdy;
- end
- reg01_waitdrdy :
- if (drdy ==1) begin
- MEASURED_VCCINT = do_drp;
- state <=read_reg02;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- read_reg02 : begin
- daddr <= 7'h02;
- den_reg <= 2'h2; // performing read
- state <=reg02_waitdrdy;
- end
- reg02_waitdrdy :
- if (drdy ==1) begin
- MEASURED_VCCAUX <= do_drp;
- state <=read_reg06;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- read_reg06 : begin
- daddr <= 7'h06;
- den_reg <= 2'h2; // performing read
- state <=reg06_waitdrdy;
- end
- reg06_waitdrdy :
- if (drdy ==1) begin
- MEASURED_VCCBRAM <= do_drp;
- state <= read_reg10;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- read_reg10 : begin
- daddr <= 7'h10;
- den_reg <= 2'h2; // performing read
- state <= reg10_waitdrdy;
- end
- reg10_waitdrdy :
- if (drdy ==1) begin
- MEASURED_AUX0 <= do_drp;
- state <= read_reg11;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- read_reg11 : begin
- daddr <= 7'h11;
- den_reg <= 2'h2; // performing read
- state <= reg11_waitdrdy;
- end
- reg11_waitdrdy :
- if (drdy ==1) begin
- MEASURED_AUX1 <= do_drp;
- state <= read_reg12;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- read_reg12 : begin
- daddr <= 7'h12;
- den_reg <= 2'h2; // performing read
- state <= reg12_waitdrdy;
- end
- reg12_waitdrdy :
- if (drdy ==1) begin
- MEASURED_AUX2 <= do_drp;
- state <= read_reg13;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- read_reg13 : begin
- daddr <= 7'h13;
- den_reg <= 2'h2; // performing read
- state <= reg13_waitdrdy;
- end
- reg13_waitdrdy :
- if (drdy ==1) begin
- MEASURED_AUX3 <= do_drp;
- state <=read_reg00;
- daddr <= 7'h00;
- end
- else begin
- den_reg <= { 1'b0, den_reg[1] } ;
- dwe_reg <= { 1'b0, dwe_reg[1] } ;
- state <= state;
- end
- default : begin
- daddr <= 7'h40;
- den_reg <= 2'h2; // performing read
- state <= init_read;
- end
- endcase
- XADC #(// Initializing the XADC Control Registers
- .INIT_40(16'h9000),// averaging of 16 selected for external channels
- .INIT_41(16'h2ef0),// Continuous Seq Mode, Disable unused ALMs, Enable calibration
- .INIT_42(16'h0400),// Set DCLK divides
- .INIT_48(16'h4701),// CHSEL1 - enable Temp VCCINT, VCCAUX, VCCBRAM, and calibration
- .INIT_49(16'h000f),// CHSEL2 - enable aux analog channels 0 - 3
- .INIT_4A(16'h0000),// SEQAVG1 disabled
- .INIT_4B(16'h0000),// SEQAVG2 disabled
- .INIT_4C(16'h0000),// SEQINMODE0
- .INIT_4D(16'h0000),// SEQINMODE1
- .INIT_4E(16'h0000),// SEQACQ0
- .INIT_4F(16'h0000),// SEQACQ1
- .INIT_50(16'hb5ed),// Temp upper alarm trigger 85
- .INIT_51(16'h5999),// Vccint upper alarm limit 1.05V
- .INIT_52(16'hA147),// Vccaux upper alarm limit 1.89V
- .INIT_53(16'hdddd),// OT upper alarm limit 125 - see Thermal Management
- .INIT_54(16'ha93a),// Temp lower alarm reset 60
- .INIT_55(16'h5111),// Vccint lower alarm limit 0.95V
- .INIT_56(16'h91Eb),// Vccaux lower alarm limit 1.71V
- .INIT_57(16'hae4e),// OT lower alarm reset 70 - see Thermal Management
- .INIT_58(16'h5999),// VCCBRAM upper alarm limit 1.05V
- .SIM_MONITOR_FILE("design.txt")// Analog Stimulus file for simulation
- )
- XADC_INST (// Connect up instance IO. See UG480 for port descriptions
- .CONVST (1'b0),// not used
- .CONVSTCLK (1'b0), // not used
- .DADDR (daddr),
- .DCLK (dclk_bufg),
- .DEN (den_reg[0]),
- .DI (di_drp),
- .DWE (dwe_reg[0]),
- .RESET (RESET),
- .VAUXN (vauxn_active ),
- .VAUXP (vauxp_active ),
- .ALM (ALM),
- .BUSY (busy),
- .CHANNEL(CHANNEL),
- .DO (do_drp),
- .DRDY (drdy),
- .EOC (eoc),
- .EOS (eos),
- .JTAGBUSY (),// not used
- .JTAGLOCKED (),// not used
- .JTAGMODIFIED (),// not used
- .OT (OT),
- .MUXADDR (),// not used
- .VP (VP),
- .VN (VN)
- );
- assign vauxp_active = {12'h000, VAUXP[3:0]};
- assign vauxn_active = {12'h000, VAUXN[3:0]};
- assign EOC = eoc;
- assign EOS = eos;
- endmodule
复制代码
1.3
UG480功能描述上述代码主要是通过DRP访问时序进行配置、读取XADC模块的寄存器,从而得到需要的温度电压等相关信息。其中的XADC模块是调用Xilinx的原语设计的。各输出信号的意义如下表所示: Table 1 ug480 信号说明 MEASURED_TEMP | 测试所得的温度值 | MEASURED_VCCINT | 测试所得的VCCINT值 | MEASURED_VCCAUX | 测试所得的VCCAUX值 | MEASURED_VCCBRAM | 测试所得的VCCBRAM值 | MEASURED_AUX0 | 4个模拟输入通道的监测 | MEASURED_AUX1 | MEASURED_AUX2 | MEASURED_AUX3 | ALM | 警报信号,超出用户设置的值就会拉高. bit[0]:温度 bit[1]: VCCINT bit[2]: VCCAUX bit[3]: VCCBRAM bit[4]: VCCPINT bit[5]: VCCPAUX bit[6]: VCCO_DDR bit[7]: bit[6:0]的逻辑或运算 | CHANNEL | 当前输出(更新)的类型,针对上述XADC的配置模式,其对应关系如下: 0x00:Temperatuere(MEASURED_TEMP) 0x01:VCCINT(MEASURED_VCCINT) 0x02:VCCAUX(MEASURED_VCCAUX) 0x06:VCCBRAM(MEASURED_VCCBRAM) 0x10:MEASURED_AUX0 0x11:MEASURED_AUX1 0x12:MEASURED_AUX2 0x13:MEASURED_AUX3 | OT | Over Temperature,温度超出用户设置的阈值之后,该信号会拉高。 | EOC | ADC转换结束标志,Active High. | EOS | 状态寄存器访问结束标志,Active High.每次刷新完状态寄存器,则给出一个EOS脉冲,此时DRP访问状态机会依次读取所有的状态寄存器。 |
从XADC的寄存器配置可以看出,温度的上限警报为85°C,超出温度(OT)的值为125°C,VCCINT上限警报为1.05V,VCCAUX上限警报为1.89V,VCCBRAM上限警报为1.05V。 Table 2 XADC ControlRegisters Name | Address | Software Attribute | Description | Configuration register 0 | 40h | INIT_40 | XADC基本配置寄存器 | Configuration register 1 | 41h | INIT_41 | Configuration register 2 | 42h | INIT_42 | Sequence registers | 48h to 4Fh | INIT_48 to INIT_4F | 通道序列配置寄存器 | Alarm registers | 50h to 5Fh | INIT_50 to INIT_5F | 警报阈值配置寄存器 |
具体的寄存器配置介绍请参考Xilinx 官方手册UG480。 ADC总是产生一个16位转换结果。但是只使用12bit的数据,这12位数据对应于16位状态寄存器中的12个MSB(最高位)。可以通过未使用的LSB(低四位)来最小化量化效应或通过求平均值或滤波来提高分辨率。对这12bit数据,需要做一个格式转换才能得到实际的摄氏度和电压值,温度转换方程如下:
Temp(℃)=(MEASURED_TEMP[15:4]* 503.975)/4096-273.15
电压转换方程如下:
VCCINT=(MEASURED_VCCINT[15:4]* 3)/4096
VCCAUX、VCCBRAM的电压转换方式和VCCINT一致。
这样,通过温度、电压转换方程即可得到较为精确的温度和电压。通过这个转换方程,可以看出例程中温度配置的警报阈值85file:///D:/Temp/msohtmlclip1/01/clip_image006.png是怎么得来的了:
同理,配置参数INIT_50给的是0xb5ed,那么温度阈值等于0xb5e * 503.975 / 4096 –273.15 = 84.89file:///D:/Temp/msohtmlclip1/01/clip_image006.png。 1.4
XADC和MIG 控制器使用技巧一个FPGA内部只有一个ADC模块,当我们使用了MIG控制器的时候,在生成MIG控制器的过程中有一个选项提示是否使能XADC,这个时候我们不能使能这个XADC模块,否则会产生冲突。Disable了MIG控制器的内部XADC模块调用之后,MIG控制器会有一个输入温度的端口提供给用户,此时就需要在外部调用这个XADC这个模块,然后将温度值MEASURED_TEMP[15:4]给到这个端口。如下: MIG制器Disable XADC:
figure 1 MIG XADC Disable 端口连接:
- .device_temp_i ( MEASURED_TEMP[15:4] ),// input [11:0] device_temp_i
复制代码
ug480例化使用:
- ug480 ug480_inst(
- //Input
- .DCLK ( Clk50M ),// Clock input for DRP
- .RESET ( !nRst ),//Active Hign
- .VAUXP ( 4'h0 ),// Auxiliary analog channel inputs
- .VAUXN ( 4'h0 ),// Auxiliary analog channel inputs
- .VP ( 1'b0 ),// Dedicated and Hardwired Analog Input Pair
- .VN ( 1'b0 ),// Dedicated and Hardwired Analog Input Pair
-
- //Output
- .MEASURED_TEMP ( MEASURED_TEMP[15:0] ),
- .MEASURED_VCCINT ( MEASURED_VCCINT[15:0] ),
- .MEASURED_VCCAUX ( MEASURED_VCCAUX[15:0] ),
- .MEASURED_VCCBRAM ( MEASURED_VCCBRAM[15:0] ),
- .MEASURED_AUX0 ( MEASURED_AUX0[15:0] ),
- .MEASURED_AUX1 ( MEASURED_AUX1[15:0] ),
- .MEASURED_AUX2 ( MEASURED_AUX2[15:0] ),
- .MEASURED_AUX3 ( MEASURED_AUX3[15:0] ),
- .temp_ref ( temp_ref ),
- .ALM ( ALM[7:0] ),
- .CHANNEL ( CHANNEL[4:0] ),
- .OT ( OT ),
- .EOC ( EOC ),
- .EOS ( EOS )
- );
-
复制代码
可以看出,ug480在例化使用时,VAUXP、VAUXN、VP、VN这几个信号直接给了0,是因为他们是用于前面提到的模数转换功能使用的,我们只使用了温度电压检测,因此这几个信号可以不用。复位信号高电平有效。
需要注意的是MIG控制器需要的温度值刷新时间间隔最小是116us,所以XADC模块使用时INIT_41这个寄存器必须设置为Continuous Seq Mode(例程中的默认设置就好),也就是按照轮训方式刷新。为了测试该轮训刷新时间,通过在7Seriers 160T测试EOS的频率为40Mhz(DCK给50M参考时钟),也就是说,ug480的配置模式在50M参考时钟的工作状态下,输出值的刷新时间是25ns.完全满足MIG的刷新时间要求。
其余输出信号如MEASURED_TEMP等可以直接提供给MCU读取,MCU读取之后用转换方程转换之后即可得到FPGA当前的工作温度和电压了。另外还可将ALM信号、OT信号以中断的形式反馈至MCU处理。 以上描述均属个人通过了解UG480之后在K7 160T测试之后得到的结论,若和UG480有冲突的地方,请以UG480为准。UG480参考文档 |