温度计模块基本功能可用,仿真无误

This commit is contained in:
yangshenbo 2026-03-22 20:36:31 +08:00
commit 281ede8487
3 changed files with 244 additions and 0 deletions

78
rtl/digital_thermometer.v Normal file
View File

@ -0,0 +1,78 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Yangshenbo
//
// Create Date: 2026/03/22
//////////////////////////////////////////////////////////////////////////////////
module digital_thermometer(
input clk,
input rst_n,
input vin,
input mode,
output reg [19:0]freq_x100hz,
output reg [15:0]temp_out,
output reg temp_valid
);
wire [19:0] freq;
wire freq_valid;
//映射表
reg [15:0] temp_lut [0:800];
integer i;
initial begin
for (i = 0; i <= 800; i = i + 1) begin
// 50.0kHz->-40°C, 130.0kHz->85°C
// temp = -400 + (1250 * i) / 800
temp_lut[i] = -400 + (1250 * i + 400) / 800;
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
freq_x100hz <= 0;
temp_out <= 0;
temp_valid <= 0;
end
else begin
temp_valid <= freq_valid;
if (freq_valid) begin
freq_x100hz <= freq;
if (mode == 0) begin
// 模式0线性输出
// 频率范围500~130050.0kHz~130.0kHz
if (freq < 500)
temp_out <= -400;
else if (freq > 1300)
temp_out <= 850;
else
temp_out <= -400 + ((freq - 500) * 1250) / 800;
end else begin
// 模式1查表输出
if (freq < 500)
temp_out <= temp_lut[0];
else if (freq > 1300)
temp_out <= temp_lut[800];
else
temp_out <= temp_lut[freq - 500];
end
end
end
end
pulse_freq_10ms u_freq_measure (
.clk (clk),
.rst_n (rst_n),
.vin (vin),
.freq (freq), //1302 ->130.2KHz
.valid (freq_valid)
);
endmodule

71
rtl/pulse_freq_10ms.v Normal file
View File

@ -0,0 +1,71 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2026/03/22 18:53:43
// Design Name:
// Module Name: pulse_freq_10ms
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
module pulse_freq_10ms #(
parameter CLK_FREQ = 50_000_000, // 系统时钟频率Hz默认50MHz
parameter WINDOW_MS = 10 // 测量时间窗口ms默认10ms
) (
input clk, // 系统时钟
input rst_n, // 异步复位低有效
input vin, // 输入方波
output reg [19:0] freq, // 时间窗口内脉冲计数如果为1302就是130.2k
output reg valid // 测量完成有效脉冲
);
// 计算窗口计数最大值
localparam WINDOW_CNT = (CLK_FREQ / 1000) * WINDOW_MS - 1;
reg [31:0] cnt_window; // 窗口计时器使用32位以防大数值
reg [19:0] pulse_cnt; // 脉冲计数器
reg vin_sync1, vin_sync2;
wire vin_rise;
// 边沿检测
always @(posedge clk) begin
vin_sync1 <= vin;
vin_sync2 <= vin_sync1;
end
assign vin_rise = vin_sync1 & ~vin_sync2;
// 核心逻辑窗口计数 + 脉冲计数 + 锁存输出
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt_window <= 0;
pulse_cnt <= 0;
valid <= 0;
end else begin
valid <= 0; // 默认无效
if (cnt_window == WINDOW_CNT) begin // 窗口时间到
freq <= pulse_cnt; // 输出计数值
valid <= 1;
cnt_window <= 0;
pulse_cnt <= 0;
end else begin
cnt_window <= cnt_window + 1;
if (vin_rise) pulse_cnt <= pulse_cnt + 1;
end
end
end
endmodule

95
tb/TB.v Normal file
View File

@ -0,0 +1,95 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2026/03/22 18:54:47
// Design Name:
// Module Name: TB
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
module tb_digital_thermometer;
reg clk;
reg rst_n;
reg vin;
reg mode;
wire [19:0] freq_x100hz;
wire [15:0] temp_out;
wire temp_valid;
// 例化待测模块
digital_thermometer uut (
.clk (clk),
.rst_n (rst_n),
.vin (vin),
.mode (mode),
.freq_x100hz (freq_x100hz),
.temp_out (temp_out),
.temp_valid (temp_valid)
);
// 时钟50MHz
initial clk = 0;
always #10 clk = ~clk;
// 测试流程
initial begin
// 复位
rst_n = 0;
mode = 0;
#100;
rst_n = 1;
gen_pulse(52,20);
gen_pulse(74,20);
gen_pulse(104.7,20);
gen_pulse(130,20);
mode = 1;
gen_pulse(52,20);
gen_pulse(74,20);
gen_pulse(104.7,20);
gen_pulse(130,20);
#10000;
$finish;
end
//
task gen_pulse;
input real freq_kHz;
input [7:0] time_ms;
integer cycles;
integer i;
begin
//操控reg vin
cycles = time_ms * freq_kHz;
vin = 0;
for (i = 0; i < cycles; i = i + 1) begin
vin = 1;
#(500000/freq_kHz);
vin = 0;
#(500000/freq_kHz);
end
end
endtask
endmodule