top.v 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /*
  2. * top.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. `include "boards.vh"
  35. module top (
  36. // SPI
  37. inout wire spi_mosi,
  38. inout wire spi_miso,
  39. inout wire spi_clk,
  40. inout wire spi_flash_cs_n,
  41. `ifdef HAS_PSRAM
  42. inout wire spi_ram_cs_n,
  43. `endif
  44. // USB
  45. inout wire usb_dp,
  46. inout wire usb_dn,
  47. output wire usb_pu,
  48. // Debug UART
  49. `ifndef BOARD_E1TRACER
  50. input wire uart_rx,
  51. `endif
  52. output wire uart_tx,
  53. // Button
  54. input wire btn,
  55. // LED
  56. output wire [2:0] rgb,
  57. `ifdef HAS_VIO
  58. // Vio
  59. output wire vio_pdm,
  60. `endif
  61. // Clock
  62. input wire clk_in
  63. );
  64. localparam WB_N = 6;
  65. localparam WB_DW = 32;
  66. localparam WB_AW = 16;
  67. localparam WB_AI = 2;
  68. localparam SPRAM_AW = 14; /* 14 => 64k, 15 => 128k */
  69. genvar i;
  70. // Signals
  71. // -------
  72. // Memory bus
  73. wire mem_valid;
  74. wire mem_instr;
  75. wire mem_ready;
  76. wire [31:0] mem_addr;
  77. wire [31:0] mem_rdata;
  78. wire [31:0] mem_wdata;
  79. wire [ 3:0] mem_wstrb;
  80. // RAM
  81. // BRAM
  82. wire [ 7:0] bram_addr;
  83. wire [31:0] bram_rdata;
  84. wire [31:0] bram_wdata;
  85. wire [ 3:0] bram_wmsk;
  86. wire bram_we;
  87. // SPRAM
  88. wire [14:0] spram_addr;
  89. wire [31:0] spram_rdata;
  90. wire [31:0] spram_wdata;
  91. wire [ 3:0] spram_wmsk;
  92. wire spram_we;
  93. // Wishbone
  94. wire [WB_AW-1:0] wb_addr;
  95. wire [WB_DW-1:0] wb_wdata;
  96. wire [(WB_DW/8)-1:0] wb_wmsk;
  97. wire [WB_DW-1:0] wb_rdata [0:WB_N-1];
  98. wire [(WB_DW*WB_N)-1:0] wb_rdata_flat;
  99. wire [WB_N-1:0] wb_cyc;
  100. wire wb_we;
  101. wire [WB_N-1:0] wb_ack;
  102. // UART
  103. // USB Core
  104. // EP Buffer
  105. wire [ 8:0] ep_tx_addr_0;
  106. wire [31:0] ep_tx_data_0;
  107. wire ep_tx_we_0;
  108. wire [ 8:0] ep_rx_addr_0;
  109. wire [31:0] ep_rx_data_1;
  110. wire ep_rx_re_0;
  111. // Bus interface
  112. wire [11:0] ub_addr;
  113. wire [15:0] ub_wdata;
  114. wire [15:0] ub_rdata;
  115. wire ub_cyc;
  116. wire ub_we;
  117. wire ub_ack;
  118. // SPI
  119. wire [7:0] sb_addr;
  120. wire [7:0] sb_di;
  121. wire [7:0] sb_do;
  122. wire sb_rw;
  123. wire sb_stb;
  124. wire sb_ack;
  125. wire sb_irq;
  126. wire sb_wkup;
  127. wire sio_miso_o, sio_miso_oe, sio_miso_i;
  128. wire sio_mosi_o, sio_mosi_oe, sio_mosi_i;
  129. wire sio_clk_o, sio_clk_oe, sio_clk_i;
  130. wire [3:0] sio_csn_o, sio_csn_oe;
  131. // LEDs
  132. reg [4:0] led_ctrl;
  133. wire [2:0] rgb_pwm;
  134. // WarmBoot
  135. reg boot_now;
  136. reg [1:0] boot_sel;
  137. // Clock / Reset logic
  138. wire clk_24m;
  139. wire clk_48m;
  140. wire rst;
  141. // SoC
  142. // ---
  143. // CPU
  144. picorv32 #(
  145. .PROGADDR_RESET(32'h 0000_0000),
  146. .STACKADDR(32'h 0000_0400),
  147. .BARREL_SHIFTER(0),
  148. .COMPRESSED_ISA(0),
  149. .ENABLE_COUNTERS(0),
  150. .ENABLE_MUL(0),
  151. .ENABLE_DIV(0),
  152. .ENABLE_IRQ(0),
  153. .ENABLE_IRQ_QREGS(0),
  154. .CATCH_MISALIGN(0),
  155. .CATCH_ILLINSN(0)
  156. ) cpu_I (
  157. .clk (clk_24m),
  158. .resetn (~rst),
  159. .mem_valid (mem_valid),
  160. .mem_instr (mem_instr),
  161. .mem_ready (mem_ready),
  162. .mem_addr (mem_addr),
  163. .mem_wdata (mem_wdata),
  164. .mem_wstrb (mem_wstrb),
  165. .mem_rdata (mem_rdata)
  166. );
  167. // Bus interface
  168. bridge #(
  169. .WB_N(WB_N),
  170. .WB_DW(WB_DW),
  171. .WB_AW(WB_AW),
  172. .WB_AI(WB_AI)
  173. ) pb_I (
  174. .pb_addr(mem_addr),
  175. .pb_rdata(mem_rdata),
  176. .pb_wdata(mem_wdata),
  177. .pb_wstrb(mem_wstrb),
  178. .pb_valid(mem_valid),
  179. .pb_ready(mem_ready),
  180. .bram_addr(bram_addr),
  181. .bram_rdata(bram_rdata),
  182. .bram_wdata(bram_wdata),
  183. .bram_wmsk(bram_wmsk),
  184. .bram_we(bram_we),
  185. .spram_addr(spram_addr),
  186. .spram_rdata(spram_rdata),
  187. .spram_wdata(spram_wdata),
  188. .spram_wmsk(spram_wmsk),
  189. .spram_we(spram_we),
  190. .wb_addr(wb_addr),
  191. .wb_wdata(wb_wdata),
  192. .wb_wmsk(wb_wmsk),
  193. .wb_rdata(wb_rdata_flat),
  194. .wb_cyc(wb_cyc),
  195. .wb_we(wb_we),
  196. .wb_ack(wb_ack),
  197. .clk(clk_24m),
  198. .rst(rst)
  199. );
  200. for (i=0; i<WB_N; i=i+1)
  201. assign wb_rdata_flat[i*WB_DW+:WB_DW] = wb_rdata[i];
  202. assign wb_rdata[0] = 0;
  203. assign wb_ack[0] = wb_cyc[0];
  204. // Boot memory
  205. soc_bram #(
  206. .INIT_FILE("boot.hex")
  207. ) bram_I (
  208. .addr(bram_addr),
  209. .rdata(bram_rdata),
  210. .wdata(bram_wdata),
  211. .wmsk(bram_wmsk),
  212. .we(bram_we),
  213. .clk(clk_24m)
  214. );
  215. // Main memory
  216. soc_spram #(
  217. .AW(SPRAM_AW)
  218. ) spram_I (
  219. .addr(spram_addr[SPRAM_AW-1:0]),
  220. .rdata(spram_rdata),
  221. .wdata(spram_wdata),
  222. .wmsk(spram_wmsk),
  223. .we(spram_we),
  224. .clk(clk_24m)
  225. );
  226. // UART
  227. // ----
  228. `ifdef BOARD_E1TRACER
  229. wire uart_rx = 1'b1;
  230. `endif
  231. uart_wb #(
  232. .DIV_WIDTH(12),
  233. .DW(WB_DW)
  234. ) uart_I (
  235. .uart_tx(uart_tx),
  236. .uart_rx(uart_rx),
  237. .bus_addr(wb_addr[1:0]),
  238. .bus_wdata(wb_wdata),
  239. .bus_rdata(wb_rdata[1]),
  240. .bus_cyc(wb_cyc[1]),
  241. .bus_ack(wb_ack[1]),
  242. .bus_we(wb_we),
  243. .clk(clk_24m),
  244. .rst(rst)
  245. );
  246. // SPI
  247. // ---
  248. // Hard-IP
  249. `ifndef SIM
  250. SB_SPI #(
  251. .BUS_ADDR74("0b0000")
  252. ) spi_I (
  253. .SBCLKI(clk_24m),
  254. .SBRWI(sb_rw),
  255. .SBSTBI(sb_stb),
  256. .SBADRI7(sb_addr[7]),
  257. .SBADRI6(sb_addr[6]),
  258. .SBADRI5(sb_addr[5]),
  259. .SBADRI4(sb_addr[4]),
  260. .SBADRI3(sb_addr[3]),
  261. .SBADRI2(sb_addr[2]),
  262. .SBADRI1(sb_addr[1]),
  263. .SBADRI0(sb_addr[0]),
  264. .SBDATI7(sb_di[7]),
  265. .SBDATI6(sb_di[6]),
  266. .SBDATI5(sb_di[5]),
  267. .SBDATI4(sb_di[4]),
  268. .SBDATI3(sb_di[3]),
  269. .SBDATI2(sb_di[2]),
  270. .SBDATI1(sb_di[1]),
  271. .SBDATI0(sb_di[0]),
  272. .MI(sio_miso_i),
  273. .SI(sio_mosi_i),
  274. .SCKI(sio_clk_i),
  275. .SCSNI(1'b1),
  276. .SBDATO7(sb_do[7]),
  277. .SBDATO6(sb_do[6]),
  278. .SBDATO5(sb_do[5]),
  279. .SBDATO4(sb_do[4]),
  280. .SBDATO3(sb_do[3]),
  281. .SBDATO2(sb_do[2]),
  282. .SBDATO1(sb_do[1]),
  283. .SBDATO0(sb_do[0]),
  284. .SBACKO(sb_ack),
  285. .SPIIRQ(sb_irq),
  286. .SPIWKUP(sb_wkup),
  287. .SO(sio_miso_o),
  288. .SOE(sio_miso_oe),
  289. .MO(sio_mosi_o),
  290. .MOE(sio_mosi_oe),
  291. .SCKO(sio_clk_o),
  292. .SCKOE(sio_clk_oe),
  293. .MCSNO3(sio_csn_o[3]),
  294. .MCSNO2(sio_csn_o[2]),
  295. .MCSNO1(sio_csn_o[1]),
  296. .MCSNO0(sio_csn_o[0]),
  297. .MCSNOE3(sio_csn_oe[3]),
  298. .MCSNOE2(sio_csn_oe[2]),
  299. .MCSNOE1(sio_csn_oe[1]),
  300. .MCSNOE0(sio_csn_oe[0])
  301. );
  302. `else
  303. reg [3:0] sim;
  304. assign sb_ack = sb_stb;
  305. assign sb_do = { sim, 4'h8 };
  306. always @(posedge clk_24m)
  307. if (rst)
  308. sim <= 0;
  309. else if (sb_ack & sb_rw)
  310. sim <= sim + 1;
  311. `endif
  312. // IO pads
  313. SB_IO #(
  314. .PIN_TYPE(6'b101001),
  315. .PULLUP(1'b1)
  316. ) spi_io_I[2:0] (
  317. .PACKAGE_PIN ({spi_mosi, spi_miso, spi_clk }),
  318. .OUTPUT_ENABLE({sio_mosi_oe, sio_miso_oe, sio_clk_oe}),
  319. .D_OUT_0 ({sio_mosi_o, sio_miso_o, sio_clk_o }),
  320. .D_IN_0 ({sio_mosi_i, sio_miso_i, sio_clk_i })
  321. );
  322. // Bypass OE for CS_n lines
  323. assign spi_flash_cs_n = sio_csn_o[0];
  324. `ifdef HAS_PSRAM
  325. assign spi_ram_cs_n = sio_csn_o[1];
  326. `endif
  327. // Bus interface
  328. assign sb_addr = { 4'h0, wb_addr[3:0] };
  329. assign sb_di = wb_wdata[7:0];
  330. assign sb_rw = wb_we;
  331. assign sb_stb = wb_cyc[2];
  332. assign wb_rdata[2] = { {(WB_DW-8){1'b0}}, wb_cyc[2] ? sb_do : 8'h00 };
  333. assign wb_ack[2] = sb_ack;
  334. // LEDs
  335. // ----
  336. SB_LEDDA_IP led_I (
  337. .LEDDCS(wb_addr[4] & wb_we),
  338. .LEDDCLK(clk_24m),
  339. .LEDDDAT7(wb_wdata[7]),
  340. .LEDDDAT6(wb_wdata[6]),
  341. .LEDDDAT5(wb_wdata[5]),
  342. .LEDDDAT4(wb_wdata[4]),
  343. .LEDDDAT3(wb_wdata[3]),
  344. .LEDDDAT2(wb_wdata[2]),
  345. .LEDDDAT1(wb_wdata[1]),
  346. .LEDDDAT0(wb_wdata[0]),
  347. .LEDDADDR3(wb_addr[3]),
  348. .LEDDADDR2(wb_addr[2]),
  349. .LEDDADDR1(wb_addr[1]),
  350. .LEDDADDR0(wb_addr[0]),
  351. .LEDDDEN(wb_cyc[3]),
  352. .LEDDEXE(led_ctrl[1]),
  353. .PWMOUT0(rgb_pwm[0]),
  354. .PWMOUT1(rgb_pwm[1]),
  355. .PWMOUT2(rgb_pwm[2]),
  356. .LEDDON()
  357. );
  358. SB_RGBA_DRV #(
  359. .CURRENT_MODE("0b1"),
  360. .RGB0_CURRENT("0b000001"),
  361. .RGB1_CURRENT("0b000001"),
  362. .RGB2_CURRENT("0b000001")
  363. ) rgb_drv_I (
  364. .RGBLEDEN(led_ctrl[2]),
  365. .RGB0PWM(rgb_pwm[0]),
  366. .RGB1PWM(rgb_pwm[1]),
  367. .RGB2PWM(rgb_pwm[2]),
  368. .CURREN(led_ctrl[3]),
  369. .RGB0(rgb[0]),
  370. .RGB1(rgb[1]),
  371. .RGB2(rgb[2])
  372. );
  373. always @(posedge clk_24m or posedge rst)
  374. if (rst)
  375. led_ctrl <= 0;
  376. else if (wb_cyc[3] & ~wb_addr[4] & wb_we)
  377. led_ctrl <= wb_wdata[4:0];
  378. assign wb_rdata[3] = { WB_DW{1'b0} };
  379. assign wb_ack[3] = wb_cyc[3];
  380. // USB Core
  381. // --------
  382. // Core
  383. usb #(
  384. .EPDW(32)
  385. ) usb_I (
  386. .pad_dp(usb_dp),
  387. .pad_dn(usb_dn),
  388. .pad_pu(usb_pu),
  389. .ep_tx_addr_0(ep_tx_addr_0),
  390. .ep_tx_data_0(ep_tx_data_0),
  391. .ep_tx_we_0(ep_tx_we_0),
  392. .ep_rx_addr_0(ep_rx_addr_0),
  393. .ep_rx_data_1(ep_rx_data_1),
  394. .ep_rx_re_0(ep_rx_re_0),
  395. .ep_clk(clk_24m),
  396. .bus_addr(ub_addr),
  397. .bus_din(ub_wdata),
  398. .bus_dout(ub_rdata),
  399. .bus_cyc(ub_cyc),
  400. .bus_we(ub_we),
  401. .bus_ack(ub_ack),
  402. .clk(clk_48m),
  403. .rst(rst)
  404. );
  405. // Cross clock bridge
  406. xclk_wb #(
  407. .DW(16),
  408. .AW(12)
  409. ) wb_48m_xclk_I (
  410. .s_addr(wb_addr[11:0]),
  411. .s_wdata(wb_wdata[15:0]),
  412. .s_rdata(wb_rdata[4][15:0]),
  413. .s_cyc(wb_cyc[4]),
  414. .s_ack(wb_ack[4]),
  415. .s_we(wb_we),
  416. .s_clk(clk_24m),
  417. .m_addr(ub_addr),
  418. .m_wdata(ub_wdata),
  419. .m_rdata(ub_rdata),
  420. .m_cyc(ub_cyc),
  421. .m_ack(ub_ack),
  422. .m_we(ub_we),
  423. .m_clk(clk_48m),
  424. .rst(rst)
  425. );
  426. assign wb_rdata[4][31:16] = 16'h0000;
  427. // EP buffer interface
  428. reg wb_ack_ep;
  429. always @(posedge clk_24m)
  430. wb_ack_ep <= wb_cyc[5] & ~wb_ack_ep;
  431. assign wb_ack[5] = wb_ack_ep;
  432. assign ep_tx_addr_0 = wb_addr[8:0];
  433. assign ep_tx_data_0 = wb_wdata;
  434. assign ep_tx_we_0 = wb_cyc[5] & ~wb_ack[5] & wb_we;
  435. assign ep_rx_addr_0 = wb_addr[8:0];
  436. assign ep_rx_re_0 = 1'b1;
  437. assign wb_rdata[5] = wb_cyc[5] ? ep_rx_data_1 : 32'h00000000;
  438. // Warm Boot
  439. // ---------
  440. // Bus interface
  441. always @(posedge clk_24m or posedge rst)
  442. if (rst) begin
  443. boot_now <= 1'b0;
  444. boot_sel <= 2'b00;
  445. end else if (wb_cyc[0] & wb_we & (wb_addr[2:0] == 3'b000)) begin
  446. boot_now <= wb_wdata[2];
  447. boot_sel <= wb_wdata[1:0];
  448. end
  449. // Helper
  450. dfu_helper #(
  451. .TIMER_WIDTH(24),
  452. .BTN_MODE(3),
  453. `ifdef DFU
  454. .DFU_MODE(1)
  455. `else
  456. .DFU_MODE(0)
  457. `endif
  458. ) dfu_helper_I (
  459. .boot_now(boot_now),
  460. .boot_sel(boot_sel),
  461. .btn_pad(btn),
  462. .btn_val(),
  463. .rst_req(),
  464. .clk(clk_24m),
  465. .rst(rst)
  466. );
  467. // Vio
  468. // ----
  469. `ifdef HAS_VIO
  470. assign vio_pdm = 1'b1;
  471. `endif
  472. // Clock / Reset
  473. // -------------
  474. `ifdef SIM
  475. reg clk_48m_s = 1'b0;
  476. reg clk_24m_s = 1'b0;
  477. reg rst_s = 1'b1;
  478. always #10.42 clk_48m_s <= !clk_48m_s;
  479. always #20.84 clk_24m_s <= !clk_24m_s;
  480. initial begin
  481. #200 rst_s = 0;
  482. end
  483. assign clk_48m = clk_48m_s;
  484. assign clk_24m = clk_24m_s;
  485. assign rst = rst_s;
  486. `else
  487. sysmgr sys_mgr_I (
  488. .clk_in(clk_in),
  489. .rst_in(1'b0),
  490. .clk_48m(clk_48m),
  491. .clk_24m(clk_24m),
  492. .rst_out(rst)
  493. );
  494. `endif
  495. endmodule // top