好久没有写文章了,这会正在跑工程,我顺便写一下这两天调的一个功能。这个功能实现的目的是获取FPGA内核温度,并将内核温度进行输出显示。那么,怎么去实现这个功能呢?主要分以下几步:一、配置XADC IP核;二、编写读温度时序逻辑;三、温度解算。下面将展开说明。
一、配置XADC IP核
①在Vivado软件 IP Catalog中搜索“XADC”,打开XADC Wizard,如下图所示;
②根据下图进行配置。
二、编写读温度时序逻辑
在编程代码之前需要知道DRP接口的时序关系,如下图所示。
FPGA读时序代码如下:
process(clk,rst)
begin
if rst = '1' then
di_in <= (others => '0');
daddr_in <= (others => '0'); --XADC温度传感器数据读取寄存器地址
den_in <= '0';
dwe_in <= '0';
elsif rising_edge (clk) then
if cnt_time = 999999 then --采样频率设置为100Hz,模块时钟100MHz
cnt_time <= (others => '0');
daddr_in <= (others => '0'); --XADC温度传感器数据读取寄存器地址
den_in <= '1';
dwe_in <= '0';
else
cnt_time <= cnt_time + 1;
den_in <= '0';
dwe_in <= '0';
end if;
end if;
end process;
XADC例化如下:
u_xadc : xadc
port map(
di_in => di_in ,
daddr_in => daddr_in ,
den_in => den_in ,
dwe_in => dwe_in ,
dclk_in => clk ,
reset_in => rst ,
vp_in => '0' ,
vn_in => '0' ,
drdy_out => drdy_out ,
do_out => do_out ,
channel_out => open ,
eoc_out => open ,
alarm_out => open ,
eos_out => open ,
busy_out => open
);
三、温度解算
温度解算的方法如下:
需要注意将输出的do_out取值为高12bit。
Note: The ADCs always produce a 16-bit conversion result. The 12-bit data correspond to the 12 MSBs (most significant) in the 16-bit status registers.
温度解算代码如下:
process(clk,rst)
begin
if rst = '1' then
data_out <= (others => '0');
temp_polarity_flag <= '1';
elsif rising_edge (clk) then
if drdy_out = '1' then
if do_out(15 downto 4) >= 2219 and do_out(15 downto 4) <= 3250 then
data_out <= ("000" & do_out(15 downto 4) & "000000000") - ("000000000" & do_out(15 downto 4) & "000");
temp_polarity_flag <= '1';
elsif do_out(15 downto 4) >= 1186 and do_out(15 downto 4) < 2219 then
data_out <= ("000" & do_out(15 downto 4) & "000000000") - ("000000000" & do_out(15 downto 4) & "000");
temp_polarity_flag <= '0';
else
data_out <= conv_std_logic_vector(3251,24);
end if;
else
data_out <= data_out;
end if;
end if;
end process;
process(clk,rst)
begin
if rst = '1' then
temp_data <= (others => '0');
drdy_out_r0 <= '0';
elsif rising_edge (clk) then
drdy_out_r0 <= drdy_out;
if drdy_out_r0 = '1' and temp_polarity_flag = '1' then
temp_data <= (x"000" & data_out(23 downto 12)) - 273;
elsif drdy_out_r0 = '1' and temp_polarity_flag = '0' then
temp_data <= 273 - (x"000" & data_out(23 downto 12));
end if;
end if;
end process;
process(clk,rst)
begin
if rst = '1' then
xadc_temp_data <= (others => '0');
elsif rising_edge (clk) then
if temp_polarity_flag = '1' then --温度为正
xadc_temp_data <= '0' & temp_data(6 downto 0); --b7为0表示正,b7为1表示负
else --温度为负
xadc_temp_data <= '1' & temp_data(6 downto 0);
end if;
end if;
end process;
四、实际效果
五、总结
以上几步可以正确的解析出FPGA核温,方法简单,无需进行乘除运算,降低资源开销。但会损失温度小数点精度。