123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- /*
- * top.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2021 Sylvain Munaut <tnt@246tNt.com>
- * SPDX-License-Identifier: CERN-OHL-P-2.0
- */
- `default_nettype none
- module top (
- // SPI
- inout wire [3:0] spi_io,
- inout wire spi_sck,
- inout wire [1:0] spi_cs_n,
- // Video output
- output wire [3:0] hdmi_r,
- output wire [3:0] hdmi_g,
- output wire [3:0] hdmi_b,
- output wire hdmi_hsync,
- output wire hdmi_vsync,
- output wire hdmi_de,
- output wire hdmi_clk,
- // Debug UART
- input wire uart_rx,
- output wire uart_tx,
- // Buttons
- input wire btn_1,
- input wire btn_2,
- input wire btn_3,
- input wire btn_n,
- // LED
- output wire [2:0] rgb,
- // PMOD LEDs
- output wire[4:0] led,
- // Clock
- input wire clk_in
- );
- localparam integer WB_N = 4;
- localparam integer WB_DW = 32;
- localparam integer WB_AW = 22;
- localparam integer WB_RW = WB_DW * WB_N;
- localparam integer WB_MW = WB_DW / 8;
- genvar i;
- // Signals
- // -------
- // Vex Misc
- wire [31:0] vex_externalResetVector;
- wire vex_timerInterrupt;
- wire vex_softwareInterrupt;
- wire [31:0] vex_externalInterruptArray;
- // Vex busses
- wire i_axi_ar_valid;
- wire i_axi_ar_ready;
- wire [31:0] i_axi_ar_payload_addr;
- wire [ 7:0] i_axi_ar_payload_len;
- wire [ 1:0] i_axi_ar_payload_burst;
- wire [ 3:0] i_axi_ar_payload_cache;
- wire [ 2:0] i_axi_ar_payload_prot;
- wire i_axi_r_valid;
- wire i_axi_r_ready;
- wire [31:0] i_axi_r_payload_data;
- wire [ 1:0] i_axi_r_payload_resp;
- wire i_axi_r_payload_last;
- wire d_wb_cyc;
- wire d_wb_stb;
- wire d_wb_ack;
- wire d_wb_we;
- wire [29:0] d_wb_adr;
- wire [31:0] d_wb_dat_miso;
- wire [31:0] d_wb_dat_mosi;
- wire [ 3:0] d_wb_sel;
- wire d_wb_err;
- wire [ 1:0] d_wb_bte;
- wire [ 2:0] d_wb_cti;
- // RAM
- wire [27:0] ram_addr;
- wire [31:0] ram_rdata;
- wire [31:0] ram_wdata;
- wire [ 3:0] ram_wmsk;
- wire ram_we;
- // Cache Request / Response interface
- wire [27:0] cache_req_addr_pre;
- wire cache_req_valid;
- wire cache_req_write;
- wire [31:0] cache_req_wdata;
- wire [ 3:0] cache_req_wmsk;
- wire cache_resp_ack;
- wire cache_resp_nak;
- wire [31:0] cache_resp_rdata;
- // Memory interface
- wire [23:0] mi_addr;
- wire [ 6:0] mi_len;
- wire mi_rw;
- wire mi_linear;
- wire mi_valid;
- wire mi_ready;
- wire [31:0] mi_wdata;
- wire [ 3:0] mi_wmsk;
- wire mi_wack;
- wire mi_wlast;
- wire [31:0] mi_rdata;
- wire mi_rstb;
- wire mi_rlast;
- // QSPI PHY signals
- wire [15:0] phy_io_i;
- wire [15:0] phy_io_o;
- wire [ 3:0] phy_io_oe;
- wire [ 3:0] phy_clk_o;
- wire [ 1:0] phy_cs_o;
- // Wishbone
- wire [WB_AW-1:0] wb_addr;
- wire [WB_DW-1:0] wb_rdata [0:WB_N-1];
- wire [WB_RW-1:0] wb_rdata_flat;
- wire [WB_DW-1:0] wb_wdata;
- wire [WB_MW-1:0] wb_wmsk;
- wire wb_we;
- wire [WB_N -1:0] wb_cyc;
- wire [WB_N -1:0] wb_ack;
- // Clock / Reset logic
- wire clk_1x;
- wire clk_4x;
- wire sync_4x;
- wire rst;
- // PMOD LEDs
- reg [4:0] desired_led;
- assign led = desired_led;
- // SoC
- // ---
- // CPU
- VexRiscv cpu_I (
- .externalResetVector (vex_externalResetVector),
- .timerInterrupt (vex_timerInterrupt),
- .softwareInterrupt (vex_softwareInterrupt),
- .externalInterruptArray (vex_externalInterruptArray),
- .iBusAXI_ar_valid (i_axi_ar_valid),
- .iBusAXI_ar_ready (i_axi_ar_ready),
- .iBusAXI_ar_payload_addr (i_axi_ar_payload_addr),
- .iBusAXI_ar_payload_len (i_axi_ar_payload_len),
- .iBusAXI_ar_payload_burst (i_axi_ar_payload_burst),
- .iBusAXI_ar_payload_cache (i_axi_ar_payload_cache),
- .iBusAXI_ar_payload_prot (i_axi_ar_payload_prot),
- .iBusAXI_r_valid (i_axi_r_valid),
- .iBusAXI_r_ready (i_axi_r_ready),
- .iBusAXI_r_payload_data (i_axi_r_payload_data),
- .iBusAXI_r_payload_resp (i_axi_r_payload_resp),
- .iBusAXI_r_payload_last (i_axi_r_payload_last),
- .dBusWishbone_CYC (d_wb_cyc),
- .dBusWishbone_STB (d_wb_stb),
- .dBusWishbone_ACK (d_wb_ack),
- .dBusWishbone_WE (d_wb_we),
- .dBusWishbone_ADR (d_wb_adr),
- .dBusWishbone_DAT_MISO (d_wb_dat_miso),
- .dBusWishbone_DAT_MOSI (d_wb_dat_mosi),
- .dBusWishbone_SEL (d_wb_sel),
- .dBusWishbone_ERR (d_wb_err),
- .dBusWishbone_BTE (d_wb_bte),
- .dBusWishbone_CTI (d_wb_cti),
- .clk (clk_1x),
- .reset (rst)
- );
- // CPU interrupt wiring
- assign vex_externalResetVector = 32'h00000000;
- assign vex_timerInterrupt = 1'b0;
- assign vex_softwareInterrupt = 1'b0;
- assign vex_externalInterruptArray = 32'h00000000;
- // Cache bus interface / bridge
- mc_bus_vex #(
- .WB_N(WB_N)
- ) cache_bus_I (
- .i_axi_ar_valid (i_axi_ar_valid),
- .i_axi_ar_ready (i_axi_ar_ready),
- .i_axi_ar_payload_addr (i_axi_ar_payload_addr),
- .i_axi_ar_payload_len (i_axi_ar_payload_len),
- .i_axi_ar_payload_burst (i_axi_ar_payload_burst),
- .i_axi_ar_payload_cache (i_axi_ar_payload_cache),
- .i_axi_ar_payload_prot (i_axi_ar_payload_prot),
- .i_axi_r_valid (i_axi_r_valid),
- .i_axi_r_ready (i_axi_r_ready),
- .i_axi_r_payload_data (i_axi_r_payload_data),
- .i_axi_r_payload_resp (i_axi_r_payload_resp),
- .i_axi_r_payload_last (i_axi_r_payload_last),
- .d_wb_cyc (d_wb_cyc),
- .d_wb_stb (d_wb_stb),
- .d_wb_ack (d_wb_ack),
- .d_wb_we (d_wb_we),
- .d_wb_adr (d_wb_adr),
- .d_wb_dat_miso (d_wb_dat_miso),
- .d_wb_dat_mosi (d_wb_dat_mosi),
- .d_wb_sel (d_wb_sel),
- .d_wb_err (d_wb_err),
- .d_wb_bte (d_wb_bte),
- .d_wb_cti (d_wb_cti),
- .wb_addr (wb_addr),
- .wb_wdata (wb_wdata),
- .wb_wmsk (wb_wmsk),
- .wb_rdata (wb_rdata_flat),
- .wb_cyc (wb_cyc),
- .wb_we (wb_we),
- .wb_ack (wb_ack),
- .ram_addr (ram_addr),
- .ram_wdata (ram_wdata),
- .ram_wmsk (ram_wmsk),
- .ram_rdata (ram_rdata),
- .ram_we (ram_we),
- .req_addr_pre (cache_req_addr_pre),
- .req_valid (cache_req_valid),
- .req_write (cache_req_write),
- .req_wdata (cache_req_wdata),
- .req_wmsk (cache_req_wmsk),
- .resp_ack (cache_resp_ack),
- .resp_nak (cache_resp_nak),
- .resp_rdata (cache_resp_rdata),
- .clk (clk_1x),
- .rst (rst)
- );
- for (i=0; i<WB_N; i=i+1)
- assign wb_rdata_flat[i*WB_DW+:WB_DW] = wb_rdata[i];
- // Boot memory
- soc_bram #(
- .AW(8),
- .INIT_FILE("boot.hex")
- ) bram_I (
- .addr (ram_addr[7:0]),
- .rdata (ram_rdata),
- .wdata (ram_wdata),
- .wmsk (ram_wmsk),
- .we (ram_we),
- .clk (clk_1x)
- );
- // Cache
- mc_core #(
- .N_WAYS(4),
- .ADDR_WIDTH(24),
- .CACHE_LINE(32),
- .CACHE_SIZE(64)
- ) cache_I (
- .req_addr_pre (cache_req_addr_pre[23:0]),
- .req_valid (cache_req_valid),
- .req_write (cache_req_write),
- .req_wdata (cache_req_wdata),
- .req_wmsk (cache_req_wmsk),
- .resp_ack (cache_resp_ack),
- .resp_nak (cache_resp_nak),
- .resp_rdata (cache_resp_rdata),
- .mi_addr (mi_addr),
- .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),
- .clk (clk_1x),
- .rst (rst)
- );
- // QSPI
- // ----
- // Simulation
- `ifdef SIM
- mem_sim #(
- .INIT_FILE("firmware.hex"),
- .AW(20)
- ) qpi_sim (
- .mi_addr ({mi_addr[22], mi_addr[18:0]}),
- .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),
- .clk (clk_1x),
- .rst (rst)
- );
- assign wb_ack[0] = wb_cyc[0];
- `else
- // Controller
- qpi_memctrl #(
- .CMD_READ (16'hEB0B),
- .CMD_WRITE (16'h0202),
- .DUMMY_CLK (6),
- .PAUSE_CLK (8),
- .FIFO_DEPTH (1),
- .N_CS (2),
- .PHY_SPEED (4),
- .PHY_WIDTH (1),
- .PHY_DELAY (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[23:22]),
- .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[7:0], mi_wdata[15:8], mi_wdata[23:16], mi_wdata[31:24]}),
- .mi_wack (mi_wack),
- .mi_wlast (mi_wlast),
- .mi_rdata ({mi_rdata[7:0], mi_rdata[15:8], mi_rdata[23:16], mi_rdata[31:24]}),
- .mi_rstb (mi_rstb),
- .mi_rlast (mi_rlast),
- .wb_wdata (wb_wdata),
- .wb_rdata (wb_rdata[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
- qpi_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)
- );
- `endif
- // Video [1]
- // -----
- vid_top vid_I (
- .hdmi_r (hdmi_r),
- .hdmi_g (hdmi_g),
- .hdmi_b (hdmi_b),
- .hdmi_hsync (hdmi_hsync),
- .hdmi_vsync (hdmi_vsync),
- .hdmi_de (hdmi_de),
- .hdmi_clk (hdmi_clk),
- .wb_addr (wb_addr[15:0]),
- .wb_rdata (wb_rdata[1]),
- .wb_wdata (wb_wdata),
- .wb_wmsk (wb_wmsk),
- .wb_we (wb_we),
- .wb_cyc (wb_cyc[1]),
- .wb_ack (wb_ack[1]),
- .clk (clk_1x),
- .rst (rst)
- );
- // UART [2]
- // ----
- uart_wb #(
- .DIV_WIDTH(12),
- .DW(WB_DW)
- ) uart_I (
- .uart_tx (uart_tx),
- .uart_rx (uart_rx),
- .wb_addr (wb_addr[1:0]),
- .wb_rdata (wb_rdata[2]),
- .wb_we (wb_we),
- .wb_wdata (wb_wdata),
- .wb_cyc (wb_cyc[2]),
- .wb_ack (wb_ack[2]),
- .clk (clk_1x),
- .rst (rst)
- );
- // LEDs [3]
- // ----
- ice40_rgb_wb #(
- .CURRENT_MODE("0b1"),
- .RGB0_CURRENT("0b000001"),
- .RGB1_CURRENT("0b000001"),
- .RGB2_CURRENT("0b000001")
- ) rgb_I (
- .pad_rgb (rgb),
- .wb_addr (wb_addr[4:0]),
- .wb_rdata (wb_rdata[3]),
- .wb_wdata (wb_wdata),
- .wb_we (wb_we),
- .wb_cyc (wb_cyc[3]),
- .wb_ack (wb_ack[3]),
- .clk (clk_1x),
- .rst (rst)
- );
- // PMOD LEDs
- always @(posedge clk_1x) begin
- desired_led[0] = btn_1 & btn_2 & btn_3;
- desired_led[1] = btn_1;
- desired_led[2] = btn_2;
- desired_led[3] = btn_3;
- desired_led[4] = !btn_n;
- end
- // Clock / Reset
- // -------------
- `ifdef SIM
- reg rst_s = 1'b1;
- reg clk_4x_s = 1'b0;
- reg clk_1x_s = 1'b0;
- reg [1:0] clk_sync_cnt = 2'b00;
- always #5 clk_4x_s <= !clk_4x_s;
- always #20 clk_1x_s <= !clk_1x_s;
- initial
- #200 rst_s = 0;
- always @(posedge clk_4x_s)
- if (rst)
- clk_sync_cnt <= 2'b00;
- else
- clk_sync_cnt <= clk_sync_cnt + 1;
- assign clk_4x = clk_4x_s;
- assign clk_1x = clk_1x_s;
- assign sync_4x = (clk_sync_cnt == 2'b10);
- assign rst = rst_s;
- `else
- sysmgr sys_mgr_I (
- .clk_in (clk_in),
- .clk_1x (clk_1x),
- .clk_4x (clk_4x),
- .sync_4x (sync_4x),
- .rst (rst)
- );
- `endif
- endmodule // top
|