diff --git a/rtl/digital_thermometer.v b/rtl/digital_thermometer.v index c707cca..226ad15 100644 --- a/rtl/digital_thermometer.v +++ b/rtl/digital_thermometer.v @@ -25,7 +25,7 @@ module digital_thermometer( wire wd_cnt_vld; reg [23:0] gap_cnt; // 上报间隔计数器 wire [23:0] cur_freq_khz; - reg signed [31:0] temp_scaled; + reg signed [23:0] temp_scaled; assign cur_freq_khz = (wd_cnt_out * 1000) / win_us; //我们将温度结果放大100倍 @@ -33,8 +33,14 @@ module digital_thermometer( if (!rst_n) begin temp_scaled <= 0; end else if (wd_cnt_vld) begin - // 线性插值计算 - temp_scaled <= ((cur_freq_khz - temp_neg_40_fre_k) * 12500) / (temp_85_fre_k - temp_neg_40_fre_k) - 4000; + // 如果当前频率低于或等于 -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 @@ -61,10 +67,10 @@ module digital_thermometer( // 模式切换输出 case (out_mode) - 2'd0: therm_out <= temp_scaled[23:0]; // 输出放大100倍的温度 + 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[23:0]; + default: therm_out <= temp_scaled; endcase end else begin diff --git a/rtl/digital_top.v b/rtl/digital_top.v index d42230e..ef7c89c 100644 --- a/rtl/digital_top.v +++ b/rtl/digital_top.v @@ -24,7 +24,8 @@ module digital_top( input clk, input rst_n, input uart_rx, - output uart_tx + output uart_tx, + input sig_in ); wire [31:0] w_wrdata; // DUT -> SRAM 写数据 @@ -33,31 +34,61 @@ wire w_wren; // 写使能 wire w_rden; // 读使能 wire [31:0] w_rddata; // SRAM -> DUT 读数据 +wire [23:0] win_us; +wire [1:0] out_mode; +wire [15:0] temp_85_fre_k; +wire [15:0] temp_neg_40_fre_k; +wire report_en; +wire [23:0] rep_gap_us; +wire therm_vld; +wire [23:0] therm_out; - // 例化待测模块 (DUT) -uart_ctrl_sysreg #( - .BAUD (115200), - .CLOCK_FREQ (50_000_000) -) u_uart_ctrl ( - .clk (clk), - .rst_n (rst_n), - .uart_rx (uart_rx), - .uart_tx (uart_tx), - .o_wrdata (w_wrdata), - .o_addr (w_addr), - .o_wren (w_wren), - .o_rden (w_rden), - .i_rddata (w_rddata) -); + uart_ctrl_sysreg #( + .BAUD (115200), + .CLOCK_FREQ (50_000_000) + ) u_uart_ctrl ( + .clk (clk), + .rst_n (rst_n), + .uart_rx (uart_rx), + .uart_tx (uart_tx), + .o_wrdata (w_wrdata), + .o_addr (w_addr), + .o_wren (w_wren), + .o_rden (w_rden), + .i_rddata (w_rddata) + ); -system_regfile u_system_regfile ( - .clk (clk), - .rst_n (rst_n), - .wrdata (w_wrdata), - .wren (w_wren), - .rwaddr (w_addr), - .rden (w_rden), - .rddata (w_rddata) -); + system_regfile u_system_regfile ( + .clk (clk), + .rst_n (rst_n), + .wrdata (w_wrdata), + .wren (w_wren), + .rwaddr (w_addr), + .rden (w_rden), + .rddata (w_rddata), + // digital_thermometer + .win_us(win_us), + .out_mode(out_mode), + .temp_85_fre_k(temp_85_fre_k), + .temp_neg_40_fre_k(temp_neg_40_fre_k), + .report_en(report_en), + .rep_gap_us(rep_gap_us), + .therm_out(therm_out), + .therm_vld(therm_vld) + ); + + digital_thermometer u_digital_thermometer ( + .clk (clk), + .rst_n (rst_n), + .sig_in (sig_in), + .win_us (win_us), + .out_mode (out_mode), + .temp_85_fre_k (temp_85_fre_k), + .temp_neg_40_fre_k (temp_neg_40_fre_k), + .report_en (report_en), + .rep_gap_us (rep_gap_us), + .therm_out (therm_out), + .therm_vld (therm_vld) + ); endmodule diff --git a/rtl/systemregfile/my_systemregfile.v b/rtl/systemregfile/my_systemregfile.v index 4a21946..b528b72 100644 --- a/rtl/systemregfile/my_systemregfile.v +++ b/rtl/systemregfile/my_systemregfile.v @@ -14,18 +14,24 @@ // SECTION G: 将 reg_new 映射给模块的输出端口。 //-FHDR-------------------------------------------------------------------------------------------------------- -module system_regfile # ( - parameter CHIPCODE = 32'hDA400801, - parameter MFDATE = 32'h20260510 -)( +module system_regfile ( // [BLOCK 0] 系统与总线接口 - input clk, // 时钟 - input rst_n, // 异步复位 (低有效) - input [31:0] wrdata, // 总线写数据 - input wren, // 写使能 - input [24:0] rwaddr, // 地址 (Byte Address) - input rden, // 读使能 - output [31:0] rddata // 总线读数据 + input clk, + input rst_n, + input [31:0] wrdata, + input wren, + input [24:0] rwaddr, + input rden, + output [31:0] rddata, + + output [23:0]win_us, + output [1:0]out_mode, //0输出对应温度, 1输出对应的频率,2单位窗口输出脉冲的个数 + output [15:0]temp_85_fre_k, //85°对应的频率,默认为600khz + output [15:0]temp_neg_40_fre_k , //-40对应的频率,默认为160khz,单位khz + output report_en, + output [23:0]rep_gap_us, //最小位win_us 小于就不上报了 + input [23:0]therm_out, + input therm_vld ); @@ -33,6 +39,11 @@ module system_regfile # ( // [SECTION A] 地址偏移定义 (Localparams) // ============================================================================= localparam TESTR = 16'h00, DATER = 16'h04; + localparam WIN_MODE_R = 16'h08; // 配置窗口时间与输出模式 + localparam CALIB_R = 16'h0C; // 标定参数寄存器 + localparam REPORT_R = 16'h10; // 上报使能与间隔 + localparam RESULT_R = 16'h14; // 状态与结果寄存器 (只读) + // ============================================================================= @@ -41,24 +52,32 @@ module system_regfile # ( // 寄存器选择信号 (Enable Wires) wire sel_testr, sel_dater; - + wire sel_win_mode, sel_calib, sel_report, sel_result; // 写使能信号 (Write Enable Wires) wire we_testr, we_dater; + wire we_win_mode, we_calib, we_report; // 寄存器存储连线 (Storage Wires) wire [31:0] testr, dater; - + wire [31:0] win_mode_r, calib_r, report_r, result_r; // ============================================================================= // [SECTION C] 译码逻辑 (Decoding) // ============================================================================= - assign sel_testr = (rwaddr[15:0] == TESTR ); - assign sel_dater = (rwaddr[15:0] == DATER ); + assign sel_testr = (rwaddr[15:0] == TESTR ); + assign sel_dater = (rwaddr[15:0] == DATER ); + assign sel_win_mode = (rwaddr[15:0] == WIN_MODE_R ); + assign sel_calib = (rwaddr[15:0] == CALIB_R ); + assign sel_report = (rwaddr[15:0] == REPORT_R ); + assign sel_result = (rwaddr[15:0] == RESULT_R ); // 写使能分配 assign we_testr = sel_testr & wren; assign we_dater = sel_dater & wren; +assign we_win_mode = sel_win_mode & wren; +assign we_calib = sel_calib & wren; +assign we_report = sel_report & wren; // ============================================================================= @@ -67,9 +86,17 @@ assign we_dater = sel_dater & wren; // --- 通用与测试寄存器 --- sirv_gnrl_dfflrd #(32) testr_dff (32'h01234567, we_testr, wrdata[31:0], testr, clk, rst_n); -sirv_gnrl_dfflrd #(32) sfrtr_dff (32'd20270403, we_dater, wrdata[31:0], dater, clk, rst_n); +sirv_gnrl_dfflrd #(32) sfrtr_dff (32'h20260406, we_dater, wrdata[31:0], dater, clk, rst_n); +// --- 温度计业务寄存器 --- +// win_mode_r: [25:24] out_mode, [23:0] win_us (默认窗口 1000us) +sirv_gnrl_dfflrd #(32) win_mode_dff (32'h0000_03E8, we_win_mode, wrdata, win_mode_r, clk, rst_n); +// calib_r: [31:16] 85度频率(默认600k), [15:0] -40度频率(默认160k) +sirv_gnrl_dfflrd #(32) calib_dff (32'h0258_00A0, we_calib, wrdata, calib_r, clk, rst_n); +// report_r: [31] report_en, [23:0] rep_gap_us (默认间隔 50ms) +sirv_gnrl_dfflrd #(32) report_dff (32'h0000_C350, we_report, wrdata, report_r, clk, rst_n); +sirv_gnrl_dffr #(32) result_dff ({8'b0,therm_out},result_r, clk, rst_n); // ============================================================================= // [SECTION E] 特殊业务逻辑 (Business Logic) @@ -84,8 +111,12 @@ sirv_gnrl_dfflrd #(32) sfrtr_dff (32'd20270403, we_dater, wrdata[31:0], dater, c reg [31:0] rddata_reg; always @(*) begin rddata_reg = 32'b0; - if (sel_testr) rddata_reg = testr; - else if (sel_dater) rddata_reg = dater; + if (sel_testr) rddata_reg = testr; + else if (sel_dater) rddata_reg = dater; + else if (sel_win_mode) rddata_reg = win_mode_r; + else if (sel_calib) rddata_reg = calib_r; + else if (sel_report) rddata_reg = report_r; + else if (sel_result) rddata_reg = result_r; end sirv_gnrl_dfflr #(32) rddata_out_dff (rden, rddata_reg, rddata, clk, rst_n); @@ -93,10 +124,11 @@ end // ============================================================================= // [SECTION G] 输出映射 (Output Assignments) // ============================================================================= -// assign sys_soft_rstn = sys_soft_rstn_r; -// assign sync_oen = syncr[18]; -// assign nco_clr = ncoctrlr[2]; -// assign nco_en = ncoctrlr[1] & doselr[2]; -// assign p2a_en = ncoctrlr[0] & doselr[2]; +assign win_us = win_mode_r[23:0]; +assign out_mode = win_mode_r[25:24]; +assign temp_85_fre_k = calib_r[31:16]; +assign temp_neg_40_fre_k = calib_r[15:0]; +assign report_en = report_r[31]; +assign rep_gap_us = report_r[23:0]; endmodule \ No newline at end of file diff --git a/tb/TB_top.sv b/tb/TB_top.sv index 6068fd9..ebc03cb 100644 --- a/tb/TB_top.sv +++ b/tb/TB_top.sv @@ -13,6 +13,7 @@ module TB_top(); reg rst_n; reg uart_rx; // 对应 DUT 的 RX wire uart_tx; // 对应 DUT 的 TX + reg sig_in; // 时钟生成 initial clk = 0; @@ -25,7 +26,8 @@ module TB_top(); .clk (clk), .rst_n (rst_n), .uart_rx (uart_rx), - .uart_tx (uart_tx) + .uart_tx (uart_tx), + .sig_in (sig_in) ); // ========================================== @@ -150,4 +152,29 @@ module TB_top(); end end + // --- Pulse Generation Task --- + // freq_khz: Target frequency (kHz) + // duration_ms: Test duration (ms) + task automatic gen_pulses(input int freq_khz, input int duration_ms); + int half_period_ns; + longint end_time_ns; + begin + if (freq_khz <= 0) begin + sig_in = 0; + #(duration_ms * 1000000); + end else begin + half_period_ns = 500000 / freq_khz; + end_time_ns = $time + (longint'(duration_ms) * 1000000); + + $display("[%0t] Start generating signal: %0d kHz", $time, freq_khz); + while ($time < end_time_ns) begin + sig_in = 1; + #(half_period_ns); + sig_in = 0; + #(half_period_ns); + end + end + end + endtask + endmodule \ No newline at end of file