thermometer_digital/rtl/digital_thermometer.v

95 lines
3.0 KiB
Verilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Yangshenbo
// version:V1.0
// Create Date: 2026/04/05
//////////////////////////////////////////////////////////////////////////////////
module digital_thermometer(
input clk,
input rst_n,
input sig_in,
input [23:0]win_us,
input [1:0]out_mode, //0输出对应温度 1输出对应的频率2单位窗口输出脉冲的个数
input [15:0]temp_85_fre_k, //85°对应的频率,默认为600khz
input [15:0]temp_neg_40_fre_k , //-40对应的频率默认为160khz,单位khz
input report_en, //主动上报使能
input [23:0]rep_gap_us, //最小位win_us
output reg [23:0]therm_out,
output reg therm_vld
);
wire [23:0] wd_cnt_out;
wire wd_cnt_vld;
reg [23:0] gap_cnt; // 上报间隔计数器
wire [23:0] cur_freq_khz;
reg signed [23:0] temp_scaled;
assign cur_freq_khz = (wd_cnt_out * 1000) / win_us;
//我们将温度结果放大100倍
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
temp_scaled <= 0;
end else if (wd_cnt_vld) begin
// 如果当前频率低于或等于 -40度对应的标定频率直接输出 -4000
if (cur_freq_khz <= temp_neg_40_fre_k) begin
temp_scaled <= -32'sd4000;
end
else begin
// 只有在频率大于下限时,才进行插值计算,避免减法溢出
temp_scaled <= ((cur_freq_khz - temp_neg_40_fre_k) * 12500) / (temp_85_fre_k - temp_neg_40_fre_k) - 4000;
end
end
end
// 上报逻辑与输出选择
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
gap_cnt <= 0;
therm_vld <= 0;
therm_out <= 0;
end else if (wd_cnt_vld) begin
if (report_en) begin
if (gap_cnt >= (rep_gap_us / win_us) - 1) begin
gap_cnt <= 0;
therm_vld <= 1'b1;
end else begin
gap_cnt <= gap_cnt + 1'b1;
therm_vld <= 1'b0;
end
end
else begin
gap_cnt <= 0;
therm_vld <= 1'b0;
end
// 模式切换输出
case (out_mode)
2'd0: therm_out <= temp_scaled; // 输出放大100倍的温度
2'd1: therm_out <= cur_freq_khz; // 输出频率(kHz)
2'd2: therm_out <= wd_cnt_out; // 输出原始脉冲计数值
default: therm_out <= temp_scaled;
endcase
end
else begin
therm_vld <= 1'b0;
end
end
// 实例化被测模块
pulse_cnt #(
.CLK_FREQ(50_000_000)
) pulse_cnt_inst (
.clk (clk),
.rst_n (rst_n),
.sig_in (sig_in),
.win_us (win_us),
.cnt_out(wd_cnt_out),
.vld_out(wd_cnt_vld)
);
endmodule