top.v 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * top.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
  7. * SPDX-License-Identifier: CERN-OHL-P-2.0
  8. */
  9. `default_nettype none
  10. `include "boards.vh"
  11. module top (
  12. // SPI
  13. inout wire spi_mosi,
  14. inout wire spi_miso,
  15. inout wire spi_clk,
  16. inout wire spi_flash_cs_n,
  17. `ifdef HAS_PSRAM
  18. inout wire spi_ram_cs_n,
  19. `endif
  20. // USB
  21. inout wire usb_dp,
  22. inout wire usb_dn,
  23. output wire usb_pu,
  24. // Debug UART
  25. input wire uart_rx,
  26. output wire uart_tx,
  27. // Button
  28. input wire btn,
  29. // LED
  30. output wire [2:0] rgb,
  31. // Clock
  32. input wire clk_in
  33. );
  34. localparam integer SPRAM_AW = 14; /* 14 => 64k, 15 => 128k */
  35. localparam integer WB_N = 6;
  36. localparam integer WB_DW = 32;
  37. localparam integer WB_AW = 16;
  38. localparam integer WB_RW = WB_DW * WB_N;
  39. localparam integer WB_MW = WB_DW / 8;
  40. genvar i;
  41. // Signals
  42. // -------
  43. // Wishbone
  44. wire [WB_AW-1:0] wb_addr;
  45. wire [WB_DW-1:0] wb_rdata [0:WB_N-1];
  46. wire [WB_RW-1:0] wb_rdata_flat;
  47. wire [WB_DW-1:0] wb_wdata;
  48. wire [WB_MW-1:0] wb_wmsk;
  49. wire [WB_N -1:0] wb_cyc;
  50. wire wb_we;
  51. wire [WB_N -1:0] wb_ack;
  52. // USB Core
  53. // EP Buffer
  54. wire [ 8:0] ep_tx_addr_0;
  55. wire [31:0] ep_tx_data_0;
  56. wire ep_tx_we_0;
  57. wire [ 8:0] ep_rx_addr_0;
  58. wire [31:0] ep_rx_data_1;
  59. wire ep_rx_re_0;
  60. // Bus interface
  61. wire [11:0] ub_addr;
  62. wire [15:0] ub_wdata;
  63. wire [15:0] ub_rdata;
  64. wire ub_cyc;
  65. wire ub_we;
  66. wire ub_ack;
  67. // SPI
  68. wire [7:0] sb_addr;
  69. wire [7:0] sb_di;
  70. wire [7:0] sb_do;
  71. wire sb_rw;
  72. wire sb_stb;
  73. wire sb_ack;
  74. wire sb_irq;
  75. wire sb_wkup;
  76. wire sio_miso_o, sio_miso_oe, sio_miso_i;
  77. wire sio_mosi_o, sio_mosi_oe, sio_mosi_i;
  78. wire sio_clk_o, sio_clk_oe, sio_clk_i;
  79. wire [3:0] sio_csn_o, sio_csn_oe;
  80. // LEDs
  81. reg [4:0] led_ctrl;
  82. wire [2:0] rgb_pwm;
  83. // WarmBoot
  84. reg boot_now;
  85. reg [1:0] boot_sel;
  86. // Clock / Reset logic
  87. wire clk_24m;
  88. wire clk_48m;
  89. wire rst;
  90. // SoC
  91. // ---
  92. soc_picorv32_base #(
  93. .WB_N (WB_N),
  94. .WB_DW (WB_DW),
  95. .WB_AW (WB_AW),
  96. .SPRAM_AW(SPRAM_AW)
  97. ) base_I (
  98. .wb_addr (wb_addr),
  99. .wb_rdata(wb_rdata_flat),
  100. .wb_wdata(wb_wdata),
  101. .wb_wmsk (wb_wmsk),
  102. .wb_we (wb_we),
  103. .wb_cyc (wb_cyc),
  104. .wb_ack (wb_ack),
  105. .clk (clk_24m),
  106. .rst (rst)
  107. );
  108. for (i=0; i<WB_N; i=i+1)
  109. assign wb_rdata_flat[i*WB_DW+:WB_DW] = wb_rdata[i];
  110. // UART
  111. // ----
  112. uart_wb #(
  113. .DIV_WIDTH(12),
  114. .DW(WB_DW)
  115. ) uart_I (
  116. .uart_tx(uart_tx),
  117. .uart_rx(uart_rx),
  118. .wb_addr(wb_addr[1:0]),
  119. .wb_rdata(wb_rdata[1]),
  120. .wb_we(wb_we),
  121. .wb_wdata(wb_wdata),
  122. .wb_cyc(wb_cyc[1]),
  123. .wb_ack(wb_ack[1]),
  124. .clk(clk_24m),
  125. .rst(rst)
  126. );
  127. // SPI
  128. // ---
  129. // Hard-IP
  130. `ifndef SIM
  131. SB_SPI #(
  132. .BUS_ADDR74("0b0000")
  133. ) spi_I (
  134. .SBCLKI(clk_24m),
  135. .SBRWI(sb_rw),
  136. .SBSTBI(sb_stb),
  137. .SBADRI7(sb_addr[7]),
  138. .SBADRI6(sb_addr[6]),
  139. .SBADRI5(sb_addr[5]),
  140. .SBADRI4(sb_addr[4]),
  141. .SBADRI3(sb_addr[3]),
  142. .SBADRI2(sb_addr[2]),
  143. .SBADRI1(sb_addr[1]),
  144. .SBADRI0(sb_addr[0]),
  145. .SBDATI7(sb_di[7]),
  146. .SBDATI6(sb_di[6]),
  147. .SBDATI5(sb_di[5]),
  148. .SBDATI4(sb_di[4]),
  149. .SBDATI3(sb_di[3]),
  150. .SBDATI2(sb_di[2]),
  151. .SBDATI1(sb_di[1]),
  152. .SBDATI0(sb_di[0]),
  153. .MI(sio_miso_i),
  154. .SI(sio_mosi_i),
  155. .SCKI(sio_clk_i),
  156. .SCSNI(1'b1),
  157. .SBDATO7(sb_do[7]),
  158. .SBDATO6(sb_do[6]),
  159. .SBDATO5(sb_do[5]),
  160. .SBDATO4(sb_do[4]),
  161. .SBDATO3(sb_do[3]),
  162. .SBDATO2(sb_do[2]),
  163. .SBDATO1(sb_do[1]),
  164. .SBDATO0(sb_do[0]),
  165. .SBACKO(sb_ack),
  166. .SPIIRQ(sb_irq),
  167. .SPIWKUP(sb_wkup),
  168. .SO(sio_miso_o),
  169. .SOE(sio_miso_oe),
  170. .MO(sio_mosi_o),
  171. .MOE(sio_mosi_oe),
  172. .SCKO(sio_clk_o),
  173. .SCKOE(sio_clk_oe),
  174. .MCSNO3(sio_csn_o[3]),
  175. .MCSNO2(sio_csn_o[2]),
  176. .MCSNO1(sio_csn_o[1]),
  177. .MCSNO0(sio_csn_o[0]),
  178. .MCSNOE3(sio_csn_oe[3]),
  179. .MCSNOE2(sio_csn_oe[2]),
  180. .MCSNOE1(sio_csn_oe[1]),
  181. .MCSNOE0(sio_csn_oe[0])
  182. );
  183. `else
  184. reg [3:0] sim;
  185. assign sb_ack = sb_stb;
  186. assign sb_do = { sim, 4'h8 };
  187. always @(posedge clk_24m)
  188. if (rst)
  189. sim <= 0;
  190. else if (sb_ack & sb_rw)
  191. sim <= sim + 1;
  192. `endif
  193. // IO pads
  194. SB_IO #(
  195. .PIN_TYPE(6'b101001),
  196. .PULLUP(1'b1)
  197. ) spi_io_I[2:0] (
  198. .PACKAGE_PIN ({spi_mosi, spi_miso, spi_clk }),
  199. .OUTPUT_ENABLE({sio_mosi_oe, sio_miso_oe, sio_clk_oe}),
  200. .D_OUT_0 ({sio_mosi_o, sio_miso_o, sio_clk_o }),
  201. .D_IN_0 ({sio_mosi_i, sio_miso_i, sio_clk_i })
  202. );
  203. // Bypass OE for CS_n lines
  204. assign spi_flash_cs_n = sio_csn_o[0];
  205. `ifdef HAS_PSRAM
  206. assign spi_ram_cs_n = sio_csn_o[1];
  207. `endif
  208. // Bus interface
  209. assign sb_addr = { 4'h0, wb_addr[3:0] };
  210. assign sb_di = wb_wdata[7:0];
  211. assign sb_rw = wb_we;
  212. assign sb_stb = wb_cyc[2];
  213. assign wb_rdata[2] = { {(WB_DW-8){1'b0}}, wb_cyc[2] ? sb_do : 8'h00 };
  214. assign wb_ack[2] = sb_ack;
  215. // LEDs
  216. // ----
  217. SB_LEDDA_IP led_I (
  218. .LEDDCS(wb_addr[4] & wb_we),
  219. .LEDDCLK(clk_24m),
  220. .LEDDDAT7(wb_wdata[7]),
  221. .LEDDDAT6(wb_wdata[6]),
  222. .LEDDDAT5(wb_wdata[5]),
  223. .LEDDDAT4(wb_wdata[4]),
  224. .LEDDDAT3(wb_wdata[3]),
  225. .LEDDDAT2(wb_wdata[2]),
  226. .LEDDDAT1(wb_wdata[1]),
  227. .LEDDDAT0(wb_wdata[0]),
  228. .LEDDADDR3(wb_addr[3]),
  229. .LEDDADDR2(wb_addr[2]),
  230. .LEDDADDR1(wb_addr[1]),
  231. .LEDDADDR0(wb_addr[0]),
  232. .LEDDDEN(wb_cyc[3]),
  233. .LEDDEXE(led_ctrl[1]),
  234. .PWMOUT0(rgb_pwm[0]),
  235. .PWMOUT1(rgb_pwm[1]),
  236. .PWMOUT2(rgb_pwm[2]),
  237. .LEDDON()
  238. );
  239. SB_RGBA_DRV #(
  240. .CURRENT_MODE("0b1"),
  241. .RGB0_CURRENT("0b000001"),
  242. .RGB1_CURRENT("0b000001"),
  243. .RGB2_CURRENT("0b000001")
  244. ) rgb_drv_I (
  245. .RGBLEDEN(led_ctrl[2]),
  246. .RGB0PWM(rgb_pwm[0]),
  247. .RGB1PWM(rgb_pwm[1]),
  248. .RGB2PWM(rgb_pwm[2]),
  249. .CURREN(led_ctrl[3]),
  250. .RGB0(rgb[0]),
  251. .RGB1(rgb[1]),
  252. .RGB2(rgb[2])
  253. );
  254. always @(posedge clk_24m or posedge rst)
  255. if (rst)
  256. led_ctrl <= 0;
  257. else if (wb_cyc[3] & ~wb_addr[4] & wb_we)
  258. led_ctrl <= wb_wdata[4:0];
  259. assign wb_rdata[3] = { WB_DW{1'b0} };
  260. assign wb_ack[3] = wb_cyc[3];
  261. // USB Core
  262. // --------
  263. // Core
  264. usb #(
  265. .EPDW(32)
  266. ) usb_I (
  267. .pad_dp(usb_dp),
  268. .pad_dn(usb_dn),
  269. .pad_pu(usb_pu),
  270. .ep_tx_addr_0(ep_tx_addr_0),
  271. .ep_tx_data_0(ep_tx_data_0),
  272. .ep_tx_we_0(ep_tx_we_0),
  273. .ep_rx_addr_0(ep_rx_addr_0),
  274. .ep_rx_data_1(ep_rx_data_1),
  275. .ep_rx_re_0(ep_rx_re_0),
  276. .ep_clk(clk_24m),
  277. .wb_addr(ub_addr),
  278. .wb_rdata(ub_rdata),
  279. .wb_wdata(ub_wdata),
  280. .wb_we(ub_we),
  281. .wb_cyc(ub_cyc),
  282. .wb_ack(ub_ack),
  283. .clk(clk_48m),
  284. .rst(rst)
  285. );
  286. // Cross clock bridge
  287. xclk_wb #(
  288. .DW(16),
  289. .AW(12)
  290. ) wb_48m_xclk_I (
  291. .s_addr(wb_addr[11:0]),
  292. .s_wdata(wb_wdata[15:0]),
  293. .s_rdata(wb_rdata[4][15:0]),
  294. .s_cyc(wb_cyc[4]),
  295. .s_ack(wb_ack[4]),
  296. .s_we(wb_we),
  297. .s_clk(clk_24m),
  298. .m_addr(ub_addr),
  299. .m_wdata(ub_wdata),
  300. .m_rdata(ub_rdata),
  301. .m_cyc(ub_cyc),
  302. .m_ack(ub_ack),
  303. .m_we(ub_we),
  304. .m_clk(clk_48m),
  305. .rst(rst)
  306. );
  307. assign wb_rdata[4][31:16] = 16'h0000;
  308. // EP buffer interface
  309. reg wb_ack_ep;
  310. always @(posedge clk_24m)
  311. wb_ack_ep <= wb_cyc[5] & ~wb_ack_ep;
  312. assign wb_ack[5] = wb_ack_ep;
  313. assign ep_tx_addr_0 = wb_addr[8:0];
  314. assign ep_tx_data_0 = wb_wdata;
  315. assign ep_tx_we_0 = wb_cyc[5] & ~wb_ack[5] & wb_we;
  316. assign ep_rx_addr_0 = wb_addr[8:0];
  317. assign ep_rx_re_0 = 1'b1;
  318. assign wb_rdata[5] = wb_cyc[5] ? ep_rx_data_1 : 32'h00000000;
  319. // Warm Boot
  320. // ---------
  321. // Bus interface
  322. always @(posedge clk_24m or posedge rst)
  323. if (rst) begin
  324. boot_now <= 1'b0;
  325. boot_sel <= 2'b00;
  326. end else if (wb_cyc[0] & wb_we & (wb_addr[2:0] == 3'b000)) begin
  327. boot_now <= wb_wdata[2];
  328. boot_sel <= wb_wdata[1:0];
  329. end
  330. assign wb_rdata[0] = 0;
  331. assign wb_ack[0] = wb_cyc[0];
  332. // Helper
  333. dfu_helper #(
  334. .TIMER_WIDTH(24),
  335. .BTN_MODE(3),
  336. .DFU_MODE(0)
  337. ) dfu_helper_I (
  338. .boot_now(boot_now),
  339. .boot_sel(boot_sel),
  340. .btn_pad(btn),
  341. .btn_val(),
  342. .rst_req(),
  343. .clk(clk_24m),
  344. .rst(rst)
  345. );
  346. // Clock / Reset
  347. // -------------
  348. `ifdef SIM
  349. reg clk_48m_s = 1'b0;
  350. reg clk_24m_s = 1'b0;
  351. reg rst_s = 1'b1;
  352. always #10.42 clk_48m_s <= !clk_48m_s;
  353. always #20.84 clk_24m_s <= !clk_24m_s;
  354. initial begin
  355. #200 rst_s = 0;
  356. end
  357. assign clk_48m = clk_48m_s;
  358. assign clk_24m = clk_24m_s;
  359. assign rst = rst_s;
  360. `else
  361. sysmgr sys_mgr_I (
  362. .clk_in(clk_in),
  363. .rst_in(1'b0),
  364. .clk_48m(clk_48m),
  365. .clk_24m(clk_24m),
  366. .rst_out(rst)
  367. );
  368. `endif
  369. endmodule // top