uart_wb.v 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * uart_wb.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2019 Sylvain Munaut <tnt@246tNt.com>
  7. * All rights reserved.
  8. *
  9. * BSD 3-clause, see LICENSE.bsd
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. * * Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * * Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * * Neither the name of the <organization> nor the
  19. * names of its contributors may be used to endorse or promote products
  20. * derived from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25. * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  26. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  29. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. `default_nettype none
  34. module uart_wb #(
  35. parameter integer DIV_WIDTH = 8,
  36. parameter integer DW = 16
  37. )(
  38. // UART
  39. output wire uart_tx,
  40. input wire uart_rx,
  41. // Bus interface
  42. input wire [1:0] bus_addr,
  43. input wire [DW-1:0] bus_wdata,
  44. output wire [DW-1:0] bus_rdata,
  45. input wire bus_cyc,
  46. output wire bus_ack,
  47. input wire bus_we,
  48. // Clock / Reset
  49. input wire clk,
  50. input wire rst
  51. );
  52. // Signals
  53. // -------
  54. // RX fifo
  55. wire [ 7:0] urf_wdata;
  56. wire urf_wren;
  57. wire urf_full;
  58. wire [ 7:0] urf_rdata;
  59. wire urf_rden;
  60. wire urf_empty;
  61. // TX fifo
  62. wire [ 7:0] utf_wdata;
  63. wire utf_wren;
  64. wire utf_full;
  65. wire [ 7:0] utf_rdata;
  66. wire utf_rden;
  67. wire utf_empty;
  68. // TX core
  69. wire [ 7:0] uart_tx_data;
  70. wire uart_tx_valid;
  71. wire uart_tx_ack;
  72. // RX core
  73. wire [ 7:0] uart_rx_data;
  74. wire uart_rx_stb;
  75. // CSR
  76. reg [DIV_WIDTH-1:0] uart_div;
  77. // Bus IF
  78. reg ub_rd_data;
  79. reg ub_wr_data;
  80. reg ub_wr_div;
  81. reg ub_ack;
  82. // TX Core
  83. // -------
  84. uart_tx #(
  85. .DIV_WIDTH(DIV_WIDTH)
  86. ) uart_tx_I (
  87. .data(uart_tx_data),
  88. .valid(uart_tx_valid),
  89. .ack(uart_tx_ack),
  90. .tx(uart_tx),
  91. .div(uart_div),
  92. .clk(clk),
  93. .rst(rst)
  94. );
  95. // TX FIFO
  96. // -------
  97. fifo_sync_ram #(
  98. .DEPTH(512),
  99. .WIDTH(8)
  100. ) uart_tx_fifo_I (
  101. .wr_data(utf_wdata),
  102. .wr_ena(utf_wren),
  103. .wr_full(utf_full),
  104. .rd_data(utf_rdata),
  105. .rd_ena(utf_rden),
  106. .rd_empty(utf_empty),
  107. .clk(clk),
  108. .rst(rst)
  109. );
  110. // TX glue
  111. assign uart_tx_data = utf_rdata;
  112. assign uart_tx_valid = ~utf_empty;
  113. assign utf_rden = uart_tx_ack;
  114. // RX Core
  115. // -------
  116. uart_rx #(
  117. .DIV_WIDTH(DIV_WIDTH),
  118. .GLITCH_FILTER(2)
  119. ) uart_rx_I (
  120. .rx(uart_rx),
  121. .data(uart_rx_data),
  122. .stb(uart_rx_stb),
  123. .div(uart_div),
  124. .clk(clk),
  125. .rst(rst)
  126. );
  127. // RX FIFO
  128. // -------
  129. fifo_sync_ram #(
  130. .DEPTH(512),
  131. .WIDTH(8)
  132. ) uart_rx_fifo_I (
  133. .wr_data(urf_wdata),
  134. .wr_ena(urf_wren),
  135. .wr_full(urf_full),
  136. .rd_data(urf_rdata),
  137. .rd_ena(urf_rden),
  138. .rd_empty(urf_empty),
  139. .clk(clk),
  140. .rst(rst)
  141. );
  142. // RX glue
  143. assign urf_wdata = uart_rx_data;
  144. assign urf_wren = uart_rx_stb & ~urf_full;
  145. // Bus interface
  146. // -------------
  147. always @(posedge clk)
  148. if (ub_ack) begin
  149. ub_rd_data <= 1'b0;
  150. ub_wr_data <= 1'b0;
  151. ub_wr_div <= 1'b0;
  152. end else begin
  153. ub_rd_data <= ~bus_we & bus_cyc & (bus_addr == 2'b00);
  154. ub_wr_data <= bus_we & bus_cyc & (bus_addr == 2'b00) & ~utf_full;
  155. ub_wr_div <= bus_we & bus_cyc & (bus_addr == 2'b01);
  156. end
  157. always @(posedge clk)
  158. if (ub_ack)
  159. ub_ack <= 1'b0;
  160. else
  161. ub_ack <= bus_cyc & (~bus_we | (bus_addr == 2'b01) | ~utf_full);
  162. always @(posedge clk)
  163. if (ub_wr_div)
  164. uart_div <= bus_wdata[DIV_WIDTH-1:0];
  165. assign utf_wdata = bus_wdata[7:0];
  166. assign utf_wren = ub_wr_data;
  167. assign urf_rden = ub_rd_data & ~urf_empty;
  168. assign bus_rdata = ub_rd_data ? { urf_empty, { (DW-9){1'b0} }, urf_rdata } : { DW{1'b0} };
  169. assign bus_ack = ub_ack;
  170. endmodule // uart_wb