/* * soc_base.v * * vim: ts=4 sw=4 * * Minimal common base for the E1 project SoC * * Copyright (C) 2019-2020 Sylvain Munaut * 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