UARTrx.v 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. //////////////////////////////////////////////////////////////////////
  2. // File Downloaded from http://www.nandland.com
  3. //////////////////////////////////////////////////////////////////////
  4. // This file contains the UART Receiver. This receiver is able to
  5. // receive 8 bits of serial data, one start bit, one stop bit,
  6. // and no parity bit. When receive is complete o_rx_dv will be
  7. // driven high for one clock cycle.
  8. //
  9. // Set Parameter CLKS_PER_BIT as follows:
  10. // CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
  11. // Example: 25 MHz Clock, 115200 baud UART
  12. // (25000000)/(115200) = 217
  13. module UARTrx (
  14. input i_Clock,
  15. input reset,
  16. input i_Rx_Serial,
  17. output o_Rx_DV,
  18. output [7:0] o_Rx_Byte
  19. );
  20. parameter CLKS_PER_BIT = 50; //1MBaud
  21. parameter s_IDLE = 3'b000;
  22. parameter s_RX_START_BIT = 3'b001;
  23. parameter s_RX_DATA_BITS = 3'b010;
  24. parameter s_RX_STOP_BIT = 3'b011;
  25. parameter s_CLEANUP = 3'b100;
  26. reg r_Rx_Data_R;
  27. reg r_Rx_Data;
  28. reg [8:0] r_Clock_Count;
  29. reg [2:0] r_Bit_Index ; //8 bits total
  30. reg [7:0] r_Rx_Byte;
  31. reg r_Rx_DV;
  32. reg [2:0] r_SM_Main;
  33. initial
  34. begin
  35. r_Rx_Data_R = 1'b1;
  36. r_Rx_Data = 1'b1;
  37. r_Clock_Count = 0;
  38. r_Bit_Index = 0;
  39. r_Rx_Byte = 0;
  40. r_Rx_DV = 0;
  41. r_SM_Main = 0;
  42. end
  43. // Purpose: Double-register the incoming data.
  44. // This allows it to be used in the UART RX Clock Domain.
  45. // (It removes problems caused by metastability)
  46. always @(posedge i_Clock)
  47. begin
  48. if (reset)
  49. begin
  50. r_Rx_Data_R = 1'b1;
  51. r_Rx_Data = 1'b1;
  52. end
  53. else
  54. begin
  55. r_Rx_Data_R <= i_Rx_Serial;
  56. r_Rx_Data <= r_Rx_Data_R;
  57. end
  58. end
  59. // Purpose: Control RX state machine
  60. always @(posedge i_Clock)
  61. begin
  62. if (reset)
  63. begin
  64. r_Clock_Count = 0;
  65. r_Bit_Index = 0;
  66. r_Rx_Byte = 0;
  67. r_Rx_DV = 0;
  68. r_SM_Main = 0;
  69. end
  70. else
  71. begin
  72. case (r_SM_Main)
  73. s_IDLE :
  74. begin
  75. r_Rx_DV <= 1'b0;
  76. r_Clock_Count <= 0;
  77. r_Bit_Index <= 0;
  78. if (r_Rx_Data == 1'b0) // Start bit detected
  79. r_SM_Main <= s_RX_START_BIT;
  80. else
  81. r_SM_Main <= s_IDLE;
  82. end
  83. // Check middle of start bit to make sure it's still low
  84. s_RX_START_BIT :
  85. begin
  86. if (r_Clock_Count == (CLKS_PER_BIT-1)/2)
  87. begin
  88. if (r_Rx_Data == 1'b0)
  89. begin
  90. r_Clock_Count <= 0; // reset counter, found the middle
  91. r_SM_Main <= s_RX_DATA_BITS;
  92. end
  93. else
  94. r_SM_Main <= s_IDLE;
  95. end
  96. else
  97. begin
  98. r_Clock_Count <= r_Clock_Count + 1;
  99. r_SM_Main <= s_RX_START_BIT;
  100. end
  101. end // case: s_RX_START_BIT
  102. // Wait CLKS_PER_BIT-1 clock cycles to sample serial data
  103. s_RX_DATA_BITS :
  104. begin
  105. if (r_Clock_Count < CLKS_PER_BIT-1)
  106. begin
  107. r_Clock_Count <= r_Clock_Count + 1;
  108. r_SM_Main <= s_RX_DATA_BITS;
  109. end
  110. else
  111. begin
  112. r_Clock_Count <= 0;
  113. r_Rx_Byte[r_Bit_Index] <= r_Rx_Data;
  114. // Check if we have received all bits
  115. if (r_Bit_Index < 7)
  116. begin
  117. r_Bit_Index <= r_Bit_Index + 1;
  118. r_SM_Main <= s_RX_DATA_BITS;
  119. end
  120. else
  121. begin
  122. r_Bit_Index <= 0;
  123. r_SM_Main <= s_RX_STOP_BIT;
  124. end
  125. end
  126. end // case: s_RX_DATA_BITS
  127. // Receive Stop bit. Stop bit = 1
  128. s_RX_STOP_BIT :
  129. begin
  130. // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
  131. if (r_Clock_Count < CLKS_PER_BIT-1)
  132. begin
  133. r_Clock_Count <= r_Clock_Count + 1;
  134. r_SM_Main <= s_RX_STOP_BIT;
  135. end
  136. else
  137. begin
  138. r_Rx_DV <= 1'b1;
  139. r_Clock_Count <= 0;
  140. r_SM_Main <= s_CLEANUP;
  141. end
  142. end // case: s_RX_STOP_BIT
  143. // Stay here 1 clock
  144. s_CLEANUP :
  145. begin
  146. r_SM_Main <= s_IDLE;
  147. end
  148. default :
  149. r_SM_Main <= s_IDLE;
  150. endcase
  151. end
  152. end
  153. assign o_Rx_DV = r_Rx_DV;
  154. assign o_Rx_Byte = r_Rx_Byte;
  155. endmodule // uart_rx