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:
parent
21b03baf47
commit
da65157363
|
@ -0,0 +1,4 @@
|
|||
build-tmp
|
||||
__pycache__
|
||||
*.vcd
|
||||
.*.swp
|
|
@ -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 $< $@
|
|
@ -0,0 +1,2 @@
|
|||
ctx.addClock("clk_sys", 30.72)
|
||||
ctx.addClock("clk_48m", 48)
|
|
@ -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
|
|
@ -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
|
|
@ -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 ]
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue