verilog串口收发

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;//去除新数据标志

相关文档
最新文档