verilog串口收发
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.//UART串行口模块,波特率9600bps
2.//陈鹏
3.//20110118
4.
5.module UART (
6. sys_clk,//系统时钟输入
7. reset_n,//异步复位输入
8. Rx,//数据输入引脚
9. NewRxData,//接收到新数据
10. RxDATA//RxDATA当前接收的数据
11. );
12.
13. input sys_clk,reset_n,Rx;
14. output NewRxData;
15. output [7 : 0] RxDATA;
16. reg [7 : 0] RxDATA;
17.
18. parameter SYS_CLK = 20000000;//系统时钟
19. parameter Rx_CLK = 9600;//9600bps
20. parameter RxDATA_W = 12;//波特率时钟发生器分频寄存器位宽
21. parameter RXCLK_DATA = SYS_CLK / Rx_CLK - 1;//波特率分频器时钟分频
值 (2083)
22.
23.
24. //波特率时钟发生器
25. reg [RxDATA_W-1 : 0] clk_cnt;
26. reg EN_RXCLK;//使能接收时钟
27. wire RX_CLK;//接收波特率时钟
28. always @ (posedge sys_clk or negedge reset_n)
29. if(!reset_n)
30. clk_cnt <= 12'd0;
31. else if(!EN_RXCLK)//不需要使能时钟
32. clk_cnt <= 12'd0;
33. else if(clk_cnt == RXCLK_DATA)
34. clk_cnt <= 12'd0;
35. else
36. clk_cnt <= clk_cnt + 1'b1;
37.
38. assign RX_CLK = (clk_cnt == RXCLK_DATA/2);//产生接收时钟
39.
40.
41. //接收数据线下降沿检测,用来启动数据接收
42. //采用边沿检测法,因为数据线空闲位高,起始位位低,因此1帧数据开始有一个下降沿
43. reg RxThis,RxLast;
44. wire RxStart;
45. always @ (posedge sys_clk or negedge reset_n)
46. if(!reset_n) begin
47. RxThis = 1'b0;
48. RxLast = 1'b0;
49. end
50. else begin
51. RxLast <= RxThis;
52. RxThis <= Rx;
53. end
54.
55. assign RxStart = RxLast&&(!RxThis);//产生起始信号
56.
57.
58. //数据接收控制逻辑
59. reg [10 : 0] RxTemp;
60. reg [4 : 0] RxState;
61. reg NewRxData;
62. always @ (posedge sys_clk or negedge reset_n)
63. if(!reset_n) begin
64. RxDATA = 8'd0;
65. RxTemp = 11'd0;
66. RxState = 5'd0;
67. EN_RXCLK = 1'b0;//停止接收时钟
68. NewRxData = 1'b0;//去除新数据标志
69. end
70. else if((RxState==5'd0) && RxStart)begin//有起始信号,并且接收器空闲,则
再次检测起始信号
71. EN_RXCLK <= 1'd1;//启动接收时钟
72. RxState <= 5'b1; //进入接收状态机
73. end
74. else if(RX_CLK) begin //每个接收时钟启动一次
75. case (RxState) //synthesis full_case
76. 5'd1 : begin
77. RxTemp[0] = Rx;//接收起始位
78. RxState <= 5'd2;
79. end
80. 5'd2 : begin
81. RxTemp[1] = Rx;//bit0
82. RxState <= 5'd3;
83. end
84. 5'd3 : begin
85. RxTemp[2] = Rx;//bit1
86. RxState <= 5'd4;
87. end
88. 5'd4 : begin
89. RxTemp[3] = Rx;//bit2
90. RxState <= 5'd5;
91. end
92. 5'd5 : begin
93. RxTemp[4] = Rx;//bit3
94. RxState <= 5'd6;
95. end
96. 5'd6 : begin
97. RxTemp[5] = Rx;//bit4
98. RxState <= 5'd7;
99. end
100. 5'd7 : begin
101. RxTemp[6] = Rx;//bit5
102. RxState <= 5'd8;
103. end
104. 5'd8 : begin
105. RxTemp[7] = Rx;//bit6
106. RxState <= 5'd9;
107. end
108. 5'd9 : begin
109. RxTemp[8] = Rx;//bit7
110. RxState <= 5'd10;
111. end
112. 5'd10 : begin
113. RxTemp[9] = Rx;//校验位
114. RxState <= 5'd11;
115. end
116. 5'd11 : begin
117. RxTemp[10] = Rx;//结束位,接收完成
118. EN_RXCLK <= 1'b0;//停止接收时钟
119. RxState <= 5'd0;//接收进入空闲状态
120. if(!RxTemp[0] && RxTemp[10]) begin//有正确的起始和停止位
121. RxDATA <= RxTemp[8 : 1];//保存接收的数据
122. NewRxData = 1'b1;//新数据标志置位
123. end
124. end
125. endcase
126. end //end else if
127. else
128. NewRxData = 1'b0;//去除新数据标志