top.v 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /*
  2. * top.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2020-2021 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. `ifdef MEM_spi
  14. inout wire [3:0] spi_io,
  15. output wire spi_sck,
  16. output wire [1:0] spi_cs_n,
  17. `endif
  18. // HyperRAM
  19. `ifdef MEM_hyperram
  20. inout wire [7:0] hram_dq,
  21. inout wire hram_rwds,
  22. output wire hram_ck,
  23. output wire [3:0] hram_cs_n,
  24. output wire hram_rst_n,
  25. `endif
  26. // HDMI pads
  27. `ifdef VIDEO_4bpp
  28. output wire [ 3:0] hdmi_data,
  29. `endif
  30. `ifdef VIDEO_12bpp
  31. output wire [11:0] hdmi_data,
  32. `endif
  33. `ifndef VIDEO_none
  34. output wire hdmi_hsync,
  35. output wire hdmi_vsync,
  36. output wire hdmi_de,
  37. output wire hdmi_clk,
  38. `endif
  39. `ifdef HAS_UART
  40. // UART
  41. input wire uart_rx,
  42. output wire uart_tx,
  43. `endif
  44. `ifdef HAS_USB
  45. // USB
  46. inout wire usb_dp,
  47. inout wire usb_dn,
  48. output wire usb_pu,
  49. `endif
  50. // Clock (12M)
  51. input wire clk_in
  52. );
  53. // Signals
  54. // -------
  55. // Control
  56. wire [31:0] aux_csr;
  57. wire dma_run;
  58. // Wishbone interface
  59. reg [31:0] wb_wdata;
  60. wire [95:0] wb_rdata;
  61. reg [15:0] wb_addr;
  62. reg wb_we;
  63. reg [ 2:0] wb_cyc;
  64. wire [ 2:0] wb_ack;
  65. // Memory interface
  66. wire [31:0] mi_addr;
  67. wire [ 6:0] mi_len;
  68. wire mi_rw;
  69. wire mi_valid;
  70. wire mi_ready;
  71. wire [31:0] mi_wdata;
  72. wire mi_wack;
  73. wire mi_wlast;
  74. wire [31:0] mi_rdata;
  75. wire mi_rstb;
  76. wire mi_rlast;
  77. // Memory interface - Memory Tester
  78. wire [31:0] mi0_addr;
  79. wire [ 6:0] mi0_len;
  80. wire mi0_rw;
  81. wire mi0_valid;
  82. wire mi0_ready;
  83. wire [31:0] mi0_wdata;
  84. wire mi0_wack;
  85. wire mi0_wlast;
  86. wire [31:0] mi0_rdata;
  87. wire mi0_rstb;
  88. wire mi0_rlast;
  89. // Memory interface - Video DMA
  90. wire [31:0] mi1_addr;
  91. wire [ 6:0] mi1_len;
  92. wire mi1_rw;
  93. wire mi1_valid;
  94. wire mi1_ready;
  95. wire [31:0] mi1_wdata;
  96. wire mi1_wack;
  97. wire mi1_wlast;
  98. wire [31:0] mi1_rdata;
  99. wire mi1_rstb;
  100. wire mi1_rlast;
  101. // Clock / Reset
  102. wire [3:0] clk_rd_delay;
  103. wire clk_1x;
  104. wire clk_2x;
  105. wire clk_4x;
  106. wire clk_rd;
  107. wire sync_4x;
  108. wire sync_rd;
  109. wire rst;
  110. wire clk_usb;
  111. wire rst_usb;
  112. wire bootloader;
  113. // Host interface
  114. // --------------
  115. `ifdef HAS_UART
  116. uart2wb #(
  117. `elsif HAS_USB
  118. muacm2wb #(
  119. `endif
  120. .WB_N(3)
  121. ) if_I (
  122. `ifdef HAS_UART
  123. .uart_rx (uart_rx),
  124. .uart_tx (uart_tx),
  125. .uart_div (8'd16),
  126. `elsif HAS_USB
  127. .usb_dp (usb_dp),
  128. .usb_dn (usb_dn),
  129. .usb_pu (usb_pu),
  130. .usb_clk (clk_usb),
  131. .usb_rst (rst_usb),
  132. .bootloader (bootloader),
  133. `endif
  134. .wb_wdata (wb_wdata),
  135. .wb_rdata (wb_rdata),
  136. .wb_addr (wb_addr),
  137. .wb_we (wb_we),
  138. .wb_cyc (wb_cyc),
  139. .wb_ack (wb_ack),
  140. .aux_csr (aux_csr),
  141. .clk (clk_1x),
  142. .rst (rst)
  143. );
  144. assign dma_run = aux_csr[0];
  145. `ifdef HAS_USB
  146. SB_WARMBOOT warmboot (
  147. .BOOT (bootloader),
  148. .S0 (1'b1),
  149. .S1 (1'b0)
  150. );
  151. `endif
  152. // QSPI Controller
  153. // ---------------
  154. `ifdef MEM_spi
  155. // Config
  156. localparam integer PHY_SPEED = 4;
  157. localparam integer PL = (4 * PHY_SPEED) - 1;
  158. localparam integer CL = PHY_SPEED - 1;
  159. // Signals
  160. wire [PL:0] phy_io_i;
  161. wire [PL:0] phy_io_o;
  162. wire [ 3:0] phy_io_oe;
  163. wire [CL:0] phy_clk_o;
  164. wire [ 1:0] phy_cs_o;
  165. // Controller
  166. qpi_memctrl #(
  167. .CMD_READ (16'hEBEB),
  168. .CMD_WRITE (16'h0202),
  169. .DUMMY_CLK (6),
  170. .PAUSE_CLK (8),
  171. .FIFO_DEPTH (1),
  172. .N_CS (2),
  173. .PHY_SPEED (PHY_SPEED),
  174. .PHY_WIDTH (1),
  175. .PHY_DELAY ((PHY_SPEED == 1) ? 2 : ((PHY_SPEED == 2) ? 3 : 4))
  176. ) memctrl_I (
  177. .phy_io_i (phy_io_i),
  178. .phy_io_o (phy_io_o),
  179. .phy_io_oe (phy_io_oe),
  180. .phy_clk_o (phy_clk_o),
  181. .phy_cs_o (phy_cs_o),
  182. .mi_addr_cs (mi_addr[31:30]),
  183. .mi_addr ({mi_addr[21:0], 2'b00 }), /* 32 bits aligned */
  184. .mi_len (mi_len),
  185. .mi_rw (mi_rw),
  186. .mi_valid (mi_valid),
  187. .mi_ready (mi_ready),
  188. .mi_wdata (mi_wdata),
  189. .mi_wack (mi_wack),
  190. .mi_wlast (mi_wlast),
  191. .mi_rdata (mi_rdata),
  192. .mi_rstb (mi_rstb),
  193. .mi_rlast (mi_rlast),
  194. .wb_wdata (wb_wdata),
  195. .wb_rdata (wb_rdata[31:0]),
  196. .wb_addr (wb_addr[4:0]),
  197. .wb_we (wb_we),
  198. .wb_cyc (wb_cyc[0]),
  199. .wb_ack (wb_ack[0]),
  200. .clk (clk_1x),
  201. .rst (rst)
  202. );
  203. // PHY
  204. generate
  205. if (PHY_SPEED == 1)
  206. qpi_phy_ice40_1x #(
  207. .N_CS (2),
  208. .WITH_CLK (1),
  209. .NEG_IN (0)
  210. ) phy_I (
  211. .pad_io (spi_io),
  212. .pad_clk (spi_sck),
  213. .pad_cs_n (spi_cs_n),
  214. .phy_io_i (phy_io_i),
  215. .phy_io_o (phy_io_o),
  216. .phy_io_oe (phy_io_oe),
  217. .phy_clk_o (phy_clk_o),
  218. .phy_cs_o (phy_cs_o),
  219. .clk (clk_1x)
  220. );
  221. else if (PHY_SPEED == 2)
  222. qpi_phy_ice40_2x #(
  223. .N_CS (2),
  224. .WITH_CLK (1),
  225. ) phy_I (
  226. .pad_io (spi_io),
  227. .pad_clk (spi_sck),
  228. .pad_cs_n (spi_cs_n),
  229. .phy_io_i (phy_io_i),
  230. .phy_io_o (phy_io_o),
  231. .phy_io_oe (phy_io_oe),
  232. .phy_clk_o (phy_clk_o),
  233. .phy_cs_o (phy_cs_o),
  234. .clk_1x (clk_1x),
  235. .clk_2x (clk_2x)
  236. );
  237. else if (PHY_SPEED == 4)
  238. qpi_phy_ice40_4x #(
  239. .N_CS (2),
  240. .WITH_CLK (1),
  241. ) phy_I (
  242. .pad_io (spi_io),
  243. .pad_clk (spi_sck),
  244. .pad_cs_n (spi_cs_n),
  245. .phy_io_i (phy_io_i),
  246. .phy_io_o (phy_io_o),
  247. .phy_io_oe (phy_io_oe),
  248. .phy_clk_o (phy_clk_o),
  249. .phy_cs_o (phy_cs_o),
  250. .clk_1x (clk_1x),
  251. .clk_4x (clk_4x),
  252. .clk_sync (sync_4x)
  253. );
  254. endgenerate
  255. assign clk_rd_delay = 4'h0;
  256. `endif
  257. // HyperRAM Controller
  258. // -------------------
  259. `ifdef MEM_hyperram
  260. // Signals
  261. wire [ 1:0] phy_ck_en;
  262. wire [ 3:0] phy_rwds_in;
  263. wire [ 3:0] phy_rwds_out;
  264. wire [ 1:0] phy_rwds_oe;
  265. wire [31:0] phy_dq_in;
  266. wire [31:0] phy_dq_out;
  267. wire [ 1:0] phy_dq_oe;
  268. wire [ 3:0] phy_cs_n;
  269. wire phy_rst_n;
  270. wire [ 7:0] phy_cfg_wdata;
  271. wire [ 7:0] phy_cfg_rdata;
  272. wire phy_cfg_stb;
  273. // Controller
  274. hbus_memctrl hram_ctrl_I (
  275. .phy_ck_en (phy_ck_en),
  276. .phy_rwds_in (phy_rwds_in),
  277. .phy_rwds_out (phy_rwds_out),
  278. .phy_rwds_oe (phy_rwds_oe),
  279. .phy_dq_in (phy_dq_in),
  280. .phy_dq_out (phy_dq_out),
  281. .phy_dq_oe (phy_dq_oe),
  282. .phy_cs_n (phy_cs_n),
  283. .phy_rst_n (phy_rst_n),
  284. .phy_cfg_wdata (phy_cfg_wdata),
  285. .phy_cfg_rdata (phy_cfg_rdata),
  286. .phy_cfg_stb (phy_cfg_stb),
  287. .mi_addr_cs (mi_addr[31:30]),
  288. .mi_addr ({1'b0, mi_addr[29:0], 1'b0}), /* 32b aligned */
  289. .mi_len (mi_len),
  290. .mi_rw (mi_rw),
  291. .mi_linear (1'b0),
  292. .mi_valid (mi_valid),
  293. .mi_ready (mi_ready),
  294. .mi_wdata (mi_wdata),
  295. .mi_wmsk (4'h0),
  296. .mi_wack (mi_wack),
  297. .mi_rdata (mi_rdata),
  298. .mi_rstb (mi_rstb),
  299. .wb_wdata (wb_wdata),
  300. .wb_rdata (wb_rdata[31:0]),
  301. .wb_addr (wb_addr[3:0]),
  302. .wb_we (wb_we),
  303. .wb_cyc (wb_cyc[0]),
  304. .wb_ack (wb_ack[0]),
  305. .clk (clk_1x),
  306. .rst (rst)
  307. );
  308. // PHY
  309. hbus_phy_ice40 hram_phy_I (
  310. .hbus_dq (hram_dq),
  311. .hbus_rwds (hram_rwds),
  312. .hbus_ck (hram_ck),
  313. .hbus_cs_n (hram_cs_n),
  314. .hbus_rst_n (hram_rst_n),
  315. .phy_ck_en (phy_ck_en),
  316. .phy_rwds_in (phy_rwds_in),
  317. .phy_rwds_out (phy_rwds_out),
  318. .phy_rwds_oe (phy_rwds_oe),
  319. .phy_dq_in (phy_dq_in),
  320. .phy_dq_out (phy_dq_out),
  321. .phy_dq_oe (phy_dq_oe),
  322. .phy_cs_n (phy_cs_n),
  323. .phy_rst_n (phy_rst_n),
  324. .phy_cfg_wdata (phy_cfg_wdata),
  325. .phy_cfg_rdata (phy_cfg_rdata),
  326. .phy_cfg_stb (phy_cfg_stb),
  327. .clk_rd_delay (clk_rd_delay),
  328. .clk_1x (clk_1x),
  329. .clk_4x (clk_4x),
  330. .clk_rd (clk_rd),
  331. .sync_4x (sync_4x),
  332. .sync_rd (sync_rd)
  333. );
  334. `endif
  335. // Memory tester
  336. // -------------
  337. memtest #(
  338. .ADDR_WIDTH(32)
  339. ) memtest_I (
  340. .mi_addr (mi0_addr),
  341. .mi_len (mi0_len),
  342. .mi_rw (mi0_rw),
  343. .mi_valid (mi0_valid),
  344. .mi_ready (mi0_ready),
  345. .mi_wdata (mi0_wdata),
  346. .mi_wack (mi0_wack),
  347. .mi_rdata (mi0_rdata),
  348. .mi_rstb (mi0_rstb),
  349. .wb_wdata (wb_wdata),
  350. .wb_rdata (wb_rdata[63:32]),
  351. .wb_addr (wb_addr[8:0]),
  352. .wb_we (wb_we),
  353. .wb_cyc (wb_cyc[1]),
  354. .wb_ack (wb_ack[1]),
  355. .clk (clk_1x),
  356. .rst (rst)
  357. );
  358. // Memory Mux
  359. // ----------
  360. assign mi_addr = dma_run ? mi1_addr : mi0_addr;
  361. assign mi_len = dma_run ? mi1_len : mi0_len;
  362. assign mi_rw = dma_run ? mi1_rw : mi0_rw;
  363. assign mi_valid = dma_run ? mi1_valid : mi0_valid;
  364. assign mi0_ready = mi_ready & ~dma_run;
  365. assign mi1_ready = mi_ready & dma_run;
  366. assign mi_wdata = dma_run ? mi1_wdata : mi0_wdata;
  367. assign mi0_wack = mi_wack & ~dma_run;
  368. assign mi0_wlast = mi_wlast;
  369. assign mi1_wack = mi_wack & dma_run;
  370. assign mi1_wlast = mi_wlast;
  371. assign mi0_rdata = mi_rdata;
  372. assign mi0_rstb = mi_rstb & ~dma_run;
  373. assign mi0_rlast = mi_rlast;
  374. assign mi1_rdata = mi_rdata;
  375. assign mi1_rstb = mi_rstb & dma_run;
  376. assign mi1_rlast = mi_rlast;
  377. // HDMI output
  378. // -----------
  379. `ifndef VIDEO_none
  380. hdmi_out #(
  381. `ifdef VIDEO_4bpp
  382. .DW(4)
  383. `endif
  384. `ifdef VIDEO_12bpp
  385. .DW(12)
  386. `endif
  387. ) hdmi_I (
  388. .hdmi_data (hdmi_data),
  389. .hdmi_hsync (hdmi_hsync),
  390. .hdmi_vsync (hdmi_vsync),
  391. .hdmi_de (hdmi_de),
  392. .hdmi_clk (hdmi_clk),
  393. .wb_wdata (wb_wdata),
  394. .wb_rdata (wb_rdata[95:64]),
  395. .wb_addr (wb_addr[6:0]),
  396. .wb_we (wb_we),
  397. .wb_cyc (wb_cyc[2]),
  398. .wb_ack (wb_ack[2]),
  399. .mi_addr (mi1_addr),
  400. .mi_len (mi1_len),
  401. .mi_rw (mi1_rw),
  402. .mi_valid (mi1_valid),
  403. .mi_ready (mi1_ready),
  404. .mi_wdata (mi1_wdata),
  405. .mi_wack (mi1_wack),
  406. .mi_rdata (mi1_rdata),
  407. .mi_rstb (mi1_rstb),
  408. .clk_1x (clk_1x),
  409. .clk_4x (clk_4x),
  410. .sync_4x (sync_4x),
  411. .rst (rst)
  412. );
  413. `else
  414. // Dummy wishbone
  415. assign wb_ack[2] = wb_cyc[2];
  416. assign wb_rdata[95:64] = 32'h00000000;
  417. // Dummy mem-if
  418. assign mi1_addr = 32'hxxxxxxxx;
  419. assign mi1_len = 7'hxx;
  420. assign mi1_rw = 1'bx;
  421. assign mi1_valid = 1'b0;
  422. assign mi1_wdata = 32'hxxxxxxxx;
  423. `endif
  424. // Clock / Reset
  425. // -------------
  426. sysmgr sysmgr_I (
  427. .delay (clk_rd_delay),
  428. .clk_in (clk_in),
  429. .clk_1x (clk_1x),
  430. .clk_2x (clk_2x),
  431. .clk_4x (clk_4x),
  432. .clk_rd (clk_rd),
  433. .sync_4x (sync_4x),
  434. .sync_rd (sync_rd),
  435. .rst (rst),
  436. .clk_usb (clk_usb),
  437. .rst_usb (rst_usb)
  438. );
  439. endmodule