baud_detect.v 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. module baud_detect (
  2. input wire sys_clock, // 修正:匹配你的SYSCLK=200MHz
  3. input wire rst_n, // 复位信号(低有效)
  4. input wire UART1_DETECT,
  5. output reg [31:0] baud_rate // 计算得到的波特率
  6. );
  7. parameter NUM_EDGES = 16; // 统计 16 次跳变
  8. reg [23:0] counter;
  9. reg [23:0] edge_times [0:NUM_EDGES-1]; // 存储每个跳变的间隔
  10. reg [3:0] index;
  11. reg last_rxd;
  12. reg [23:0] min_time; // 记录最小的跳变时间
  13. integer i;
  14. // reg uart_sync1, uart_sync2;
  15. // always @(posedge sys_clock or negedge rst_n) begin
  16. // if(!rst_n) begin
  17. // uart_sync1 <= 1'b1;
  18. // uart_sync2 <= 1'b1;
  19. // end else begin
  20. // uart_sync1 <= UART1_DETECT;
  21. // uart_sync2 <= uart_sync1;
  22. // end
  23. // end
  24. always @(posedge sys_clock or negedge rst_n) begin
  25. if (!rst_n) begin
  26. counter <= 0;
  27. index <= 0;
  28. last_rxd <= 1; // UART 空闲态通常是高电平
  29. min_time <= 32'hFFFFFFFF;
  30. end else begin
  31. counter <= counter + 1;
  32. // 仅在 `UART1_DETECT` 上升沿或下降沿时记录时间
  33. if (last_rxd != UART1_DETECT) begin
  34. edge_times[index] <= counter;
  35. index <= (index + 1) % NUM_EDGES; // 取模存储最新的16个值
  36. counter <= 0; // 重新计时
  37. end
  38. last_rxd <= UART1_DETECT; // 记录上一周期的状态
  39. end
  40. end
  41. // 在 16 个间隔值中寻找最短的一个,作为 Bit 时间
  42. always @(posedge sys_clock) begin
  43. min_time = 32'hFFFFFFFF; // 初始化为最大值
  44. for (i = 0; i < NUM_EDGES; i = i + 1) begin
  45. if (edge_times[i] > 0 && edge_times[i] < min_time) begin
  46. min_time = edge_times[i];
  47. end
  48. end
  49. // 计算波特率
  50. if (min_time > 0 && min_time != 32'hFFFFFFFF) begin
  51. baud_rate <= min_time;
  52. end
  53. end
  54. endmodule
  55. // module baud_detect (
  56. // input wire sys_clock, // 72MHz
  57. // input wire rst_n,
  58. // input wire UART1_DETECT, // 原始输入(无过滤)
  59. // output reg [31:0] baud_rate // 实时真实波特率
  60. // );
  61. // parameter SYS_CLK_FREQ = 32'd72000000;
  62. // parameter RESET_TIME = 32'd144000000; // 每2s重置一次最小值(72MHz*1ms=72000)
  63. // // 1. 异步打2拍同步(硬件必需,无修改)
  64. // reg uart_sync1, uart_sync2;
  65. // always @(posedge sys_clock or negedge rst_n) begin
  66. // if(!rst_n) begin
  67. // uart_sync1 <= 1'b1;
  68. // uart_sync2 <= 1'b1;
  69. // end else begin
  70. // uart_sync1 <= UART1_DETECT;
  71. // uart_sync2 <= uart_sync1;
  72. // end
  73. // end
  74. // // 2. 计数器 + 最小值记录
  75. // reg [31:0] bit_cnt;
  76. // reg [31:0] min_bit_time;
  77. // reg last_uart;
  78. // // 3. 自动重置计时器(1ms自动清最小值,不让毛刺永久霸占)
  79. // reg [31:0] reset_cnt;
  80. // always @(posedge sys_clock or negedge rst_n) begin
  81. // if(!rst_n) begin
  82. // bit_cnt <= 32'd0;
  83. // min_bit_time <= 32'hFFFFFFFF;
  84. // last_uart <= 1'b1;
  85. // reset_cnt <= 32'd0;
  86. // baud_rate <= 32'd0;
  87. // end else begin
  88. // bit_cnt <= bit_cnt + 1'd1;
  89. // reset_cnt <= reset_cnt + 1'd1;
  90. // // ===================== 关键:1ms自动重置最小值 =====================
  91. // if(reset_cnt == RESET_TIME) begin
  92. // min_bit_time <= 32'hFFFFFFFF; // 清空最小值,重新开始记录
  93. // reset_cnt <= 32'd0;
  94. // end
  95. // // ===================== 记录所有跳变(无过滤、无限制) =====================
  96. // if(last_uart != uart_sync2) begin
  97. // // 只更新更小的时间(原理必需)
  98. // if(bit_cnt < min_bit_time) begin
  99. // min_bit_time <= bit_cnt;
  100. // end
  101. // bit_cnt <= 32'd0;
  102. // end
  103. // last_uart <= uart_sync2;
  104. // // ===================== 实时计算波特率(无修改) =====================
  105. // if(min_bit_time > 0 && min_bit_time != 32'hFFFFFFFF) begin
  106. // baud_rate <= SYS_CLK_FREQ / min_bit_time;
  107. // end else begin
  108. // baud_rate <= 32'd0;
  109. // end
  110. // end
  111. // end
  112. // endmodule