gateware: Initial import of all common parts

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
Sylvain Munaut 2020-09-14 10:01:45 +02:00
parent 1599a58344
commit 21b03baf47
25 changed files with 5648 additions and 0 deletions

15
.gitmodules vendored Normal file
View File

@ -0,0 +1,15 @@
[submodule "gateware/build"]
path = gateware/build
url = https://github.com/no2fpga/no2build.git
[submodule "gateware/cores/no2e1"]
path = gateware/cores/no2e1
url = https://github.com/no2fpga/no2e1.git
[submodule "gateware/cores/no2ice40"]
path = gateware/cores/no2ice40
url = https://github.com/no2fpga/no2ice40.git
[submodule "gateware/cores/no2misc"]
path = gateware/cores/no2misc
url = https://github.com/no2fpga/no2misc.git
[submodule "gateware/cores/no2usb"]
path = gateware/cores/no2usb
url = https://github.com/no2fpga/no2usb.git

19
gateware/README.md Normal file
View File

@ -0,0 +1,19 @@
E1 related gateware
===================
This directory contains the iCE40 gateware for various boards hosted
in this repository.
Licensing
---------
Most of the cores/HDL in here is licensed under one of the CERL OHL 2.0
license. See the `doc/` subdirectory for the full license texts and refer
to each file header to know the license applicable to each file.
Some files have been imported from other projects with compatible licenses.
Refer to each file header for the proper copyright and license information.
The repository also includes submodules which have their own licensing
and copyright terms.

1
gateware/build Submodule

@ -0,0 +1 @@
Subproject commit e9d0d86baff55e1341ccd0ab510eb7e17f9c0fb7

3
gateware/common/fw/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.elf
*.bin
*.hex

View File

@ -0,0 +1,22 @@
CROSS = riscv-none-embed-
CC := $(CROSS)gcc
OBJCOPY := $(CROSS)objcopy
CFLAGS=-Wall -Os -march=rv32i -mabi=ilp32 -ffreestanding -flto -nostartfiles -fomit-frame-pointer -Wl,--gc-section
all: boot.hex
boot.elf: lnk-boot.lds boot.S
$(CC) $(CFLAGS) -Wl,-Bstatic,-T,lnk-boot.lds,--strip-debug -DAPP_FLASH_ADDR=0x000a0000 -o $@ boot.S
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
%.hex: %.bin
./bin2hex.py $< $@
clean:
rm -f *.bin *.hex *.elf *.o
.PHONY: clean

22
gateware/common/fw/bin2hex.py Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python3
#
# Converts binary into something that can be used by `readmemh`
#
# Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
# SPDX-License-Identifier: MIT
#
import struct
import sys
def main(argv0, in_name, out_name):
with open(in_name, 'rb') as in_fh, open(out_name, 'w') as out_fh:
while True:
b = in_fh.read(4)
if len(b) < 4:
break
out_fh.write('%08x\n' % struct.unpack('<I', b))
if __name__ == '__main__':
main(*sys.argv)

144
gateware/common/fw/boot.S Normal file
View File

@ -0,0 +1,144 @@
/*
* boot.S
*
* SPI boot code
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: MIT
*/
#ifndef APP_FLASH_ADDR
#define APP_FLASH_ADDR 0x00100000
#endif
#ifndef APP_SRAM_ADDR
#define APP_SRAM_ADDR 0x00020000
#endif
#ifndef APP_SIZE
#define APP_SIZE 0x00010000
#endif
.section .text.start
.global _start
_start:
// SPI init
jal spi_init
// Read from flash to SRAM
li a0, APP_SRAM_ADDR
li a1, APP_SIZE
li a2, APP_FLASH_ADDR
jal spi_flash_read
// Setup reboot code
li t0, 0x0002006f
sw t0, 0(zero)
// Jump to main code
j APP_SRAM_ADDR
.equ SPI_BASE, 0x80000000
.equ SPICR0, 4 * 0x08
.equ SPICR1, 4 * 0x09
.equ SPICR2, 4 * 0x0a
.equ SPIBR, 4 * 0x0b
.equ SPISR, 4 * 0x0c
.equ SPITXDR, 4 * 0x0d
.equ SPIRXDR, 4 * 0x0e
.equ SPICSR, 4 * 0x0f
spi_init:
li a0, SPI_BASE
li a1, 0xff
sw a1, SPICR0(a0)
li a1, 0x80
sw a1, SPICR1(a0)
li a1, 0xc0
sw a1, SPICR2(a0)
li a1, 0x03
sw a1, SPIBR(a0)
li a1, 0x0f
sw a1, SPICSR(a0)
ret
// Params:
// a0 - destination pointer
// a1 - length (bytes)
// a2 - flash offset
//
spi_flash_read:
// Save params
mv s0, a0
mv s1, a1
mv s2, ra
// Setup CS
li t0, SPI_BASE
li t1, 0x0e
sw t1, SPICSR(t0)
// Send command
li a0, 0x03
jal _spi_do_one
srli a0, a2, 16
and a0, a0, 0xff
jal _spi_do_one
srli a0, a2, 8
and a0, a0, 0xff
jal _spi_do_one
and a0, a2, 0xff
jal _spi_do_one
// Read loop
_spi_loop:
li a0, 0x00
jal _spi_do_one
sb a0, 0(s0)
addi s0, s0, 1
addi s1, s1, -1
bne s1, zero, _spi_loop
// Release CS
li t0, SPI_BASE
li t1, 0x0f
sw t1, SPICSR(t0)
// Done
jr s2
// Params: a0 - Data to TX
// Returns: a0 - RX data
// Clobbers t0, t1
_spi_do_one:
li t0, SPI_BASE
li t1, 0x08
// Write TX data
sw a0, SPITXDR(t0)
// Wait for RXRDY
1:
lw a0, SPISR(t0)
and a0, a0, t1
bne a0, t1, 1b
// Read RX data
lw a0, SPIRXDR(t0)
// Done
ret

View File

@ -0,0 +1,14 @@
MEMORY
{
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x0400
}
ENTRY(_start)
SECTIONS {
.text :
{
. = ALIGN(4);
*(.text.start)
*(.text)
*(.text*)
} >ROM
}

View File

@ -0,0 +1,162 @@
/*
* dfu_helper.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module dfu_helper #(
parameter integer TIMER_WIDTH = 24,
parameter integer BTN_MODE = 3, // [2] Use btn_tick, [1] Include IO buffer, [0] Invert (active-low)
parameter integer DFU_MODE = 0 // 0 = For user app, 1 = For bootloader
)(
// External control
input wire [1:0] boot_sel,
input wire boot_now,
// Button
input wire btn_pad,
input wire btn_tick,
// Outputs
output wire btn_val,
output reg rst_req,
// Clock
input wire clk,
input wire rst
);
// Signals
// -------
// Button
wire btn_iob;
wire btn_v;
wire btn_r;
wire btn_f;
// Timer and arming logic
reg armed;
reg [TIMER_WIDTH-1:0] timer;
(* keep="true" *) wire timer_act;
// Boot logic
reg [1:0] wb_sel;
reg wb_req;
reg wb_now;
// Button logic
// ------------
// IOB
generate
if (BTN_MODE[1])
SB_IO #(
.PIN_TYPE(6'b000000), // Reg input, no output
.PULLUP(1'b1),
.IO_STANDARD("SB_LVCMOS")
) btn_iob_I (
.PACKAGE_PIN(btn_pad),
.INPUT_CLK (clk),
.D_IN_0 (btn_iob)
);
else
assign btn_iob = btn_pad;
endgenerate
// Deglitch
glitch_filter #(
.L(BTN_MODE[2] ? 2 : 4),
.RST_VAL(BTN_MODE[0]),
.WITH_SYNCHRONIZER(1),
.WITH_SAMP_COND(BTN_MODE[2])
) btn_flt_I (
.in (btn_iob ^ BTN_MODE[0]),
.samp_cond(btn_tick),
.val (btn_v),
.rise (btn_r),
.fall (btn_f),
.clk (clk),
`ifdef SIM
.rst (rst)
`else
// Don't reset so we let the filter settle before
// the rest of the logic engages
.rst (1'b0)
`endif
);
assign btn_val = btn_v;
// Arming & Timer
// --------------
assign timer_act = btn_v ^ armed;
always @(posedge clk or posedge rst)
if (rst)
armed <= 1'b0;
else
armed <= armed | timer[TIMER_WIDTH-2];
always @(posedge clk or posedge rst)
if (rst)
timer <= 0;
else
timer <= timer_act ? { TIMER_WIDTH{1'b0} } : (timer + { { (TIMER_WIDTH-1){1'b0} }, ~timer[TIMER_WIDTH-1] });
// Boot Logic
// ----------
// Decision
always @(posedge clk or posedge rst)
if (rst) begin
wb_sel <= 2'b00;
wb_req <= 1'b0;
rst_req <= 1'b0;
end else if (~wb_req) begin
if (boot_now) begin
// External boot request
wb_sel <= boot_sel;
wb_req <= 1'b1;
rst_req <= 1'b0;
end else begin
if (DFU_MODE == 1) begin
// We're in a DFU bootloader, any button press results in
// boot to application
wb_sel <= 2'b10;
wb_req <= wb_now | (armed & btn_f);
rst_req <= 1'b0;
end else begin
// We're in user application, short press resets the
// logic, long press triggers DFU reboot
wb_sel <= 2'b01;
wb_req <= wb_now | (armed & btn_f & timer[TIMER_WIDTH-1]);
rst_req <= rst_req | (armed & btn_f & ~timer[TIMER_WIDTH-1]);
end
end
end
// Ensure select bits are set before the boot pulse
always @(posedge clk or posedge rst)
if (rst)
wb_now <= 1'b0;
else
wb_now <= wb_req;
// IP core
SB_WARMBOOT warmboot (
.BOOT(wb_now),
.S0(wb_sel[0]),
.S1(wb_sel[1])
);
endmodule // dfu_helper

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,544 @@
/*
* 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

View File

@ -0,0 +1,38 @@
/*
* soc_bram.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module soc_bram #(
parameter integer AW = 8,
parameter INIT_FILE = ""
)(
input wire [AW-1:0] addr,
output reg [31:0] rdata,
input wire [31:0] wdata,
input wire [ 3:0] wmsk,
input wire we,
input wire clk
);
reg [31:0] mem [0:(1<<AW)-1];
initial
if (INIT_FILE != "")
$readmemh(INIT_FILE, mem);
always @(posedge clk) begin
rdata <= mem[addr];
if (we & ~wmsk[0]) mem[addr][ 7: 0] <= wdata[ 7: 0];
if (we & ~wmsk[1]) mem[addr][15: 8] <= wdata[15: 8];
if (we & ~wmsk[2]) mem[addr][23:16] <= wdata[23:16];
if (we & ~wmsk[3]) mem[addr][31:24] <= wdata[31:24];
end
endmodule // soc_bram

View File

@ -0,0 +1,261 @@
/*
* soc_iobuf.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-S-2.0
*/
`default_nettype none
module soc_iobuf (
// Wishbone slave (from CPU)
input wire [15:0] wb_cpu_addr,
output wire [31:0] wb_cpu_rdata,
input wire [31:0] wb_cpu_wdata,
input wire [ 3:0] wb_cpu_wmsk,
input wire wb_cpu_we,
input wire [ 2:0] wb_cpu_cyc, // 0=EP buf, 1=SPRAM, 2=DMA
output wire [ 2:0] wb_cpu_ack,
// Wishbone slave (from E1)
input wire [13:0] wb_e1_addr,
output wire [31:0] wb_e1_rdata,
input wire [31:0] wb_e1_wdata,
input wire [ 3:0] wb_e1_wmsk,
input wire wb_e1_we,
input wire wb_e1_cyc,
output wire wb_e1_ack,
// USB EP-Buf master
output wire [ 8:0] ep_tx_addr_0,
output wire [31:0] ep_tx_data_0,
output wire ep_tx_we_0,
output wire [ 8:0] ep_rx_addr_0,
input wire [31:0] ep_rx_data_1,
output wire ep_rx_re_0,
/* Clock / Reset */
input wire clk,
input wire rst
);
// Signals
// -------
// SPRAM
wire [13:0] spr_addr;
wire [31:0] spr_rdata;
wire [31:0] spr_wdata;
wire [ 3:0] spr_wmsk;
wire spr_we;
wire spr_cyc;
wire spr_ack;
wire [13:0] spr0_addr;
wire [31:0] spr0_rdata;
wire [31:0] spr0_wdata;
wire [ 3:0] spr0_wmsk;
wire spr0_we;
wire spr0_cyc;
wire spr0_ack;
wire [13:0] spr1_addr;
wire [31:0] spr1_rdata;
wire [31:0] spr1_wdata;
wire [ 3:0] spr1_wmsk;
wire spr1_we;
wire spr1_cyc;
wire spr1_ack;
wire [13:0] spr2_addr;
wire [31:0] spr2_rdata;
wire [31:0] spr2_wdata;
wire [ 3:0] spr2_wmsk;
wire spr2_we;
wire spr2_cyc;
wire spr2_ack;
// EP Buffer
wire [ 8:0] epb_addr;
wire [31:0] epb_rdata;
wire [31:0] epb_wdata;
wire epb_we;
wire epb_cyc;
wire epb_ack;
wire [ 8:0] epb0_addr;
wire [31:0] epb0_rdata;
wire [31:0] epb0_wdata;
wire epb0_we;
wire epb0_cyc;
wire epb0_ack;
wire [ 8:0] epb1_addr;
wire [31:0] epb1_rdata;
wire [31:0] epb1_wdata;
wire epb1_we;
wire epb1_cyc;
wire epb1_ack;
// DMA
wire [31:0] wb_rdata_dma;
// SPRAM
// -----
// Instance
ice40_spram_wb #(
.DW(32),
.AW(14),
.ZERO_RDATA(0)
) spram_I (
.wb_addr (spr_addr),
.wb_rdata(spr_rdata),
.wb_wdata(spr_wdata),
.wb_wmsk (spr_wmsk),
.wb_we (spr_we),
.wb_cyc (spr_cyc),
.wb_ack (spr_ack),
.clk (clk),
.rst (rst)
);
// Arbiter
wb_arbiter #(
.N(3),
.DW(32),
.AW(14)
) spram_arb_I (
.s_addr ({spr2_addr, spr1_addr, spr0_addr}),
.s_rdata({spr2_rdata, spr1_rdata, spr0_rdata}),
.s_wdata({spr2_wdata, spr1_wdata, spr0_wdata}),
.s_wmsk ({spr2_wmsk, spr1_wmsk, spr0_wmsk}),
.s_we ({spr2_we, spr1_we, spr0_we}),
.s_cyc ({spr2_cyc, spr1_cyc, spr0_cyc}),
.s_ack ({spr2_ack, spr1_ack, spr0_ack}),
.m_addr (spr_addr),
.m_rdata(spr_rdata),
.m_wdata(spr_wdata),
.m_wmsk (spr_wmsk),
.m_we (spr_we),
.m_cyc (spr_cyc),
.m_ack (spr_ack),
.clk (clk),
.rst (rst)
);
// EP buffer
// ---------
// Instance
wb_epbuf #(
.AW(9),
.DW(32)
) epbuf_I (
.wb_addr (epb_addr),
.wb_rdata (epb_rdata),
.wb_wdata (epb_wdata),
.wb_we (epb_we),
.wb_cyc (epb_cyc),
.wb_ack (epb_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),
.rst (rst)
);
// Arbiter
wb_arbiter #(
.N(2),
.DW(32),
.AW(9)
) epbam_arb_I (
.s_addr ({epb1_addr, epb0_addr}),
.s_rdata({epb1_rdata, epb0_rdata}),
.s_wdata({epb1_wdata, epb0_wdata}),
.s_wmsk (8'hff),
.s_we ({epb1_we, epb0_we}),
.s_cyc ({epb1_cyc, epb0_cyc}),
.s_ack ({epb1_ack, epb0_ack}),
.m_addr (epb_addr),
.m_rdata(epb_rdata),
.m_wdata(epb_wdata),
.m_we (epb_we),
.m_cyc (epb_cyc),
.m_ack (epb_ack),
.clk (clk),
.rst (rst)
);
// DMA
// ---
wb_dma #(
.A0W(14),
.A1W(9),
.DW(32)
) dma_I (
.m0_addr (spr2_addr),
.m0_rdata (spr2_rdata),
.m0_wdata (spr2_wdata),
.m0_we (spr2_we),
.m0_cyc (spr2_cyc),
.m0_ack (spr2_ack),
.m1_addr (epb1_addr),
.m1_rdata (epb1_rdata),
.m1_wdata (epb1_wdata),
.m1_we (epb1_we),
.m1_cyc (epb1_cyc),
.m1_ack (epb1_ack),
.ctl_addr (wb_cpu_addr[1:0]),
.ctl_rdata(wb_rdata_dma),
.ctl_wdata(wb_cpu_wdata),
.ctl_we (wb_cpu_we),
.ctl_cyc (wb_cpu_cyc[2]),
.ctl_ack (wb_cpu_ack[2]),
.clk (clk),
.rst (rst)
);
assign spr2_wmsk = 4'h0;
// External accesses
// -----------------
// CPU
assign spr1_addr = wb_cpu_addr[13:0];
assign spr1_wdata = wb_cpu_wdata;
assign spr1_wmsk = wb_cpu_wmsk;
assign spr1_we = wb_cpu_we;
assign spr1_cyc = wb_cpu_cyc[1];
assign wb_cpu_ack[1] = spr1_ack;
assign epb0_addr = wb_cpu_addr[8:0];
assign epb0_wdata = wb_cpu_wdata;
assign epb0_we = wb_cpu_we;
assign epb0_cyc = wb_cpu_cyc[0];
assign wb_cpu_ack[0] = epb0_ack;
assign wb_cpu_rdata = spr1_rdata | epb0_rdata | wb_rdata_dma;
// E1
assign spr0_addr = wb_e1_addr;
assign spr0_wdata = wb_e1_wdata;
assign spr0_wmsk = wb_e1_wmsk;
assign spr0_we = wb_e1_we;
assign spr0_cyc = wb_e1_cyc;
assign wb_e1_rdata = spr0_rdata;
assign wb_e1_ack = spr0_ack;
endmodule // soc_iobuf

View File

@ -0,0 +1,186 @@
/*
* soc_picorv32_bridge.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module soc_picorv32_bridge #(
parameter integer WB_N = 8,
parameter integer WB_DW = 32,
parameter integer WB_AW = 16,
parameter integer WB_AI = 2,
parameter integer WB_REG = 0 // [0] = cyc / [1] = addr/wdata/wstrb / [2] = ack/rdata
)(
/* PicoRV32 bus */
input wire [31:0] pb_addr,
output wire [31:0] pb_rdata,
input wire [31:0] pb_wdata,
input wire [ 3:0] pb_wstrb,
input wire pb_valid,
output wire pb_ready,
/* BRAM */
output wire [ 7:0] bram_addr,
input wire [31:0] bram_rdata,
output wire [31:0] bram_wdata,
output wire [ 3:0] bram_wmsk,
output wire bram_we,
/* SPRAM */
output wire [14:0] spram_addr,
input wire [31:0] spram_rdata,
output wire [31:0] spram_wdata,
output wire [ 3:0] spram_wmsk,
output wire spram_we,
/* Wishbone buses */
output wire [WB_AW-1:0] wb_addr,
input wire [(WB_DW*WB_N)-1:0] wb_rdata,
output wire [WB_DW-1:0] wb_wdata,
output wire [(WB_DW/8)-1:0] wb_wmsk,
output wire wb_we,
output wire [WB_N-1:0] wb_cyc,
input wire [WB_N-1:0] wb_ack,
/* Clock / Reset */
input wire clk,
input wire rst
);
// Signals
// -------
wire ram_sel;
reg ram_rdy;
wire [31:0] ram_rdata;
(* keep *) wire [WB_N-1:0] wb_match;
(* keep *) wire wb_cyc_rst;
reg [31:0] wb_rdata_or;
wire [31:0] wb_rdata_out;
wire wb_rdy;
// RAM access
// ----------
// BRAM : 0x00000000 -> 0x000003ff
// SPRAM : 0x00020000 -> 0x0003ffff
assign bram_addr = pb_addr[ 9:2];
assign spram_addr = pb_addr[16:2];
assign bram_wdata = pb_wdata;
assign spram_wdata = pb_wdata;
assign bram_wmsk = ~pb_wstrb;
assign spram_wmsk = ~pb_wstrb;
assign bram_we = pb_valid & ~pb_addr[31] & |pb_wstrb & ~pb_addr[17];
assign spram_we = pb_valid & ~pb_addr[31] & |pb_wstrb & pb_addr[17];
assign ram_rdata = ~pb_addr[31] ? (pb_addr[17] ? spram_rdata : bram_rdata) : 32'h00000000;
assign ram_sel = pb_valid & ~pb_addr[31];
always @(posedge clk)
ram_rdy <= ram_sel && ~ram_rdy;
// Wishbone
// --------
// wb[x] = 0x8x000000 - 0x8xffffff
// Access Cycle
genvar i;
for (i=0; i<WB_N; i=i+1)
assign wb_match[i] = (pb_addr[27:24] == i);
if (WB_REG & 1) begin
// Register
reg [WB_N-1:0] wb_cyc_reg;
always @(posedge clk)
if (wb_cyc_rst)
wb_cyc_reg <= 0;
else
wb_cyc_reg <= wb_match & ~wb_ack;
assign wb_cyc = wb_cyc_reg;
end else begin
// Direct connection
assign wb_cyc = wb_cyc_rst ? { WB_N{1'b0} } : wb_match;
end
// Addr / Write-Data / Write-Mask / Write-Enable
if (WB_REG & 2) begin
// Register
reg [WB_AW-1:0] wb_addr_reg;
reg [WB_DW-1:0] wb_wdata_reg;
reg [(WB_DW/8)-1:0] wb_wmsk_reg;
reg wb_we_reg;
always @(posedge clk)
begin
wb_addr_reg <= pb_addr[WB_AW+WB_AI-1:WB_AI];
wb_wdata_reg <= pb_wdata[WB_DW-1:0];
wb_wmsk_reg <= ~pb_wstrb[(WB_DW/8)-1:0];
wb_we_reg <= |pb_wstrb;
end
assign wb_addr = wb_addr_reg;
assign wb_wdata = wb_wdata_reg;
assign wb_wmsk = wb_wmsk_reg;
assign wb_we = wb_we_reg;
end else begin
// Direct connection
assign wb_addr = pb_addr[WB_AW+WB_AI-1:WB_AI];
assign wb_wdata = pb_wdata[WB_DW-1:0];
assign wb_wmsk = pb_wstrb[(WB_DW/8)-1:0];
assign wb_we = |pb_wstrb;
end
// Ack / Read-Data
always @(*)
begin : wb_or
integer i;
wb_rdata_or = 0;
for (i=0; i<WB_N; i=i+1)
wb_rdata_or[WB_DW-1:0] = wb_rdata_or[WB_DW-1:0] | wb_rdata[WB_DW*i+:WB_DW];
end
if (WB_REG & 4) begin
// Register
reg wb_rdy_reg;
reg [31:0] wb_rdata_reg;
always @(posedge clk)
wb_rdy_reg <= |wb_ack;
always @(posedge clk)
if (wb_cyc_rst)
wb_rdata_reg <= 32'h00000000;
else
wb_rdata_reg <= wb_rdata_or;
assign wb_cyc_rst = ~pb_valid | ~pb_addr[31] | wb_rdy_reg;
assign wb_rdy = wb_rdy_reg;
assign wb_rdata_out = wb_rdata_reg;
end else begin
// Direct connection
assign wb_cyc_rst = ~pb_valid | ~pb_addr[31];
assign wb_rdy = |wb_ack;
assign wb_rdata_out = wb_rdata_or;
end
// Final data combining
// --------------------
assign pb_rdata = ram_rdata | wb_rdata_out;
assign pb_ready = ram_rdy | wb_rdy;
endmodule // soc_picorv32_bridge

View File

@ -0,0 +1,43 @@
/*
* soc_spram.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module soc_spram #(
parameter integer AW = 14
)(
input wire [AW-1:0] addr,
output wire [31:0] rdata,
input wire [31:0] wdata,
input wire [ 3:0] wmsk,
input wire we,
input wire clk
);
wire [7:0] msk_nibble = {
wmsk[3], wmsk[3],
wmsk[2], wmsk[2],
wmsk[1], wmsk[1],
wmsk[0], wmsk[0]
};
ice40_spram_gen #(
.ADDR_WIDTH(AW),
.DATA_WIDTH(32)
) spram_I (
.addr(addr),
.rd_data(rdata),
.rd_ena(1'b1),
.wr_data(wdata),
.wr_mask(msk_nibble),
.wr_ena(we),
.clk(clk)
);
endmodule // soc_spram

View File

@ -0,0 +1,127 @@
/*
* wb_arbiter.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module wb_arbiter #(
parameter integer N = 3,
parameter integer DW = 32,
parameter integer AW = 16,
parameter integer MW = DW / 8
)(
/* Slave buses */
input wire [(N*AW)-1:0] s_addr,
output wire [(N*DW)-1:0] s_rdata,
input wire [(N*DW)-1:0] s_wdata,
input wire [(N*MW)-1:0] s_wmsk,
input wire [ N -1:0] s_we,
input wire [ N -1:0] s_cyc,
output wire [ N -1:0] s_ack,
/* Master bus */
output reg [AW-1:0] m_addr,
input wire [DW-1:0] m_rdata,
output reg [DW-1:0] m_wdata,
output reg [MW-1:0] m_wmsk,
output reg m_we,
output wire m_cyc,
input wire m_ack,
/* Clock / Reset */
input wire clk,
input wire rst
);
// Signals
// -------
genvar i;
reg [AW-1:0] mux_addr;
reg [DW-1:0] mux_wdata;
reg [MW-1:0] mux_wmsk;
reg [N-1:0] sel_nxt;
reg [N-1:0] sel;
reg busy;
wire reselect;
// Muxing
// ------
for (i=0; i<N; i=i+1)
begin
assign s_rdata[DW*i+:DW] = sel[i] ? m_rdata : { DW{1'b0} };
assign s_ack[i] = sel[i] ? m_ack : 1'b0;
end
always @(*)
begin : mux
integer i;
mux_addr = { AW{1'b0} };
mux_wdata = { DW{1'b0} };
mux_wmsk = { MW{1'b0} };
for (i=N-1; i>=0; i=i-1) begin
mux_addr = mux_addr | (sel_nxt[i] ? s_addr[AW*i+:AW] : { AW{1'b0} });
mux_wdata = mux_wdata | (sel_nxt[i] ? s_wdata[DW*i+:DW] : { DW{1'b0} });
mux_wmsk = mux_wmsk | (sel_nxt[i] ? s_wmsk[MW*i+:MW] : { MW{1'b0} });
end
end
always @(posedge clk or posedge rst)
begin
if (rst) begin
m_addr <= { AW{1'b0} };
m_wdata <= { DW{1'b0} };
m_wmsk <= { MW{1'b0} };
m_we <= 1'b0;
end else if (reselect) begin
m_addr <= mux_addr;
m_wdata <= mux_wdata;
m_wmsk <= mux_wmsk;
m_we <= |(s_we & sel_nxt);
end
end
// Arbitration
// -----------
// Priority encoder for the next master
always @(*)
begin : prio
integer i;
sel_nxt <= 0;
for (i=N-1; i>=0; i=i-1)
if (s_cyc[i] & ~sel[i]) begin
sel_nxt <= 0;
sel_nxt[i] <= 1'b1;
end
end
// When to reselect
assign reselect = m_ack | ~busy;
// Register current master (if any)
always @(posedge clk or posedge rst)
if (rst) begin
busy <= 1'b0;
sel <= 0;
end else if (reselect) begin
busy <= |(s_cyc & ~sel);
sel <= sel_nxt;
end
assign m_cyc = busy;
endmodule // wb_arbiter

View File

@ -0,0 +1,208 @@
/*
* wb_dma.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module wb_dma #(
parameter integer A0W = 9,
parameter integer A1W = 9,
parameter integer DW = 32
)(
// Master 0
output wire [A0W-1:0] m0_addr,
input wire [ DW-1:0] m0_rdata,
output wire [ DW-1:0] m0_wdata,
output wire m0_we,
output wire m0_cyc,
input wire m0_ack,
// Master 1
output wire [A1W-1:0] m1_addr,
input wire [ DW-1:0] m1_rdata,
output wire [ DW-1:0] m1_wdata,
output wire m1_we,
output wire m1_cyc,
input wire m1_ack,
// Slave (control)
input wire [ 1:0] ctl_addr,
output wire [DW-1:0] ctl_rdata,
input wire [DW-1:0] ctl_wdata,
input wire ctl_we,
input wire ctl_cyc,
output wire ctl_ack,
// Clock / Reset
input wire clk,
input wire rst
);
// Signals
// -------
// Control
reg [1:0] state; // [1] = busy [0] = phase 0(read) 1(write)
reg [1:0] state_nxt;
reg dir; // 0 = M0->M1, 1 = M1->M0
reg go;
wire ack_rd;
wire ack_wr;
// Data register
wire data_ce;
reg [DW-1:0] data_reg;
// Address counters
wire m0_addr_ce;
wire m0_addr_ld;
reg [A0W-1:0] m0_addr_i;
wire m1_addr_ce;
wire m1_addr_ld;
reg [A1W-1:0] m1_addr_i;
// Length counter
wire len_ce;
wire len_ld;
reg [12:0] len;
wire len_last;
// Control IF
reg ctl_do_write;
reg ctl_do_read;
reg ctl_ack_i;
// Control
// -------
always @(posedge clk or posedge rst)
if (rst)
go <= 1'b0;
else
go <= ctl_do_write & (ctl_addr[1:0] == 2'b00) & ctl_wdata[15];
always @(posedge clk or posedge rst)
if (rst)
state <= 2'b00;
else
state <= state_nxt;
always @(*)
begin
state_nxt <= state;
case (state)
2'b00: begin
if (go)
state_nxt <= 2'b10;
end
2'b10: begin
if (ack_rd)
state_nxt <= 2'b11;
end
2'b11: begin
if (ack_wr)
state_nxt <= len_last ? 2'b00 : 2'b10;
end
default:
state_nxt <= 2'b00;
endcase
end
assign ack_rd = (m0_ack & ~dir) | (m1_ack & dir);
assign ack_wr = (m0_ack & dir) | (m1_ack & ~dir);
// WB transaction
// --------------
assign m0_cyc = state[1] & ~(state[0] ^ dir);
assign m1_cyc = state[1] & (state[0] ^ dir);
assign m0_we = dir;
assign m1_we = ~dir;
// Data register
// -------------
assign data_ce = ack_rd;
always @(posedge clk)
if (data_ce)
data_reg <= dir ? m1_rdata : m0_rdata;
assign m0_wdata = data_reg;
assign m1_wdata = data_reg;
// Address counters
// ----------------
always @(posedge clk)
if (m0_addr_ce)
m0_addr_i <= m0_addr_ld ? ctl_wdata[A0W-1:0] : (m0_addr_i + 1);
always @(posedge clk)
if (m1_addr_ce)
m1_addr_i <= m1_addr_ld ? ctl_wdata[A1W-1:0] : (m1_addr_i + 1);
assign m0_addr_ce = m0_addr_ld | ack_wr;
assign m1_addr_ce = m1_addr_ld | ack_wr;
assign m0_addr_ld = ctl_do_write & (ctl_addr[1:0] == 2'b10);
assign m1_addr_ld = ctl_do_write & (ctl_addr[1:0] == 2'b11);
assign m0_addr = m0_addr_i;
assign m1_addr = m1_addr_i;
// Length counter
// --------------
always @(posedge clk)
if (len_ce)
len <= len_ld ? { 1'b0, ctl_wdata[11:0] } : (len - 1);
always @(posedge clk)
if (len_ld)
dir <= ctl_wdata[14];
assign len_ce = len_ld | ack_wr;
assign len_ld = ctl_do_write & (ctl_addr[1:0] == 2'b00);
assign len_last = len[12];
// Control IF
// ----------
always @(posedge clk or posedge rst)
if (rst) begin
ctl_do_write <= 1'b0;
ctl_do_read <= 1'b0;
ctl_ack_i <= 1'b0;
end else begin
ctl_do_write <= ~ctl_ack_i & ctl_cyc & ctl_we;
ctl_do_read <= ~ctl_ack_i & ctl_cyc & ~ctl_we & (ctl_addr[1:0] == 2'b00);
ctl_ack_i <= ~ctl_ack_i & ctl_cyc;
end
assign ctl_ack = ctl_ack_i;
assign ctl_rdata = {
{(DW-16){1'b0}},
(ctl_do_read ? { state[1], dir, 1'b0, len } : 16'h0000)
};
endmodule // wb_dma

View File

@ -0,0 +1,57 @@
/*
* wb_epbuf.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module wb_epbuf #(
parameter integer AW = 9,
parameter integer DW = 32
)(
// Wishbone slave
input wire [AW-1:0] wb_addr,
output wire [DW-1:0] wb_rdata,
input wire [DW-1:0] wb_wdata,
input wire wb_we,
input wire wb_cyc,
output wire wb_ack,
// USB EP-Buf master
output wire [AW-1:0] ep_tx_addr_0,
output wire [DW-1:0] ep_tx_data_0,
output wire ep_tx_we_0,
output wire [AW-1:0] ep_rx_addr_0,
input wire [DW-1:0] ep_rx_data_1,
output wire ep_rx_re_0,
// Clock / Reset
input wire clk,
input wire rst
);
reg ack_i;
assign ep_tx_addr_0 = wb_addr;
assign ep_rx_addr_0 = wb_addr;
assign ep_tx_data_0 = wb_wdata;
assign wb_rdata = ep_rx_data_1;
assign ep_tx_we_0 = wb_cyc & wb_we & ~ack_i;
assign ep_rx_re_0 = 1'b1;
assign wb_ack = ack_i;
always @(posedge clk or posedge rst)
if (rst)
ack_i <= 1'b0;
else
ack_i <= wb_cyc & ~ack_i;
endmodule // wb_epbuf

1
gateware/cores/no2e1 Submodule

@ -0,0 +1 @@
Subproject commit 5284ef1b6e3fc142a0a96c8db4e9fe13872dceec

@ -0,0 +1 @@
Subproject commit aef7d3a8ed1db329fe4815453d52518b9a08e633

@ -0,0 +1 @@
Subproject commit 16103ac61c8f11e63e043229a0a7a085bc38bde0

1
gateware/cores/no2usb Submodule

@ -0,0 +1 @@
Subproject commit af0a06fb057b19005f2583a9b571ab0aebdee845

View File

@ -0,0 +1,199 @@
CERN Open Hardware Licence Version 2 - Permissive
Preamble
CERN has developed this licence to promote collaboration among
hardware designers and to provide a legal tool which supports the
freedom to use, study, modify, share and distribute hardware designs
and products based on those designs. Version 2 of the CERN Open
Hardware Licence comes in three variants: this licence, CERN-OHL-P
(permissive); and two reciprocal licences: CERN-OHL-W (weakly
reciprocal) and CERN-OHL-S (strongly reciprocal).
The CERN-OHL-P is copyright CERN 2020. Anyone is welcome to use it, in
unmodified form only.
Use of this Licence does not imply any endorsement by CERN of any
Licensor or their designs nor does it imply any involvement by CERN in
their development.
1 Definitions
1.1 'Licence' means this CERN-OHL-P.
1.2 'Source' means information such as design materials or digital
code which can be applied to Make or test a Product or to
prepare a Product for use, Conveyance or sale, regardless of its
medium or how it is expressed. It may include Notices.
1.3 'Covered Source' means Source that is explicitly made available
under this Licence.
1.4 'Product' means any device, component, work or physical object,
whether in finished or intermediate form, arising from the use,
application or processing of Covered Source.
1.5 'Make' means to create or configure something, whether by
manufacture, assembly, compiling, loading or applying Covered
Source or another Product or otherwise.
1.6 'Notice' means copyright, acknowledgement and trademark notices,
references to the location of any Notices, modification notices
(subsection 3.3(b)) and all notices that refer to this Licence
and to the disclaimer of warranties that are included in the
Covered Source.
1.7 'Licensee' or 'You' means any person exercising rights under
this Licence.
1.8 'Licensor' means a person who creates Source or modifies Covered
Source and subsequently Conveys the resulting Covered Source
under the terms and conditions of this Licence. A person may be
a Licensee and a Licensor at the same time.
1.9 'Convey' means to communicate to the public or distribute.
2 Applicability
2.1 This Licence governs the use, copying, modification, Conveying
of Covered Source and Products, and the Making of Products. By
exercising any right granted under this Licence, You irrevocably
accept these terms and conditions.
2.2 This Licence is granted by the Licensor directly to You, and
shall apply worldwide and without limitation in time.
2.3 You shall not attempt to restrict by contract or otherwise the
rights granted under this Licence to other Licensees.
2.4 This Licence is not intended to restrict fair use, fair dealing,
or any other similar right.
3 Copying, Modifying and Conveying Covered Source
3.1 You may copy and Convey verbatim copies of Covered Source, in
any medium, provided You retain all Notices.
3.2 You may modify Covered Source, other than Notices.
You may only delete Notices if they are no longer applicable to
the corresponding Covered Source as modified by You and You may
add additional Notices applicable to Your modifications.
3.3 You may Convey modified Covered Source (with the effect that You
shall also become a Licensor) provided that You:
a) retain Notices as required in subsection 3.2; and
b) add a Notice to the modified Covered Source stating that You
have modified it, with the date and brief description of how
You have modified it.
3.4 You may Convey Covered Source or modified Covered Source under
licence terms which differ from the terms of this Licence
provided that:
a) You comply at all times with subsection 3.3; and
b) You provide a copy of this Licence to anyone to whom You
Convey Covered Source or modified Covered Source.
4 Making and Conveying Products
You may Make Products, and/or Convey them, provided that You ensure
that the recipient of the Product has access to any Notices applicable
to the Product.
5 DISCLAIMER AND LIABILITY
5.1 DISCLAIMER OF WARRANTY -- The Covered Source and any Products
are provided 'as is' and any express or implied warranties,
including, but not limited to, implied warranties of
merchantability, of satisfactory quality, non-infringement of
third party rights, and fitness for a particular purpose or use
are disclaimed in respect of any Source or Product to the
maximum extent permitted by law. The Licensor makes no
representation that any Source or Product does not or will not
infringe any patent, copyright, trade secret or other
proprietary right. The entire risk as to the use, quality, and
performance of any Source or Product shall be with You and not
the Licensor. This disclaimer of warranty is an essential part
of this Licence and a condition for the grant of any rights
granted under this Licence.
5.2 EXCLUSION AND LIMITATION OF LIABILITY -- The Licensor shall, to
the maximum extent permitted by law, have no liability for
direct, indirect, special, incidental, consequential, exemplary,
punitive or other damages of any character including, without
limitation, procurement of substitute goods or services, loss of
use, data or profits, or business interruption, however caused
and on any theory of contract, warranty, tort (including
negligence), product liability or otherwise, arising in any way
in relation to the Covered Source, modified Covered Source
and/or the Making or Conveyance of a Product, even if advised of
the possibility of such damages, and You shall hold the
Licensor(s) free and harmless from any liability, costs,
damages, fees and expenses, including claims by third parties,
in relation to such use.
6 Patents
6.1 Subject to the terms and conditions of this Licence, each
Licensor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as
stated in this section 6, or where terminated by the Licensor
for cause) patent license to Make, have Made, use, offer to
sell, sell, import, and otherwise transfer the Covered Source
and Products, where such licence applies only to those patent
claims licensable by such Licensor that are necessarily
infringed by exercising rights under the Covered Source as
Conveyed by that Licensor.
6.2 If You institute patent litigation against any entity (including
a cross-claim or counterclaim in a lawsuit) alleging that the
Covered Source or a Product constitutes direct or contributory
patent infringement, or You seek any declaration that a patent
licensed to You under this Licence is invalid or unenforceable
then any rights granted to You under this Licence shall
terminate as of the date such process is initiated.
7 General
7.1 If any provisions of this Licence are or subsequently become
invalid or unenforceable for any reason, the remaining
provisions shall remain effective.
7.2 You shall not use any of the name (including acronyms and
abbreviations), image, or logo by which the Licensor or CERN is
known, except where needed to comply with section 3, or where
the use is otherwise allowed by law. Any such permitted use
shall be factual and shall not be made so as to suggest any kind
of endorsement or implication of involvement by the Licensor or
its personnel.
7.3 CERN may publish updated versions and variants of this Licence
which it considers to be in the spirit of this version, but may
differ in detail to address new problems or concerns. New
versions will be published with a unique version number and a
variant identifier specifying the variant. If the Licensor has
specified that a given variant applies to the Covered Source
without specifying a version, You may treat that Covered Source
as being released under any version of the CERN-OHL with that
variant. If no variant is specified, the Covered Source shall be
treated as being released under CERN-OHL-S. The Licensor may
also specify that the Covered Source is subject to a specific
version of the CERN-OHL or any later version in which case You
may apply this or any later version of CERN-OHL with the same
variant identifier published by CERN.
7.4 This Licence shall not be enforceable except by a Licensor
acting as such, and third party beneficiary rights are
specifically excluded.

View File

@ -0,0 +1,289 @@
CERN Open Hardware Licence Version 2 - Strongly Reciprocal
Preamble
CERN has developed this licence to promote collaboration among
hardware designers and to provide a legal tool which supports the
freedom to use, study, modify, share and distribute hardware designs
and products based on those designs. Version 2 of the CERN Open
Hardware Licence comes in three variants: CERN-OHL-P (permissive); and
two reciprocal licences: CERN-OHL-W (weakly reciprocal) and this
licence, CERN-OHL-S (strongly reciprocal).
The CERN-OHL-S is copyright CERN 2020. Anyone is welcome to use it, in
unmodified form only.
Use of this Licence does not imply any endorsement by CERN of any
Licensor or their designs nor does it imply any involvement by CERN in
their development.
1 Definitions
1.1 'Licence' means this CERN-OHL-S.
1.2 'Compatible Licence' means
a) any earlier version of the CERN Open Hardware licence, or
b) any version of the CERN-OHL-S, or
c) any licence which permits You to treat the Source to which
it applies as licensed under CERN-OHL-S provided that on
Conveyance of any such Source, or any associated Product You
treat the Source in question as being licensed under
CERN-OHL-S.
1.3 'Source' means information such as design materials or digital
code which can be applied to Make or test a Product or to
prepare a Product for use, Conveyance or sale, regardless of its
medium or how it is expressed. It may include Notices.
1.4 'Covered Source' means Source that is explicitly made available
under this Licence.
1.5 'Product' means any device, component, work or physical object,
whether in finished or intermediate form, arising from the use,
application or processing of Covered Source.
1.6 'Make' means to create or configure something, whether by
manufacture, assembly, compiling, loading or applying Covered
Source or another Product or otherwise.
1.7 'Available Component' means any part, sub-assembly, library or
code which:
a) is licensed to You as Complete Source under a Compatible
Licence; or
b) is available, at the time a Product or the Source containing
it is first Conveyed, to You and any other prospective
licensees
i) as a physical part with sufficient rights and
information (including any configuration and
programming files and information about its
characteristics and interfaces) to enable it either to
be Made itself, or to be sourced and used to Make the
Product; or
ii) as part of the normal distribution of a tool used to
design or Make the Product.
1.8 'Complete Source' means the set of all Source necessary to Make
a Product, in the preferred form for making modifications,
including necessary installation and interfacing information
both for the Product, and for any included Available Components.
If the format is proprietary, it must also be made available in
a format (if the proprietary tool can create it) which is
viewable with a tool available to potential licensees and
licensed under a licence approved by the Free Software
Foundation or the Open Source Initiative. Complete Source need
not include the Source of any Available Component, provided that
You include in the Complete Source sufficient information to
enable a recipient to Make or source and use the Available
Component to Make the Product.
1.9 'Source Location' means a location where a Licensor has placed
Covered Source, and which that Licensor reasonably believes will
remain easily accessible for at least three years for anyone to
obtain a digital copy.
1.10 'Notice' means copyright, acknowledgement and trademark notices,
Source Location references, modification notices (subsection
3.3(b)) and all notices that refer to this Licence and to the
disclaimer of warranties that are included in the Covered
Source.
1.11 'Licensee' or 'You' means any person exercising rights under
this Licence.
1.12 'Licensor' means a natural or legal person who creates or
modifies Covered Source. A person may be a Licensee and a
Licensor at the same time.
1.13 'Convey' means to communicate to the public or distribute.
2 Applicability
2.1 This Licence governs the use, copying, modification, Conveying
of Covered Source and Products, and the Making of Products. By
exercising any right granted under this Licence, You irrevocably
accept these terms and conditions.
2.2 This Licence is granted by the Licensor directly to You, and
shall apply worldwide and without limitation in time.
2.3 You shall not attempt to restrict by contract or otherwise the
rights granted under this Licence to other Licensees.
2.4 This Licence is not intended to restrict fair use, fair dealing,
or any other similar right.
3 Copying, Modifying and Conveying Covered Source
3.1 You may copy and Convey verbatim copies of Covered Source, in
any medium, provided You retain all Notices.
3.2 You may modify Covered Source, other than Notices, provided that
You irrevocably undertake to make that modified Covered Source
available from a Source Location should You Convey a Product in
circumstances where the recipient does not otherwise receive a
copy of the modified Covered Source. In each case subsection 3.3
shall apply.
You may only delete Notices if they are no longer applicable to
the corresponding Covered Source as modified by You and You may
add additional Notices applicable to Your modifications.
Including Covered Source in a larger work is modifying the
Covered Source, and the larger work becomes modified Covered
Source.
3.3 You may Convey modified Covered Source (with the effect that You
shall also become a Licensor) provided that You:
a) retain Notices as required in subsection 3.2;
b) add a Notice to the modified Covered Source stating that You
have modified it, with the date and brief description of how
You have modified it;
c) add a Source Location Notice for the modified Covered Source
if You Convey in circumstances where the recipient does not
otherwise receive a copy of the modified Covered Source; and
d) license the modified Covered Source under the terms and
conditions of this Licence (or, as set out in subsection
8.3, a later version, if permitted by the licence of the
original Covered Source). Such modified Covered Source must
be licensed as a whole, but excluding Available Components
contained in it, which remain licensed under their own
applicable licences.
4 Making and Conveying Products
You may Make Products, and/or Convey them, provided that You either
provide each recipient with a copy of the Complete Source or ensure
that each recipient is notified of the Source Location of the Complete
Source. That Complete Source is Covered Source, and You must
accordingly satisfy Your obligations set out in subsection 3.3. If
specified in a Notice, the Product must visibly and securely display
the Source Location on it or its packaging or documentation in the
manner specified in that Notice.
5 Research and Development
You may Convey Covered Source, modified Covered Source or Products to
a legal entity carrying out development, testing or quality assurance
work on Your behalf provided that the work is performed on terms which
prevent the entity from both using the Source or Products for its own
internal purposes and Conveying the Source or Products or any
modifications to them to any person other than You. Any modifications
made by the entity shall be deemed to be made by You pursuant to
subsection 3.2.
6 DISCLAIMER AND LIABILITY
6.1 DISCLAIMER OF WARRANTY -- The Covered Source and any Products
are provided 'as is' and any express or implied warranties,
including, but not limited to, implied warranties of
merchantability, of satisfactory quality, non-infringement of
third party rights, and fitness for a particular purpose or use
are disclaimed in respect of any Source or Product to the
maximum extent permitted by law. The Licensor makes no
representation that any Source or Product does not or will not
infringe any patent, copyright, trade secret or other
proprietary right. The entire risk as to the use, quality, and
performance of any Source or Product shall be with You and not
the Licensor. This disclaimer of warranty is an essential part
of this Licence and a condition for the grant of any rights
granted under this Licence.
6.2 EXCLUSION AND LIMITATION OF LIABILITY -- The Licensor shall, to
the maximum extent permitted by law, have no liability for
direct, indirect, special, incidental, consequential, exemplary,
punitive or other damages of any character including, without
limitation, procurement of substitute goods or services, loss of
use, data or profits, or business interruption, however caused
and on any theory of contract, warranty, tort (including
negligence), product liability or otherwise, arising in any way
in relation to the Covered Source, modified Covered Source
and/or the Making or Conveyance of a Product, even if advised of
the possibility of such damages, and You shall hold the
Licensor(s) free and harmless from any liability, costs,
damages, fees and expenses, including claims by third parties,
in relation to such use.
7 Patents
7.1 Subject to the terms and conditions of this Licence, each
Licensor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as
stated in subsections 7.2 and 8.4) patent license to Make, have
Made, use, offer to sell, sell, import, and otherwise transfer
the Covered Source and Products, where such licence applies only
to those patent claims licensable by such Licensor that are
necessarily infringed by exercising rights under the Covered
Source as Conveyed by that Licensor.
7.2 If You institute patent litigation against any entity (including
a cross-claim or counterclaim in a lawsuit) alleging that the
Covered Source or a Product constitutes direct or contributory
patent infringement, or You seek any declaration that a patent
licensed to You under this Licence is invalid or unenforceable
then any rights granted to You under this Licence shall
terminate as of the date such process is initiated.
8 General
8.1 If any provisions of this Licence are or subsequently become
invalid or unenforceable for any reason, the remaining
provisions shall remain effective.
8.2 You shall not use any of the name (including acronyms and
abbreviations), image, or logo by which the Licensor or CERN is
known, except where needed to comply with section 3, or where
the use is otherwise allowed by law. Any such permitted use
shall be factual and shall not be made so as to suggest any kind
of endorsement or implication of involvement by the Licensor or
its personnel.
8.3 CERN may publish updated versions and variants of this Licence
which it considers to be in the spirit of this version, but may
differ in detail to address new problems or concerns. New
versions will be published with a unique version number and a
variant identifier specifying the variant. If the Licensor has
specified that a given variant applies to the Covered Source
without specifying a version, You may treat that Covered Source
as being released under any version of the CERN-OHL with that
variant. If no variant is specified, the Covered Source shall be
treated as being released under CERN-OHL-S. The Licensor may
also specify that the Covered Source is subject to a specific
version of the CERN-OHL or any later version in which case You
may apply this or any later version of CERN-OHL with the same
variant identifier published by CERN.
8.4 This Licence shall terminate with immediate effect if You fail
to comply with any of its terms and conditions.
8.5 However, if You cease all breaches of this Licence, then Your
Licence from any Licensor is reinstated unless such Licensor has
terminated this Licence by giving You, while You remain in
breach, a notice specifying the breach and requiring You to cure
it within 30 days, and You have failed to come into compliance
in all material respects by the end of the 30 day period. Should
You repeat the breach after receipt of a cure notice and
subsequent reinstatement, this Licence will terminate
immediately and permanently. Section 6 shall continue to apply
after any termination.
8.6 This Licence shall not be enforceable except by a Licensor
acting as such, and third party beneficiary rights are
specifically excluded.

View File

@ -0,0 +1,311 @@
CERN Open Hardware Licence Version 2 - Weakly Reciprocal
Preamble
CERN has developed this licence to promote collaboration among
hardware designers and to provide a legal tool which supports the
freedom to use, study, modify, share and distribute hardware designs
and products based on those designs. Version 2 of the CERN Open
Hardware Licence comes in three variants: CERN-OHL-P (permissive); and
two reciprocal licences: this licence, CERN-OHL-W (weakly reciprocal)
and CERN-OHL-S (strongly reciprocal).
The CERN-OHL-W is copyright CERN 2020. Anyone is welcome to use it, in
unmodified form only.
Use of this Licence does not imply any endorsement by CERN of any
Licensor or their designs nor does it imply any involvement by CERN in
their development.
1 Definitions
1.1 'Licence' means this CERN-OHL-W.
1.2 'Compatible Licence' means
a) any earlier version of the CERN Open Hardware licence, or
b) any version of the CERN-OHL-S or the CERN-OHL-W, or
c) any licence which permits You to treat the Source to which
it applies as licensed under CERN-OHL-S or CERN-OHL-W
provided that on Conveyance of any such Source, or any
associated Product You treat the Source in question as being
licensed under CERN-OHL-S or CERN-OHL-W as appropriate.
1.3 'Source' means information such as design materials or digital
code which can be applied to Make or test a Product or to
prepare a Product for use, Conveyance or sale, regardless of its
medium or how it is expressed. It may include Notices.
1.4 'Covered Source' means Source that is explicitly made available
under this Licence.
1.5 'Product' means any device, component, work or physical object,
whether in finished or intermediate form, arising from the use,
application or processing of Covered Source.
1.6 'Make' means to create or configure something, whether by
manufacture, assembly, compiling, loading or applying Covered
Source or another Product or otherwise.
1.7 'Available Component' means any part, sub-assembly, library or
code which:
a) is licensed to You as Complete Source under a Compatible
Licence; or
b) is available, at the time a Product or the Source containing
it is first Conveyed, to You and any other prospective
licensees
i) with sufficient rights and information (including any
configuration and programming files and information
about its characteristics and interfaces) to enable it
either to be Made itself, or to be sourced and used to
Make the Product; or
ii) as part of the normal distribution of a tool used to
design or Make the Product.
1.8 'External Material' means anything (including Source) which:
a) is only combined with Covered Source in such a way that it
interfaces with the Covered Source using a documented
interface which is described in the Covered Source; and
b) is not a derivative of or contains Covered Source, or, if it
is, it is solely to the extent necessary to facilitate such
interfacing.
1.9 'Complete Source' means the set of all Source necessary to Make
a Product, in the preferred form for making modifications,
including necessary installation and interfacing information
both for the Product, and for any included Available Components.
If the format is proprietary, it must also be made available in
a format (if the proprietary tool can create it) which is
viewable with a tool available to potential licensees and
licensed under a licence approved by the Free Software
Foundation or the Open Source Initiative. Complete Source need
not include the Source of any Available Component, provided that
You include in the Complete Source sufficient information to
enable a recipient to Make or source and use the Available
Component to Make the Product.
1.10 'Source Location' means a location where a Licensor has placed
Covered Source, and which that Licensor reasonably believes will
remain easily accessible for at least three years for anyone to
obtain a digital copy.
1.11 'Notice' means copyright, acknowledgement and trademark notices,
Source Location references, modification notices (subsection
3.3(b)) and all notices that refer to this Licence and to the
disclaimer of warranties that are included in the Covered
Source.
1.12 'Licensee' or 'You' means any person exercising rights under
this Licence.
1.13 'Licensor' means a natural or legal person who creates or
modifies Covered Source. A person may be a Licensee and a
Licensor at the same time.
1.14 'Convey' means to communicate to the public or distribute.
2 Applicability
2.1 This Licence governs the use, copying, modification, Conveying
of Covered Source and Products, and the Making of Products. By
exercising any right granted under this Licence, You irrevocably
accept these terms and conditions.
2.2 This Licence is granted by the Licensor directly to You, and
shall apply worldwide and without limitation in time.
2.3 You shall not attempt to restrict by contract or otherwise the
rights granted under this Licence to other Licensees.
2.4 This Licence is not intended to restrict fair use, fair dealing,
or any other similar right.
3 Copying, Modifying and Conveying Covered Source
3.1 You may copy and Convey verbatim copies of Covered Source, in
any medium, provided You retain all Notices.
3.2 You may modify Covered Source, other than Notices, provided that
You irrevocably undertake to make that modified Covered Source
available from a Source Location should You Convey a Product in
circumstances where the recipient does not otherwise receive a
copy of the modified Covered Source. In each case subsection 3.3
shall apply.
You may only delete Notices if they are no longer applicable to
the corresponding Covered Source as modified by You and You may
add additional Notices applicable to Your modifications.
3.3 You may Convey modified Covered Source (with the effect that You
shall also become a Licensor) provided that You:
a) retain Notices as required in subsection 3.2;
b) add a Notice to the modified Covered Source stating that You
have modified it, with the date and brief description of how
You have modified it;
c) add a Source Location Notice for the modified Covered Source
if You Convey in circumstances where the recipient does not
otherwise receive a copy of the modified Covered Source; and
d) license the modified Covered Source under the terms and
conditions of this Licence (or, as set out in subsection
8.3, a later version, if permitted by the licence of the
original Covered Source). Such modified Covered Source must
be licensed as a whole, but excluding Available Components
contained in it or External Material to which it is
interfaced, which remain licensed under their own applicable
licences.
4 Making and Conveying Products
4.1 You may Make Products, and/or Convey them, provided that You
either provide each recipient with a copy of the Complete Source
or ensure that each recipient is notified of the Source Location
of the Complete Source. That Complete Source includes Covered
Source and You must accordingly satisfy Your obligations set out
in subsection 3.3. If specified in a Notice, the Product must
visibly and securely display the Source Location on it or its
packaging or documentation in the manner specified in that
Notice.
4.2 Where You Convey a Product which incorporates External Material,
the Complete Source for that Product which You are required to
provide under subsection 4.1 need not include any Source for the
External Material.
4.3 You may license Products under terms of Your choice, provided
that such terms do not restrict or attempt to restrict any
recipients' rights under this Licence to the Covered Source.
5 Research and Development
You may Convey Covered Source, modified Covered Source or Products to
a legal entity carrying out development, testing or quality assurance
work on Your behalf provided that the work is performed on terms which
prevent the entity from both using the Source or Products for its own
internal purposes and Conveying the Source or Products or any
modifications to them to any person other than You. Any modifications
made by the entity shall be deemed to be made by You pursuant to
subsection 3.2.
6 DISCLAIMER AND LIABILITY
6.1 DISCLAIMER OF WARRANTY -- The Covered Source and any Products
are provided 'as is' and any express or implied warranties,
including, but not limited to, implied warranties of
merchantability, of satisfactory quality, non-infringement of
third party rights, and fitness for a particular purpose or use
are disclaimed in respect of any Source or Product to the
maximum extent permitted by law. The Licensor makes no
representation that any Source or Product does not or will not
infringe any patent, copyright, trade secret or other
proprietary right. The entire risk as to the use, quality, and
performance of any Source or Product shall be with You and not
the Licensor. This disclaimer of warranty is an essential part
of this Licence and a condition for the grant of any rights
granted under this Licence.
6.2 EXCLUSION AND LIMITATION OF LIABILITY -- The Licensor shall, to
the maximum extent permitted by law, have no liability for
direct, indirect, special, incidental, consequential, exemplary,
punitive or other damages of any character including, without
limitation, procurement of substitute goods or services, loss of
use, data or profits, or business interruption, however caused
and on any theory of contract, warranty, tort (including
negligence), product liability or otherwise, arising in any way
in relation to the Covered Source, modified Covered Source
and/or the Making or Conveyance of a Product, even if advised of
the possibility of such damages, and You shall hold the
Licensor(s) free and harmless from any liability, costs,
damages, fees and expenses, including claims by third parties,
in relation to such use.
7 Patents
7.1 Subject to the terms and conditions of this Licence, each
Licensor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as
stated in subsections 7.2 and 8.4) patent license to Make, have
Made, use, offer to sell, sell, import, and otherwise transfer
the Covered Source and Products, where such licence applies only
to those patent claims licensable by such Licensor that are
necessarily infringed by exercising rights under the Covered
Source as Conveyed by that Licensor.
7.2 If You institute patent litigation against any entity (including
a cross-claim or counterclaim in a lawsuit) alleging that the
Covered Source or a Product constitutes direct or contributory
patent infringement, or You seek any declaration that a patent
licensed to You under this Licence is invalid or unenforceable
then any rights granted to You under this Licence shall
terminate as of the date such process is initiated.
8 General
8.1 If any provisions of this Licence are or subsequently become
invalid or unenforceable for any reason, the remaining
provisions shall remain effective.
8.2 You shall not use any of the name (including acronyms and
abbreviations), image, or logo by which the Licensor or CERN is
known, except where needed to comply with section 3, or where
the use is otherwise allowed by law. Any such permitted use
shall be factual and shall not be made so as to suggest any kind
of endorsement or implication of involvement by the Licensor or
its personnel.
8.3 CERN may publish updated versions and variants of this Licence
which it considers to be in the spirit of this version, but may
differ in detail to address new problems or concerns. New
versions will be published with a unique version number and a
variant identifier specifying the variant. If the Licensor has
specified that a given variant applies to the Covered Source
without specifying a version, You may treat that Covered Source
as being released under any version of the CERN-OHL with that
variant. If no variant is specified, the Covered Source shall be
treated as being released under CERN-OHL-S. The Licensor may
also specify that the Covered Source is subject to a specific
version of the CERN-OHL or any later version in which case You
may apply this or any later version of CERN-OHL with the same
variant identifier published by CERN.
You may treat Covered Source licensed under CERN-OHL-W as
licensed under CERN-OHL-S if and only if all Available
Components referenced in the Covered Source comply with the
corresponding definition of Available Component for CERN-OHL-S.
8.4 This Licence shall terminate with immediate effect if You fail
to comply with any of its terms and conditions.
8.5 However, if You cease all breaches of this Licence, then Your
Licence from any Licensor is reinstated unless such Licensor has
terminated this Licence by giving You, while You remain in
breach, a notice specifying the breach and requiring You to cure
it within 30 days, and You have failed to come into compliance
in all material respects by the end of the 30 day period. Should
You repeat the breach after receipt of a cure notice and
subsequent reinstatement, this Licence will terminate
immediately and permanently. Section 6 shall continue to apply
after any termination.
8.6 This Licence shall not be enforceable except by a Licensor
acting as such, and third party beneficiary rights are
specifically excluded.