基本完成digital_top的设计,但是主动上报还没搞

This commit is contained in:
yangshenbo 2026-04-06 14:30:17 +08:00
parent c38356bc50
commit 8213e6443c
4 changed files with 150 additions and 54 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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