mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-28 12:39:16 +00:00
uart: Import and hook up opencore 16550 compatible UART
This imports via fusesoc a 16550 compatible (ie "standard") UART, and wires it up optionally in the SoC instead of the potato one. This also adds support for a second UART (which is always a 16550) to Arty, wired to JC "bottom" port. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
@@ -13,10 +13,10 @@ set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart_mai
|
||||
# Pmod Header JC: UART (bottom)
|
||||
################################################################################
|
||||
|
||||
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_cts_n }];
|
||||
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_tx }];
|
||||
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_rx }];
|
||||
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_rts_n }];
|
||||
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_cts_n }];
|
||||
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_tx }];
|
||||
set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_rx }];
|
||||
set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_rts_n }];
|
||||
|
||||
################################################################################
|
||||
# RGB LEDs
|
||||
|
||||
@@ -22,7 +22,9 @@ entity toplevel is
|
||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
||||
LOG_LENGTH : natural := 512;
|
||||
USE_LITEETH : boolean := false
|
||||
USE_LITEETH : boolean := false;
|
||||
UART_IS_16550 : boolean := false;
|
||||
HAS_UART1 : boolean := false
|
||||
);
|
||||
port(
|
||||
ext_clk : in std_ulogic;
|
||||
@@ -32,6 +34,12 @@ entity toplevel is
|
||||
uart_main_tx : out std_ulogic;
|
||||
uart_main_rx : in std_ulogic;
|
||||
|
||||
-- UART1 signals:
|
||||
uart_pmod_tx : out std_ulogic;
|
||||
uart_pmod_rx : in std_ulogic;
|
||||
uart_pmod_cts_n : in std_ulogic;
|
||||
uart_pmod_rts_n : out std_ulogic;
|
||||
|
||||
-- LEDs
|
||||
led0_b : out std_ulogic;
|
||||
led0_g : out std_ulogic;
|
||||
@@ -170,7 +178,9 @@ begin
|
||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
||||
LOG_LENGTH => LOG_LENGTH,
|
||||
USE_LITEETH => USE_LITEETH
|
||||
HAS_LITEETH => USE_LITEETH,
|
||||
UART0_IS_16550 => UART_IS_16550,
|
||||
HAS_UART1 => HAS_UART1
|
||||
)
|
||||
port map (
|
||||
-- System signals
|
||||
@@ -181,6 +191,10 @@ begin
|
||||
uart0_txd => uart_main_tx,
|
||||
uart0_rxd => uart_main_rx,
|
||||
|
||||
-- UART1 signals
|
||||
uart1_txd => uart_pmod_tx,
|
||||
uart1_rxd => uart_pmod_rx,
|
||||
|
||||
-- SPI signals
|
||||
spi_flash_sck => spi_sck,
|
||||
spi_flash_cs_n => spi_cs_n,
|
||||
@@ -202,6 +216,8 @@ begin
|
||||
alt_reset => core_alt_reset
|
||||
);
|
||||
|
||||
uart_pmod_rts_n <= '0';
|
||||
|
||||
-- SPI Flash
|
||||
--
|
||||
-- Note: Unlike many other boards, the SPI flash on the Arty has
|
||||
|
||||
@@ -11,7 +11,8 @@ entity toplevel is
|
||||
RESET_LOW : boolean := true;
|
||||
CLK_INPUT : positive := 100000000;
|
||||
CLK_FREQUENCY : positive := 100000000;
|
||||
DISABLE_FLATTEN_CORE : boolean := false
|
||||
DISABLE_FLATTEN_CORE : boolean := false;
|
||||
UART_IS_16550 : boolean := false
|
||||
);
|
||||
port(
|
||||
ext_clk : in std_ulogic;
|
||||
@@ -67,7 +68,8 @@ begin
|
||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
||||
SIM => false,
|
||||
CLK_FREQ => CLK_FREQUENCY,
|
||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
|
||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
|
||||
UART0_IS_16550 => UART_IS_16550
|
||||
)
|
||||
port map (
|
||||
system_clk => system_clk,
|
||||
|
||||
@@ -19,7 +19,8 @@ entity toplevel is
|
||||
DISABLE_FLATTEN_CORE : boolean := false;
|
||||
SPI_FLASH_OFFSET : integer := 10485760;
|
||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
||||
SPI_FLASH_DEF_QUAD : boolean := true
|
||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
||||
UART_IS_16550 : boolean := false;
|
||||
);
|
||||
port(
|
||||
ext_clk : in std_ulogic;
|
||||
@@ -126,7 +127,8 @@ begin
|
||||
SPI_FLASH_DLINES => 4,
|
||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD
|
||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
||||
UART0_IS_16550 => UART_IS_16550
|
||||
)
|
||||
port map (
|
||||
-- System signals
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#define SYS_REG_INFO_HAS_BRAM (1ull << 2)
|
||||
#define SYS_REG_INFO_HAS_SPI_FLASH (1ull << 3)
|
||||
#define SYS_REG_INFO_HAS_LITEETH (1ull << 4)
|
||||
#define SYS_REG_INFO_HAS_LARGE_SYSCON (1ull << 5)
|
||||
#define SYS_REG_INFO_HAS_UART1 (1ull << 6)
|
||||
#define SYS_REG_BRAMINFO 0x10
|
||||
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
|
||||
#define SYS_REG_DRAMINFO 0x18
|
||||
@@ -50,7 +52,9 @@
|
||||
#define SYS_REG_DRAMINITINFO 0x30
|
||||
#define SYS_REG_SPI_INFO 0x38
|
||||
#define SYS_REG_SPI_INFO_FLASH_OFF_MASK 0xffffffff
|
||||
|
||||
#define SYS_REG_UART0_INFO 0x40
|
||||
#define SYS_REG_UART1_INFO 0x48
|
||||
#define SYS_REG_UART_IS_16550 (1ull << 32)
|
||||
|
||||
|
||||
/*
|
||||
@@ -66,6 +70,53 @@
|
||||
#define POTATO_CONSOLE_CLOCK_DIV 0x18
|
||||
#define POTATO_CONSOLE_IRQ_EN 0x20
|
||||
|
||||
/*
|
||||
* Register definitionss for our standard (16550 style) UART
|
||||
*/
|
||||
#define UART_REG_RX 0x00
|
||||
#define UART_REG_TX 0x00
|
||||
#define UART_REG_DLL 0x00
|
||||
#define UART_REG_IER 0x04
|
||||
#define UART_REG_DLM 0x04
|
||||
#define UART_REG_IIR 0x08
|
||||
#define UART_REG_FCR 0x08
|
||||
#define UART_REG_FCR_EN_FIFO 0x01
|
||||
#define UART_REG_FCR_CLR_RCVR 0x02
|
||||
#define UART_REG_FCR_CLR_XMIT 0x04
|
||||
#define UART_REG_FCR_TRIG1 0x00
|
||||
#define UART_REG_FCR_TRIG4 0x40
|
||||
#define UART_REG_FCR_TRIG8 0x80
|
||||
#define UART_REG_FCR_TRIG14 0xc0
|
||||
#define UART_REG_LCR 0x0c
|
||||
#define UART_REG_LCR_5BIT 0x00
|
||||
#define UART_REG_LCR_6BIT 0x01
|
||||
#define UART_REG_LCR_7BIT 0x02
|
||||
#define UART_REG_LCR_8BIT 0x03
|
||||
#define UART_REG_LCR_STOP 0x04
|
||||
#define UART_REG_LCR_PAR 0x08
|
||||
#define UART_REG_LCR_EVEN_PAR 0x10
|
||||
#define UART_REG_LCR_STIC_PAR 0x20
|
||||
#define UART_REG_LCR_BREAK 0x40
|
||||
#define UART_REG_LCR_DLAB 0x80
|
||||
#define UART_REG_MCR 0x10
|
||||
#define UART_REG_MCR_DTR 0x01
|
||||
#define UART_REG_MCR_RTS 0x02
|
||||
#define UART_REG_MCR_OUT1 0x04
|
||||
#define UART_REG_MCR_OUT2 0x08
|
||||
#define UART_REG_MCR_LOOP 0x10
|
||||
#define UART_REG_LSR 0x14
|
||||
#define UART_REG_LSR_DR 0x01
|
||||
#define UART_REG_LSR_OE 0x02
|
||||
#define UART_REG_LSR_PE 0x04
|
||||
#define UART_REG_LSR_FE 0x08
|
||||
#define UART_REG_LSR_BI 0x10
|
||||
#define UART_REG_LSR_THRE 0x20
|
||||
#define UART_REG_LSR_TEMT 0x40
|
||||
#define UART_REG_LSR_FIFOE 0x80
|
||||
#define UART_REG_MSR 0x18
|
||||
#define UART_REG_SCR 0x1c
|
||||
|
||||
|
||||
/*
|
||||
* Register definitions for the SPI controller
|
||||
*/
|
||||
|
||||
@@ -103,10 +103,13 @@ filesets:
|
||||
liteeth:
|
||||
depend : [":microwatt:liteeth"]
|
||||
|
||||
uart16550:
|
||||
depend : ["::uart16550"]
|
||||
|
||||
targets:
|
||||
nexys_a7:
|
||||
default_tool: vivado
|
||||
filesets: [core, nexys_a7, soc, fpga, debug_xilinx, xilinx_specific]
|
||||
filesets: [core, nexys_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -114,13 +117,15 @@ targets:
|
||||
- clk_frequency
|
||||
- disable_flatten_core
|
||||
- log_length=2048
|
||||
- uart_is_16550
|
||||
- has_uart1
|
||||
tools:
|
||||
vivado: {part : xc7a100tcsg324-1}
|
||||
toplevel : toplevel
|
||||
|
||||
nexys_video-nodram:
|
||||
default_tool: vivado
|
||||
filesets: [core, nexys_video, soc, fpga, debug_xilinx, xilinx_specific]
|
||||
filesets: [core, nexys_video, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -129,13 +134,15 @@ targets:
|
||||
- disable_flatten_core
|
||||
- spi_flash_offset=10485760
|
||||
- log_length=2048
|
||||
- uart_is_16550
|
||||
- has_uart1
|
||||
tools:
|
||||
vivado: {part : xc7a200tsbg484-1}
|
||||
toplevel : toplevel
|
||||
|
||||
nexys_video:
|
||||
default_tool: vivado
|
||||
filesets: [core, nexys_video, soc, fpga, debug_xilinx, litedram, xilinx_specific]
|
||||
filesets: [core, nexys_video, soc, fpga, debug_xilinx, litedram, uart16550, xilinx_specific]
|
||||
parameters:
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -151,7 +158,7 @@ targets:
|
||||
|
||||
arty_a7-35-nodram:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -160,13 +167,15 @@ targets:
|
||||
- disable_flatten_core
|
||||
- spi_flash_offset=3145728
|
||||
- log_length=512
|
||||
- uart_is_16550
|
||||
- has_uart1
|
||||
tools:
|
||||
vivado: {part : xc7a35ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
|
||||
arty_a7-35:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -176,6 +185,8 @@ targets:
|
||||
- no_bram
|
||||
- spi_flash_offset=3145728
|
||||
- log_length=512
|
||||
- uart_is_16550
|
||||
- has_uart1
|
||||
generate: [litedram_arty, liteeth_arty]
|
||||
tools:
|
||||
vivado: {part : xc7a35ticsg324-1L}
|
||||
@@ -183,7 +194,7 @@ targets:
|
||||
|
||||
arty_a7-100-nodram:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -192,13 +203,15 @@ targets:
|
||||
- disable_flatten_core
|
||||
- spi_flash_offset=4194304
|
||||
- log_length=2048
|
||||
- uart_is_16550
|
||||
- has_uart1
|
||||
tools:
|
||||
vivado: {part : xc7a100ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
|
||||
arty_a7-100:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific]
|
||||
parameters:
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -208,6 +221,8 @@ targets:
|
||||
- no_bram
|
||||
- spi_flash_offset=4194304
|
||||
- log_length=2048
|
||||
- uart_is_16550
|
||||
- has_uart1
|
||||
generate: [litedram_arty, liteeth_arty]
|
||||
tools:
|
||||
vivado: {part : xc7a100ticsg324-1L}
|
||||
@@ -215,7 +230,7 @@ targets:
|
||||
|
||||
cmod_a7-35:
|
||||
default_tool: vivado
|
||||
filesets: [core, cmod_a7-35, soc, fpga, debug_xilinx, xilinx_specific]
|
||||
filesets: [core, cmod_a7-35, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -224,6 +239,8 @@ targets:
|
||||
- clk_frequency
|
||||
- disable_flatten_core
|
||||
- log_length=512
|
||||
- uart_is_16550
|
||||
- has_uart1
|
||||
tools:
|
||||
vivado: {part : xc7a35tcpg236-1}
|
||||
toplevel : toplevel
|
||||
@@ -294,6 +311,18 @@ parameters:
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
uart_is_16550:
|
||||
datatype : bool
|
||||
description : Use 16550-compatible UART from OpenCores
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
has_uart1:
|
||||
datatype : bool
|
||||
description : Enable second UART (always 16550-compatible)
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
no_bram:
|
||||
datatype : bool
|
||||
description : No internal block RAM (only DRAM and init code carrying payload)
|
||||
|
||||
179
soc.vhdl
179
soc.vhdl
@@ -20,6 +20,7 @@ use work.wishbone_types.all;
|
||||
-- IO Bus:
|
||||
-- 0xc0000000: SYSCON
|
||||
-- 0xc0002000: UART0
|
||||
-- 0xc0003000: UART1 (if any)
|
||||
-- 0xc0004000: XICS ICP
|
||||
-- 0xc0005000: XICS ICS
|
||||
-- 0xc0006000: SPI Flash controller
|
||||
@@ -61,7 +62,9 @@ entity soc is
|
||||
SPI_FLASH_DEF_CKDV : natural := 2;
|
||||
SPI_FLASH_DEF_QUAD : boolean := false;
|
||||
LOG_LENGTH : natural := 512;
|
||||
HAS_LITEETH : boolean := false
|
||||
HAS_LITEETH : boolean := false;
|
||||
UART0_IS_16550 : boolean := false;
|
||||
HAS_UART1 : boolean := false
|
||||
);
|
||||
port(
|
||||
rst : in std_ulogic;
|
||||
@@ -85,6 +88,10 @@ entity soc is
|
||||
uart0_txd : out std_ulogic;
|
||||
uart0_rxd : in std_ulogic := '0';
|
||||
|
||||
-- UART1 signals:
|
||||
uart1_txd : out std_ulogic;
|
||||
uart1_rxd : in std_ulogic := '0';
|
||||
|
||||
-- SPI Flash signals
|
||||
spi_flash_sck : out std_ulogic;
|
||||
spi_flash_cs_n : out std_ulogic;
|
||||
@@ -137,6 +144,12 @@ architecture behaviour of soc is
|
||||
signal uart0_dat8 : std_ulogic_vector(7 downto 0);
|
||||
signal uart0_irq : std_ulogic;
|
||||
|
||||
-- UART1 signals:
|
||||
signal wb_uart1_in : wb_io_master_out;
|
||||
signal wb_uart1_out : wb_io_slave_out;
|
||||
signal uart1_dat8 : std_ulogic_vector(7 downto 0);
|
||||
signal uart1_irq : std_ulogic;
|
||||
|
||||
-- SPI Flash controller signals:
|
||||
signal wb_spiflash_in : wb_io_master_out;
|
||||
signal wb_spiflash_out : wb_io_slave_out;
|
||||
@@ -188,12 +201,37 @@ architecture behaviour of soc is
|
||||
SLAVE_IO_UART,
|
||||
SLAVE_IO_ICP,
|
||||
SLAVE_IO_ICS,
|
||||
SLAVE_IO_UART1,
|
||||
SLAVE_IO_SPI_FLASH_REG,
|
||||
SLAVE_IO_SPI_FLASH_MAP,
|
||||
SLAVE_IO_EXTERNAL,
|
||||
SLAVE_IO_NONE);
|
||||
signal slave_io_dbg : slave_io_type;
|
||||
|
||||
-- This is the component exported by the 16550 compatible
|
||||
-- UART from FuseSoC.
|
||||
--
|
||||
component uart_top port (
|
||||
wb_clk_i : in std_ulogic;
|
||||
wb_rst_i : in std_ulogic;
|
||||
wb_adr_i : in std_ulogic_vector(2 downto 0);
|
||||
wb_dat_i : in std_ulogic_vector(7 downto 0);
|
||||
wb_dat_o : out std_ulogic_vector(7 downto 0);
|
||||
wb_we_i : in std_ulogic;
|
||||
wb_stb_i : in std_ulogic;
|
||||
wb_cyc_i : in std_ulogic;
|
||||
wb_ack_o : out std_ulogic;
|
||||
int_o : out std_ulogic;
|
||||
stx_pad_o : out std_ulogic;
|
||||
srx_pad_i : in std_ulogic;
|
||||
rts_pad_o : out std_ulogic;
|
||||
cts_pad_i : in std_ulogic;
|
||||
dtr_pad_o : out std_ulogic;
|
||||
dsr_pad_i : in std_ulogic;
|
||||
ri_pad_i : in std_ulogic;
|
||||
dcd_pad_i : in std_ulogic
|
||||
);
|
||||
end component;
|
||||
begin
|
||||
|
||||
resets: process(system_clk)
|
||||
@@ -458,7 +496,7 @@ begin
|
||||
|
||||
-- IO wishbone slave intercon.
|
||||
--
|
||||
slave_io_intercon: process(wb_sio_out, wb_syscon_out, wb_uart0_out,
|
||||
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)
|
||||
variable slave_io : slave_io_type;
|
||||
@@ -478,6 +516,8 @@ begin
|
||||
slave_io := SLAVE_IO_SYSCON;
|
||||
elsif std_match(match, x"C0002") then
|
||||
slave_io := SLAVE_IO_UART;
|
||||
elsif std_match(match, x"C0003") then
|
||||
slave_io := SLAVE_IO_UART1;
|
||||
elsif std_match(match, x"C8---") then
|
||||
slave_io := SLAVE_IO_EXTERNAL;
|
||||
elsif std_match(match, x"C0004") then
|
||||
@@ -490,6 +530,8 @@ begin
|
||||
slave_io_dbg <= slave_io;
|
||||
wb_uart0_in <= wb_sio_out;
|
||||
wb_uart0_in.cyc <= '0';
|
||||
wb_uart1_in <= wb_sio_out;
|
||||
wb_uart1_in.cyc <= '0';
|
||||
wb_spiflash_in <= wb_sio_out;
|
||||
wb_spiflash_in.cyc <= '0';
|
||||
wb_spiflash_is_reg <= '0';
|
||||
@@ -559,6 +601,9 @@ begin
|
||||
when SLAVE_IO_ICS =>
|
||||
wb_xics_ics_in.cyc <= wb_sio_out.cyc;
|
||||
wb_sio_in <= wb_xics_ics_out;
|
||||
when SLAVE_IO_UART1 =>
|
||||
wb_uart1_in.cyc <= wb_sio_out.cyc;
|
||||
wb_sio_in <= wb_uart1_out;
|
||||
when SLAVE_IO_SPI_FLASH_MAP =>
|
||||
-- Clear top bits so they don't make their way to the
|
||||
-- fash chip.
|
||||
@@ -586,7 +631,9 @@ begin
|
||||
CLK_FREQ => CLK_FREQ,
|
||||
HAS_SPI_FLASH => HAS_SPI_FLASH,
|
||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
||||
HAS_LITEETH => HAS_LITEETH
|
||||
HAS_LITEETH => HAS_LITEETH,
|
||||
UART0_IS_16550 => UART0_IS_16550,
|
||||
HAS_UART1 => HAS_UART1
|
||||
)
|
||||
port map(
|
||||
clk => system_clk,
|
||||
@@ -598,30 +645,115 @@ begin
|
||||
soc_reset => open -- XXX TODO
|
||||
);
|
||||
|
||||
-- Simulated memory and UART
|
||||
--
|
||||
-- UART0
|
||||
--
|
||||
-- Either potato (legacy) or 16550
|
||||
--
|
||||
uart0_pp: if not UART0_IS_16550 generate
|
||||
uart0: entity work.pp_soc_uart
|
||||
generic map(
|
||||
FIFO_DEPTH => 32
|
||||
)
|
||||
port map(
|
||||
clk => system_clk,
|
||||
reset => rst_uart,
|
||||
txd => uart0_txd,
|
||||
rxd => uart0_rxd,
|
||||
irq => uart0_irq,
|
||||
wb_adr_in => wb_uart0_in.adr(11 downto 0),
|
||||
wb_dat_in => wb_uart0_in.dat(7 downto 0),
|
||||
wb_dat_out => uart0_dat8,
|
||||
wb_cyc_in => wb_uart0_in.cyc,
|
||||
wb_stb_in => wb_uart0_in.stb,
|
||||
wb_we_in => wb_uart0_in.we,
|
||||
wb_ack_out => wb_uart0_out.ack
|
||||
);
|
||||
end generate;
|
||||
|
||||
uart0_16550 : if UART0_IS_16550 generate
|
||||
signal irq_l : std_ulogic;
|
||||
begin
|
||||
uart0: uart_top
|
||||
port map (
|
||||
wb_clk_i => system_clk,
|
||||
wb_rst_i => rst_uart,
|
||||
wb_adr_i => wb_uart0_in.adr(4 downto 2),
|
||||
wb_dat_i => wb_uart0_in.dat(7 downto 0),
|
||||
wb_dat_o => uart0_dat8,
|
||||
wb_we_i => wb_uart0_in.we,
|
||||
wb_stb_i => wb_uart0_in.stb,
|
||||
wb_cyc_i => wb_uart0_in.cyc,
|
||||
wb_ack_o => wb_uart0_out.ack,
|
||||
int_o => irq_l,
|
||||
stx_pad_o => uart0_txd,
|
||||
srx_pad_i => uart0_rxd,
|
||||
rts_pad_o => open,
|
||||
cts_pad_i => '1',
|
||||
dtr_pad_o => open,
|
||||
dsr_pad_i => '1',
|
||||
ri_pad_i => '0',
|
||||
dcd_pad_i => '1'
|
||||
);
|
||||
|
||||
-- Add a register on the irq out, helps timing
|
||||
uart0_irq_latch: process(system_clk)
|
||||
begin
|
||||
if rising_edge(system_clk) then
|
||||
uart0_irq <= irq_l;
|
||||
end if;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
-- UART0 wishbone slave
|
||||
uart0: entity work.pp_soc_uart
|
||||
generic map(
|
||||
FIFO_DEPTH => 32
|
||||
)
|
||||
port map(
|
||||
clk => system_clk,
|
||||
reset => rst_uart,
|
||||
txd => uart0_txd,
|
||||
rxd => uart0_rxd,
|
||||
irq => uart0_irq,
|
||||
wb_adr_in => wb_uart0_in.adr(11 downto 0),
|
||||
wb_dat_in => wb_uart0_in.dat(7 downto 0),
|
||||
wb_dat_out => uart0_dat8,
|
||||
wb_cyc_in => wb_uart0_in.cyc,
|
||||
wb_stb_in => wb_uart0_in.stb,
|
||||
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;
|
||||
|
||||
--
|
||||
-- UART1
|
||||
--
|
||||
-- Always 16550 if it exists
|
||||
--
|
||||
uart1: if HAS_UART1 generate
|
||||
signal irq_l : std_ulogic;
|
||||
begin
|
||||
uart1: uart_top
|
||||
port map (
|
||||
wb_clk_i => system_clk,
|
||||
wb_rst_i => rst_uart,
|
||||
wb_adr_i => wb_uart1_in.adr(4 downto 2),
|
||||
wb_dat_i => wb_uart1_in.dat(7 downto 0),
|
||||
wb_dat_o => uart1_dat8,
|
||||
wb_we_i => wb_uart1_in.we,
|
||||
wb_stb_i => wb_uart1_in.stb,
|
||||
wb_cyc_i => wb_uart1_in.cyc,
|
||||
wb_ack_o => wb_uart1_out.ack,
|
||||
int_o => irq_l,
|
||||
stx_pad_o => uart1_txd,
|
||||
srx_pad_i => uart1_rxd,
|
||||
rts_pad_o => open,
|
||||
cts_pad_i => '1',
|
||||
dtr_pad_o => open,
|
||||
dsr_pad_i => '1',
|
||||
ri_pad_i => '0',
|
||||
dcd_pad_i => '1'
|
||||
);
|
||||
-- Add a register on the irq out, helps timing
|
||||
uart0_irq_latch: process(system_clk)
|
||||
begin
|
||||
if rising_edge(system_clk) then
|
||||
uart1_irq <= irq_l;
|
||||
end if;
|
||||
end process;
|
||||
wb_uart1_out.dat <= x"000000" & uart1_dat8;
|
||||
wb_uart1_out.stall <= not wb_uart1_out.ack;
|
||||
end generate;
|
||||
|
||||
no_uart1 : if not HAS_UART1 generate
|
||||
wb_uart1_out.dat <= x"00000000";
|
||||
wb_uart1_out.ack <= wb_uart1_in.cyc and wb_uart1_in.stb;
|
||||
wb_uart1_out.stall <= '0';
|
||||
end generate;
|
||||
|
||||
spiflash_gen: if HAS_SPI_FLASH generate
|
||||
spiflash: entity work.spi_flash_ctrl
|
||||
generic map (
|
||||
@@ -680,6 +812,7 @@ begin
|
||||
int_level_in <= (others => '0');
|
||||
int_level_in(0) <= uart0_irq;
|
||||
int_level_in(1) <= ext_irq_eth;
|
||||
int_level_in(2) <= uart1_irq;
|
||||
end process;
|
||||
|
||||
-- BRAM Memory slave
|
||||
|
||||
62
syscon.vhdl
62
syscon.vhdl
@@ -17,7 +17,9 @@ entity syscon is
|
||||
DRAM_INIT_SIZE : integer;
|
||||
HAS_SPI_FLASH : boolean;
|
||||
SPI_FLASH_OFFSET : integer;
|
||||
HAS_LITEETH : boolean
|
||||
HAS_LITEETH : boolean;
|
||||
UART0_IS_16550 : boolean;
|
||||
HAS_UART1 : boolean
|
||||
);
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
@@ -37,27 +39,31 @@ end entity syscon;
|
||||
|
||||
architecture behaviour of syscon is
|
||||
-- Register address bits
|
||||
constant SYS_REG_BITS : positive := 3;
|
||||
constant SYS_REG_BITS : positive := 6;
|
||||
|
||||
-- Register addresses (matches wishbone addr downto 3, ie, 8 bytes per reg)
|
||||
constant SYS_REG_SIG : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000";
|
||||
constant SYS_REG_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001";
|
||||
constant SYS_REG_BRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "010";
|
||||
constant SYS_REG_DRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "011";
|
||||
constant SYS_REG_CLKINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "100";
|
||||
constant SYS_REG_CTRL : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "101";
|
||||
constant SYS_REG_DRAMINITINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "110";
|
||||
constant SYS_REG_SPIFLASHINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "111";
|
||||
constant SYS_REG_SIG : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000000";
|
||||
constant SYS_REG_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000001";
|
||||
constant SYS_REG_BRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000010";
|
||||
constant SYS_REG_DRAMINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000011";
|
||||
constant SYS_REG_CLKINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000100";
|
||||
constant SYS_REG_CTRL : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000101";
|
||||
constant SYS_REG_DRAMINITINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000110";
|
||||
constant SYS_REG_SPIFLASHINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "000111";
|
||||
constant SYS_REG_UART0_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001000";
|
||||
constant SYS_REG_UART1_INFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "001001";
|
||||
|
||||
-- Muxed reg read signal
|
||||
signal reg_out : std_ulogic_vector(63 downto 0);
|
||||
|
||||
-- INFO register bits
|
||||
constant SYS_REG_INFO_HAS_UART : integer := 0;
|
||||
constant SYS_REG_INFO_HAS_DRAM : integer := 1;
|
||||
constant SYS_REG_INFO_HAS_BRAM : integer := 2;
|
||||
constant SYS_REG_INFO_HAS_SPIF : integer := 3;
|
||||
constant SYS_REG_INFO_HAS_LETH : integer := 4;
|
||||
constant SYS_REG_INFO_HAS_UART : integer := 0; -- Has a UART (always set)
|
||||
constant SYS_REG_INFO_HAS_DRAM : integer := 1; -- Has DRAM
|
||||
constant SYS_REG_INFO_HAS_BRAM : integer := 2; -- Has "main" BRAM
|
||||
constant SYS_REG_INFO_HAS_SPIF : integer := 3; -- Has SPI flash
|
||||
constant SYS_REG_INFO_HAS_LETH : integer := 4; -- Has LiteEth ethernet
|
||||
constant SYS_REG_INFO_HAS_LSYS : integer := 5; -- Has 6-bit address syscon
|
||||
constant SYS_REG_INFO_HAS_URT1 : integer := 6; -- Has second UART
|
||||
|
||||
-- BRAMINFO contains the BRAM size in the bottom 52 bits
|
||||
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
|
||||
@@ -76,6 +82,12 @@ architecture behaviour of syscon is
|
||||
-- reserved for the FPGA bitfile if any
|
||||
constant SYS_REG_SPI_INFO_IS_FLASH : integer := 0;
|
||||
|
||||
-- UART0/1 info registers bits
|
||||
--
|
||||
-- 0 ..31 : UART clock freq (in HZ)
|
||||
-- 32 : UART is 16550 (otherwise pp)
|
||||
--
|
||||
|
||||
-- Ctrl register
|
||||
signal reg_ctrl : std_ulogic_vector(SYS_REG_CTRL_BITS-1 downto 0);
|
||||
signal reg_ctrl_out : std_ulogic_vector(63 downto 0);
|
||||
@@ -87,13 +99,18 @@ architecture behaviour of syscon is
|
||||
signal reg_dramiinfo : std_ulogic_vector(63 downto 0);
|
||||
signal reg_clkinfo : std_ulogic_vector(63 downto 0);
|
||||
signal reg_spiinfo : std_ulogic_vector(63 downto 0);
|
||||
signal reg_uart0info : std_ulogic_vector(63 downto 0);
|
||||
signal reg_uart1info : std_ulogic_vector(63 downto 0);
|
||||
signal info_has_dram : std_ulogic;
|
||||
signal info_has_bram : std_ulogic;
|
||||
signal info_has_uart : std_ulogic;
|
||||
signal info_has_spif : std_ulogic;
|
||||
signal info_has_leth : std_ulogic;
|
||||
signal info_has_urt1 : 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;
|
||||
signal uinfo_freq : std_ulogic_vector(31 downto 0);
|
||||
|
||||
-- Wishbone response latch
|
||||
signal wb_rsp : wb_io_slave_out;
|
||||
@@ -110,12 +127,15 @@ begin
|
||||
info_has_bram <= '1' when BRAM_SIZE /= 0 else '0';
|
||||
info_has_spif <= '1' when HAS_SPI_FLASH else '0';
|
||||
info_has_leth <= '1' when HAS_LITEETH else '0';
|
||||
info_has_urt1 <= '1' when HAS_UART1 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,
|
||||
SYS_REG_INFO_HAS_BRAM => info_has_bram,
|
||||
SYS_REG_INFO_HAS_SPIF => info_has_spif,
|
||||
SYS_REG_INFO_HAS_LETH => info_has_leth,
|
||||
SYS_REG_INFO_HAS_LSYS => '1',
|
||||
SYS_REG_INFO_HAS_URT1 => info_has_urt1,
|
||||
others => '0');
|
||||
|
||||
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
|
||||
@@ -133,6 +153,16 @@ begin
|
||||
reg_ctrl_out <= (63 downto SYS_REG_CTRL_BITS => '0',
|
||||
SYS_REG_CTRL_BITS-1 downto 0 => reg_ctrl);
|
||||
|
||||
-- UART info registers read composition
|
||||
uinfo_16550 <= '1' when UART0_IS_16550 else '0';
|
||||
uinfo_freq <= std_ulogic_vector(to_unsigned(CLK_FREQ, 32));
|
||||
reg_uart0info <= (32 => uinfo_16550,
|
||||
31 downto 0 => uinfo_freq,
|
||||
others => '0');
|
||||
reg_uart1info <= (32 => '1',
|
||||
31 downto 0 => uinfo_freq,
|
||||
others => '0');
|
||||
|
||||
-- Wishbone response
|
||||
wb_rsp.ack <= wishbone_in.cyc and wishbone_in.stb;
|
||||
with wishbone_in.adr(SYS_REG_BITS+2 downto 3) select reg_out <=
|
||||
@@ -144,6 +174,8 @@ begin
|
||||
reg_clkinfo when SYS_REG_CLKINFO,
|
||||
reg_ctrl_out when SYS_REG_CTRL,
|
||||
reg_spiinfo when SYS_REG_SPIFLASHINFO,
|
||||
reg_uart0info when SYS_REG_UART0_INFO,
|
||||
reg_uart1info when SYS_REG_UART1_INFO,
|
||||
(others => '0') when others;
|
||||
wb_rsp.dat <= reg_out(63 downto 32) when wishbone_in.adr(2) = '1' else
|
||||
reg_out(31 downto 0);
|
||||
|
||||
Reference in New Issue
Block a user