top.v 10 KB

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