soc: Add DRAM address decoding

Still not attached to any board

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
pull/170/head
Benjamin Herrenschmidt 5 years ago
parent 6853d22203
commit 8bb3c8f8b6

@ -14,6 +14,10 @@ architecture behave of core_tb is

-- testbench signals
constant clk_period : time := 10 ns;

-- Dummy DRAM
signal wb_dram_in : wishbone_master_out;
signal wb_dram_out : wishbone_slave_out;
begin

soc0: entity work.soc
@ -28,6 +32,8 @@ begin
system_clk => clk,
uart0_rxd => '0',
uart0_txd => open,
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
alt_reset => '0'
);

@ -48,4 +54,10 @@ begin
end process;

jtag: entity work.sim_jtag;

-- Dummy DRAM
wb_dram_out.ack <= wb_dram_in.cyc and wb_dram_in.stb;
wb_dram_out.dat <= x"FFFFFFFFFFFFFFFF";
wb_dram_out.stall <= wb_dram_in.cyc and not wb_dram_out.ack;

end;

@ -30,6 +30,10 @@ architecture behaviour of toplevel is
signal system_clk : std_ulogic;
signal system_clk_locked : std_ulogic;

-- Dummy DRAM
signal wb_dram_in : wishbone_master_out;
signal wb_dram_out : wishbone_slave_out;

begin

reset_controller: entity work.soc_reset
@ -73,4 +77,9 @@ begin
uart0_rxd => uart0_rxd
);

-- Dummy DRAM
wb_dram_out.ack <= wb_dram_in.cyc and wb_dram_in.stb;
wb_dram_out.dat <= x"FFFFFFFFFFFFFFFF";
wb_dram_out.stall <= wb_dram_in.cyc and not wb_dram_out.ack;

end architecture behaviour;

@ -10,24 +10,39 @@ use work.common.all;
use work.wishbone_types.all;


-- 0x00000000: Main memory (1 MB)
-- 0xc0002000: UART0 (for host communication)
-- Memory map:
--
-- 0x00000000: Block RAM
-- 0x40000000: DRAM (when present)
-- 0xc0002000: UART0
-- 0xc0004000: XICS ICP
-- 0xf0000000: Block RAM (aliased & repeated)
-- 0xffff0000: DRAM init code (if any)

entity soc is
generic (
MEMORY_SIZE : positive;
RAM_INIT_FILE : string;
RESET_LOW : boolean;
SIM : boolean;
DISABLE_FLATTEN_CORE : boolean := false
DISABLE_FLATTEN_CORE : boolean := false;
HAS_DRAM : boolean := false
);
port(
rst : in std_ulogic;
system_clk : in std_ulogic;

-- DRAM controller signals
wb_dram_in : out wishbone_master_out;
wb_dram_out : in wishbone_slave_out;
wb_dram_csr : out std_ulogic;
wb_dram_init : out std_ulogic;

-- UART0 signals:
uart0_txd : out std_ulogic;
uart0_rxd : in std_ulogic;

-- DRAM controller signals
alt_reset : in std_ulogic
);
end entity soc;
@ -130,26 +145,36 @@ begin
);

-- Wishbone slaves address decoder & mux
slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out)
slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out, wb_dram_out)
-- Selected slave
type slave_type is (SLAVE_UART_0,
SLAVE_MEMORY,
type slave_type is (SLAVE_UART,
SLAVE_BRAM,
SLAVE_DRAM,
SLAVE_DRAM_INIT,
SLAVE_DRAM_CSR,
SLAVE_ICP_0,
SLAVE_NONE);
variable slave : slave_type;
begin
-- Simple address decoder.
slave := SLAVE_NONE;
if wb_master_out.adr(31 downto 24) = x"00" then
slave := SLAVE_MEMORY;
elsif wb_master_out.adr(31 downto 24) = x"c0" then
if wb_master_out.adr(23 downto 12) = x"002" then
slave := SLAVE_UART_0;
end if;
if wb_master_out.adr(23 downto 12) = x"004" then
-- Simple address decoder. Ignore top bits to save silicon for now
slave := SLAVE_NONE;
if std_match(wb_master_out.adr, x"0-------") then
slave := SLAVE_BRAM;
elsif std_match(wb_master_out.adr, x"FFFF----") then
slave := SLAVE_DRAM_INIT;
elsif std_match(wb_master_out.adr, x"F-------") then
slave := SLAVE_BRAM;
elsif std_match(wb_master_out.adr, x"4-------") and HAS_DRAM then
slave := SLAVE_DRAM;
elsif std_match(wb_master_out.adr, x"C0002---") then
slave := SLAVE_UART;
elsif std_match(wb_master_out.adr, x"C01-----") then
slave := SLAVE_DRAM_CSR;
elsif std_match(wb_master_out.adr, x"C0004---") then
slave := SLAVE_ICP_0;
end if;
end if;

-- Wishbone muxing. Defaults:
wb_bram_in <= wb_master_out;
@ -162,11 +187,27 @@ begin
wb_xics0_in.adr <= (others => '0');
wb_xics0_in.adr(7 downto 0) <= wb_master_out.adr(7 downto 0);
wb_xics0_in.cyc <= '0';

wb_dram_in <= wb_master_out;
wb_dram_in.cyc <= '0';
wb_dram_csr <= '0';
wb_dram_init <= '0';
case slave is
when SLAVE_MEMORY =>
when SLAVE_BRAM =>
wb_bram_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_bram_out;
when SLAVE_UART_0 =>
when SLAVE_DRAM =>
wb_dram_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_dram_out;
when SLAVE_DRAM_INIT =>
wb_dram_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_dram_out;
wb_dram_init <= '1';
when SLAVE_DRAM_CSR =>
wb_dram_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_dram_out;
wb_dram_csr <= '1';
when SLAVE_UART =>
wb_uart0_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_uart0_out;
when SLAVE_ICP_0 =>

Loading…
Cancel
Save