Skip to content

Commit

Permalink
valentyusb: Add USB UART to SOC and OrangeCrab
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mkj committed Feb 10, 2022
1 parent 5a2e535 commit f32b16b
Show file tree
Hide file tree
Showing 17 changed files with 5,067 additions and 7 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 12 additions & 0 deletions fpga/top-orangecrab0.2.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
7 changes: 6 additions & 1 deletion include/microwatt_soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -26,6 +29,7 @@
*/
#define IRQ_UART0 0
#define IRQ_ETHERNET 1
#define IRQ_UARTUSB 5

/*
* Register definitions for the syscon registers
Expand All @@ -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
Expand Down
105 changes: 100 additions & 5 deletions soc.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -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 (**)
Expand All @@ -50,6 +51,7 @@ use work.wishbone_types.all;
-- 2 : UART1
-- 3 : SD card
-- 4 : GPIO
-- 5 : UARTUSB

entity soc is
generic (
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -242,6 +256,7 @@ architecture behaviour of soc is
SLAVE_IO_SPI_FLASH_REG,
SLAVE_IO_SPI_FLASH_MAP,
SLAVE_IO_GPIO,
SLAVE_IO_UARTUSB,
SLAVE_IO_EXTERNAL,
SLAVE_IO_NONE);
signal slave_io_dbg : slave_io_type;
Expand Down Expand Up @@ -302,6 +317,7 @@ architecture behaviour of soc is
);
end component;

constant UART0_IS_POTATO : boolean := not UART0_IS_16550;
begin

resets: process(system_clk)
Expand Down Expand Up @@ -594,7 +610,7 @@ begin
--
slave_io_intercon: process(wb_sio_out, wb_syscon_out, wb_uart0_out, wb_uart1_out,
wb_ext_io_out, wb_xics_icp_out, wb_xics_ics_out,
wb_spiflash_out)
wb_spiflash_out, wb_uartusb_out)
variable slave_io : slave_io_type;

variable match : std_ulogic_vector(31 downto 12);
Expand Down Expand Up @@ -624,6 +640,8 @@ begin
slave_io := SLAVE_IO_SPI_FLASH_REG;
elsif std_match(match, x"C0007") then
slave_io := SLAVE_IO_GPIO;
elsif std_match(match, x"C0008") then
slave_io := SLAVE_IO_UARTUSB;
end if;
slave_io_dbg <= slave_io;
wb_uart0_in <= wb_sio_out;
Expand All @@ -637,6 +655,12 @@ begin
wb_gpio_in <= wb_sio_out;
wb_gpio_in.cyc <= '0';

wb_uartusb_in <= wb_sio_out;
wb_uartusb_in.cyc <= '0';
-- 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');
Expand Down Expand Up @@ -708,6 +732,9 @@ begin
when SLAVE_IO_UART1 =>
wb_uart1_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_uart1_out;
when SLAVE_IO_UARTUSB =>
wb_uartusb_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_uartusb_out;
when SLAVE_IO_SPI_FLASH_MAP =>
-- Clear top bits so they don't make their way to the
-- fash chip.
Expand Down Expand Up @@ -741,7 +768,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,
Expand All @@ -758,7 +786,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
Expand All @@ -777,6 +805,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
Expand Down Expand Up @@ -811,10 +842,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
Expand Down Expand Up @@ -942,6 +1036,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
Expand Down
7 changes: 6 additions & 1 deletion syscon.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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));
Expand Down
Loading

0 comments on commit f32b16b

Please sign in to comment.