xmas-snoopy/gateware/rtl/top.v

333 lines
5.9 KiB
Verilog

/*
* top.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2019-2020 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,
output wire spi_clk,
output wire spi_cs_n,
// USB
inout wire usb_dp,
inout wire usb_dn,
output wire usb_pu,
// Power
input wire pwr_usb_n,
input wire pwr_chg_n,
output wire pwr_off,
// Buttons
input wire [1:0] btn,
// I2C
inout wire scl,
inout wire sda,
// Speaker
output wire hp_p,
output wire hp_n,
// LED matrix
output wire [13:0] led_a,
output wire [2:0] led_c
);
localparam integer WN = 6;
genvar i;
// Signals
// -------
// Wishbone
wire [15:0] wb_addr;
wire [31:0] wb_rdata [0:WN-1];
wire [31:0] wb_wdata;
wire [3:0] wb_wmsk;
wire [WN-1:0] wb_cyc;
wire wb_we;
wire [WN-1:0] wb_ack;
wire [(32*WN)-1:0] wb_rdata_flat;
// I2C
wire i2c_scl_oe;
wire i2c_scl_i;
wire i2c_sda_oe;
wire i2c_sda_i;
// USB Core
// Wishbone in 48 MHz domain
wire [11:0] ub_addr;
wire [15:0] ub_wdata;
wire [15:0] ub_rdata;
wire ub_cyc;
wire ub_we;
wire ub_ack;
// EP Buffer
wire [ 8:0] ep_tx_addr_0;
wire [31:0] ep_tx_data_0;
wire ep_tx_we_0;
wire [ 8:0] ep_rx_addr_0;
wire [31:0] ep_rx_data_1;
wire ep_rx_re_0;
// Clock Control
wire wakeup;
wire sys_start;
wire sys_stop;
wire usb_ena;
// Clock / Reset
wire clk_led;
wire rst_led;
wire clk_sys;
wire rst_sys;
wire clk_usb;
wire rst_usb;
// SoC
// ---
soc_vex_base #(
.WB_N (WN),
.WB_DW (32),
.WB_AW (16),
.BRAM_AW (8), // 1k BRAM
.SPRAM_AW (14) // 64k SPRAM
) base_I (
.wb_addr (wb_addr),
.wb_rdata (wb_rdata_flat),
.wb_wdata (wb_wdata),
.wb_wmsk (wb_wmsk),
.wb_we (wb_we),
.wb_cyc (wb_cyc),
.wb_ack (wb_ack),
.clk (clk_sys),
.rst (rst_sys)
);
for (i=0; i<WN; i=i+1)
assign wb_rdata_flat[i*32+:32] = wb_rdata[i];
// PMU [0]
// ---
pmu pmu_I (
.wb_addr (wb_addr[15:0]),
.wb_rdata (wb_rdata[0]),
.wb_wdata (wb_wdata),
.wb_we (wb_we),
.wb_cyc (wb_cyc[0]),
.wb_ack (wb_ack[0]),
.btn (btn),
.pwr_usb_n (pwr_usb_n),
.pwr_chg_n (pwr_chg_n),
.pwr_off (pwr_off),
.sys_start (sys_start),
.sys_stop (sys_stop),
.usb_ena (usb_ena),
.wakeup (wakeup),
.clk (clk_sys),
.rst (rst_sys)
);
// SPI [1]
// ---
ice40_spi_wb #(
.N_CS(1),
.WITH_IOB(1),
.UNIT(0)
) spi_I (
.pad_mosi (spi_io[0]),
.pad_miso (spi_io[1]),
.pad_clk (spi_clk),
.pad_csn (spi_cs_n),
.wb_addr (wb_addr[3:0]),
.wb_rdata (wb_rdata[1]),
.wb_wdata (wb_wdata),
.wb_we (wb_we),
.wb_cyc (wb_cyc[1]),
.wb_ack (wb_ack[1]),
.clk (clk_sys),
.rst (rst_sys)
);
assign spi_io[3:2] = 4'bzz;
// I2C [2]
// ---
// Controller
i2c_master_wb #(
.DW(4),
.TW(15),
.CLOCK_STRETCH(1),
.FIFO_DEPTH(0)
) i2c_I (
.scl_oe (i2c_scl_oe),
.scl_i (i2c_scl_i),
.sda_oe (i2c_sda_oe),
.sda_i (i2c_sda_i),
.wb_rdata(wb_rdata[2]),
.wb_wdata(wb_wdata),
.wb_we (wb_we),
.wb_cyc (wb_cyc[2]),
.wb_ack (wb_ack[2]),
.clk (clk_sys),
.rst (rst_sys)
);
// IOBs
SB_IO #(
.PIN_TYPE(6'b110100),
.PULLUP(1'b1),
.IO_STANDARD("SB_LVCMOS")
) i2c_iob_I[1:0] (
.PACKAGE_PIN ({scl, sda}),
.INPUT_CLK (clk_sys),
.OUTPUT_CLK (clk_sys),
.OUTPUT_ENABLE({i2c_scl_oe, i2c_sda_oe}),
.D_OUT_0 (1'b0),
.D_IN_0 ({i2c_scl_i, i2c_sda_i})
);
// USB Buffer [3]
// ----------
soc_usb_buf_bridge usb_buf_I (
.wb_addr (wb_addr),
.wb_rdata (wb_rdata[3]),
.wb_wdata (wb_wdata),
.wb_wmsk (wb_wmsk),
.wb_we (wb_we),
.wb_cyc (wb_cyc[3]),
.wb_ack (wb_ack[3]),
.ep_tx_addr_0 (ep_tx_addr_0),
.ep_tx_data_0 (ep_tx_data_0),
.ep_tx_we_0 (ep_tx_we_0),
.ep_rx_addr_0 (ep_rx_addr_0),
.ep_rx_data_1 (ep_rx_data_1),
.ep_rx_re_0 (ep_rx_re_0),
.clk (clk_sys),
.rst (rst_sys)
);
// USB core [4]
// --------
// Cross-clock
xclk_wb #(
.DW(16),
.AW(12)
) wb_48m_xclk_I (
.s_addr (wb_addr[11:0]),
.s_wdata (wb_wdata[15:0]),
.s_rdata (wb_rdata[4][15:0]),
.s_cyc (wb_cyc[4]),
.s_ack (wb_ack[4]),
.s_we (wb_we),
.s_clk (clk_sys),
.m_addr (ub_addr),
.m_wdata (ub_wdata),
.m_rdata (ub_rdata),
.m_cyc (ub_cyc),
.m_ack (ub_ack),
.m_we (ub_we),
.m_clk (clk_usb),
.rst (rst_usb)
);
assign wb_rdata[4][31:16] = 0;
// Core
usb #(
.EPDW(32)
) usb_I (
.pad_dp (usb_dp),
.pad_dn (usb_dn),
.pad_pu (usb_pu),
.ep_tx_addr_0 (ep_tx_addr_0),
.ep_tx_data_0 (ep_tx_data_0),
.ep_tx_we_0 (ep_tx_we_0),
.ep_rx_addr_0 (ep_rx_addr_0),
.ep_rx_data_1 (ep_rx_data_1),
.ep_rx_re_0 (ep_rx_re_0),
.ep_clk (clk_sys),
.wb_addr (ub_addr),
.wb_rdata (ub_rdata),
.wb_wdata (ub_wdata),
.wb_we (ub_we),
.wb_cyc (ub_cyc),
.wb_ack (ub_ack),
.clk (clk_usb),
.rst (rst_usb)
);
// LED matrix controller [5]
// ---------------------
led_ctrl led_I (
.led_a (led_a),
.led_c (led_c),
.led_clk (clk_led),
.led_rst (rst_led),
.trig_out (wakeup),
.wb_addr (wb_addr[15:0]),
.wb_rdata (wb_rdata[5]),
.wb_wdata (wb_wdata),
.wb_we (wb_we),
.wb_cyc (wb_cyc[5]),
.wb_ack (wb_ack[5]),
.wb_clk (clk_sys),
.wb_rst (rst_sys)
);
// CRG
// ---
`ifdef SIM
sysmgr_sim crg_I (
`else
sysmgr crg_I (
`endif
.sys_start (sys_start),
.sys_stop (sys_stop),
.usb_ena (usb_ena),
.clk_led (clk_led),
.rst_led (rst_led),
.clk_sys (clk_sys),
.rst_sys (rst_sys),
.clk_usb (clk_usb),
.rst_usb (rst_usb)
);
// Unused
// ------
assign hp_p = 1'bz;
assign hp_n = 1'bz;
endmodule // top