温度计模块基本功能可用,仿真无误
This commit is contained in:
commit
281ede8487
|
|
@ -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~1300(50.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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue