当前位置:   article > 正文

UART协议以及verilog实现_uart verilog读写

uart verilog读写

uart介绍

UART (Universal Asynchronous Receiver/Transmitter) 是一种常用的串行通讯协议,用于数据在电子设备之间的传输和通讯。它是一种异步数据传输协议,在通讯时不需要发送方和接收方之间的时钟信号同步。

uart的工作过程

UART 协议通常使用两条线路进行通讯,一条用于数据传输(TX),一条用于数据接收(RX)。uart的传输格式如下:(TX跟RX均为一位)

 空闲状态:空闲状态时,uart传输位始终保持高电平状态

 起始位:uart传输位拉低一个低电平并且持续一个周期,传输开始

 数据传输状态:uart实际要传输的数据位数,可以是 5、6、7 或 8 位。

 奇偶校验状态:是可选的,可以选择奇校验还是偶校验,用于数据的验证,通常为 0 (即不使用奇偶校验)或 1 位。

      奇校验:数据1个数为奇时,校验为0,反之为1;

      偶校验:数据0个数为奇时,校验为0,反之为1;

停止位状态:用于标识数据传输的结束位置,通常为 1 或 2 位。uart传输位恢复高电平

uart的verilog实现 

本次的实验代码使用的数据传输位数为8位,奇偶校验位数为1位,停止位为1位

uart_tx模块

uart_tx模块主要是负责将要传输的八位数据进行并串转化,输出八个单bit数据,优先输出高位uart的发送端模块分为空闲状态,开始状态,传输数据状态,奇偶校验状态和停止模块。状态图如下:

verilog代码如下: 

  1. module uart_tx(
  2. input sysclk ,
  3. input rst_n ,
  4. input [7:0] tx_data,
  5. input tx_en ,
  6. output reg tx ,
  7. output reg tx_done
  8. );
  9. parameter CLK_FREQ = 50000000 ; //
  10. parameter UART_BPS = 9600 ;
  11. localparam BPS_CNT = CLK_FREQ/UART_BPS;//每个数据位占用的周期
  12. parameter EVEN_ODD_CHECK = 1 ;
  13. parameter IDLE =5'b00001;
  14. parameter START=5'b00010;
  15. parameter DATA =5'b00100;
  16. parameter CHECK=5'b01000;
  17. parameter DONE =5'b10000;
  18. reg [4:0] state ;
  19. reg tx_flag ;//数据正在传输
  20. reg [3:0] tx_cnt ;//数据传输位计数器,
  21. reg [15:0] data_cnt ;
  22. reg check_flag;
  23. always@(posedge sysclk or negedge rst_n) begin
  24. if(rst_n==1'b0)
  25. data_cnt<=16'd0 ;
  26. else if(data_cnt==BPS_CNT)
  27. data_cnt<=16'd0 ;
  28. else if(tx_en==1'b1)
  29. data_cnt<=data_cnt+1'b1;
  30. else
  31. data_cnt<=data_cnt ;
  32. end
  33. always@(posedge sysclk or negedge rst_n) begin
  34. if(rst_n==1'b0)
  35. tx_cnt<=4'd0 ;
  36. else if(tx_cnt==4'd11)
  37. tx_cnt<=4'd0 ;
  38. else if ((tx_en==1'b1)&&(data_cnt==BPS_CNT))
  39. tx_cnt<=tx_cnt+1'b1;
  40. else
  41. tx_cnt<=tx_cnt ;
  42. end
  43. always @(posedge sysclk or negedge rst_n )
  44. if(rst_n==1'b0) begin
  45. state<=IDLE;
  46. end
  47. else
  48. case (state)
  49. IDLE: begin
  50. if((tx_en==1'b1)&&(tx_cnt==4'd1))
  51. state<=START;
  52. else
  53. state<=IDLE;
  54. end
  55. START :begin
  56. if(tx_cnt==4'd2)
  57. state<=DATA;
  58. else
  59. state<=START;
  60. end
  61. DATA:begin
  62. if(tx_cnt==4'd10)
  63. state<=CHECK;
  64. else
  65. state<=DATA;
  66. end
  67. CHECK:begin
  68. if(check_flag)
  69. state<=DONE;
  70. else
  71. state<=CHECK;
  72. end
  73. DONE:begin
  74. if(tx_done==1'b1)
  75. state<=IDLE;
  76. else
  77. state<=DONE;
  78. end
  79. default begin
  80. state<=IDLE;
  81. end
  82. endcase
  83. always @(posedge sysclk or negedge rst_n) begin
  84. if(rst_n==1'b0)
  85. tx_flag<=1'b0;
  86. else if (state==DATA)
  87. tx_flag<=1'b1;
  88. else
  89. tx_flag<=tx_flag;
  90. end
  91. always@(posedge sysclk or negedge rst_n) begin
  92. if (rst_n==1'b0)
  93. tx_done<=1'b0;
  94. else if ((state==DONE)&&(data_cnt==BPS_CNT))
  95. tx_done<=1'b1;
  96. else
  97. tx_done<=1'b0;
  98. end
  99. reg [7:0] data;
  100. reg [2:0] cnt;
  101. reg check;
  102. always@(posedge sysclk or negedge rst_n) begin
  103. if(rst_n==1'b0)
  104. tx<=1'b1;
  105. else if(state==IDLE)
  106. tx<=1'b1;
  107. else if(state==START)
  108. tx<=1'b0;
  109. else if(state==DATA)
  110. tx<=data[7-cnt];
  111. else if(state==CHECK)
  112. tx<=check;
  113. else if(state==DONE)
  114. tx<=1'b1;
  115. else
  116. tx<=tx;
  117. end
  118. always@(posedge sysclk or negedge rst_n) begin
  119. if(rst_n==1'b0)
  120. data<=8'd0;
  121. else if (state==START)
  122. data<=tx_data;
  123. else
  124. data<=data;
  125. end
  126. always@(posedge sysclk or negedge rst_n) begin
  127. if(rst_n==1'b0)
  128. cnt<=3'd0;
  129. else
  130. case(tx_cnt)
  131. 4'd0:cnt<=3'd0;
  132. 4'd1:cnt<=3'd0;
  133. 4'd2:cnt<=3'd1;
  134. 4'd3:cnt<=3'd2;
  135. 4'd4:cnt<=3'd3;
  136. 4'd5:cnt<=3'd4;
  137. 4'd6:cnt<=3'd5;
  138. 4'd7:cnt<=3'd6;
  139. 4'd8:cnt<=3'd7;
  140. 4'd9:cnt<=3'd0;
  141. 4'd10:cnt<=3'd0;
  142. default begin
  143. cnt<=cnt;
  144. end
  145. endcase
  146. end
  147. always@(posedge sysclk or negedge rst_n) begin
  148. if(rst_n==1'b0)
  149. check_flag<=1'b0;
  150. else if ((data_cnt==BPS_CNT)&&(state==CHECK))
  151. check_flag<=1'b1;
  152. else
  153. check_flag<=1'b0;
  154. end
  155. reg even_check;
  156. reg odd_check;
  157. always@(posedge sysclk or negedge rst_n)
  158. if(rst_n==1'b0) begin
  159. even_check<=1'b0;
  160. odd_check <=1'b0;
  161. end
  162. else if(tx==1'b1) begin
  163. even_check<=^tx_data;
  164. odd_check<=~^tx_data;
  165. end
  166. else begin
  167. even_check<=even_check;
  168. odd_check<=odd_check;
  169. end
  170. always@(posedge sysclk or negedge rst_n) begin
  171. if(rst_n==1'b0)
  172. check<=1'b0;
  173. else if(tx_en==1'b1&&EVEN_ODD_CHECK==1'b1)
  174. check<=even_check;
  175. else if(tx_en==1'b1&&EVEN_ODD_CHECK==1'b0)
  176. check<=odd_check;
  177. else
  178. check<=check;
  179. end
  180. endmodule

uart_rx模块

uart接收模块负责将接收到的单bit数据进行串并转化,输出一个8位的数据,先传输过来的数据放在高位。uart的发送端模块分为空闲状态,开始状态,传输数据状态,奇偶校验状态和停止模块。状态图如下:

verilog代码如下: 

  1. module uart_rx(
  2. input sysclk ,
  3. input rst_n ,
  4. input tx ,
  5. input tx_done,
  6. output reg[7:0] rx_data,
  7. output reg error ,
  8. output reg rx_done
  9. );
  10. parameter CLK_FREQ = 50000000 ; //
  11. parameter UART_BPS = 9600 ;
  12. localparam BPS_CNT = CLK_FREQ/UART_BPS;//每个数据位占用的周期
  13. parameter EVEN_ODD_CHECK = 1 ;
  14. parameter IDLE =5'b00001;
  15. parameter START=5'b00010;
  16. parameter DATA =5'b00100;//接收数据
  17. parameter CHECK=5'b01000;
  18. parameter DONE =5'b10000;
  19. reg [4:0]state;
  20. reg [15:0] data_cnt ;//计数到BPS_CNT
  21. always@(posedge sysclk or negedge rst_n) begin
  22. if(rst_n==1'b0)
  23. data_cnt<=16'd0 ;
  24. else if(data_cnt>BPS_CNT)
  25. data_cnt<=16'd0 ;
  26. else if(data_cnt<BPS_CNT)
  27. data_cnt<=data_cnt+1'b1;
  28. else
  29. data_cnt<=data_cnt ;
  30. end
  31. reg [3:0] rx_cnt;//每到bps_cnt计数
  32. always@(posedge sysclk or negedge rst_n)begin
  33. if(rst_n==1'b0)
  34. rx_cnt<=4'd0 ;
  35. else if(rx_cnt==4'd11)
  36. rx_cnt<=4'd0 ;
  37. else if (data_cnt==BPS_CNT)
  38. rx_cnt<=rx_cnt+1'b1;
  39. else
  40. rx_cnt<=rx_cnt ;
  41. end
  42. reg start_end;
  43. always@(posedge sysclk or negedge rst_n) begin
  44. if(rst_n==1'b0)
  45. start_end<=1'b0;
  46. else if((state==START)&&(data_cnt==BPS_CNT))
  47. start_end<=1'b1;
  48. else
  49. start_end<=start_end;
  50. end
  51. reg check_flag;
  52. always@(posedge sysclk or negedge rst_n) begin
  53. if(rst_n==1'b0)
  54. check_flag<=1'b0;
  55. else if ((data_cnt==BPS_CNT)&&(state==CHECK))
  56. check_flag<=1'b1;
  57. else
  58. check_flag<=1'b0;
  59. end
  60. reg [2:0]cnt;
  61. always@(posedge sysclk or negedge rst_n) begin
  62. if(rst_n==1'b0)
  63. cnt<=3'd0;
  64. else
  65. case(rx_cnt)
  66. 4'd0:cnt<=3'd0;
  67. 4'd1:cnt<=3'd0;
  68. 4'd2:cnt<=3'd1;
  69. 4'd3:cnt<=3'd2;
  70. 4'd4:cnt<=3'd3;
  71. 4'd5:cnt<=3'd4;
  72. 4'd6:cnt<=3'd5;
  73. 4'd7:cnt<=3'd6;
  74. 4'd8:cnt<=3'd7;
  75. 4'd9:cnt<=3'd0;
  76. 4'd10:cnt<=3'd0;
  77. default begin
  78. cnt<=cnt;
  79. end
  80. endcase
  81. end
  82. reg data_done;//当state==data,cnt=7时拉�?
  83. always@(posedge sysclk or negedge rst_n) begin
  84. if(rst_n==1'b0)
  85. data_done<=1'b0;
  86. else if (cnt==3'd7&&state==DATA)
  87. data_done<=1'b1;
  88. else
  89. data_done<=1'b0;
  90. end
  91. //state
  92. reg check;
  93. always @(posedge sysclk or negedge rst_n )
  94. if(rst_n==1'b0) begin
  95. state<=IDLE;
  96. end
  97. else
  98. case (state)
  99. IDLE: begin
  100. if(tx_done)
  101. state<=START;
  102. else
  103. state<=IDLE;
  104. end
  105. START :begin
  106. if(start_end)
  107. state<=DATA;
  108. else
  109. state<=START;
  110. end
  111. DATA:begin
  112. if(data_done)
  113. state<=CHECK;
  114. else
  115. state<=DATA;
  116. end
  117. CHECK:begin
  118. if(check_flag)
  119. state<=DONE;
  120. else
  121. state<=CHECK;
  122. end
  123. DONE:begin
  124. if(rx_done==1'b1)
  125. state<=IDLE;
  126. else
  127. state<=DONE;
  128. end
  129. default begin
  130. state<=IDLE;
  131. end
  132. endcase
  133. reg [7:0]shift_reg;
  134. always@(posedge sysclk or negedge rst_n) begin
  135. if(rst_n==1'b0)
  136. shift_reg<=8'd0;
  137. else if((state==DATA)&&(data_cnt==BPS_CNT))
  138. shift_reg<={tx,shift_reg[7:1]};
  139. else
  140. shift_reg<=shift_reg;
  141. end
  142. always@(posedge sysclk or negedge rst_n)
  143. if(rst_n==1'b0) begin
  144. rx_data<=8'd0;
  145. rx_done<=1'b0;
  146. end
  147. else if(state==DATA&&rx_cnt==3'd7) begin
  148. rx_data<=shift_reg;
  149. rx_done<=1'b1;
  150. end
  151. else begin
  152. rx_data<=rx_data;
  153. rx_done<=rx_done;
  154. end
  155. reg even_check;
  156. reg odd_check;
  157. always@(posedge sysclk or negedge rst_n)
  158. if(rst_n==1'b0) begin
  159. even_check<=1'b0;
  160. odd_check <=1'b0;
  161. end
  162. else if(tx==1'b1) begin
  163. even_check<=^rx_data;
  164. odd_check<=~^rx_data;
  165. end
  166. else begin
  167. even_check<=even_check;
  168. odd_check<=odd_check;
  169. end
  170. always@(posedge sysclk or negedge rst_n) begin
  171. if(rst_n==1'b0)
  172. check<=1'b0;
  173. else if(EVEN_ODD_CHECK==1'b1)
  174. check<=even_check;
  175. else if(EVEN_ODD_CHECK==1'b0)
  176. check<=odd_check;
  177. else
  178. check<=check;
  179. end
  180. always@(posedge sysclk or negedge rst_n) begin
  181. if(rst_n==1'b0)
  182. error<=1'b0;
  183. else if((state==CHECK)&&(tx==check))
  184. error<=1'b0;
  185. else if(state==CHECK&&tx!=check)
  186. error<=1'b1;
  187. else
  188. error<=error;
  189. end
  190. endmodule

uart的top模块

  1. module uart_top(
  2. input sysclk ,
  3. input rst_n ,
  4. input [7:0] tx_data,
  5. input tx_en ,
  6. output [7:0] rx_data,
  7. output error ,
  8. output rx_done
  9. );
  10. wire tx_done;
  11. wire tx ;
  12. uart_tx uart_tx_u(
  13. .sysclk (sysclk ),
  14. .rst_n (rst_n ),
  15. .tx_data(tx_data),
  16. .tx_en (tx_en ),
  17. .tx (tx ),
  18. .tx_done(tx_done)
  19. );
  20. uart_rx uart_rx_u(
  21. .sysclk (sysclk ),
  22. .rst_n (rst_n ),
  23. .tx (tx ),
  24. .tx_done(tx_done),
  25. .rx_data(rx_data),
  26. .error (error ),
  27. .rx_done(rx_done)
  28. );
  29. endmodule

uart的tb模块

  1. module uart_tb();
  2. reg sysclk ;
  3. reg rst_n ;
  4. reg [7:0] tx_data;
  5. reg tx_en ;
  6. wire [7:0] rx_data;
  7. wire error ;
  8. wire rx_done;
  9. uart_top uart_top_u(
  10. .sysclk (sysclk ),
  11. .rst_n (rst_n ),
  12. .tx_data(tx_data),
  13. .tx_en (tx_en ),
  14. .rx_data(rx_data),
  15. .error (error ),
  16. .rx_done(rx_done)
  17. );
  18. initial begin
  19. sysclk <=1'b0 ;
  20. rst_n <=1'b0 ;
  21. tx_data<=8'd0 ;
  22. tx_en <=1'b0 ;
  23. #10;
  24. rst_n <=1'b1 ;
  25. tx_en <=1'b1 ;
  26. #15;
  27. tx_data<=8'd36;
  28. end
  29. always #10sysclk=!sysclk;
  30. endmodule

uart仿真原理图

可以看出,uart_tx模块跟uart_rx模块仅使用两条线路进行通讯

uart仿真波形

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

闽ICP备14008679号