uart2wb.v 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * uart2wb.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2020 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 uart2wb #(
  35. parameter integer WB_N = 3,
  36. // auto
  37. parameter integer DL = (32*WB_N)-1,
  38. parameter integer CL = WB_N-1
  39. )(
  40. // UART
  41. input wire uart_rx,
  42. output wire uart_tx,
  43. input wire [ 7:0] uart_div,
  44. // Wishbone
  45. output reg [31:0] wb_wdata,
  46. input wire [DL:0] wb_rdata,
  47. output reg [15:0] wb_addr,
  48. output reg wb_we,
  49. output reg [CL:0] wb_cyc,
  50. input wire [CL:0] wb_ack,
  51. // Aux-CSR
  52. output reg [31:0] aux_csr,
  53. // Clock / Reset
  54. input wire clk,
  55. input wire rst
  56. );
  57. localparam
  58. CMD_SYNC = 4'h0,
  59. CMD_REG_ACCESS = 4'h1,
  60. CMD_DATA_SET = 4'h2,
  61. CMD_DATA_GET = 4'h3,
  62. CMD_AUX_CSR = 4'h4;
  63. // Signals
  64. // -------
  65. // UART serdes
  66. wire [7:0] rx_data;
  67. wire rx_stb;
  68. wire [7:0] tx_data;
  69. wire tx_ack;
  70. wire tx_valid;
  71. // Command RX
  72. reg [39:0] rx_reg;
  73. reg [ 2:0] rx_cnt;
  74. wire [ 3:0] cmd_code;
  75. wire [31:0] cmd_data;
  76. reg cmd_stb;
  77. // Response TX
  78. reg [31:0] tx_reg;
  79. reg [ 2:0] tx_cnt;
  80. reg [31:0] resp_data;
  81. reg resp_ld;
  82. // Wishbone interface
  83. reg [31:0] wb_rdata_i;
  84. wire wb_ack_i;
  85. // Host interface
  86. // --------------
  87. // UART module
  88. uart_rx #(
  89. .DIV_WIDTH(8),
  90. .GLITCH_FILTER(0)
  91. ) rx_I (
  92. .rx(uart_rx),
  93. .data(rx_data),
  94. .stb(rx_stb),
  95. .div(uart_div),
  96. .clk(clk),
  97. .rst(rst)
  98. );
  99. uart_tx #(
  100. .DIV_WIDTH(8)
  101. ) tx_I (
  102. .tx(uart_tx),
  103. .data(tx_data),
  104. .valid(tx_valid),
  105. .ack(tx_ack),
  106. .div(uart_div),
  107. .clk(clk),
  108. .rst(rst)
  109. );
  110. // Command input
  111. always @(posedge clk or posedge rst)
  112. if (rst)
  113. rx_cnt <= 3'd0;
  114. else if (rx_stb)
  115. rx_cnt <= rx_cnt[2] ? 3'd0 : (rx_cnt + 1);
  116. always @(posedge clk)
  117. if (rx_stb)
  118. rx_reg <= { rx_reg[31:0], rx_data };
  119. assign cmd_code = rx_reg[39:36];
  120. assign cmd_data = rx_reg[31: 0];
  121. always @(posedge clk)
  122. cmd_stb <= rx_cnt[2] & rx_stb;
  123. // Response output
  124. always @(posedge clk or posedge rst)
  125. if (rst)
  126. tx_cnt <= 3'd0;
  127. else begin
  128. if (resp_ld)
  129. tx_cnt <= 3'd4;
  130. else if (tx_ack)
  131. tx_cnt <= tx_cnt - 1;
  132. end
  133. always @(posedge clk)
  134. if (resp_ld)
  135. tx_reg <= resp_data;
  136. else if (tx_ack)
  137. tx_reg <= { tx_reg[23:0], 8'h00 };
  138. assign tx_data = tx_reg[31:24];
  139. assign tx_valid = |tx_cnt;
  140. // Commands
  141. always @(posedge clk)
  142. begin
  143. // Defaults
  144. resp_ld <= 1'b0;
  145. resp_data <= 40'hxxxxxxxxxx;
  146. // Commands
  147. if (cmd_stb) begin
  148. case (cmd_code)
  149. CMD_SYNC: begin
  150. resp_data <= 432'hcafebabe;
  151. resp_ld <= 1'b1;
  152. end
  153. CMD_REG_ACCESS: begin
  154. wb_addr <= cmd_data[15:0];
  155. wb_we <= ~cmd_data[20];
  156. wb_cyc <= (1 << cmd_data[19:16]);
  157. end
  158. CMD_DATA_SET: begin
  159. wb_wdata <= cmd_data;
  160. end
  161. CMD_DATA_GET: begin
  162. resp_ld <= 1'b1;
  163. resp_data <= wb_wdata;
  164. end
  165. CMD_AUX_CSR: begin
  166. aux_csr <= cmd_data;
  167. end
  168. endcase
  169. end
  170. if (wb_ack_i) begin
  171. // Cycle done
  172. wb_cyc <= 0;
  173. // Capture read response
  174. if (~wb_we)
  175. wb_wdata <= wb_rdata_i;
  176. end
  177. if (rst) begin
  178. wb_cyc <= 0;
  179. aux_csr <= 32'h00000000;
  180. end
  181. end
  182. // Wishbone multi-slave handling
  183. assign wb_ack_i = |wb_ack;
  184. always @(*)
  185. begin : rdata
  186. integer i;
  187. wb_rdata_i = 32'h00000000;
  188. for (i=0; i<WB_N; i=i+1)
  189. wb_rdata_i = wb_rdata_i | wb_rdata[32*i+:32];
  190. end
  191. endmodule