当前位置:   article > 正文

【逻辑学习笔记】uart_rx模块-verilog_verilog uart 16倍过采样

verilog uart 16倍过采样

功能

接收并行数据,将数据转成并行数据,依次发出。

和发送端的区别:

  1. 发送端只需要按照规范或标准进行设计;
  2. 接收端不仅要按照规范或标准进行设计,而且需要考虑很多异常处理设计,比如发送端没有按照约定发送怎么办,比如链路上有干扰怎么办

接口

信号名

方向

含义

BAUD_RATE

parameter/input

parameter类型,波特率

clk

input

模块工作时钟

reset_n

input

模块复位信号

uart_rxd

input

接收的串行数据

rx_data[7:0]

output

解析出的并行数据

rx_dv

output

接收数据有效指示信号,因为端口是clk,这个信号是clk的时钟域,一个时钟宽度

时序图

 

实现思路

对串行线上进行16倍波特率的过采样(upsampling)(即1位数据采样16次),这样可以避免线上干扰,收发时钟skew的问题,通过过采样的数据判断起始位,数据位,还是停止位。

起始位判断这里有个技术细节:从哪一次开始计数到16次,这里需要边沿检测,检测到边沿后开始计数。

沿检测的方法:上一个时钟采样到1,下一个时钟采样到0(下降沿),这个时钟用哪个有不同的区别,这里选择与数据判断一致的16倍波特率时钟

每解析出一位数据位,将这一位数据存在寄存器中,等停止位判断正确后,将rx_dv拉高一个时钟周期。

如果停止位不对,就舍弃这8位数据,重新等待起始位。

这次rx的难度明显比tx大,其中一个关键点,就是多了一个时钟,如果觉得复杂,是否可以拆分成更小的module,每个module使用一个时钟

将rx分成如下几个部分:

Baud_rate_clk产生部分:输入系统时钟,输出预期波特率16倍的时钟

位检测处理部分:输入波特率16倍的时钟,输入串行数据,输入串行数据有效标志,输出位检测结果,并伴随数据有效信号

——这部分相对独立,可以考虑将其封装成一个module

调试过程中总结

  1. 写代码脑中一片空白,不知道从而写起,就把各个部分的核心语句以伪代码的形势先想出来,可以写在这个word中
  2. 养成赋值#1的习惯
  3. 这次rx的难度明显比tx大,其中一个关键点,就是多了一个时钟,如果觉得复杂,是否可以拆分成更小的module,每个module使用一个时钟
  4. 每个always块最好只对一个变量幅值
  5. 为了减少状态机,不使用中间变量negedge_detect,这样使得state能够和数据对应,而不会晚一拍
  1. module uart_rx
  2. #(parameter SYSCLK = 50_000_000, BAUDRATE = 115200)
  3. (
  4. clk,
  5. reset_n,
  6. uart_rxd,
  7. rx_data,
  8. rx_dv
  9. );
  10. input clk;
  11. input reset_n;
  12. input uart_rxd;
  13. output reg [7:0] rx_data;
  14. output reg rx_dv;
  15. wire baud_clk_16;
  16. reg uart_rxd_r;
  17. wire sdata;
  18. reg sdata_valid;
  19. wire bit;
  20. wire bit_valid;
  21. parameter IDLE = 4'b0000;
  22. parameter START_BIT = 4'b0001;
  23. parameter RXD_BIT0 = 4'b0010;
  24. parameter RXD_BIT1 = 4'b0011;
  25. parameter RXD_BIT2 = 4'b0100;
  26. parameter RXD_BIT3 = 4'b0101;
  27. parameter RXD_BIT4 = 4'b0110;
  28. parameter RXD_BIT5 = 4'b0111;
  29. parameter RXD_BIT6 = 4'b1000;
  30. parameter RXD_BIT7 = 4'b1001;
  31. parameter STOP_BIT = 4'b1010;
  32. reg [3:0] state;
  33. reg [7:0] temp_data;
  34. reg [3:0] rxd_bit_cnt;
  35. //产生波特�??16倍的时钟
  36. baud_clk_gen
  37. #(SYSCLK, BAUDRATE)
  38. baud_clk_gen_inst
  39. (
  40. .clk(clk),
  41. .reset_n(reset_n),
  42. .baud_clk_16(baud_clk_16)
  43. );
  44. //起始位下降沿�??�??
  45. always@(posedge baud_clk_16)
  46. begin
  47. uart_rxd_r <= #1 uart_rxd;
  48. end
  49. //状�?�机
  50. //主状态机的输�??
  51. always@(posedge clk or negedge reset_n)
  52. begin
  53. if(!reset_n)
  54. begin
  55. rx_dv <= #1 0;
  56. rx_data <= #1 8'b0;
  57. temp_data <= #1 8'b0;
  58. end
  59. else
  60. begin
  61. case(state)
  62. RXD_BIT0:
  63. begin
  64. rx_dv <= #1 0;
  65. rx_data <= #1 rx_data;
  66. if(bit_valid)
  67. temp_data <= #1 {temp_data[7:1],bit};
  68. end
  69. RXD_BIT1:
  70. begin
  71. rx_dv <= #1 0;
  72. rx_data <= #1 rx_data;
  73. if(bit_valid)
  74. temp_data <= #1 {temp_data[7:2],bit,temp_data[0]};
  75. end
  76. RXD_BIT2:
  77. begin
  78. rx_dv <= #1 0;
  79. rx_data <= #1 rx_data;
  80. if(bit_valid)
  81. temp_data <= #1 {temp_data[7:3],bit,temp_data[1:0]};
  82. end
  83. RXD_BIT3:
  84. begin
  85. rx_dv <= #1 0;
  86. rx_data <= #1 rx_data;
  87. if(bit_valid)
  88. temp_data <= #1 {temp_data[7:4],bit,temp_data[2:0]};
  89. end
  90. RXD_BIT4:
  91. begin
  92. rx_dv <= #1 0;
  93. rx_data <= #1 rx_data;
  94. if(bit_valid)
  95. temp_data <= #1 {temp_data[7:5],bit,temp_data[3:0]};
  96. end
  97. RXD_BIT5:
  98. begin
  99. rx_dv <= #1 0;
  100. rx_data <= #1 rx_data;
  101. if(bit_valid)
  102. temp_data <= #1 {temp_data[7:6],bit,temp_data[4:0]};
  103. end
  104. RXD_BIT6:
  105. begin
  106. rx_dv <= #1 0;
  107. rx_data <= #1 rx_data;
  108. if(bit_valid)
  109. temp_data <= #1 {temp_data[7],bit,temp_data[5:0]};
  110. end
  111. RXD_BIT7:
  112. begin
  113. rx_dv <= #1 0;
  114. rx_data <= #1 rx_data;
  115. if(bit_valid)
  116. temp_data <= #1 {bit,temp_data[6:0]};
  117. end
  118. STOP_BIT:
  119. begin
  120. if(bit_valid & (1 == bit) & (0 ==rx_dv))
  121. begin
  122. rx_dv <= #1 1;
  123. rx_data <= #1 temp_data;
  124. end
  125. else
  126. begin
  127. rx_dv <= #1 0;
  128. rx_data <= #1 rx_data;
  129. end
  130. temp_data <= #1 temp_data;
  131. end
  132. default:
  133. begin
  134. rx_dv <= #1 0;
  135. rx_data <= #1 rx_data;
  136. temp_data <= #1 temp_data;
  137. end
  138. endcase
  139. end
  140. end
  141. //状�?�机的跳转条�??
  142. always@(posedge baud_clk_16 or negedge reset_n)
  143. begin
  144. if(!reset_n)
  145. state <= #1 IDLE;
  146. else if((IDLE == state) & (1 == uart_rxd_r) & (0 == uart_rxd))
  147. state <= #1 START_BIT;
  148. else if((START_BIT == state) & bit_valid & (0 == bit))
  149. state <= #1 RXD_BIT0;
  150. else if((START_BIT == state) & bit_valid & (1 == bit))
  151. state <= #1 IDLE;
  152. else if((RXD_BIT0 == state) & bit_valid)
  153. state <= #1 RXD_BIT1;
  154. else if((RXD_BIT1 == state) & bit_valid)
  155. state <= #1 RXD_BIT2;
  156. else if((RXD_BIT2 == state) & bit_valid)
  157. state <= #1 RXD_BIT3;
  158. else if((RXD_BIT3 == state) & bit_valid)
  159. state <= #1 RXD_BIT4;
  160. else if((RXD_BIT4 == state) & bit_valid)
  161. state <= #1 RXD_BIT5;
  162. else if((RXD_BIT5 == state) & bit_valid)
  163. state <= #1 RXD_BIT6;
  164. else if((RXD_BIT6 == state) & bit_valid)
  165. state <= #1 RXD_BIT7;
  166. else if((RXD_BIT7 == state) & bit_valid)
  167. state <= #1 STOP_BIT;
  168. else if((STOP_BIT == state) & bit_valid)
  169. state <= #1 IDLE;
  170. else
  171. state <= #1 state;
  172. end
  173. //位数据采�??
  174. assign sdata = uart_rxd_r;
  175. bit_sample bit_sample_inst
  176. (
  177. .baud_clk_16(baud_clk_16),
  178. .reset_n(reset_n),
  179. .sdata(sdata),
  180. .sdata_valid(sdata_valid),
  181. .bit(bit),
  182. .bit_valid(bit_valid)
  183. );
  184. always@(posedge baud_clk_16 or negedge reset_n)
  185. begin
  186. if(!reset_n)
  187. sdata_valid <= #1 0;
  188. else if((IDLE == state) & (1 == uart_rxd_r) & (0 == uart_rxd))
  189. sdata_valid <= #1 1;
  190. else if(IDLE == state)
  191. sdata_valid <= #1 0;
  192. else if((START_BIT == state) & bit_valid & (0 == bit))
  193. sdata_valid <= #1 1;
  194. else if((START_BIT == state) & bit_valid & (1 == bit))
  195. sdata_valid <= #1 0;
  196. else if((STOP_BIT == state) & bit_valid)
  197. sdata_valid <= #1 0;
  198. else
  199. sdata_valid <= #1 1;
  200. end
  201. endmodule
  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2022/09/18 17:13:49
  7. // Design Name:
  8. // Module Name: baud_clk_gen
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. // 产生期望的波特率×16倍的时钟,这个期望通过parameter传递,这个期望的波特率BAUDRATE需要小于等于SYSCLK/32
  14. // 如SYSCLK = 50MHz,BAUDRATE = 1.5625Mbps,640ns per bit,baud_clk_16=25MHz,50ns per bit
  15. // Dependencies:
  16. //
  17. // Revision:
  18. // Revision 0.01 - File Created
  19. // Additional Comments:
  20. //
  21. //
  22. module baud_clk_gen
  23. #(parameter SYSCLK = 50_000_000, BAUDRATE = 115200)
  24. (
  25. clk,
  26. reset_n,
  27. baud_clk_16
  28. );
  29. input clk;
  30. input reset_n;
  31. output reg baud_clk_16;
  32. reg [7:0] cnt;
  33. always@(posedge clk or negedge reset_n)
  34. begin
  35. if(!reset_n)
  36. baud_clk_16 <= #1 1;
  37. else if((SYSCLK/BAUDRATE/16/2 -1) == cnt)
  38. baud_clk_16 <= #1 ~ baud_clk_16;
  39. else
  40. baud_clk_16 <= #1 baud_clk_16;
  41. end
  42. always@(posedge clk or negedge reset_n)
  43. begin
  44. if(!reset_n)
  45. cnt <= #1 8'b0;
  46. else if((SYSCLK/BAUDRATE/16/2-1) == cnt)
  47. cnt <= #1 8'b0;
  48. else
  49. cnt <= #1 cnt + 1'b1;
  50. end
  51. endmodule
  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2022/09/18 21:28:06
  7. // Design Name:
  8. // Module Name: bit_sample
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. // 每个bit位的采集。对16个采样值进行划分,前4不用,后3不用,
  14. // 选中间的9个值,9个值中,1的个数超过一半,即大于等于5,就算这一位是1
  15. // 如果0的个数超过一半,即大于等于5,就算这一位是0
  16. // Dependencies:
  17. //
  18. // Revision:
  19. // Revision 0.01 - File Created
  20. // Additional Comments:
  21. //
  22. //
  23. module bit_sample
  24. (
  25. baud_clk_16,
  26. reset_n,
  27. sdata,
  28. sdata_valid,
  29. bit,
  30. bit_valid
  31. );
  32. input baud_clk_16;
  33. input reset_n;
  34. input sdata;
  35. input sdata_valid;
  36. output reg bit;
  37. output reg bit_valid;
  38. reg [3:0] cnt;
  39. always@(posedge baud_clk_16 or negedge reset_n)
  40. begin
  41. if(!reset_n)
  42. cnt <= #1 4'b0;
  43. else if(4'b1111 == cnt)
  44. cnt <= #1 4'b0;
  45. else if(1 == sdata_valid)
  46. cnt <= #1 cnt + 1;
  47. else
  48. cnt <= #1 cnt;
  49. end
  50. reg [3:0] temp;
  51. always@(posedge baud_clk_16 or negedge reset_n)
  52. begin
  53. if(!reset_n)
  54. temp <= #1 4'b0;
  55. else if(4'b0000 == cnt)
  56. temp <= #1 4'b0;
  57. else if((4'b0100 <= cnt) & (4'b1100 >= cnt))
  58. temp <= #1 temp + sdata;
  59. else
  60. temp <= #1 temp;
  61. end
  62. always@(posedge baud_clk_16 or negedge reset_n)
  63. begin
  64. if(!reset_n)
  65. begin
  66. bit <= #1 0;
  67. bit_valid <= #1 0;
  68. end
  69. else if(4'b1110 == cnt)
  70. begin
  71. bit <= #1 (temp >= 5) ? 1 : 0;
  72. bit_valid <= #1 1;
  73. end
  74. else
  75. begin
  76. bit <= #1 bit;
  77. bit_valid <= #1 0;
  78. end
  79. end
  80. endmodule

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号