uart_tx.v 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. module uart_tx #(parameter DATA_WIDTH = 8, FIFO_DEPTH = 1) (
  2. input clk,
  3. input rstn,
  4. input baud16,
  5. input tx_write,
  6. input [DATA_WIDTH-1:0] tx_data,
  7. input lcr_sps,
  8. input lcr_stp2,
  9. input lcr_eps,
  10. input lcr_pen,
  11. input tx_clear,
  12. output tx_full,
  13. output tx_empty,
  14. output tx_busy,
  15. output reg tx_complete,
  16. input tx_dma_en,
  17. input tx_dma_clr,
  18. output reg tx_dma_req,
  19. output reg uart_txd
  20. );
  21. parameter UART_IDLE = 3'h0;
  22. parameter UART_START = 3'h1;
  23. parameter UART_DATA = 3'h2;
  24. parameter UART_PARITY = 3'h3;
  25. parameter UART_STOP = 3'h4;
  26. reg [2:0] tx_state;
  27. reg [DATA_WIDTH-1:0] tx_shift_reg;
  28. reg tx_parity;
  29. reg [3:0] tx_baud_cnt;
  30. reg tx_bit;
  31. reg [$clog2(DATA_WIDTH)-1:0] tx_data_cnt;
  32. reg tx_stop_cnt;
  33. wire fifo_rden = !tx_empty && (!tx_busy || tx_state == UART_STOP && tx_stop_cnt == 0 && tx_bit);
  34. wire [DATA_WIDTH-1:0] fifo_out;
  35. wire tx_stop = tx_empty && !tx_busy;
  36. sync_fifo #(.WIDTH(DATA_WIDTH), .DEPTH(FIFO_DEPTH), .SHOWAEAD(1)) tx_fifo(
  37. .clk (clk ),
  38. .rstn (rstn ),
  39. .wren (tx_write ),
  40. .rden (fifo_rden),
  41. .din (tx_data ),
  42. .dout (fifo_out ),
  43. .full (tx_full ),
  44. .empty(tx_empty )
  45. );
  46. assign tx_busy = tx_state != UART_IDLE;
  47. always @(posedge clk or negedge rstn) begin
  48. if (!rstn) begin
  49. tx_state <= UART_IDLE;
  50. end else begin
  51. case (tx_state)
  52. UART_IDLE: if (fifo_rden) tx_state <= UART_START;
  53. UART_START: if (tx_bit) tx_state <= UART_DATA;
  54. UART_DATA: if (tx_bit && tx_data_cnt == 0) tx_state <= lcr_pen ? UART_PARITY : UART_STOP;
  55. UART_PARITY: if (tx_bit) tx_state <= UART_STOP;
  56. UART_STOP: if (tx_bit && tx_stop_cnt == 0) tx_state <= tx_empty ? UART_IDLE : UART_START;
  57. endcase
  58. end
  59. end
  60. always @(posedge clk or negedge rstn) begin
  61. if (!rstn) begin
  62. tx_shift_reg <= 0;
  63. end else if (fifo_rden) begin
  64. tx_shift_reg <= fifo_out;
  65. end else if (tx_bit && tx_state == UART_DATA) begin
  66. tx_shift_reg <= { tx_shift_reg[0], tx_shift_reg[DATA_WIDTH-1:1] };
  67. end
  68. end
  69. always @(posedge clk) begin
  70. if (tx_state == UART_START) begin
  71. tx_parity <= !lcr_eps;
  72. end else if (tx_state == UART_DATA && tx_bit && !lcr_sps) begin
  73. tx_parity <= tx_parity ^ tx_shift_reg[0];
  74. end
  75. end
  76. always @(posedge clk) begin
  77. if (tx_state == UART_START) begin
  78. tx_data_cnt <= DATA_WIDTH - 1;
  79. end else if (tx_state == UART_DATA && tx_bit) begin
  80. tx_data_cnt <= tx_data_cnt - 1;
  81. end
  82. end
  83. always @(posedge clk) begin
  84. if (tx_state == UART_START) begin
  85. tx_stop_cnt <= lcr_stp2;
  86. end else if (tx_state == UART_STOP && tx_bit) begin
  87. tx_stop_cnt <= tx_stop_cnt - 1;
  88. end
  89. end
  90. always @(posedge clk or negedge rstn) begin
  91. if (!rstn) begin
  92. tx_baud_cnt <= 0;
  93. end else if (tx_stop) begin
  94. tx_baud_cnt <= 0;
  95. end else if (baud16) begin
  96. tx_baud_cnt <= tx_baud_cnt + 1;
  97. end
  98. end
  99. always @(posedge clk or negedge rstn) begin
  100. if (!rstn) begin
  101. tx_bit <= 1'b0;
  102. end else if (baud16 && tx_baud_cnt == 15) begin
  103. tx_bit <= 1'b1;
  104. end else begin
  105. tx_bit <= 1'b0;
  106. end
  107. end
  108. always @(posedge clk or negedge rstn) begin
  109. if (!rstn) begin
  110. tx_complete <= 1'b0;
  111. end else if (tx_state == UART_STOP && tx_bit && tx_stop_cnt == 0 && tx_empty) begin
  112. tx_complete <= 1'b1;
  113. end else if (tx_clear || !tx_empty) begin
  114. tx_complete <= 1'b0;
  115. end
  116. end
  117. always @(posedge clk or negedge rstn) begin
  118. if (!rstn) begin
  119. tx_dma_req <= 1'b0;
  120. end else if (!tx_dma_en || tx_dma_clr) begin
  121. tx_dma_req <= 1'b0;
  122. end else if (!tx_full) begin
  123. tx_dma_req <= 1'b1;
  124. end
  125. end
  126. always @(posedge clk or negedge rstn) begin
  127. if (!rstn) begin
  128. uart_txd <= 1'b1;
  129. end else begin
  130. case (tx_state)
  131. UART_IDLE: uart_txd <= 1'b1;
  132. UART_START: uart_txd <= 1'b0;
  133. UART_DATA: uart_txd <= tx_shift_reg[0];
  134. UART_PARITY: uart_txd <= tx_parity;
  135. UART_STOP: uart_txd <= 1'b1;
  136. endcase
  137. end
  138. end
  139. endmodule