@ -22,9 +22,17 @@ 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".
entity soc is
generic (
@ -46,13 +54,15 @@ 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 := wishbone_slave_out_init;
wb_dram_ctrl_in : out wb_io_master_out;
wb_dram_ctrl_out : in wb_io_slave_out := wb_io_slave_out_init;
wb_dram_is_csr : out std_ulogic;
wb_dram_is_init : out std_ulogic;
-- "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;
@ -156,11 +166,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
@ -426,25 +435,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
@ -464,35 +474,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';
case slave_io is
when SLAVE_IO_DRAM_INIT =>
if HAS_DRAM then
wb_dram_ctrl_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_dram_ctrl_out;
else
wb_sio_in.ack <= wb_sio_out.cyc and wb_sio_out.stb;
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_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;
wb_dram_is_init <= '1';
when SLAVE_IO_DRAM_CSR =>
if HAS_DRAM then
wb_dram_ctrl_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_dram_ctrl_out;
else
wb_sio_in.ack <= wb_sio_out.cyc and wb_sio_out.stb;
wb_sio_in.dat <= (others => '1');
wb_sio_in.stall <= '0';
if ext_valid then
wb_ext_io_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_ext_io_out;
end if;
wb_dram_is_csr <= '1';
when SLAVE_IO_SYSCON =>
wb_syscon_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_syscon_out;
@ -514,9 +530,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;