top.v 9.4 KB

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