好久没有写文章了,这会正在跑工程,我顺便写一下这两天调的一个功能。这个功能实现的目的是获取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核温,方法简单,无需进行乘除运算,降低资源开销。但会损失温度小数点精度。
评论记录:
回复评论: