|
|
|
@ -22,15 +22,25 @@ use work.wishbone_types.all;
|
|
|
|
|
-- 0xc0002000: UART0
|
|
|
|
|
-- 0xc0004000: XICS ICP
|
|
|
|
|
-- 0xc0006000: SPI Flash controller
|
|
|
|
|
-- 0xc0100000: LiteDRAM control (CSRs)
|
|
|
|
|
-- 0xc8nnnnnn: External IO bus
|
|
|
|
|
-- 0xf0000000: Flash "ROM" mapping
|
|
|
|
|
-- 0xff000000: DRAM init code (if any) or flash ROM
|
|
|
|
|
-- 0xff000000: DRAM init code (if any) or flash ROM (**)
|
|
|
|
|
|
|
|
|
|
-- External IO bus:
|
|
|
|
|
-- 0xc8000000: LiteDRAM control (CSRs)
|
|
|
|
|
|
|
|
|
|
-- (**) DRAM init code is currently special and goes to the external
|
|
|
|
|
-- IO bus, this will be fixed when it's moved out of litedram and
|
|
|
|
|
-- into the main SoC once we have a common "firmware".
|
|
|
|
|
|
|
|
|
|
-- Interrupt numbers:
|
|
|
|
|
--
|
|
|
|
|
-- 0 : UART0
|
|
|
|
|
|
|
|
|
|
entity soc is
|
|
|
|
|
generic (
|
|
|
|
|
MEMORY_SIZE : natural;
|
|
|
|
|
RAM_INIT_FILE : string;
|
|
|
|
|
RESET_LOW : boolean;
|
|
|
|
|
CLK_FREQ : positive;
|
|
|
|
|
SIM : boolean;
|
|
|
|
|
DISABLE_FLATTEN_CORE : boolean := false;
|
|
|
|
@ -47,27 +57,29 @@ entity soc is
|
|
|
|
|
rst : in std_ulogic;
|
|
|
|
|
system_clk : in std_ulogic;
|
|
|
|
|
|
|
|
|
|
-- DRAM controller signals
|
|
|
|
|
-- "Large" (64-bit) DRAM wishbone
|
|
|
|
|
wb_dram_in : out wishbone_master_out;
|
|
|
|
|
wb_dram_out : in wishbone_slave_out;
|
|
|
|
|
wb_dram_ctrl_in : out wb_io_master_out;
|
|
|
|
|
wb_dram_ctrl_out : in wb_io_slave_out;
|
|
|
|
|
wb_dram_is_csr : out std_ulogic;
|
|
|
|
|
wb_dram_is_init : out std_ulogic;
|
|
|
|
|
wb_dram_out : in wishbone_slave_out := wishbone_slave_out_init;
|
|
|
|
|
|
|
|
|
|
-- "Small" (32-bit) external IO wishbone
|
|
|
|
|
wb_ext_io_in : out wb_io_master_out;
|
|
|
|
|
wb_ext_io_out : in wb_io_slave_out := wb_io_slave_out_init;
|
|
|
|
|
wb_ext_is_dram_csr : out std_ulogic;
|
|
|
|
|
wb_ext_is_dram_init : out std_ulogic;
|
|
|
|
|
|
|
|
|
|
-- UART0 signals:
|
|
|
|
|
uart0_txd : out std_ulogic;
|
|
|
|
|
uart0_rxd : in std_ulogic;
|
|
|
|
|
uart0_rxd : in std_ulogic := '0';
|
|
|
|
|
|
|
|
|
|
-- SPI Flash signals
|
|
|
|
|
spi_flash_sck : out std_ulogic;
|
|
|
|
|
spi_flash_cs_n : out std_ulogic;
|
|
|
|
|
spi_flash_sdat_o : out std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0);
|
|
|
|
|
spi_flash_sdat_oe : out std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0);
|
|
|
|
|
spi_flash_sdat_i : in std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0);
|
|
|
|
|
spi_flash_sdat_i : in std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0) := (others => '1');
|
|
|
|
|
|
|
|
|
|
-- DRAM controller signals
|
|
|
|
|
alt_reset : in std_ulogic
|
|
|
|
|
alt_reset : in std_ulogic := '0'
|
|
|
|
|
);
|
|
|
|
|
end entity soc;
|
|
|
|
|
|
|
|
|
@ -108,7 +120,8 @@ architecture behaviour of soc is
|
|
|
|
|
-- UART0 signals:
|
|
|
|
|
signal wb_uart0_in : wb_io_master_out;
|
|
|
|
|
signal wb_uart0_out : wb_io_slave_out;
|
|
|
|
|
signal uart_dat8 : std_ulogic_vector(7 downto 0);
|
|
|
|
|
signal uart0_dat8 : std_ulogic_vector(7 downto 0);
|
|
|
|
|
signal uart0_irq : std_ulogic;
|
|
|
|
|
|
|
|
|
|
-- SPI Flash controller signals:
|
|
|
|
|
signal wb_spiflash_in : wb_io_master_out;
|
|
|
|
@ -157,11 +170,10 @@ architecture behaviour of soc is
|
|
|
|
|
-- IO branch split:
|
|
|
|
|
type slave_io_type is (SLAVE_IO_SYSCON,
|
|
|
|
|
SLAVE_IO_UART,
|
|
|
|
|
SLAVE_IO_DRAM_INIT,
|
|
|
|
|
SLAVE_IO_DRAM_CSR,
|
|
|
|
|
SLAVE_IO_ICP_0,
|
|
|
|
|
SLAVE_IO_SPI_FLASH_REG,
|
|
|
|
|
SLAVE_IO_SPI_FLASH_MAP,
|
|
|
|
|
SLAVE_IO_EXTERNAL,
|
|
|
|
|
SLAVE_IO_NONE);
|
|
|
|
|
signal slave_io_dbg : slave_io_type;
|
|
|
|
|
begin
|
|
|
|
@ -268,8 +280,14 @@ begin
|
|
|
|
|
wb_bram_in.cyc <= wb_master_out.cyc;
|
|
|
|
|
wb_master_in <= wb_bram_out;
|
|
|
|
|
when SLAVE_TOP_DRAM =>
|
|
|
|
|
if HAS_DRAM then
|
|
|
|
|
wb_dram_in.cyc <= wb_master_out.cyc;
|
|
|
|
|
wb_master_in <= wb_dram_out;
|
|
|
|
|
else
|
|
|
|
|
wb_master_in.ack <= wb_master_out.cyc and wb_master_out.stb;
|
|
|
|
|
wb_master_in.dat <= (others => '1');
|
|
|
|
|
wb_master_in.stall <= '0';
|
|
|
|
|
end if;
|
|
|
|
|
when SLAVE_TOP_IO =>
|
|
|
|
|
wb_io_in.cyc <= wb_master_out.cyc;
|
|
|
|
|
wb_master_in <= wb_io_out;
|
|
|
|
@ -421,25 +439,26 @@ begin
|
|
|
|
|
-- IO wishbone slave intercon.
|
|
|
|
|
--
|
|
|
|
|
slave_io_intercon: process(wb_sio_out, wb_syscon_out, wb_uart0_out,
|
|
|
|
|
wb_dram_ctrl_out, wb_xics0_out, wb_spiflash_out)
|
|
|
|
|
wb_ext_io_out, wb_xics0_out, wb_spiflash_out)
|
|
|
|
|
variable slave_io : slave_io_type;
|
|
|
|
|
|
|
|
|
|
variable match : std_ulogic_vector(31 downto 12);
|
|
|
|
|
variable ext_valid : boolean;
|
|
|
|
|
begin
|
|
|
|
|
|
|
|
|
|
-- Simple address decoder.
|
|
|
|
|
slave_io := SLAVE_IO_NONE;
|
|
|
|
|
match := "11" & wb_sio_out.adr(29 downto 12);
|
|
|
|
|
if std_match(match, x"FF---") and HAS_DRAM then
|
|
|
|
|
slave_io := SLAVE_IO_DRAM_INIT;
|
|
|
|
|
slave_io := SLAVE_IO_EXTERNAL;
|
|
|
|
|
elsif std_match(match, x"F----") then
|
|
|
|
|
slave_io := SLAVE_IO_SPI_FLASH_MAP;
|
|
|
|
|
elsif std_match(match, x"C0000") then
|
|
|
|
|
slave_io := SLAVE_IO_SYSCON;
|
|
|
|
|
elsif std_match(match, x"C0002") then
|
|
|
|
|
slave_io := SLAVE_IO_UART;
|
|
|
|
|
elsif std_match(match, x"C01--") then
|
|
|
|
|
slave_io := SLAVE_IO_DRAM_CSR;
|
|
|
|
|
elsif std_match(match, x"C8---") then
|
|
|
|
|
slave_io := SLAVE_IO_EXTERNAL;
|
|
|
|
|
elsif std_match(match, x"C0004") then
|
|
|
|
|
slave_io := SLAVE_IO_ICP_0;
|
|
|
|
|
elsif std_match(match, x"C0006") then
|
|
|
|
@ -459,23 +478,41 @@ begin
|
|
|
|
|
wb_xics0_in.adr(7 downto 0) <= wb_sio_out.adr(7 downto 0);
|
|
|
|
|
wb_xics0_in.cyc <= '0';
|
|
|
|
|
|
|
|
|
|
wb_dram_ctrl_in <= wb_sio_out;
|
|
|
|
|
wb_dram_ctrl_in.cyc <= '0';
|
|
|
|
|
wb_dram_is_csr <= '0';
|
|
|
|
|
wb_dram_is_init <= '0';
|
|
|
|
|
wb_ext_io_in <= wb_sio_out;
|
|
|
|
|
wb_ext_io_in.cyc <= '0';
|
|
|
|
|
|
|
|
|
|
wb_syscon_in <= wb_sio_out;
|
|
|
|
|
wb_syscon_in.cyc <= '0';
|
|
|
|
|
|
|
|
|
|
wb_ext_is_dram_csr <= '0';
|
|
|
|
|
wb_ext_is_dram_init <= '0';
|
|
|
|
|
|
|
|
|
|
-- Default response, ack & return all 1's
|
|
|
|
|
wb_sio_in.dat <= (others => '1');
|
|
|
|
|
wb_sio_in.ack <= wb_sio_out.stb and wb_sio_out.cyc;
|
|
|
|
|
wb_sio_in.stall <= '0';
|
|
|
|
|
|
|
|
|
|
case slave_io is
|
|
|
|
|
when SLAVE_IO_DRAM_INIT =>
|
|
|
|
|
wb_dram_ctrl_in.cyc <= wb_sio_out.cyc;
|
|
|
|
|
wb_sio_in <= wb_dram_ctrl_out;
|
|
|
|
|
wb_dram_is_init <= '1';
|
|
|
|
|
when SLAVE_IO_DRAM_CSR =>
|
|
|
|
|
wb_dram_ctrl_in.cyc <= wb_sio_out.cyc;
|
|
|
|
|
wb_sio_in <= wb_dram_ctrl_out;
|
|
|
|
|
wb_dram_is_csr <= '1';
|
|
|
|
|
when SLAVE_IO_EXTERNAL =>
|
|
|
|
|
-- Ext IO "chip selects"
|
|
|
|
|
--
|
|
|
|
|
-- DRAM init is special at 0xFF* so we just test the top
|
|
|
|
|
-- bit. Everything else is at 0xC8* so we test only bits
|
|
|
|
|
-- 23 downto 16.
|
|
|
|
|
--
|
|
|
|
|
ext_valid := false;
|
|
|
|
|
if wb_sio_out.adr(29) = '1' and HAS_DRAM then -- DRAM init is special
|
|
|
|
|
wb_ext_is_dram_init <= '1';
|
|
|
|
|
ext_valid := true;
|
|
|
|
|
elsif wb_sio_out.adr(23 downto 16) = x"00" and HAS_DRAM then
|
|
|
|
|
wb_ext_is_dram_csr <= '1';
|
|
|
|
|
ext_valid := true;
|
|
|
|
|
end if;
|
|
|
|
|
if ext_valid then
|
|
|
|
|
wb_ext_io_in.cyc <= wb_sio_out.cyc;
|
|
|
|
|
wb_sio_in <= wb_ext_io_out;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
when SLAVE_IO_SYSCON =>
|
|
|
|
|
wb_syscon_in.cyc <= wb_sio_out.cyc;
|
|
|
|
|
wb_sio_in <= wb_syscon_out;
|
|
|
|
@ -497,9 +534,6 @@ begin
|
|
|
|
|
wb_sio_in <= wb_spiflash_out;
|
|
|
|
|
wb_spiflash_is_reg <= '1';
|
|
|
|
|
when others =>
|
|
|
|
|
wb_sio_in.dat <= (others => '1');
|
|
|
|
|
wb_sio_in.ack <= wb_sio_out.stb and wb_sio_out.cyc;
|
|
|
|
|
wb_sio_in.stall <= '0';
|
|
|
|
|
end case;
|
|
|
|
|
|
|
|
|
|
end process;
|
|
|
|
@ -538,16 +572,16 @@ begin
|
|
|
|
|
reset => rst_uart,
|
|
|
|
|
txd => uart0_txd,
|
|
|
|
|
rxd => uart0_rxd,
|
|
|
|
|
irq => int_level_in(0),
|
|
|
|
|
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 => uart_dat8,
|
|
|
|
|
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" & uart_dat8;
|
|
|
|
|
wb_uart0_out.dat <= x"000000" & uart0_dat8;
|
|
|
|
|
wb_uart0_out.stall <= not wb_uart0_out.ack;
|
|
|
|
|
|
|
|
|
|
spiflash_gen: if HAS_SPI_FLASH generate
|
|
|
|
@ -591,6 +625,13 @@ begin
|
|
|
|
|
core_irq_out => core_ext_irq
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- Assign external interrupts
|
|
|
|
|
interrupts: process(all)
|
|
|
|
|
begin
|
|
|
|
|
int_level_in <= (others => '0');
|
|
|
|
|
int_level_in(0) <= uart0_irq;
|
|
|
|
|
end process;
|
|
|
|
|
|
|
|
|
|
-- BRAM Memory slave
|
|
|
|
|
bram: if MEMORY_SIZE /= 0 generate
|
|
|
|
|
bram0: entity work.wishbone_bram_wrapper
|
|
|
|
|