valentyusb: Add USB UART to SOC and OrangeCrab

An extra uart is added at 0xc0008000 attached to valentyusb, using
the OrangeCrab's onboard USB port.
This has a liteuart interface, an identifier bit is added to syscon.

Generated from branch hw_cdc_eptri of
https://github.com/litex-hub/valentyusb

The generate script is based on valentyusb/sim/generate_verilog.py

UARTUSB: usbserial@8000 {
        device_type = "serial";
        compatible = "litex,liteuart";
        reg = <0x8000 0x100>;
        interrupts = <0x15 0x1>;
};

(requires extra kernel patches for early console at present v5.16)

Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
pull/347/head
Matt Johnston 2 years ago
parent f57e206841
commit 6be3e1a336

@ -192,6 +192,7 @@ ECP_FLASH_OFFSET=0x80000
toplevel=fpga/top-orangecrab0.2.vhdl
litedram_target=orangecrab-85-0.2
soc_extra_v += litesdcard/generated/lattice/litesdcard_core.v
soc_extra_v += valentyusb/generated/orangecrab-85-0.2/gateware/valentyusb.v
dmi_dtm=dmi_dtm_ecp5.vhdl
endif


@ -23,6 +23,7 @@ entity toplevel is
LOG_LENGTH : natural := 0;
UART_IS_16550 : boolean := true;
HAS_UART1 : boolean := false;
HAS_UARTUSB : boolean := true;
USE_LITESDCARD : boolean := true;
ICACHE_NUM_LINES : natural := 64;
NGPIO : natural := 0
@ -35,6 +36,11 @@ entity toplevel is
pin_gpio_0 : out std_ulogic;
pin_gpio_1 : in std_ulogic;

-- USB signals:
usb_d_p : in std_ulogic;
usb_d_n : in std_ulogic;
usb_pullup : out std_ulogic;

-- LEDs
led0_b : out std_ulogic;
led0_g : out std_ulogic;
@ -186,6 +192,7 @@ begin
LOG_LENGTH => LOG_LENGTH,
UART0_IS_16550 => UART_IS_16550,
HAS_UART1 => HAS_UART1,
HAS_UARTUSB => HAS_UARTUSB,
HAS_SD_CARD => USE_LITESDCARD,
ICACHE_NUM_LINES => ICACHE_NUM_LINES,
HAS_SHORT_MULT => true,
@ -194,12 +201,17 @@ begin
port map (
-- System signals
system_clk => system_clk,
clk_48 => ext_clk,
rst => soc_rst,

-- UART signals
uart0_txd => pin_gpio_0,
uart0_rxd => pin_gpio_1,

usb_d_p => usb_d_p,
usb_d_n => usb_d_n,
usb_pullup => usb_pullup,

-- UART1 signals
--uart1_txd => uart_pmod_tx,
--uart1_rxd => uart_pmod_rx,

@ -10,10 +10,13 @@
#define BRAM_BASE 0x80000000 /* Internal BRAM */

#define SYSCON_BASE 0xc0000000 /* System control regs */
#define UART_BASE 0xc0002000 /* UART */
#define UART0_BASE 0xc0002000 /* UART */
#define UART_BASE UART0_BASE
#define UART1_BASE 0xc0003000 /* UART */
#define XICS_ICP_BASE 0xc0004000 /* Interrupt controller */
#define XICS_ICS_BASE 0xc0005000 /* Interrupt controller */
#define SPI_FCTRL_BASE 0xc0006000 /* SPI flash controller registers */
#define UARTUSB_BASE 0xc0008000 /* ValentyUSB UART */
#define DRAM_CTRL_BASE 0xc8000000 /* LiteDRAM control registers */
#define LETH_CSR_BASE 0xc8020000 /* LiteEth CSR registers */
#define LETH_SRAM_BASE 0xc8030000 /* LiteEth MMIO space */
@ -26,6 +29,7 @@
*/
#define IRQ_UART0 0
#define IRQ_ETHERNET 1
#define IRQ_UARTUSB 5

/*
* Register definitions for the syscon registers
@ -42,6 +46,7 @@
#define SYS_REG_INFO_HAS_UART1 (1ull << 6)
#define SYS_REG_INFO_HAS_ARTB (1ull << 7)
#define SYS_REG_INFO_HAS_LITESDCARD (1ull << 8)
#define SYS_REG_INFO_HAS_UARTUSB (1ull << 9)
#define SYS_REG_BRAMINFO 0x10
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
#define SYS_REG_DRAMINFO 0x18

@ -25,6 +25,7 @@ use work.wishbone_types.all;
-- 0xc0005000: XICS ICS
-- 0xc0006000: SPI Flash controller
-- 0xc0007000: GPIO controller
-- 0xc0008000: USB UART (valentyusb)
-- 0xc8nnnnnn: External IO bus
-- 0xf0000000: Flash "ROM" mapping
-- 0xff000000: DRAM init code (if any) or flash ROM (**)
@ -50,6 +51,7 @@ use work.wishbone_types.all;
-- 2 : UART1
-- 3 : SD card
-- 4 : GPIO
-- 5 : UARTUSB

entity soc is
generic (
@ -74,6 +76,7 @@ entity soc is
HAS_LITEETH : boolean := false;
UART0_IS_16550 : boolean := true;
HAS_UART1 : boolean := false;
HAS_UARTUSB : boolean := false;
ICACHE_NUM_LINES : natural := 64;
ICACHE_NUM_WAYS : natural := 2;
ICACHE_TLB_SIZE : natural := 64;
@ -88,6 +91,7 @@ entity soc is
port(
rst : in std_ulogic;
system_clk : in std_ulogic;
clk_48 : in std_ulogic := '0';

-- "Large" (64-bit) DRAM wishbone
wb_dram_in : out wishbone_master_out;
@ -117,6 +121,11 @@ entity soc is
uart1_txd : out std_ulogic;
uart1_rxd : in std_ulogic := '0';

-- USB signals:
usb_d_p : in std_ulogic := '0';
usb_d_n : in std_ulogic := '0';
usb_pullup : out std_ulogic;

-- SPI Flash signals
spi_flash_sck : out std_ulogic;
spi_flash_cs_n : out std_ulogic;
@ -181,6 +190,11 @@ architecture behaviour of soc is
signal uart1_dat8 : std_ulogic_vector(7 downto 0);
signal uart1_irq : std_ulogic;

-- UARTUSB signals:
signal wb_uartusb_in : wb_io_master_out;
signal wb_uartusb_out : wb_io_slave_out;
signal uartusb_irq : std_ulogic;

-- SPI Flash controller signals:
signal wb_spiflash_in : wb_io_master_out;
signal wb_spiflash_out : wb_io_slave_out;
@ -241,6 +255,7 @@ architecture behaviour of soc is
SLAVE_IO_UART1,
SLAVE_IO_SPI_FLASH,
SLAVE_IO_GPIO,
SLAVE_IO_UARTUSB,
SLAVE_IO_EXTERNAL);
signal current_io_decode : slave_io_type;

@ -248,6 +263,7 @@ architecture behaviour of soc is
signal io_cycle_syscon : std_ulogic;
signal io_cycle_uart : std_ulogic;
signal io_cycle_uart1 : std_ulogic;
signal io_cycle_uartusb : std_ulogic;
signal io_cycle_icp : std_ulogic;
signal io_cycle_ics : std_ulogic;
signal io_cycle_spi_flash : std_ulogic;
@ -310,6 +326,7 @@ architecture behaviour of soc is
);
end component;

constant UART0_IS_POTATO : boolean := not UART0_IS_16550;
begin

resets: process(system_clk)
@ -609,6 +626,7 @@ begin
io_cycle_syscon <= '0';
io_cycle_uart <= '0';
io_cycle_uart1 <= '0';
io_cycle_uartusb <= '0';
io_cycle_icp <= '0';
io_cycle_ics <= '0';
io_cycle_spi_flash <= '0';
@ -675,6 +693,9 @@ begin
elsif std_match(match, x"C0007") then
slave_io := SLAVE_IO_GPIO;
io_cycle_gpio <= '1';
elsif std_match(match, x"C0008") then
slave_io := SLAVE_IO_UARTUSB;
io_cycle_uartusb <= '1';
else
io_cycle_none <= '1';
end if;
@ -702,6 +723,12 @@ begin
wb_gpio_in <= wb_sio_out;
wb_gpio_in.cyc <= io_cycle_gpio;

wb_uartusb_in <= wb_sio_out;
wb_uartusb_in.cyc <= io_cycle_uartusb;
-- valentyusb was built at base 0x0, it only needs 5 low bits
wb_uartusb_in.adr <= (others => '0');
wb_uartusb_in.adr(4 downto 0) <= wb_sio_out.adr(4 downto 0);

-- Only give xics 8 bits of wb addr (for now...)
wb_xics_icp_in <= wb_sio_out;
wb_xics_icp_in.adr <= (others => '0');
@ -731,6 +758,8 @@ begin
wb_sio_in <= wb_xics_ics_out;
when SLAVE_IO_UART1 =>
wb_sio_in <= wb_uart1_out;
when SLAVE_IO_UARTUSB =>
wb_sio_in <= wb_uartusb_out;
when SLAVE_IO_SPI_FLASH =>
wb_sio_in <= wb_spiflash_out;
when SLAVE_IO_GPIO =>
@ -760,7 +789,8 @@ begin
HAS_LITEETH => HAS_LITEETH,
HAS_SD_CARD => HAS_SD_CARD,
UART0_IS_16550 => UART0_IS_16550,
HAS_UART1 => HAS_UART1
HAS_UART1 => HAS_UART1,
HAS_UARTUSB => HAS_UARTUSB
)
port map(
clk => system_clk,
@ -777,7 +807,7 @@ begin
--
-- Either potato (legacy) or 16550
--
uart0_pp: if not UART0_IS_16550 generate
uart0_pp: if UART0_IS_POTATO generate
uart0: entity work.pp_soc_uart
generic map(
FIFO_DEPTH => 32
@ -796,6 +826,9 @@ begin
wb_we_in => wb_uart0_in.we,
wb_ack_out => wb_uart0_out.ack
);

wb_uart0_out.dat <= x"000000" & uart0_dat8;
wb_uart0_out.stall <= not wb_uart0_out.ack;
end generate;

uart0_16550 : if UART0_IS_16550 generate
@ -830,10 +863,73 @@ begin
uart0_irq <= irq_l;
end if;
end process;

wb_uart0_out.dat <= x"000000" & uart0_dat8;
wb_uart0_out.stall <= not wb_uart0_out.ack;
end generate;

wb_uart0_out.dat <= x"000000" & uart0_dat8;
wb_uart0_out.stall <= not wb_uart0_out.ack;

uart0_valentyusb : if HAS_UARTUSB generate
component valentyusb port (
clk_clksys : in std_ulogic;
clk_clk48 : in std_ulogic;
reset : in std_ulogic;
usb_d_p : in std_ulogic;
usb_d_n : in std_ulogic;
usb_pullup : out std_ulogic;
usb_tx_en : out std_ulogic;
interrupt : out std_ulogic;
wishbone_adr : in std_ulogic_vector(29 downto 0);
wishbone_dat_w : in std_ulogic_vector(31 downto 0);
wishbone_dat_r : out std_ulogic_vector(31 downto 0);
wishbone_sel : in std_ulogic_vector(3 downto 0);
wishbone_cyc : in std_ulogic;
wishbone_stb : in std_ulogic;
wishbone_ack : out std_ulogic;
wishbone_we : in std_ulogic;
wishbone_cti : in std_ulogic_vector(2 downto 0);
wishbone_bte : in std_ulogic_vector(1 downto 0);
wishbone_err : out std_ulogic
);
end component;
signal irq_l : std_ulogic;
begin
uart0: valentyusb
port map (
clk_clksys => system_clk,
clk_clk48 => clk_48,
reset => rst_uart,
usb_d_p => usb_d_p,
usb_d_n => usb_d_n,
usb_pullup => usb_pullup,
-- TODO, output flag
usb_tx_en => open,
wishbone_adr => "0000000000000000" & wb_uartusb_in.adr(13 downto 0),
wishbone_dat_r => wb_uartusb_out.dat,
wishbone_dat_w => wb_uartusb_in.dat,
wishbone_sel => wb_uartusb_in.sel,
wishbone_cyc => wb_uartusb_in.cyc,
wishbone_stb => wb_uartusb_in.stb,
wishbone_ack => wb_uartusb_out.ack,
wishbone_we => wb_uartusb_in.we,
interrupt => irq_l,
-- XXX matt check this
wishbone_cti => "000",
-- XXX matt check this
wishbone_bte => "00",
wishbone_err => open
);

wb_uartusb_out.stall <= not wb_uartusb_out.ack;

-- Add a register on the irq out, helps timing
uartusb_irq_latch: process(system_clk)
begin
if rising_edge(system_clk) then
uartusb_irq <= irq_l;
end if;
end process;
end generate;

--
-- UART1
@ -961,6 +1057,7 @@ begin
int_level_in(2) <= uart1_irq;
int_level_in(3) <= ext_irq_sdcard;
int_level_in(4) <= gpio_intr;
int_level_in(5) <= uartusb_irq;
end process;

-- BRAM Memory slave

@ -20,7 +20,8 @@ entity syscon is
HAS_LITEETH : boolean;
HAS_SD_CARD : boolean;
UART0_IS_16550 : boolean;
HAS_UART1 : boolean
HAS_UART1 : boolean;
HAS_UARTUSB : boolean := false
);
port (
clk : in std_ulogic;
@ -67,6 +68,7 @@ architecture behaviour of syscon is
constant SYS_REG_INFO_HAS_URT1 : integer := 6; -- Has second UART
constant SYS_REG_INFO_HAS_ARTB : integer := 7; -- Has architected TB frequency
constant SYS_REG_INFO_HAS_SDCARD : integer := 8; -- Has LiteSDCard SD-card interface
constant SYS_REG_INFO_HAS_URTU : integer := 9; -- Has USB UART

-- BRAMINFO contains the BRAM size in the bottom 52 bits
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
@ -111,6 +113,7 @@ architecture behaviour of syscon is
signal info_has_leth : std_ulogic;
signal info_has_lsdc : std_ulogic;
signal info_has_urt1 : std_ulogic;
signal info_has_urtu : std_ulogic;
signal info_clk : std_ulogic_vector(39 downto 0);
signal info_fl_off : std_ulogic_vector(31 downto 0);
signal uinfo_16550 : std_ulogic;
@ -133,6 +136,7 @@ begin
info_has_leth <= '1' when HAS_LITEETH else '0';
info_has_lsdc <= '1' when HAS_SD_CARD else '0';
info_has_urt1 <= '1' when HAS_UART1 else '0';
info_has_urtu <= '1' when HAS_UARTUSB else '0';
info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40));
reg_info <= (SYS_REG_INFO_HAS_UART => info_has_uart,
SYS_REG_INFO_HAS_DRAM => info_has_dram,
@ -142,6 +146,7 @@ begin
SYS_REG_INFO_HAS_SDCARD => info_has_lsdc,
SYS_REG_INFO_HAS_LSYS => '1',
SYS_REG_INFO_HAS_URT1 => info_has_urt1,
SYS_REG_INFO_HAS_URTU => info_has_urtu,
others => '0');

reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));

@ -0,0 +1,263 @@
#!/usr/bin/env python3

# Based on valentyusb/sim/generate_verilog.py , modified
# for Microwatt

# This variable defines all the external programs that this module
# relies on. lxbuildenv reads this variable in order to ensure
# the build will finish without exiting due to missing third-party
# programs.
LX_DEPENDENCIES = []

# Import lxbuildenv to integrate the deps/ directory
#import lxbuildenv

# Disable pylint's E1101, which breaks completely on migen
#pylint:disable=E1101

import argparse
import os
import yaml

#from migen import *
from migen import Module, Signal, Instance, ClockDomain, If
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.fhdl.specials import TSTriple
from migen.fhdl.bitcontainer import bits_for
from migen.fhdl.structure import ClockSignal, ResetSignal, Replicate, Cat

# from litex.build.sim.platform import SimPlatform
from litex.build.lattice import LatticePlatform
from litex.build.generic_platform import Pins, IOStandard, Misc, Subsignal
from litex.soc.integration.soc_core import SoCCore
from litex.soc.integration.builder import Builder
from litex.soc.interconnect import wishbone
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage

from valentyusb import usbcore
from valentyusb.usbcore import io as usbio
from valentyusb.usbcore.cpu import dummyusb, cdc_eptri, eptri, epfifo
from valentyusb.usbcore.endpoint import EndpointType

_connectors = []

class _CRG(Module):
def __init__(self, platform):
clk = platform.request("clk")
rst = platform.request("reset")

clk12 = Signal()

self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_usb_12 = ClockDomain()
self.clock_domains.cd_usb_48 = ClockDomain()
self.clock_domains.cd_usb_48_to_12 = ClockDomain()

clk48 = clk.clk48

self.comb += self.cd_usb_48.clk.eq(clk48)
self.comb += self.cd_usb_48_to_12.clk.eq(clk48)

clk12_counter = Signal(2)
self.sync.usb_48_to_12 += clk12_counter.eq(clk12_counter + 1)

self.comb += clk12.eq(clk12_counter[1])

self.comb += self.cd_sys.clk.eq(clk.clksys)
self.comb += self.cd_usb_12.clk.eq(clk12)

self.comb += [
ResetSignal("sys").eq(rst),
ResetSignal("usb_12").eq(rst),
ResetSignal("usb_48").eq(rst),
]

class BaseSoC(SoCCore):

def __init__(self, platform, io, sys_freq, output_dir="build", usb_variant='dummy', **kwargs):
# Disable integrated RAM as we'll add it later
self.integrated_sram_size = 0

self.output_dir = output_dir

platform.add_extension(io)

self.submodules.crg = _CRG(platform)

# prior to SocCore.__init__
self.csr_map = {
"uart": 0, # microwatt soc will remap addresses to 0
}

SoCCore.__init__(self, platform, sys_freq,
cpu_type=None,
integrated_rom_size=0x0,
integrated_sram_size=0x0,
integrated_main_ram_size=0x0,
csr_address_width=14, csr_data_width=32,
with_uart=False, with_timer=False)

# Add USB pads
usb_pads = platform.request("usb")
usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup)
self.comb += usb_pads.tx_en.eq(usb_iobuf.usb_tx_en)
if usb_variant == 'eptri':
self.submodules.usb = eptri.TriEndpointInterface(usb_iobuf, debug=True)
elif usb_variant == 'epfifo':
self.submodules.usb = epfifo.PerEndpointFifoInterface(usb_iobuf, debug=True)
elif usb_variant == 'cdc_eptri':
extra_args = {}
passthrough = ['product', 'manufacturer']
for p in passthrough:
try:
extra_args[p] = kwargs[p]
except KeyError:
pass
self.submodules.uart = cdc_eptri.CDCUsb(usb_iobuf, debug=True, **extra_args)
elif usb_variant == 'dummy':
self.submodules.usb = dummyusb.DummyUsb(usb_iobuf, debug=True)
else:
raise ValueError('Invalid endpoints value. It is currently \'eptri\' and \'dummy\'')
try:
self.add_wb_master(self.usb.debug_bridge.wishbone)
except AttributeError:
pass

if self.uart:
self.comb += self.platform.request("interrupt").eq(self.uart.ev.irq)

wb_ctrl = wishbone.Interface()
self.add_wb_master(wb_ctrl)
platform.add_extension(wb_ctrl.get_ios("wb_ctrl"))
self.comb += wb_ctrl.connect_to_pads(self.platform.request("wishbone"), mode="slave")

def add_fsm_state_names():
"""Hack the FSM module to add state names to the output"""
from migen.fhdl.visit import NodeTransformer
from migen.genlib.fsm import NextState, NextValue, _target_eq
from migen.fhdl.bitcontainer import value_bits_sign

class My_LowerNext(NodeTransformer):
def __init__(self, next_state_signal, next_state_name_signal, encoding, aliases):
self.next_state_signal = next_state_signal
self.next_state_name_signal = next_state_name_signal
self.encoding = encoding
self.aliases = aliases
# (target, next_value_ce, next_value)
self.registers = []

def _get_register_control(self, target):
for x in self.registers:
if _target_eq(target, x[0]):
return x[1], x[2]
raise KeyError

def visit_unknown(self, node):
if isinstance(node, NextState):
try:
actual_state = self.aliases[node.state]
except KeyError:
actual_state = node.state
return [
self.next_state_signal.eq(self.encoding[actual_state]),
self.next_state_name_signal.eq(int.from_bytes(actual_state.encode(), byteorder="big"))
]
elif isinstance(node, NextValue):
try:
next_value_ce, next_value = self._get_register_control(node.target)
except KeyError:
related = node.target if isinstance(node.target, Signal) else None
next_value = Signal(bits_sign=value_bits_sign(node.target), related=related)
next_value_ce = Signal(related=related)
self.registers.append((node.target, next_value_ce, next_value))
return next_value.eq(node.value), next_value_ce.eq(1)
else:
return node
import migen.genlib.fsm as fsm
def my_lower_controls(self):
self.state_name = Signal(len(max(self.encoding,key=len))*8, reset=int.from_bytes(self.reset_state.encode(), byteorder="big"))
self.next_state_name = Signal(len(max(self.encoding,key=len))*8, reset=int.from_bytes(self.reset_state.encode(), byteorder="big"))
self.comb += self.next_state_name.eq(self.state_name)
self.sync += self.state_name.eq(self.next_state_name)
return My_LowerNext(self.next_state, self.next_state_name, self.encoding, self.state_aliases)
fsm.FSM._lower_controls = my_lower_controls


_io = [
# Wishbone
("wishbone", 0,
Subsignal("adr", Pins(30)),
Subsignal("dat_r", Pins(32)),
Subsignal("dat_w", Pins(32)),
Subsignal("sel", Pins(4)),
Subsignal("cyc", Pins(1)),
Subsignal("stb", Pins(1)),
Subsignal("ack", Pins(1)),
Subsignal("we", Pins(1)),
Subsignal("cti", Pins(3)),
Subsignal("bte", Pins(2)),
Subsignal("err", Pins(1))
),
("usb", 0,
Subsignal("d_p", Pins(1)),
Subsignal("d_n", Pins(1)),
Subsignal("pullup", Pins(1)),
Subsignal("tx_en", Pins(1)),
),
("clk", 0,
Subsignal("clk48", Pins(1)),
Subsignal("clksys", Pins(1)),
),
("interrupt", 0, Pins(1)),
("reset", 0, Pins(1)),
]

def generate(core_config, output_dir, csr_csv):

toolchain = core_config["toolchain"]
if toolchain == "trellis":
platform = LatticePlatform(core_config["device"], [], toolchain=toolchain)
else:
raise ValueError(f"Unknown config toolchain {toolchain}")

soc = BaseSoC(platform, _io, core_config["sys_freq"],
usb_variant=core_config["usb_variant"],
cpu_type=None, cpu_variant=None,
output_dir=output_dir,
product=core_config["product"],
manufacturer="Microwatt")
builder = Builder(soc, output_dir=output_dir,
csr_csv=csr_csv,
compile_software=False)
vns = builder.build(run=False, build_name='valentyusb')
soc.do_exit(vns)

def main():
parser = argparse.ArgumentParser(description="Build standalone ValentyUSB verilog output")
# parser.add_argument('variant', metavar='VARIANT',
# choices=['dummy', 'cdc_eptri', 'eptri', 'epfifo'],
# default='dummy',
# help='USB variant. Choices: [%(choices)s] (default: %(default)s)' )
parser.add_argument('--dir', metavar='DIRECTORY',
default='build',
help='Output directory (default: %(default)s)' )
parser.add_argument('--csr', metavar='CSR',
default='csr.csv',
help='csr file (default: %(default)s)')
parser.add_argument('config', type=argparse.FileType('r'),
help='Input platform config file')
args = parser.parse_args()

core_config = yaml.load(args.config.read(), Loader=yaml.Loader)
# XXX matt - not sure if this needed, maybe only for sim target?
# add_fsm_state_names()
output_dir = args.dir
generate(core_config, output_dir, args.csr)

print(
"""Build complete. Output files:
{}/gateware/valentyusb.v Source Verilog file.
""".format(output_dir))

if __name__ == "__main__":
main()

@ -0,0 +1,15 @@
#!/bin/sh

# This requires https://github.com/litex-hub/valentyusb branch hw_cdc_eptri
# Tested with
# commit 912d8e6dc72d45e092e608ffcaabfeaaa6d4580f
# Date: Wed Jan 6 09:42:42 2021 +0100

set -e

GENSRCDIR=$(dirname $0)
cd $GENSRCDIR

for b in orangecrab-85-0.2; do
./generate.py --dir ../generated/$b $b.yml
done

@ -0,0 +1,7 @@
{
"device": "LFE5U-85F-8MG285C",
"toolchain": "trellis",
"usb_variant": "cdc_eptri",
"sys_freq": 48000000,
"product": "Microwatt on OrangeCrab",
}

@ -0,0 +1,5 @@
# Autogenerated by LiteX / git: --------
set -e
yosys -l valentyusb.rpt valentyusb.ys
nextpnr-ecp5 --json valentyusb.json --lpf valentyusb.lpf --textcfg valentyusb.config --85k --package CSFBGA285 --speed 8 --timing-allow-fail --seed 1
ecppack valentyusb.config --svf valentyusb.svf --bit valentyusb.bit --bootaddr 0

@ -0,0 +1,249 @@
00
09
02
3e
00
02
01
00
80
32
09
04
00
00
01
02
02
00
00
05
24
00
10
01
04
24
02
02
05
24
06
00
01
07
05
81
03
08
00
40
09
04
01
00
02
0a
00
00
00
07
05
02
02
40
00
00
07
05
82
02
40
00
00
12
01
00
02
02
00
00
40
09
12
f2
5b
01
01
01
02
00
01
04
03
09
04
14
03
4d
00
69
00
63
00
72
00
6f
00
77
00
61
00
74
00
74
00
30
03
4d
00
69
00
63
00
72
00
6f
00
77
00
61
00
74
00
74
00
20
00
6f
00
6e
00
20
00
4f
00
72
00
61
00
6e
00
67
00
65
00
43
00
72
00
61
00
62
00
05
0f
1d
00
01
18
10
05
00
38
b6
08
34
a9
09
a0
47
8b
fd
a0
76
88
15
b6
65
00
01
02
01
12
03
4d
53
46
54
31
30
30
7e
00
00
00
00
00
00
00
00
28
00
00
00
00
01
04
00
01
00
00
00
00
00
00
00
00
01
57
49
4e
55
53
42
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
c2
01
00
00
00
08

@ -0,0 +1,118 @@
BLOCK RESETPATHS;
BLOCK ASYNCPATHS;
LOCATE COMP "clk_clk48" SITE "X";
LOCATE COMP "clk_clksys" SITE "X";
LOCATE COMP "reset" SITE "X";
LOCATE COMP "usb_d_p" SITE "X";
LOCATE COMP "usb_d_n" SITE "X";
LOCATE COMP "usb_pullup" SITE "X";
LOCATE COMP "usb_tx_en" SITE "X";
LOCATE COMP "interrupt" SITE "X";
LOCATE COMP "wishbone_adr[0]" SITE "X";
LOCATE COMP "wishbone_adr[1]" SITE "X";
LOCATE COMP "wishbone_adr[2]" SITE "X";
LOCATE COMP "wishbone_adr[3]" SITE "X";
LOCATE COMP "wishbone_adr[4]" SITE "X";
LOCATE COMP "wishbone_adr[5]" SITE "X";
LOCATE COMP "wishbone_adr[6]" SITE "X";
LOCATE COMP "wishbone_adr[7]" SITE "X";
LOCATE COMP "wishbone_adr[8]" SITE "X";
LOCATE COMP "wishbone_adr[9]" SITE "X";
LOCATE COMP "wishbone_adr[10]" SITE "X";
LOCATE COMP "wishbone_adr[11]" SITE "X";
LOCATE COMP "wishbone_adr[12]" SITE "X";
LOCATE COMP "wishbone_adr[13]" SITE "X";
LOCATE COMP "wishbone_adr[14]" SITE "X";
LOCATE COMP "wishbone_adr[15]" SITE "X";
LOCATE COMP "wishbone_adr[16]" SITE "X";
LOCATE COMP "wishbone_adr[17]" SITE "X";
LOCATE COMP "wishbone_adr[18]" SITE "X";
LOCATE COMP "wishbone_adr[19]" SITE "X";
LOCATE COMP "wishbone_adr[20]" SITE "X";
LOCATE COMP "wishbone_adr[21]" SITE "X";
LOCATE COMP "wishbone_adr[22]" SITE "X";
LOCATE COMP "wishbone_adr[23]" SITE "X";
LOCATE COMP "wishbone_adr[24]" SITE "X";
LOCATE COMP "wishbone_adr[25]" SITE "X";
LOCATE COMP "wishbone_adr[26]" SITE "X";
LOCATE COMP "wishbone_adr[27]" SITE "X";
LOCATE COMP "wishbone_adr[28]" SITE "X";
LOCATE COMP "wishbone_adr[29]" SITE "X";
LOCATE COMP "wishbone_dat_r[0]" SITE "X";
LOCATE COMP "wishbone_dat_r[1]" SITE "X";
LOCATE COMP "wishbone_dat_r[2]" SITE "X";
LOCATE COMP "wishbone_dat_r[3]" SITE "X";
LOCATE COMP "wishbone_dat_r[4]" SITE "X";
LOCATE COMP "wishbone_dat_r[5]" SITE "X";
LOCATE COMP "wishbone_dat_r[6]" SITE "X";
LOCATE COMP "wishbone_dat_r[7]" SITE "X";
LOCATE COMP "wishbone_dat_r[8]" SITE "X";
LOCATE COMP "wishbone_dat_r[9]" SITE "X";
LOCATE COMP "wishbone_dat_r[10]" SITE "X";
LOCATE COMP "wishbone_dat_r[11]" SITE "X";
LOCATE COMP "wishbone_dat_r[12]" SITE "X";
LOCATE COMP "wishbone_dat_r[13]" SITE "X";
LOCATE COMP "wishbone_dat_r[14]" SITE "X";
LOCATE COMP "wishbone_dat_r[15]" SITE "X";
LOCATE COMP "wishbone_dat_r[16]" SITE "X";
LOCATE COMP "wishbone_dat_r[17]" SITE "X";
LOCATE COMP "wishbone_dat_r[18]" SITE "X";
LOCATE COMP "wishbone_dat_r[19]" SITE "X";
LOCATE COMP "wishbone_dat_r[20]" SITE "X";
LOCATE COMP "wishbone_dat_r[21]" SITE "X";
LOCATE COMP "wishbone_dat_r[22]" SITE "X";
LOCATE COMP "wishbone_dat_r[23]" SITE "X";
LOCATE COMP "wishbone_dat_r[24]" SITE "X";
LOCATE COMP "wishbone_dat_r[25]" SITE "X";
LOCATE COMP "wishbone_dat_r[26]" SITE "X";
LOCATE COMP "wishbone_dat_r[27]" SITE "X";
LOCATE COMP "wishbone_dat_r[28]" SITE "X";
LOCATE COMP "wishbone_dat_r[29]" SITE "X";
LOCATE COMP "wishbone_dat_r[30]" SITE "X";
LOCATE COMP "wishbone_dat_r[31]" SITE "X";
LOCATE COMP "wishbone_dat_w[0]" SITE "X";
LOCATE COMP "wishbone_dat_w[1]" SITE "X";
LOCATE COMP "wishbone_dat_w[2]" SITE "X";
LOCATE COMP "wishbone_dat_w[3]" SITE "X";
LOCATE COMP "wishbone_dat_w[4]" SITE "X";
LOCATE COMP "wishbone_dat_w[5]" SITE "X";
LOCATE COMP "wishbone_dat_w[6]" SITE "X";
LOCATE COMP "wishbone_dat_w[7]" SITE "X";
LOCATE COMP "wishbone_dat_w[8]" SITE "X";
LOCATE COMP "wishbone_dat_w[9]" SITE "X";
LOCATE COMP "wishbone_dat_w[10]" SITE "X";
LOCATE COMP "wishbone_dat_w[11]" SITE "X";
LOCATE COMP "wishbone_dat_w[12]" SITE "X";
LOCATE COMP "wishbone_dat_w[13]" SITE "X";
LOCATE COMP "wishbone_dat_w[14]" SITE "X";
LOCATE COMP "wishbone_dat_w[15]" SITE "X";
LOCATE COMP "wishbone_dat_w[16]" SITE "X";
LOCATE COMP "wishbone_dat_w[17]" SITE "X";
LOCATE COMP "wishbone_dat_w[18]" SITE "X";
LOCATE COMP "wishbone_dat_w[19]" SITE "X";
LOCATE COMP "wishbone_dat_w[20]" SITE "X";
LOCATE COMP "wishbone_dat_w[21]" SITE "X";
LOCATE COMP "wishbone_dat_w[22]" SITE "X";
LOCATE COMP "wishbone_dat_w[23]" SITE "X";
LOCATE COMP "wishbone_dat_w[24]" SITE "X";
LOCATE COMP "wishbone_dat_w[25]" SITE "X";
LOCATE COMP "wishbone_dat_w[26]" SITE "X";
LOCATE COMP "wishbone_dat_w[27]" SITE "X";
LOCATE COMP "wishbone_dat_w[28]" SITE "X";
LOCATE COMP "wishbone_dat_w[29]" SITE "X";
LOCATE COMP "wishbone_dat_w[30]" SITE "X";
LOCATE COMP "wishbone_dat_w[31]" SITE "X";
LOCATE COMP "wishbone_sel[0]" SITE "X";
LOCATE COMP "wishbone_sel[1]" SITE "X";
LOCATE COMP "wishbone_sel[2]" SITE "X";
LOCATE COMP "wishbone_sel[3]" SITE "X";
LOCATE COMP "wishbone_cyc" SITE "X";
LOCATE COMP "wishbone_stb" SITE "X";
LOCATE COMP "wishbone_ack" SITE "X";
LOCATE COMP "wishbone_we" SITE "X";
LOCATE COMP "wishbone_cti[0]" SITE "X";
LOCATE COMP "wishbone_cti[1]" SITE "X";
LOCATE COMP "wishbone_cti[2]" SITE "X";
LOCATE COMP "wishbone_bte[0]" SITE "X";
LOCATE COMP "wishbone_bte[1]" SITE "X";
LOCATE COMP "wishbone_err" SITE "X";

File diff suppressed because it is too large Load Diff

@ -0,0 +1,6 @@
verilog_defaults -push
verilog_defaults -add -defer
read_verilog /home/matt/3rd/fpga/microwatt/valentyusb/generated/orangecrab-85-0.2/gateware/valentyusb.v
verilog_defaults -pop
attrmap -tocase keep -imap keep="true" keep=1 -imap keep="false" keep=0 -remove keep=0
synth_ecp5 -json valentyusb.json -top valentyusb

@ -0,0 +1,232 @@
//--------------------------------------------------------------------------------
// Auto-generated by Migen (--------) & LiteX (--------) on 2022-02-07 17:23:11
//--------------------------------------------------------------------------------
#include <generated/soc.h>
#ifndef __GENERATED_CSR_H
#define __GENERATED_CSR_H
#include <stdint.h>
#include <system.h>
#ifndef CSR_ACCESSORS_DEFINED
#include <hw/common.h>
#endif /* ! CSR_ACCESSORS_DEFINED */
#ifndef CSR_BASE
#define CSR_BASE 0x0L
#endif

/* uart */
#define CSR_UART_BASE (CSR_BASE + 0x0L)
#define CSR_UART_RXTX_ADDR (CSR_BASE + 0x0L)
#define CSR_UART_RXTX_SIZE 1
static inline uint32_t uart_rxtx_read(void) {
return csr_read_simple(CSR_BASE + 0x0L);
}
static inline void uart_rxtx_write(uint32_t v) {
csr_write_simple(v, CSR_BASE + 0x0L);
}
#define CSR_UART_TXFULL_ADDR (CSR_BASE + 0x4L)
#define CSR_UART_TXFULL_SIZE 1
static inline uint32_t uart_txfull_read(void) {
return csr_read_simple(CSR_BASE + 0x4L);
}
#define CSR_UART_RXEMPTY_ADDR (CSR_BASE + 0x8L)
#define CSR_UART_RXEMPTY_SIZE 1
static inline uint32_t uart_rxempty_read(void) {
return csr_read_simple(CSR_BASE + 0x8L);
}
#define CSR_UART_EV_STATUS_ADDR (CSR_BASE + 0xcL)
#define CSR_UART_EV_STATUS_SIZE 1
static inline uint32_t uart_ev_status_read(void) {
return csr_read_simple(CSR_BASE + 0xcL);
}
#define CSR_UART_EV_STATUS_TX_OFFSET 0
#define CSR_UART_EV_STATUS_TX_SIZE 1
static inline uint32_t uart_ev_status_tx_extract(uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t uart_ev_status_tx_read(void) {
uint32_t word = uart_ev_status_read();
return uart_ev_status_tx_extract(word);
}
#define CSR_UART_EV_STATUS_RX_OFFSET 1
#define CSR_UART_EV_STATUS_RX_SIZE 1
static inline uint32_t uart_ev_status_rx_extract(uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t uart_ev_status_rx_read(void) {
uint32_t word = uart_ev_status_read();
return uart_ev_status_rx_extract(word);
}
#define CSR_UART_EV_PENDING_ADDR (CSR_BASE + 0x10L)
#define CSR_UART_EV_PENDING_SIZE 1
static inline uint32_t uart_ev_pending_read(void) {
return csr_read_simple(CSR_BASE + 0x10L);
}
static inline void uart_ev_pending_write(uint32_t v) {
csr_write_simple(v, CSR_BASE + 0x10L);
}
#define CSR_UART_EV_PENDING_TX_OFFSET 0
#define CSR_UART_EV_PENDING_TX_SIZE 1
static inline uint32_t uart_ev_pending_tx_extract(uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t uart_ev_pending_tx_read(void) {
uint32_t word = uart_ev_pending_read();
return uart_ev_pending_tx_extract(word);
}
static inline uint32_t uart_ev_pending_tx_replace(uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void uart_ev_pending_tx_write(uint32_t plain_value) {
uint32_t oldword = uart_ev_pending_read();
uint32_t newword = uart_ev_pending_tx_replace(oldword, plain_value);
uart_ev_pending_write(newword);
}
#define CSR_UART_EV_PENDING_RX_OFFSET 1
#define CSR_UART_EV_PENDING_RX_SIZE 1
static inline uint32_t uart_ev_pending_rx_extract(uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t uart_ev_pending_rx_read(void) {
uint32_t word = uart_ev_pending_read();
return uart_ev_pending_rx_extract(word);
}
static inline uint32_t uart_ev_pending_rx_replace(uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
}
static inline void uart_ev_pending_rx_write(uint32_t plain_value) {
uint32_t oldword = uart_ev_pending_read();
uint32_t newword = uart_ev_pending_rx_replace(oldword, plain_value);
uart_ev_pending_write(newword);
}
#define CSR_UART_EV_ENABLE_ADDR (CSR_BASE + 0x14L)
#define CSR_UART_EV_ENABLE_SIZE 1
static inline uint32_t uart_ev_enable_read(void) {
return csr_read_simple(CSR_BASE + 0x14L);
}
static inline void uart_ev_enable_write(uint32_t v) {
csr_write_simple(v, CSR_BASE + 0x14L);
}
#define CSR_UART_EV_ENABLE_TX_OFFSET 0
#define CSR_UART_EV_ENABLE_TX_SIZE 1
static inline uint32_t uart_ev_enable_tx_extract(uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t uart_ev_enable_tx_read(void) {
uint32_t word = uart_ev_enable_read();
return uart_ev_enable_tx_extract(word);
}
static inline uint32_t uart_ev_enable_tx_replace(uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void uart_ev_enable_tx_write(uint32_t plain_value) {
uint32_t oldword = uart_ev_enable_read();
uint32_t newword = uart_ev_enable_tx_replace(oldword, plain_value);
uart_ev_enable_write(newword);
}
#define CSR_UART_EV_ENABLE_RX_OFFSET 1
#define CSR_UART_EV_ENABLE_RX_SIZE 1
static inline uint32_t uart_ev_enable_rx_extract(uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t uart_ev_enable_rx_read(void) {
uint32_t word = uart_ev_enable_read();
return uart_ev_enable_rx_extract(word);
}
static inline uint32_t uart_ev_enable_rx_replace(uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
}
static inline void uart_ev_enable_rx_write(uint32_t plain_value) {
uint32_t oldword = uart_ev_enable_read();
uint32_t newword = uart_ev_enable_rx_replace(oldword, plain_value);
uart_ev_enable_write(newword);
}
#define CSR_UART_TUNING_WORD_ADDR (CSR_BASE + 0x18L)
#define CSR_UART_TUNING_WORD_SIZE 1
static inline uint32_t uart_tuning_word_read(void) {
return csr_read_simple(CSR_BASE + 0x18L);
}
static inline void uart_tuning_word_write(uint32_t v) {
csr_write_simple(v, CSR_BASE + 0x18L);
}
#define CSR_UART_CONFIGURED_ADDR (CSR_BASE + 0x1cL)
#define CSR_UART_CONFIGURED_SIZE 1
static inline uint32_t uart_configured_read(void) {
return csr_read_simple(CSR_BASE + 0x1cL);
}
static inline void uart_configured_write(uint32_t v) {
csr_write_simple(v, CSR_BASE + 0x1cL);
}

/* ctrl */
#define CSR_CTRL_BASE (CSR_BASE + 0x800L)
#define CSR_CTRL_RESET_ADDR (CSR_BASE + 0x800L)
#define CSR_CTRL_RESET_SIZE 1
static inline uint32_t ctrl_reset_read(void) {
return csr_read_simple(CSR_BASE + 0x800L);
}
static inline void ctrl_reset_write(uint32_t v) {
csr_write_simple(v, CSR_BASE + 0x800L);
}
#define CSR_CTRL_RESET_SOC_RST_OFFSET 0
#define CSR_CTRL_RESET_SOC_RST_SIZE 1
static inline uint32_t ctrl_reset_soc_rst_extract(uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t ctrl_reset_soc_rst_read(void) {
uint32_t word = ctrl_reset_read();
return ctrl_reset_soc_rst_extract(word);
}
static inline uint32_t ctrl_reset_soc_rst_replace(uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void ctrl_reset_soc_rst_write(uint32_t plain_value) {
uint32_t oldword = ctrl_reset_read();
uint32_t newword = ctrl_reset_soc_rst_replace(oldword, plain_value);
ctrl_reset_write(newword);
}
#define CSR_CTRL_RESET_CPU_RST_OFFSET 1
#define CSR_CTRL_RESET_CPU_RST_SIZE 1
static inline uint32_t ctrl_reset_cpu_rst_extract(uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t ctrl_reset_cpu_rst_read(void) {
uint32_t word = ctrl_reset_read();
return ctrl_reset_cpu_rst_extract(word);
}
static inline uint32_t ctrl_reset_cpu_rst_replace(uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
}
static inline void ctrl_reset_cpu_rst_write(uint32_t plain_value) {
uint32_t oldword = ctrl_reset_read();
uint32_t newword = ctrl_reset_cpu_rst_replace(oldword, plain_value);
ctrl_reset_write(newword);
}
#define CSR_CTRL_SCRATCH_ADDR (CSR_BASE + 0x804L)
#define CSR_CTRL_SCRATCH_SIZE 1
static inline uint32_t ctrl_scratch_read(void) {
return csr_read_simple(CSR_BASE + 0x804L);
}
static inline void ctrl_scratch_write(uint32_t v) {
csr_write_simple(v, CSR_BASE + 0x804L);
}
#define CSR_CTRL_BUS_ERRORS_ADDR (CSR_BASE + 0x808L)
#define CSR_CTRL_BUS_ERRORS_SIZE 1
static inline uint32_t ctrl_bus_errors_read(void) {
return csr_read_simple(CSR_BASE + 0x808L);
}

#endif

@ -0,0 +1,9 @@
//--------------------------------------------------------------------------------
// Auto-generated by Migen (--------) & LiteX (--------) on 2022-02-07 17:23:11
//--------------------------------------------------------------------------------
#ifndef __GENERATED_GIT_H
#define __GENERATED_GIT_H

#define MIGEN_GIT_SHA1 "--------"
#define LITEX_GIT_SHA1 "--------"
#endif

@ -0,0 +1,15 @@
//--------------------------------------------------------------------------------
// Auto-generated by Migen (--------) & LiteX (--------) on 2022-02-07 17:23:11
//--------------------------------------------------------------------------------
#ifndef __GENERATED_MEM_H
#define __GENERATED_MEM_H

#ifndef CSR_BASE
#define CSR_BASE 0x00000000L
#define CSR_SIZE 0x00010000
#endif

#ifndef MEM_REGIONS
#define MEM_REGIONS "CSR 0x00000000 0x10000 "
#endif
#endif

@ -0,0 +1,40 @@
//--------------------------------------------------------------------------------
// Auto-generated by Migen (--------) & LiteX (--------) on 2022-02-07 17:23:11
//--------------------------------------------------------------------------------
#ifndef __GENERATED_SOC_H
#define __GENERATED_SOC_H
#define CONFIG_CLOCK_FREQUENCY 48000000
#define CONFIG_CPU_TYPE_NONE
#define CONFIG_CPU_VARIANT_STANDARD
#define CONFIG_CPU_HUMAN_NAME "Unknown"
#define CONFIG_CSR_DATA_WIDTH 32
#define CONFIG_CSR_ALIGNMENT 32
#define CONFIG_BUS_STANDARD "WISHBONE"
#define CONFIG_BUS_DATA_WIDTH 32
#define CONFIG_BUS_ADDRESS_WIDTH 32

#ifndef __ASSEMBLER__
static inline int config_clock_frequency_read(void) {
return 48000000;
}
static inline const char * config_cpu_human_name_read(void) {
return "Unknown";
}
static inline int config_csr_data_width_read(void) {
return 32;
}
static inline int config_csr_alignment_read(void) {
return 32;
}
static inline const char * config_bus_standard_read(void) {
return "WISHBONE";
}
static inline int config_bus_data_width_read(void) {
return 32;
}
static inline int config_bus_address_width_read(void) {
return 32;
}
#endif // !__ASSEMBLER__

#endif
Loading…
Cancel
Save