module baud_detect ( input wire sys_clock, // 修正:匹配你的SYSCLK=200MHz input wire rst_n, // 复位信号(低有效) input wire UART1_DETECT, output reg [31:0] baud_rate // 计算得到的波特率 ); parameter NUM_EDGES = 16; // 统计 16 次跳变 reg [23:0] counter; reg [23:0] edge_times [0:NUM_EDGES-1]; // 存储每个跳变的间隔 reg [3:0] index; reg last_rxd; reg [23:0] min_time; // 记录最小的跳变时间 integer i; // reg uart_sync1, uart_sync2; // always @(posedge sys_clock or negedge rst_n) begin // if(!rst_n) begin // uart_sync1 <= 1'b1; // uart_sync2 <= 1'b1; // end else begin // uart_sync1 <= UART1_DETECT; // uart_sync2 <= uart_sync1; // end // end always @(posedge sys_clock or negedge rst_n) begin if (!rst_n) begin counter <= 0; index <= 0; last_rxd <= 1; // UART 空闲态通常是高电平 min_time <= 32'hFFFFFFFF; end else begin counter <= counter + 1; // 仅在 `UART1_DETECT` 上升沿或下降沿时记录时间 if (last_rxd != UART1_DETECT) begin edge_times[index] <= counter; index <= (index + 1) % NUM_EDGES; // 取模存储最新的16个值 counter <= 0; // 重新计时 end last_rxd <= UART1_DETECT; // 记录上一周期的状态 end end // 在 16 个间隔值中寻找最短的一个,作为 Bit 时间 always @(posedge sys_clock) begin min_time = 32'hFFFFFFFF; // 初始化为最大值 for (i = 0; i < NUM_EDGES; i = i + 1) begin if (edge_times[i] > 0 && edge_times[i] < min_time) begin min_time = edge_times[i]; end end // 计算波特率 if (min_time > 0 && min_time != 32'hFFFFFFFF) begin baud_rate <= min_time; end end endmodule // module baud_detect ( // input wire sys_clock, // 72MHz // input wire rst_n, // input wire UART1_DETECT, // 原始输入(无过滤) // output reg [31:0] baud_rate // 实时真实波特率 // ); // parameter SYS_CLK_FREQ = 32'd72000000; // parameter RESET_TIME = 32'd144000000; // 每2s重置一次最小值(72MHz*1ms=72000) // // 1. 异步打2拍同步(硬件必需,无修改) // reg uart_sync1, uart_sync2; // always @(posedge sys_clock or negedge rst_n) begin // if(!rst_n) begin // uart_sync1 <= 1'b1; // uart_sync2 <= 1'b1; // end else begin // uart_sync1 <= UART1_DETECT; // uart_sync2 <= uart_sync1; // end // end // // 2. 计数器 + 最小值记录 // reg [31:0] bit_cnt; // reg [31:0] min_bit_time; // reg last_uart; // // 3. 自动重置计时器(1ms自动清最小值,不让毛刺永久霸占) // reg [31:0] reset_cnt; // always @(posedge sys_clock or negedge rst_n) begin // if(!rst_n) begin // bit_cnt <= 32'd0; // min_bit_time <= 32'hFFFFFFFF; // last_uart <= 1'b1; // reset_cnt <= 32'd0; // baud_rate <= 32'd0; // end else begin // bit_cnt <= bit_cnt + 1'd1; // reset_cnt <= reset_cnt + 1'd1; // // ===================== 关键:1ms自动重置最小值 ===================== // if(reset_cnt == RESET_TIME) begin // min_bit_time <= 32'hFFFFFFFF; // 清空最小值,重新开始记录 // reset_cnt <= 32'd0; // end // // ===================== 记录所有跳变(无过滤、无限制) ===================== // if(last_uart != uart_sync2) begin // // 只更新更小的时间(原理必需) // if(bit_cnt < min_bit_time) begin // min_bit_time <= bit_cnt; // end // bit_cnt <= 32'd0; // end // last_uart <= uart_sync2; // // ===================== 实时计算波特率(无修改) ===================== // if(min_bit_time > 0 && min_bit_time != 32'hFFFFFFFF) begin // baud_rate <= SYS_CLK_FREQ / min_bit_time; // end else begin // baud_rate <= 32'd0; // end // end // end // endmodule