123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- /*
- * top.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the <organization> nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- `default_nettype none
- module top (
- // SPI
- `ifdef MEM_spi
- inout wire [3:0] spi_io,
- output wire spi_sck,
- output wire [1:0] spi_cs_n,
- `endif
- // HyperRAM
- `ifdef MEM_hyperram
- inout wire [7:0] hram_dq,
- inout wire hram_rwds,
- output wire hram_ck,
- output wire [3:0] hram_cs_n,
- output wire hram_rst_n,
- `endif
- // HDMI pads
- `ifdef VIDEO_4bpp
- output wire [ 3:0] hdmi_data,
- `endif
- `ifdef VIDEO_12bpp
- output wire [11:0] hdmi_data,
- `endif
- `ifndef VIDEO_none
- output wire hdmi_hsync,
- output wire hdmi_vsync,
- output wire hdmi_de,
- output wire hdmi_clk,
- `endif
- // UART
- input wire uart_rx,
- output wire uart_tx,
- // Clock (12M)
- input wire clk_in
- );
- // Signals
- // -------
- // Control
- wire [31:0] aux_csr;
- wire dma_run;
- // Wishbone interface
- reg [31:0] wb_wdata;
- wire [95:0] wb_rdata;
- reg [15:0] wb_addr;
- reg wb_we;
- reg [ 2:0] wb_cyc;
- wire [ 2:0] wb_ack;
- // Memory interface
- wire [31:0] mi_addr;
- wire [ 6:0] mi_len;
- wire mi_rw;
- wire mi_valid;
- wire mi_ready;
- wire [31:0] mi_wdata;
- wire mi_wack;
- wire mi_wlast;
- wire [31:0] mi_rdata;
- wire mi_rstb;
- wire mi_rlast;
- // Memory interface - Memory Tester
- wire [31:0] mi0_addr;
- wire [ 6:0] mi0_len;
- wire mi0_rw;
- wire mi0_valid;
- wire mi0_ready;
- wire [31:0] mi0_wdata;
- wire mi0_wack;
- wire mi0_wlast;
- wire [31:0] mi0_rdata;
- wire mi0_rstb;
- wire mi0_rlast;
- // Memory interface - Video DMA
- wire [31:0] mi1_addr;
- wire [ 6:0] mi1_len;
- wire mi1_rw;
- wire mi1_valid;
- wire mi1_ready;
- wire [31:0] mi1_wdata;
- wire mi1_wack;
- wire mi1_wlast;
- wire [31:0] mi1_rdata;
- wire mi1_rstb;
- wire mi1_rlast;
- // Clock / Reset
- wire [3:0] clk_rd_delay;
- wire clk_1x;
- wire clk_2x;
- wire clk_4x;
- wire clk_rd;
- wire sync_4x;
- wire sync_rd;
- wire rst;
- // Host interface
- // --------------
- uart2wb #(
- .WB_N(3)
- ) if_I (
- .uart_rx(uart_rx),
- .uart_tx(uart_tx),
- .uart_div(8'd16),
- .wb_wdata(wb_wdata),
- .wb_rdata(wb_rdata),
- .wb_addr(wb_addr),
- .wb_we(wb_we),
- .wb_cyc(wb_cyc),
- .wb_ack(wb_ack),
- .aux_csr(aux_csr),
- .clk(clk_1x),
- .rst(rst)
- );
- assign dma_run = aux_csr[0];
- // QSPI Controller
- // ---------------
- `ifdef MEM_spi
- // Config
- localparam integer PHY_SPEED = 4;
- localparam integer PL = (4 * PHY_SPEED) - 1;
- localparam integer CL = PHY_SPEED - 1;
- // Signals
- wire [PL:0] phy_io_i;
- wire [PL:0] phy_io_o;
- wire [ 3:0] phy_io_oe;
- wire [CL:0] phy_clk_o;
- wire [ 1:0] phy_cs_o;
- // Controller
- qspi_master #(
- .CMD_READ(16'hEBEB),
- .CMD_WRITE(16'h0202),
- .DUMMY_CLK(6),
- .PAUSE_CLK(8),
- .FIFO_DEPTH(1),
- .N_CS(2),
- .PHY_SPEED(PHY_SPEED),
- .PHY_WIDTH(1),
- .PHY_DELAY((PHY_SPEED == 1) ? 2 : ((PHY_SPEED == 2) ? 3 : 4))
- ) memctrl_I (
- .phy_io_i(phy_io_i),
- .phy_io_o(phy_io_o),
- .phy_io_oe(phy_io_oe),
- .phy_clk_o(phy_clk_o),
- .phy_cs_o(phy_cs_o),
- .mi_addr_cs(mi_addr[31:30]),
- .mi_addr({mi_addr[21:0], 2'b00 }), /* 32 bits aligned */
- .mi_len(mi_len),
- .mi_rw(mi_rw),
- .mi_valid(mi_valid),
- .mi_ready(mi_ready),
- .mi_wdata(mi_wdata),
- .mi_wack(mi_wack),
- .mi_wlast(mi_wlast),
- .mi_rdata(mi_rdata),
- .mi_rstb(mi_rstb),
- .mi_rlast(mi_rlast),
- .wb_wdata(wb_wdata),
- .wb_rdata(wb_rdata[31:0]),
- .wb_addr(wb_addr[4:0]),
- .wb_we(wb_we),
- .wb_cyc(wb_cyc[0]),
- .wb_ack(wb_ack[0]),
- .clk(clk_1x),
- .rst(rst)
- );
- // PHY
- generate
- if (PHY_SPEED == 1)
- qspi_phy_ice40_1x #(
- .N_CS(2),
- .WITH_CLK(1),
- .NEG_IN(0)
- ) phy_I (
- .pad_io(spi_io),
- .pad_clk(spi_sck),
- .pad_cs_n(spi_cs_n),
- .phy_io_i(phy_io_i),
- .phy_io_o(phy_io_o),
- .phy_io_oe(phy_io_oe),
- .phy_clk_o(phy_clk_o),
- .phy_cs_o(phy_cs_o),
- .clk(clk_1x)
- );
- else if (PHY_SPEED == 2)
- qspi_phy_ice40_2x #(
- .N_CS(2),
- .WITH_CLK(1),
- ) phy_I (
- .pad_io(spi_io),
- .pad_clk(spi_sck),
- .pad_cs_n(spi_cs_n),
- .phy_io_i(phy_io_i),
- .phy_io_o(phy_io_o),
- .phy_io_oe(phy_io_oe),
- .phy_clk_o(phy_clk_o),
- .phy_cs_o(phy_cs_o),
- .clk_1x(clk_1x),
- .clk_2x(clk_2x)
- );
- else if (PHY_SPEED == 4)
- qspi_phy_ice40_4x #(
- .N_CS(2),
- .WITH_CLK(1),
- ) phy_I (
- .pad_io(spi_io),
- .pad_clk(spi_sck),
- .pad_cs_n(spi_cs_n),
- .phy_io_i(phy_io_i),
- .phy_io_o(phy_io_o),
- .phy_io_oe(phy_io_oe),
- .phy_clk_o(phy_clk_o),
- .phy_cs_o(phy_cs_o),
- .clk_1x(clk_1x),
- .clk_4x(clk_4x),
- .clk_sync(sync_4x)
- );
- endgenerate
- assign clk_rd_delay = 4'h0;
- `endif
- // HyperRAM Controller
- // -------------------
- `ifdef MEM_hyperram
- // Signals
- wire [ 1:0] phy_ck_en;
- wire [ 3:0] phy_rwds_in;
- wire [ 3:0] phy_rwds_out;
- wire [ 1:0] phy_rwds_oe;
- wire [31:0] phy_dq_in;
- wire [31:0] phy_dq_out;
- wire [ 1:0] phy_dq_oe;
- wire [ 3:0] phy_cs_n;
- wire phy_rst_n;
- wire [ 7:0] phy_cfg_wdata;
- wire [ 7:0] phy_cfg_rdata;
- wire phy_cfg_stb;
- // Controller
- hram_top hram_ctrl_I (
- .phy_ck_en(phy_ck_en),
- .phy_rwds_in(phy_rwds_in),
- .phy_rwds_out(phy_rwds_out),
- .phy_rwds_oe(phy_rwds_oe),
- .phy_dq_in(phy_dq_in),
- .phy_dq_out(phy_dq_out),
- .phy_dq_oe(phy_dq_oe),
- .phy_cs_n(phy_cs_n),
- .phy_rst_n(phy_rst_n),
- .phy_cfg_wdata(phy_cfg_wdata),
- .phy_cfg_rdata(phy_cfg_rdata),
- .phy_cfg_stb(phy_cfg_stb),
- .mi_addr_cs(mi_addr[31:30]),
- .mi_addr({1'b0, mi_addr[29:0], 1'b0}), /* 32b aligned */
- .mi_len(mi_len),
- .mi_rw(mi_rw),
- .mi_linear(1'b0),
- .mi_valid(mi_valid),
- .mi_ready(mi_ready),
- .mi_wdata(mi_wdata),
- .mi_wmsk(4'h0),
- .mi_wack(mi_wack),
- .mi_rdata(mi_rdata),
- .mi_rstb(mi_rstb),
- .wb_wdata(wb_wdata),
- .wb_rdata(wb_rdata[31:0]),
- .wb_addr(wb_addr[3:0]),
- .wb_we(wb_we),
- .wb_cyc(wb_cyc[0]),
- .wb_ack(wb_ack[0]),
- .clk(clk_1x),
- .rst(rst)
- );
- // PHY
- hram_phy_ice40 hram_phy_I (
- .hram_dq(hram_dq),
- .hram_rwds(hram_rwds),
- .hram_ck(hram_ck),
- .hram_cs_n(hram_cs_n),
- .hram_rst_n(hram_rst_n),
- .phy_ck_en(phy_ck_en),
- .phy_rwds_in(phy_rwds_in),
- .phy_rwds_out(phy_rwds_out),
- .phy_rwds_oe(phy_rwds_oe),
- .phy_dq_in(phy_dq_in),
- .phy_dq_out(phy_dq_out),
- .phy_dq_oe(phy_dq_oe),
- .phy_cs_n(phy_cs_n),
- .phy_rst_n(phy_rst_n),
- .phy_cfg_wdata(phy_cfg_wdata),
- .phy_cfg_rdata(phy_cfg_rdata),
- .phy_cfg_stb(phy_cfg_stb),
- .clk_rd_delay(clk_rd_delay),
- .clk_1x(clk_1x),
- .clk_4x(clk_4x),
- .clk_rd(clk_rd),
- .sync_4x(sync_4x),
- .sync_rd(sync_rd)
- );
- `endif
- // Memory tester
- // -------------
- memtest #(
- .ADDR_WIDTH(32)
- ) memtest_I (
- .mi_addr(mi0_addr),
- .mi_len(mi0_len),
- .mi_rw(mi0_rw),
- .mi_valid(mi0_valid),
- .mi_ready(mi0_ready),
- .mi_wdata(mi0_wdata),
- .mi_wack(mi0_wack),
- .mi_rdata(mi0_rdata),
- .mi_rstb(mi0_rstb),
- .wb_wdata(wb_wdata),
- .wb_rdata(wb_rdata[63:32]),
- .wb_addr(wb_addr[8:0]),
- .wb_we(wb_we),
- .wb_cyc(wb_cyc[1]),
- .wb_ack(wb_ack[1]),
- .clk(clk_1x),
- .rst(rst)
- );
- // Memory Mux
- // ----------
- assign mi_addr = dma_run ? mi1_addr : mi0_addr;
- assign mi_len = dma_run ? mi1_len : mi0_len;
- assign mi_rw = dma_run ? mi1_rw : mi0_rw;
- assign mi_valid = dma_run ? mi1_valid : mi0_valid;
- assign mi0_ready = mi_ready & ~dma_run;
- assign mi1_ready = mi_ready & dma_run;
- assign mi_wdata = dma_run ? mi1_wdata : mi0_wdata;
- assign mi0_wack = mi_wack & ~dma_run;
- assign mi0_wlast = mi_wlast;
- assign mi1_wack = mi_wack & dma_run;
- assign mi1_wlast = mi_wlast;
- assign mi0_rdata = mi_rdata;
- assign mi0_rstb = mi_rstb & ~dma_run;
- assign mi0_rlast = mi_rlast;
- assign mi1_rdata = mi_rdata;
- assign mi1_rstb = mi_rstb & dma_run;
- assign mi1_rlast = mi_rlast;
- // HDMI output
- // -----------
- `ifndef VIDEO_none
- hdmi_out #(
- `ifdef VIDEO_4bpp
- .DW(4)
- `endif
- `ifdef VIDEO_12bpp
- .DW(12)
- `endif
- ) hdmi_I (
- .hdmi_data(hdmi_data),
- .hdmi_hsync(hdmi_hsync),
- .hdmi_vsync(hdmi_vsync),
- .hdmi_de(hdmi_de),
- .hdmi_clk(hdmi_clk),
- .wb_wdata(wb_wdata),
- .wb_rdata(wb_rdata[95:64]),
- .wb_addr(wb_addr[6:0]),
- .wb_we(wb_we),
- .wb_cyc(wb_cyc[2]),
- .wb_ack(wb_ack[2]),
- .mi_addr(mi1_addr),
- .mi_len(mi1_len),
- .mi_rw(mi1_rw),
- .mi_valid(mi1_valid),
- .mi_ready(mi1_ready),
- .mi_wdata(mi1_wdata),
- .mi_wack(mi1_wack),
- .mi_rdata(mi1_rdata),
- .mi_rstb(mi1_rstb),
- .clk_1x(clk_1x),
- .clk_4x(clk_4x),
- .sync_4x(sync_4x),
- .rst(rst)
- );
- `else
- // Dummy wishbone
- assign wb_ack[2] = wb_cyc[2];
- assign wb_rdata[95:64] = 32'h00000000;
- // Dummy mem-if
- assign mi1_addr = 32'hxxxxxxxx;
- assign mi1_len = 7'hxx;
- assign mi1_rw = 1'bx;
- assign mi1_valid = 1'b0;
- assign mi1_wdata = 32'hxxxxxxxx;
- `endif
- // Clock / Reset
- // -------------
- sys_mgr sys_mgr_I (
- .delay(clk_rd_delay),
- .clk_in(clk_in),
- .clk_1x(clk_1x),
- .clk_2x(clk_2x),
- .clk_4x(clk_4x),
- .clk_rd(clk_rd),
- .sync_4x(sync_4x),
- .sync_rd(sync_rd),
- .rst(rst)
- );
- endmodule
|