From 281ede848714b5a095b03dd7a1d90fe5fa258e64 Mon Sep 17 00:00:00 2001 From: yangshenbo Date: Sun, 22 Mar 2026 20:36:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=A9=E5=BA=A6=E8=AE=A1=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=8A=9F=E8=83=BD=E5=8F=AF=E7=94=A8=EF=BC=8C?= =?UTF-8?q?=E4=BB=BF=E7=9C=9F=E6=97=A0=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rtl/digital_thermometer.v | 78 ++++++++++++++++++++++++++++++++ rtl/pulse_freq_10ms.v | 71 +++++++++++++++++++++++++++++ tb/TB.v | 95 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 rtl/digital_thermometer.v create mode 100644 rtl/pulse_freq_10ms.v create mode 100644 tb/TB.v diff --git a/rtl/digital_thermometer.v b/rtl/digital_thermometer.v new file mode 100644 index 0000000..e8785e2 --- /dev/null +++ b/rtl/digital_thermometer.v @@ -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 diff --git a/rtl/pulse_freq_10ms.v b/rtl/pulse_freq_10ms.v new file mode 100644 index 0000000..c95c8e3 --- /dev/null +++ b/rtl/pulse_freq_10ms.v @@ -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 \ No newline at end of file diff --git a/tb/TB.v b/tb/TB.v new file mode 100644 index 0000000..96393bd --- /dev/null +++ b/tb/TB.v @@ -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