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