top.v 10 KB

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