545 lines
11 KiB
Verilog
545 lines
11 KiB
Verilog
/*
|
|
* soc_base.v
|
|
*
|
|
* vim: ts=4 sw=4
|
|
*
|
|
* Minimal common base for the E1 project SoC
|
|
*
|
|
* Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
|
|
* SPDX-License-Identifier: CERN-OHL-S-2.0
|
|
*/
|
|
|
|
`default_nettype none
|
|
|
|
module soc_base #(
|
|
parameter integer WB_N = 1,
|
|
parameter integer E1_N = 1,
|
|
parameter E1_UNIT_HAS_RX = 1'b1,
|
|
parameter E1_UNIT_HAS_TX = 1'b1,
|
|
parameter integer E1_LIU = 0
|
|
)(
|
|
// E1 pads
|
|
// Raw PHY
|
|
input wire [E1_N-1:0] e1_rx_hi_p,
|
|
input wire [E1_N-1:0] e1_rx_hi_n,
|
|
input wire [E1_N-1:0] e1_rx_lo_p,
|
|
input wire [E1_N-1:0] e1_rx_lo_n,
|
|
|
|
output wire [E1_N-1:0] e1_tx_hi,
|
|
output wire [E1_N-1:0] e1_tx_lo,
|
|
|
|
// LIU
|
|
input wire [E1_N-1:0] e1_rx_data,
|
|
input wire [E1_N-1:0] e1_rx_clk,
|
|
|
|
output wire [E1_N-1:0] e1_tx_data,
|
|
output wire [E1_N-1:0] e1_tx_clk,
|
|
|
|
// USB
|
|
inout wire usb_dp,
|
|
inout wire usb_dn,
|
|
output wire usb_pu,
|
|
|
|
// Flash SPI (raw)
|
|
input wire flash_mosi_i,
|
|
output wire flash_mosi_o,
|
|
output wire flash_mosi_oe,
|
|
|
|
input wire flash_miso_i,
|
|
output wire flash_miso_o,
|
|
output wire flash_miso_oe,
|
|
|
|
input wire flash_clk_i,
|
|
output wire flash_clk_o,
|
|
output wire flash_clk_oe,
|
|
|
|
output wire flash_csn_o,
|
|
|
|
// Debug UART
|
|
input wire dbg_rx,
|
|
output wire dbg_tx,
|
|
|
|
// RGB LEDs
|
|
output wire [2:0] rgb,
|
|
|
|
// External Master Wishbone bus (CPU -> Peripheral)
|
|
output wire [15:0] wb_m_addr,
|
|
input wire [(WB_N*32)-1:0] wb_m_rdata,
|
|
output wire [31:0] wb_m_wdata,
|
|
output wire [ 3:0] wb_m_wmsk,
|
|
output wire wb_m_we,
|
|
output wire [ WB_N -1:0] wb_m_cyc,
|
|
input wire [ WB_N -1:0] wb_m_ack,
|
|
|
|
// Ticks
|
|
output wire [E1_N-1:0] tick_e1_rx,
|
|
output wire [E1_N-1:0] tick_e1_tx,
|
|
output wire tick_usb_sof,
|
|
|
|
// Clock / Reset
|
|
input wire clk_sys,
|
|
input wire rst_sys,
|
|
input wire clk_48m,
|
|
input wire rst_48m
|
|
);
|
|
|
|
genvar i;
|
|
|
|
localparam integer WB_LN = 8;
|
|
localparam integer WB_TN = WB_N + WB_LN;
|
|
localparam integer WB_DW = 32;
|
|
localparam integer WB_MW = WB_DW / 8;
|
|
localparam integer WB_AW = 16;
|
|
localparam integer WB_AI = 2;
|
|
|
|
|
|
// Signals
|
|
// -------
|
|
|
|
// Picorv32 native bus
|
|
wire pb_valid;
|
|
wire pb_instr;
|
|
wire pb_ready;
|
|
wire [31:0] pb_addr;
|
|
wire [31:0] pb_rdata;
|
|
wire [31:0] pb_wdata;
|
|
wire [ 3:0] pb_wstrb;
|
|
|
|
// SoC RAM
|
|
// BRAM
|
|
wire [ 7:0] bram_addr;
|
|
wire [31:0] bram_rdata;
|
|
wire [31:0] bram_wdata;
|
|
wire [ 3:0] bram_wmsk;
|
|
wire bram_we;
|
|
|
|
// SPRAM
|
|
wire [14:0] spram_addr;
|
|
wire [31:0] spram_rdata;
|
|
wire [31:0] spram_wdata;
|
|
wire [ 3:0] spram_wmsk;
|
|
wire spram_we;
|
|
|
|
// Peripheral wishbone
|
|
wire [WB_AW-1:0] wb_addr;
|
|
wire [WB_DW-1:0] wb_rdata [0:WB_LN-1];
|
|
wire [WB_DW-1:0] wb_wdata;
|
|
wire [WB_MW-1:0] wb_wmsk;
|
|
wire wb_we;
|
|
wire [WB_TN-1:0] wb_cyc;
|
|
wire [WB_TN-1:0] wb_ack;
|
|
|
|
wire [(WB_DW*WB_TN)-1:0] wb_rdata_flat;
|
|
|
|
// USB
|
|
// Wishbone ( @ 48 MHz )
|
|
wire [11:0] ub_addr;
|
|
wire [15:0] ub_rdata;
|
|
wire [15:0] ub_wdata;
|
|
wire ub_we;
|
|
wire ub_cyc;
|
|
wire ub_ack;
|
|
|
|
// EP interface
|
|
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;
|
|
|
|
// SoF
|
|
wire usb_sof;
|
|
|
|
// Wishbone bus E1 to IO buffers
|
|
wire [13:0] wb_e1_addr;
|
|
wire [31:0] wb_e1_rdata;
|
|
wire [31:0] wb_e1_wdata;
|
|
wire [ 3:0] wb_e1_wmsk;
|
|
wire wb_e1_we;
|
|
wire wb_e1_cyc;
|
|
wire wb_e1_ack;
|
|
|
|
// E1 buffer interface
|
|
wire [(E1_N*8)-1:0] e1_buf_rx_data;
|
|
wire [(E1_N*5)-1:0] e1_buf_rx_ts;
|
|
wire [(E1_N*4)-1:0] e1_buf_rx_frame;
|
|
wire [(E1_N*7)-1:0] e1_buf_rx_mf;
|
|
wire [ E1_N -1:0] e1_buf_rx_we;
|
|
wire [ E1_N -1:0] e1_buf_rx_rdy;
|
|
wire [(E1_N*8)-1:0] e1_buf_tx_data;
|
|
wire [(E1_N*5)-1:0] e1_buf_tx_ts;
|
|
wire [(E1_N*4)-1:0] e1_buf_tx_frame;
|
|
wire [(E1_N*7)-1:0] e1_buf_tx_mf;
|
|
wire [ E1_N -1:0] e1_buf_tx_re;
|
|
wire [ E1_N -1:0] e1_buf_tx_rdy;
|
|
|
|
|
|
// SoC core
|
|
// --------
|
|
|
|
// Local CPU reset
|
|
reg pb_rst_n;
|
|
|
|
always @(posedge clk_sys or posedge rst_sys)
|
|
if (rst_sys)
|
|
pb_rst_n <= 1'b0;
|
|
else
|
|
pb_rst_n <= 1'b1;
|
|
|
|
// CPU
|
|
picorv32 #(
|
|
.PROGADDR_RESET(32'h 0000_0000),
|
|
.STACKADDR(32'h 0000_0400),
|
|
.BARREL_SHIFTER(0),
|
|
`ifdef BOARD_E1_TRACER
|
|
.TWO_CYCLE_COMPARE(0),
|
|
.TWO_CYCLE_ALU(0),
|
|
`else
|
|
.TWO_CYCLE_COMPARE(0),
|
|
.TWO_CYCLE_ALU(1),
|
|
`endif
|
|
.COMPRESSED_ISA(0),
|
|
.ENABLE_COUNTERS(0),
|
|
.ENABLE_MUL(0),
|
|
.ENABLE_DIV(0),
|
|
.ENABLE_IRQ(0),
|
|
.ENABLE_IRQ_QREGS(0),
|
|
.CATCH_MISALIGN(0),
|
|
.CATCH_ILLINSN(0)
|
|
) cpu_I (
|
|
.clk (clk_sys),
|
|
.resetn (pb_rst_n),
|
|
.mem_valid (pb_valid),
|
|
.mem_instr (pb_instr),
|
|
.mem_ready (pb_ready),
|
|
.mem_addr (pb_addr),
|
|
.mem_wdata (pb_wdata),
|
|
.mem_wstrb (pb_wstrb),
|
|
.mem_rdata (pb_rdata)
|
|
);
|
|
|
|
// CPU bridge
|
|
soc_picorv32_bridge #(
|
|
.WB_N (WB_TN),
|
|
.WB_DW (32),
|
|
.WB_AW (16),
|
|
.WB_AI ( 2),
|
|
.WB_REG( 0)
|
|
) bridge_I (
|
|
.pb_addr (pb_addr),
|
|
.pb_rdata (pb_rdata),
|
|
.pb_wdata (pb_wdata),
|
|
.pb_wstrb (pb_wstrb),
|
|
.pb_valid (pb_valid),
|
|
.pb_ready (pb_ready),
|
|
.bram_addr (bram_addr),
|
|
.bram_rdata (bram_rdata),
|
|
.bram_wdata (bram_wdata),
|
|
.bram_wmsk (bram_wmsk),
|
|
.bram_we (bram_we),
|
|
.spram_addr (spram_addr),
|
|
.spram_rdata(spram_rdata),
|
|
.spram_wdata(spram_wdata),
|
|
.spram_wmsk (spram_wmsk),
|
|
.spram_we (spram_we),
|
|
.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<WB_LN; i=i+1)
|
|
assign wb_rdata_flat[i*WB_DW+:WB_DW] = wb_rdata[i];
|
|
|
|
// Boot memory - 1k
|
|
soc_bram #(
|
|
.AW(8),
|
|
.INIT_FILE("boot.hex"),
|
|
) bram_I (
|
|
.addr (bram_addr),
|
|
.rdata(bram_rdata),
|
|
.wdata(bram_wdata),
|
|
.wmsk (bram_wmsk),
|
|
.we (bram_we),
|
|
.clk (clk_sys)
|
|
);
|
|
|
|
// Main SoC memory - 64k
|
|
soc_spram #(
|
|
.AW(14)
|
|
) spram_I (
|
|
.addr (spram_addr[13:0]),
|
|
.rdata(spram_rdata),
|
|
.wdata(spram_wdata),
|
|
.wmsk (spram_wmsk),
|
|
.we (spram_we),
|
|
.clk (clk_sys)
|
|
);
|
|
|
|
// Peripheral wishbone export
|
|
assign wb_m_addr = wb_addr;
|
|
assign wb_m_wdata = wb_wdata;
|
|
assign wb_m_wmsk = wb_wmsk;
|
|
assign wb_m_we = wb_we;
|
|
assign wb_m_cyc = wb_cyc[WB_TN-1:WB_LN];
|
|
|
|
assign wb_rdata_flat[(WB_TN*WB_DW)-1:(WB_LN*WB_DW)] = wb_m_rdata;
|
|
assign wb_ack[WB_TN-1:WB_LN] = wb_m_ack;
|
|
|
|
|
|
// SPI [0]
|
|
// ---
|
|
|
|
ice40_spi_wb #(
|
|
.N_CS(1),
|
|
.WITH_IOB(0),
|
|
.UNIT(0)
|
|
) spi_I (
|
|
.sio_mosi_i (flash_mosi_i),
|
|
.sio_mosi_o (flash_mosi_o),
|
|
.sio_mosi_oe(flash_mosi_oe),
|
|
.sio_miso_i (flash_miso_i),
|
|
.sio_miso_o (flash_miso_o),
|
|
.sio_miso_oe(flash_miso_oe),
|
|
.sio_clk_i (flash_clk_i),
|
|
.sio_clk_o (flash_clk_o),
|
|
.sio_clk_oe (flash_clk_oe),
|
|
.sio_csn_o (flash_csn_o),
|
|
.sio_csn_oe (),
|
|
.wb_addr (wb_addr[3:0]),
|
|
.wb_rdata (wb_rdata[0]),
|
|
.wb_wdata (wb_wdata),
|
|
.wb_we (wb_we),
|
|
.wb_cyc (wb_cyc[0]),
|
|
.wb_ack (wb_ack[0]),
|
|
.clk (clk_sys),
|
|
.rst (rst_sys)
|
|
);
|
|
|
|
|
|
// Debug UART [1]
|
|
// ----------
|
|
|
|
uart_wb #(
|
|
.DIV_WIDTH(12),
|
|
.DW(WB_DW)
|
|
) uart_I (
|
|
.uart_tx (dbg_tx),
|
|
.uart_rx (dbg_rx),
|
|
.wb_addr (wb_addr[1: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)
|
|
);
|
|
|
|
|
|
// RGB LEDs [2]
|
|
// --------
|
|
|
|
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[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)
|
|
);
|
|
|
|
|
|
// USB [3]
|
|
// ---
|
|
|
|
// Core instance ( @ 48 MHz )
|
|
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),
|
|
.sof (usb_sof),
|
|
.clk (clk_48m),
|
|
.rst (rst_48m)
|
|
);
|
|
|
|
// Cross clock bridge
|
|
xclk_wb #(
|
|
.DW(16),
|
|
.AW(12)
|
|
) wb_48m_xclk_I (
|
|
.s_addr (wb_addr[11:0]),
|
|
.s_rdata(wb_rdata[3][15:0]),
|
|
.s_wdata(wb_wdata[15:0]),
|
|
.s_we (wb_we),
|
|
.s_cyc (wb_cyc[3]),
|
|
.s_ack (wb_ack[3]),
|
|
.s_clk (clk_sys),
|
|
.m_addr (ub_addr),
|
|
.m_rdata(ub_rdata),
|
|
.m_wdata(ub_wdata),
|
|
.m_we (ub_we),
|
|
.m_cyc (ub_cyc),
|
|
.m_ack (ub_ack),
|
|
.m_clk (clk_48m),
|
|
.rst (rst_sys)
|
|
);
|
|
|
|
assign wb_rdata[3][31:16] = 16'h0000;
|
|
|
|
// Cross clock SoF
|
|
xclk_strobe sof_xclk_I (
|
|
.in_stb (usb_sof),
|
|
.in_clk (clk_48m),
|
|
.out_stb(tick_usb_sof),
|
|
.out_clk(clk_sys),
|
|
.rst (rst_sys)
|
|
);
|
|
|
|
|
|
// IO buffers & DMA
|
|
// ----------------
|
|
// [4] USB EP buffer
|
|
// [5] E1 SPRAM buffer
|
|
// [6] DMA
|
|
|
|
soc_iobuf iobuf_I (
|
|
.wb_cpu_addr (wb_addr),
|
|
.wb_cpu_rdata(wb_rdata[4]),
|
|
.wb_cpu_wdata(wb_wdata),
|
|
.wb_cpu_wmsk (wb_wmsk),
|
|
.wb_cpu_we (wb_we),
|
|
.wb_cpu_cyc (wb_cyc[6:4]),
|
|
.wb_cpu_ack (wb_ack[6:4]),
|
|
.wb_e1_addr (wb_e1_addr),
|
|
.wb_e1_rdata (wb_e1_rdata),
|
|
.wb_e1_wdata (wb_e1_wdata),
|
|
.wb_e1_wmsk (wb_e1_wmsk),
|
|
.wb_e1_we (wb_e1_we),
|
|
.wb_e1_cyc (wb_e1_cyc),
|
|
.wb_e1_ack (wb_e1_ack),
|
|
.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)
|
|
);
|
|
|
|
assign wb_rdata[5] = 32'h00000000;
|
|
assign wb_rdata[6] = 32'h00000000;
|
|
|
|
|
|
// E1 [7]
|
|
// --
|
|
|
|
// E1 wishbone module
|
|
e1_wb #(
|
|
.N(E1_N),
|
|
.UNIT_HAS_RX(E1_UNIT_HAS_RX),
|
|
.UNIT_HAS_TX(E1_UNIT_HAS_TX),
|
|
.LIU(E1_LIU),
|
|
.MFW(7)
|
|
) e1_I (
|
|
.pad_rx_hi_p (e1_rx_hi_p),
|
|
.pad_rx_hi_n (e1_rx_hi_n),
|
|
.pad_rx_lo_p (e1_rx_lo_p),
|
|
.pad_rx_lo_n (e1_rx_lo_n),
|
|
.pad_tx_hi (e1_tx_hi),
|
|
.pad_tx_lo (e1_tx_lo),
|
|
.pad_rx_data (e1_rx_data),
|
|
.pad_rx_clk (e1_rx_clk),
|
|
.pad_tx_data (e1_tx_data),
|
|
.pad_tx_clk (e1_tx_clk),
|
|
.buf_rx_data (e1_buf_rx_data),
|
|
.buf_rx_ts (e1_buf_rx_ts),
|
|
.buf_rx_frame(e1_buf_rx_frame),
|
|
.buf_rx_mf (e1_buf_rx_mf),
|
|
.buf_rx_we (e1_buf_rx_we),
|
|
.buf_rx_rdy (e1_buf_rx_rdy),
|
|
.buf_tx_data (e1_buf_tx_data),
|
|
.buf_tx_ts (e1_buf_tx_ts),
|
|
.buf_tx_frame(e1_buf_tx_frame),
|
|
.buf_tx_mf (e1_buf_tx_mf),
|
|
.buf_tx_re (e1_buf_tx_re),
|
|
.buf_tx_rdy (e1_buf_tx_rdy),
|
|
.wb_addr (wb_addr[7:0]),
|
|
.wb_rdata (wb_rdata[7][15:0]),
|
|
.wb_wdata (wb_wdata[15:0]),
|
|
.wb_we (wb_we),
|
|
.wb_cyc (wb_cyc[7]),
|
|
.wb_ack (wb_ack[7]),
|
|
.irq (),
|
|
.tick_rx (tick_e1_rx),
|
|
.tick_tx (tick_e1_tx),
|
|
.clk (clk_sys),
|
|
.rst (rst_sys)
|
|
);
|
|
|
|
assign wb_rdata[7][31:16] = 16'h0000;
|
|
|
|
// E1 buffer interface to Wishbone
|
|
e1_buf_if_wb #(
|
|
.N(E1_N),
|
|
.UNIT_HAS_RX(E1_UNIT_HAS_RX),
|
|
.UNIT_HAS_TX(E1_UNIT_HAS_TX),
|
|
.MFW(7),
|
|
.DW(32)
|
|
) e1_buf_I (
|
|
.wb_addr (wb_e1_addr),
|
|
.wb_rdata (wb_e1_rdata),
|
|
.wb_wdata (wb_e1_wdata),
|
|
.wb_wmsk (wb_e1_wmsk),
|
|
.wb_we (wb_e1_we),
|
|
.wb_cyc (wb_e1_cyc),
|
|
.wb_ack (wb_e1_ack),
|
|
.buf_rx_data (e1_buf_rx_data),
|
|
.buf_rx_ts (e1_buf_rx_ts),
|
|
.buf_rx_frame(e1_buf_rx_frame),
|
|
.buf_rx_mf (e1_buf_rx_mf),
|
|
.buf_rx_we (e1_buf_rx_we),
|
|
.buf_rx_rdy (e1_buf_rx_rdy),
|
|
.buf_tx_data (e1_buf_tx_data),
|
|
.buf_tx_ts (e1_buf_tx_ts),
|
|
.buf_tx_frame(e1_buf_tx_frame),
|
|
.buf_tx_mf (e1_buf_tx_mf),
|
|
.buf_tx_re (e1_buf_tx_re),
|
|
.buf_tx_rdy (e1_buf_tx_rdy),
|
|
.clk (clk_sys),
|
|
.rst (rst_sys)
|
|
);
|
|
|
|
endmodule // soc_base
|