# 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
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;
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;
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
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,
alt_reset => core_alt_reset
);
+ uart_pmod_rts_n <= '0';
+
-- SPI Flash
--
-- Note: Unlike many other boards, the SPI flash on the Arty has
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;
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,
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;
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
#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
#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)
/*
#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
*/
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
- 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
- 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
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
- 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
- no_bram
- spi_flash_offset=3145728
- log_length=512
+ - uart_is_16550
+ - has_uart1
generate: [litedram_arty, liteeth_arty]
tools:
vivado: {part : xc7a35ticsg324-1L}
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
- 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
- no_bram
- spi_flash_offset=4194304
- log_length=2048
+ - uart_is_16550
+ - has_uart1
generate: [litedram_arty, liteeth_arty]
tools:
vivado: {part : xc7a100ticsg324-1L}
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
- clk_frequency
- disable_flatten_core
- log_length=512
+ - uart_is_16550
+ - has_uart1
tools:
vivado: {part : xc7a35tcpg236-1}
toplevel : toplevel
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)
-- IO Bus:
-- 0xc0000000: SYSCON
-- 0xc0002000: UART0
+-- 0xc0003000: UART1 (if any)
-- 0xc0004000: XICS ICP
-- 0xc0005000: XICS ICS
-- 0xc0006000: SPI Flash controller
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;
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;
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;
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)
-- 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;
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
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';
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.
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,
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 (
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
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;
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
-- 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);
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;
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));
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 <=
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);