gateware/icE1usb-proto: Initial import

This is the project specific to the PMOD based early prototype.
It was used either with the icebreaker or the icebreaker-bitsy
board as host. Set BOARD variable appropriately during build.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
Sylvain Munaut 2020-09-14 10:10:49 +02:00
parent 21b03baf47
commit da65157363
9 changed files with 875 additions and 0 deletions

4
gateware/icE1usb-proto/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
build-tmp
__pycache__
*.vcd
.*.swp

View File

@ -0,0 +1,43 @@
# Project config
PROJ=icE1usb-proto
PROJ_DEPS := no2e1 no2ice40 no2misc no2usb
PROJ_RTL_SRCS := $(addprefix rtl/, \
misc.v \
sysmgr.v \
)
PROJ_RTL_SRCS += $(addprefix ../common/rtl/, \
dfu_helper.v \
picorv32.v \
soc_base.v \
soc_bram.v \
soc_iobuf.v \
soc_picorv32_bridge.v \
soc_spram.v \
wb_arbiter.v \
wb_dma.v \
wb_epbuf.v \
)
PROJ_PREREQ = \
$(BUILD_TMP)/boot.hex \
$(NULL)
PROJ_TOP_SRC := rtl/top.v
PROJ_TOP_MOD := top
# Target config
BOARD ?= icebreaker
DEVICE = up5k
PACKAGE = sg48
NEXTPNR_ARGS = --pre-pack data/clocks.py --seed 4
# Include default rules
NO2BUILD_DIR := ../build
include $(NO2BUILD_DIR)/project-rules.mk
# Custom rules
../common/fw/boot.hex:
make -C ../common/fw boot.hex
$(BUILD_TMP)/boot.hex: ../common/fw/boot.hex
cp $< $@

View File

@ -0,0 +1,2 @@
ctx.addClock("clk_sys", 30.72)
ctx.addClock("clk_48m", 48)

View File

@ -0,0 +1,40 @@
# E1 PHY
set_io e1_rx_hi_p 48
set_io e1_rx_hi_n 45
set_io e1_rx_lo_p 4
set_io e1_rx_lo_n 3
set_io e1_tx_hi 46
set_io e1_tx_lo 47
set_io e1_vref_ct_pdm 32
set_io e1_vref_p_pdm 27
set_io e1_vref_n_pdm 34
# USB
set_io usb_dp 43
set_io usb_dn 42
set_io usb_pu 38
# Flash
set_io -pullup yes flash_mosi 14
set_io -pullup yes flash_miso 17
set_io -pullup yes flash_clk 15
set_io -pullup yes flash_cs_n 16
# Button
set_io -pullup yes btn 10
# Clock
set_io clk_in 44
set_io clk_tune_hi 28
set_io clk_tune_lo 31
# Debug UART
set_io -pullup yes dbg_rx 18
set_io -pullup yes dbg_tx 19
# RGB LEDs
set_io rgb[0] 39
set_io rgb[1] 40
set_io rgb[2] 41

View File

@ -0,0 +1,41 @@
# E1 PHY
set_io e1_rx_hi_p 43
set_io e1_rx_hi_n 36
set_io e1_rx_lo_p 42
set_io e1_rx_lo_n 38
set_io e1_tx_hi 32
set_io e1_tx_lo 31
set_io e1_vref_ct_pdm 46
set_io e1_vref_p_pdm 34
set_io e1_vref_n_pdm 28
# USB
set_io usb_dp 4
set_io usb_dn 3
set_io usb_pu 2
set_io -nowarn usb_vsense 48
# Flash
set_io -pullup yes flash_mosi 14
set_io -pullup yes flash_miso 17
set_io -pullup yes flash_clk 15
set_io -pullup yes flash_cs_n 16
# Button
set_io -pullup yes btn 10
# Clock
set_io clk_in 44
set_io clk_tune_hi 47
set_io clk_tune_lo 45
# Debug UART
set_io -pullup yes dbg_rx 6
set_io -pullup yes dbg_tx 9
# RGB LEDs
set_io rgb[0] 39
set_io rgb[1] 40
set_io rgb[2] 41

View File

@ -0,0 +1,226 @@
icE1usb-proto SoC Memory Map
============================
Overview
--------
| Base | Size | Description | IP Core doc
|-------------|------------------|-----------------|-------------
|`0x00000000` | `0x00400` (1k) | Boot ROM |
|`0x00020000` | `0x10000` (64k) | Main SRAM |
|`0x80000000` | | Flash SPI | [`no2ice40/ice40_spi_wb`](../../cores/no2ice40/doc/ice40_spi_wb.md)
|`0x81000000` | | Debug UART | [`no2misc/uart_wb`](../../cores/no2misc/doc/uart_wb.md)
|`0x82000000` | | RGB LED | [`no2ice40/ice40_rgb_wb`](../../cores/no2ice40/doc/ice40_rgb_wb.md)
|`0x83000000` | | USB core | [`no2usb`](../../cores/no2usb/doc/mem-map.md)
|`0x84000000` | `0x01000` (4k) | USB data buffer |
|`0x85000000` | `0x10000` (64k) | E1 data buffer |
|`0x86000000` | | DMA | See below
|`0x87000000` | | E1 core | [`no2e1`](../../cores/no2e1/doc/mem-map.md). See notes below.
|`0x88000000` | | Misc | See below
Memory
------
### `0x00000000`: Boot ROM
This memory zone is initialized directly in the FPGA bitstream itself.
It contains the bootstrap program that will load the main firmware from
flash into the main SRAM and jump to it.
### `0x00020000`: Main SRAM
The main SoC SRAM, implemented using the UP5k SPRAMs. It can't be initialized
in the FPGA bitstream directly, hence the need for the Boot ROM zone.
### `0x84000000`: USB data buffer
This 4k zone actually correspond to 8k of SRAM inside the USB core.
The RX and TX buffer for the USB are distinct and are accessed independently
depending if read or write access are made to this zone. (RX buffer can only
be read, TX buffer can only be written). All accesses must also be 32 bit
wide !
### `0x85000000`: E1 data buffer
This 64k buffer is reserved for E1 data and is what is used by the E1 core.
Address mapping is :
```text
,---------------------------------------------------------------,
| f | e | d | c | b | a | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---------------------------------------------------------------|
| multi-frame | frame | timeslot |
'---------------------------------------------------------------'
```
and the `multi-frame` number is what is exchanged in the E1 core buffer
descriptors.
Custom Peripherals
------------------
### `0x86000000`: DMA
Very simple DMA core allowing direct copy of data between the USB and E1 data
buffers.
#### Status (Read Only, addr `0x00`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| / | b| d| /| len |
'-----------------------------------------------------------------------------------------------'
* [ 15] - b : Busy flag
* [ 14] - d : Direction ( 0=E1 to USB, 1=USB to E1 )
* [12: 0] - len : Remaining length of the in-progress transfer ( -1 = done )
```
#### Transfer start/direction/length (Write Only, addr `0x00`)
Write to this register initiate the transfer.
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| / | d| / | len |
'-----------------------------------------------------------------------------------------------'
* [ 14] - d : Direction ( 0=E1 to USB, 1=USB to E1 )
* [11: 0] - len : Transfer length ( Number of Words - 2 )
```
#### E1 buffer offset (Write Only, addr `0x08`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| / | e1_ofs |
'-----------------------------------------------------------------------------------------------'
* [13:0] - e1_ofs
```
Word offset inside the E1 data buffer where the next transfer will start
#### USB buffer offset (Write Only, addr `0x0C`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| / | usb_ofs |
'-----------------------------------------------------------------------------------------------'
* [9:0] - usb_ofs
```
Word offset inside the USB End Point buffer where the next transfer will start
### `0x87000000`: E1 core
Refer to the [`no2e1` core documentation](../../cores/no2e1/doc/mem-map.md)
for register description.
The core instanciated here has a 1 single channel containing both
RX and TX units.
### `0x88000000`: Misc
Collection of small auxiliary peripherals.
#### Boot (Write Only, addr `0x00`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| / | x| sel |
'-----------------------------------------------------------------------------------------------'
* [ 2] - d : boot eXecute
* [11:0] - sel : boot select
```
Write to this register with bit 2 set will trigger a FPGA reload of the selected image.
#### E1 tick channel 0 (Read Only, addr `0x04`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| tx_tick | rx_tick |
'-----------------------------------------------------------------------------------------------'
* [31:16] - tx_tick
* [15: 0] - rx_tick
```
An internal counter is incremented at every bit received/transmitted by the corresponding E1
channel. That counter value is then captured at every USB Start-of-Frame packet and the last
captured value made available here.
#### Time (Read Only, addr `0x07`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| time |
'-----------------------------------------------------------------------------------------------'
* [31:0] - time
```
32 bit counter incremented at the system clock rate ( 30.72 MHz )
#### PDM (Read/Write, addr `0x08-0x0f`)
This exposes configurable voltages ( DACs ). Some channels are 12 bits, some are 8 bits.
```text
12 bits:
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
|en| / | value |
'-----------------------------------------------------------------------------------------------'
* [31 ] - enable (output tristated if 0)
* [11:0] - value
8 bits:
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
|en| / | value |
'-----------------------------------------------------------------------------------------------'
* [31 ] - enable (output tristated if 0)
* [11:0] - value
```
Channels :
* `0`: Clock tune ( low ) [ 12 bits ]
* `1`: Clock tune ( high ) [ 12 bits ]
* `2`: E1 RX Negative bias [ 8 bits ]
* `3`: E1 RX Positive bias [ 8 bits ]
* `4`: E1 RX Center Tap bias [ 8 bits ]

View File

@ -0,0 +1,217 @@
/*
* misc.v
*
* vim: ts=4 sw=4
*
* Misc peripheral functions
*
* Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-S-2.0
*/
`default_nettype none
module misc (
// PDM outputs
output wire e1_vref_ct_pdm,
output wire e1_vref_p_pdm,
output wire e1_vref_n_pdm,
output wire clk_tune_hi,
output wire clk_tune_lo,
// Button
input wire btn,
// Ticks
input wire tick_e1_rx,
input wire tick_e1_tx,
input wire tick_usb_sof,
// Reset request
output wire rst_req,
// Wishbone
input wire [ 7:0] wb_addr,
output reg [31:0] wb_rdata,
input wire [31:0] wb_wdata,
input wire wb_we,
input wire wb_cyc,
output reg wb_ack,
// Clock / Reset
input wire clk,
input wire rst
);
// Signals
// -------
// Bus
wire bus_clr;
reg bus_we_boot;
reg [ 1:0] bus_we_pdm_clk;
reg [ 2:0] bus_we_pdm_e1;
// Counters
reg [15:0] cnt_e1_rx;
reg [15:0] cap_e1_rx;
reg [15:0] cnt_e1_tx;
reg [15:0] cap_e1_tx;
reg [31:0] cnt_time;
// PDM
reg [12:0] pdm_clk[0:1];
reg [ 8:0] pdm_e1[0:2];
// Boot
reg [1:0] boot_sel;
reg boot_now;
// Bus interface
// -------------
// Ack
always @(posedge clk)
wb_ack <= wb_cyc & ~wb_ack;
assign bus_clr = ~wb_cyc | wb_ack;
// Write enables
always @(posedge clk)
if (bus_clr | ~wb_we) begin
bus_we_boot <= 1'b0;
bus_we_pdm_clk[0] <= 1'b0;
bus_we_pdm_clk[1] <= 1'b0;
bus_we_pdm_e1[0] <= 1'b0;
bus_we_pdm_e1[1] <= 1'b0;
bus_we_pdm_e1[2] <= 1'b0;
end else begin
bus_we_boot <= wb_addr == 4'h0;
bus_we_pdm_clk[0] <= wb_addr == 4'h8;
bus_we_pdm_clk[1] <= wb_addr == 4'h9;
bus_we_pdm_e1[0] <= wb_addr == 4'ha;
bus_we_pdm_e1[1] <= wb_addr == 4'hb;
bus_we_pdm_e1[2] <= wb_addr == 4'hc;
end
// Read mux
always @(posedge clk)
if (bus_clr)
wb_rdata <= 32'h00000000;
else
case (wb_addr[3:0])
4'h4: wb_rdata <= { cap_e1_rx, cap_e1_tx };
4'h7: wb_rdata <= cnt_time;
4'h8: wb_rdata <= { pdm_clk[0][12], 19'h00000, pdm_clk[0][11:0] };
4'h9: wb_rdata <= { pdm_clk[1][12], 19'h00000, pdm_clk[1][11:0] };
4'ha: wb_rdata <= { pdm_e1[0][8], 23'h000000, pdm_e1[0][ 7:0] };
4'hb: wb_rdata <= { pdm_e1[1][8], 23'h000000, pdm_e1[1][ 7:0] };
4'hc: wb_rdata <= { pdm_e1[2][8], 23'h000000, pdm_e1[2][ 7:0] };
default: wb_rdata <= 32'hxxxxxxxx;
endcase
// Counters
// --------
// E1 ticks
always @(posedge clk or posedge rst)
if (rst)
cnt_e1_rx <= 16'h0000;
else if (tick_e1_rx)
cnt_e1_rx <= cnt_e1_rx + 1;
always @(posedge clk or posedge rst)
if (rst)
cnt_e1_tx <= 16'h0000;
else if (tick_e1_tx)
cnt_e1_tx <= cnt_e1_tx + 1;
always @(posedge clk)
if (tick_usb_sof) begin
cap_e1_rx <= cnt_e1_rx;
cap_e1_tx <= cnt_e1_tx;
end
// Time counter
always @(posedge clk)
if (rst)
cnt_time <= 32'h00000000;
else
cnt_time <= cnt_time + 1;
// PDM outputs
// -----------
// Registers
always @(posedge clk or posedge rst)
if (rst) begin
pdm_clk[0] <= 0; // 13'h1800;
pdm_clk[1] <= 0; // 13'h1800;
pdm_e1[0] <= 0; // 9'h190;
pdm_e1[1] <= 0; // 9'h190;
pdm_e1[2] <= 0; // 9'h190;
end else begin
if (bus_we_pdm_clk[0]) pdm_clk[0] <= { wb_wdata[31], wb_wdata[11:0] };
if (bus_we_pdm_clk[1]) pdm_clk[1] <= { wb_wdata[31], wb_wdata[11:0] };
if (bus_we_pdm_e1[0]) pdm_e1[0] <= { wb_wdata[31], wb_wdata[ 7:0] };
if (bus_we_pdm_e1[1]) pdm_e1[1] <= { wb_wdata[31], wb_wdata[ 7:0] };
if (bus_we_pdm_e1[2]) pdm_e1[2] <= { wb_wdata[31], wb_wdata[ 7:0] };
end
// PDM cores
pdm #(
.WIDTH(12),
.PHY("ICE40"),
.DITHER("YES")
) pdm_clk_I[1:0] (
.pdm ({ clk_tune_hi, clk_tune_lo }),
.cfg_val({ pdm_clk[1][11:0], pdm_clk[0][11:0] }),
.cfg_oe ({ pdm_clk[1][12], pdm_clk[0][12] }),
.clk (clk),
.rst (rst)
);
pdm #(
.WIDTH(8),
.PHY("ICE40"),
.DITHER("NO")
) pdm_e1_I[2:0] (
.pdm ({ e1_vref_ct_pdm, e1_vref_p_pdm, e1_vref_n_pdm }),
.cfg_val({ pdm_e1[2][7:0], pdm_e1[1][7:0], pdm_e1[0][7:0] }),
.cfg_oe ({ pdm_e1[2][8], pdm_e1[1][8], pdm_e1[0][8] }),
.clk (clk),
.rst (rst)
);
// DFU / Reboot
// ------------
always @(posedge clk or posedge rst)
if (rst) begin
boot_now <= 1'b0;
boot_sel <= 2'b00;
end else if (bus_we_boot) begin
boot_now <= wb_wdata[2];
boot_sel <= wb_wdata[1:0];
end
dfu_helper #(
.TIMER_WIDTH(26),
.BTN_MODE(3),
.DFU_MODE(0)
) dfu_I (
.boot_sel(boot_sel),
.boot_now(boot_now),
.btn_pad (btn),
.btn_val (),
.rst_req (rst_req),
.clk (clk),
.rst (rst)
);
endmodule // misc

View File

@ -0,0 +1,100 @@
/*
* sysmgr.v
*
* vim: ts=4 sw=4
*
* System Clock / Reset generation
*
* Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-S-2.0
*/
`default_nettype none
module sysmgr (
input wire clk_in,
input wire rst_in,
output wire clk_sys,
output wire rst_sys,
output wire clk_48m,
output wire rst_48m
);
// Signals
wire pll_lock;
wire pll_reset_n;
wire clk_30m72_i;
wire rst_30m72_i;
wire clk_48m_i;
reg rst_48m_i;
reg [3:0] rst_cnt;
// Global input buffer for 30.72 MHz clock
SB_GB_IO #(
.PIN_TYPE(6'b000001),
) gb_in (
.PACKAGE_PIN(clk_in),
.GLOBAL_BUFFER_OUTPUT(clk_30m72_i),
);
// PLL instance
SB_PLL40_CORE #(
.DIVR(4'b0000),
.DIVF(7'b0011000),
.DIVQ(3'b100),
.FILTER_RANGE(3'b011),
.FEEDBACK_PATH("SIMPLE"),
.DELAY_ADJUSTMENT_MODE_FEEDBACK("FIXED"),
.FDA_FEEDBACK(4'b0000),
.SHIFTREG_DIV_MODE(2'b00),
.PLLOUT_SELECT("GENCLK"),
.ENABLE_ICEGATE(1'b0),
) pll_I (
.REFERENCECLK(clk_30m72_i),
.PLLOUTCORE(),
.PLLOUTGLOBAL(clk_48m_i),
.EXTFEEDBACK(1'b0),
.DYNAMICDELAY(8'h00),
.RESETB(pll_reset_n),
.BYPASS(1'b0),
.LATCHINPUTVALUE(1'b0),
.LOCK(pll_lock),
.SDI(1'b0),
.SDO(),
.SCLK(1'b0)
);
assign clk_sys = clk_30m72_i;
assign clk_48m = clk_48m_i;
// PLL reset generation
assign pll_reset_n = ~rst_in;
// Logic reset generation
always @(posedge clk_30m72_i or negedge pll_lock)
if (!pll_lock)
rst_cnt <= 4'h0;
else if (~rst_cnt[3])
rst_cnt <= rst_cnt + 1;
assign rst_30m72_i = ~rst_cnt[3];
always @(posedge clk_48m or posedge rst_30m72_i)
if (rst_30m72_i)
rst_48m_i <= 1'b1;
else
rst_48m_i <= 1'b0;
SB_GB rst_sys_gbuf_I (
.USER_SIGNAL_TO_GLOBAL_BUFFER(rst_30m72_i),
.GLOBAL_BUFFER_OUTPUT(rst_sys)
);
SB_GB rst_48m_gbuf_I (
.USER_SIGNAL_TO_GLOBAL_BUFFER(rst_48m_i),
.GLOBAL_BUFFER_OUTPUT(rst_48m)
);
endmodule // sysmgr

View File

@ -0,0 +1,202 @@
/*
* top.v
*
* vim: ts=4 sw=4
*
* Top-level for the icE1usb icebreaker/bitsy based prototypes
*
* Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-S-2.0
*/
`default_nettype none
module top (
// E1 PHY
input wire e1_rx_hi_p,
// input wire e1_rx_hi_n,
input wire e1_rx_lo_p,
// input wire e1_rx_lo_n,
output wire e1_tx_hi,
output wire e1_tx_lo,
output wire e1_vref_ct_pdm,
output wire e1_vref_p_pdm,
output wire e1_vref_n_pdm,
// USB
inout wire usb_dp,
inout wire usb_dn,
output wire usb_pu,
// Flash
inout wire flash_mosi,
inout wire flash_miso,
inout wire flash_clk,
inout wire flash_cs_n,
// Button
input wire btn,
// Clock (30.72 MHz)
input wire clk_in,
output wire clk_tune_hi,
output wire clk_tune_lo,
// Debug UART
input wire dbg_rx,
output wire dbg_tx,
// RGB LEDs
output wire [2:0] rgb
);
localparam integer WB_N = 1;
genvar i;
// Signals
// -------
// Flash SPI internal signals
wire flash_mosi_i, flash_miso_i, flash_clk_i;
wire flash_mosi_o, flash_miso_o, flash_clk_o;
wire flash_mosi_oe, flash_miso_oe, flash_clk_oe;
wire flash_csn_o;
// Peripheral wishbone
wire [15:0] wb_addr;
wire [31:0] wb_rdata [0:WB_N-1];
wire [31:0] wb_wdata;
wire [ 3:0] wb_wmsk;
wire wb_we;
wire [WB_N-1:0] wb_cyc;
wire [WB_N-1:0] wb_ack;
wire [(WB_N*32)-1:0] wb_rdata_flat;
// Ticks
wire tick_e1_rx;
wire tick_e1_tx;
wire tick_usb_sof;
// Clocks / Reset
wire rst_req;
wire clk_sys;
wire rst_sys;
wire clk_48m;
wire rst_48m;
// SoC base
// --------
// Instance
soc_base #(
.WB_N(WB_N),
.E1_N(1),
.E1_UNIT_HAS_RX(1'b1),
.E1_UNIT_HAS_TX(1'b1),
.E1_LIU(0)
) soc_I (
.e1_rx_hi_p (e1_rx_hi_p),
// .e1_rx_hi_n (e1_rx_hi_n),
.e1_rx_lo_p (e1_rx_lo_p),
// .e1_rx_lo_n (e1_rx_lo_n),
.e1_tx_hi (e1_tx_hi),
.e1_tx_lo (e1_tx_lo),
.e1_rx_data (),
.e1_rx_clk (),
.e1_tx_data (),
.e1_tx_clk (),
.usb_dp (usb_dp),
.usb_dn (usb_dn),
.usb_pu (usb_pu),
.flash_mosi_i (flash_mosi_i),
.flash_mosi_o (flash_mosi_o),
.flash_mosi_oe(flash_mosi_oe),
.flash_miso_i (flash_miso_i),
.flash_miso_o (flash_miso_o),
.flash_miso_oe(flash_miso_oe),
.flash_clk_i (flash_clk_i),
.flash_clk_o (flash_clk_o),
.flash_clk_oe (flash_clk_oe),
.flash_csn_o (flash_csn_o),
.dbg_rx (dbg_rx),
.dbg_tx (dbg_tx),
.rgb (rgb),
.wb_m_addr (wb_addr),
.wb_m_rdata (wb_rdata_flat),
.wb_m_wdata (wb_wdata),
.wb_m_wmsk (wb_wmsk),
.wb_m_we (wb_we),
.wb_m_cyc (wb_cyc),
.wb_m_ack (wb_ack),
.tick_e1_rx (tick_e1_rx),
.tick_e1_tx (tick_e1_tx),
.tick_usb_sof (tick_usb_sof),
.clk_sys (clk_sys),
.rst_sys (rst_sys),
.clk_48m (clk_48m),
.rst_48m (rst_48m)
);
// WB read data flattening
for (i=0; i<WB_N; i=i+1)
assign wb_rdata_flat[i*32+:32] = wb_rdata[i];
// SPI IO
SB_IO #(
.PIN_TYPE(6'b101001),
.PULLUP(1'b1)
) spi_io_I[2:0] (
.PACKAGE_PIN ({flash_mosi, flash_miso, flash_clk }),
.OUTPUT_ENABLE({flash_mosi_oe, flash_miso_oe, flash_clk_oe}),
.D_OUT_0 ({flash_mosi_o, flash_miso_o, flash_clk_o }),
.D_IN_0 ({flash_mosi_i, flash_miso_i, flash_clk_i })
);
assign flash_cs_n = flash_csn_o;
// Misc [0]
// ----
misc misc_I (
.e1_vref_ct_pdm(e1_vref_ct_pdm),
.e1_vref_p_pdm (e1_vref_p_pdm),
.e1_vref_n_pdm (e1_vref_n_pdm),
.clk_tune_hi (clk_tune_hi),
.clk_tune_lo (clk_tune_lo),
.btn (btn),
.tick_e1_rx (tick_e1_rx),
.tick_e1_tx (tick_e1_tx),
.tick_usb_sof (tick_usb_sof),
.rst_req (rst_req),
.wb_addr (wb_addr[7: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)
);
// Clock / Reset
// -------------
sysmgr sys_mgr_I (
.clk_in (clk_in),
.rst_in (rst_req),
.clk_sys(clk_sys),
.rst_sys(rst_sys),
.clk_48m(clk_48m),
.rst_48m(rst_48m)
);
endmodule // top