soc: Add DRAM address decoding
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 10 Sep 2019 17:05:56 +0000 (18:05 +0100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 8 May 2020 01:41:06 +0000 (11:41 +1000)
Still not attached to any board

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
core_tb.vhdl
fpga/toplevel.vhdl
soc.vhdl

index 81289933bd4819a26f27fcd297f701323e447629..c473de329c874083d5f1c7915eba74503980cdf1 100644 (file)
@@ -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;
index a3b8282fbd2602065d33711d0face773db4a82b1..c0f1920bd26c218bbfbe1ad65526a84b29d81de3 100644 (file)
@@ -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;
index 2318d0ac40f7e3b5e11518dc3a69a8acbe7329e3..53fa2f1f6b85d20ab5215a82f72e773104450e29 100644 (file)
--- a/soc.vhdl
+++ b/soc.vhdl
@@ -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;
@@ -35,9 +50,9 @@ end entity soc;
 architecture behaviour of soc is
 
     -- Wishbone master signals:
-    signal wishbone_dcore_in : wishbone_slave_out;
+    signal wishbone_dcore_in  : wishbone_slave_out;
     signal wishbone_dcore_out : wishbone_master_out;
-    signal wishbone_icore_in : wishbone_slave_out;
+    signal wishbone_icore_in  : wishbone_slave_out;
     signal wishbone_icore_out : wishbone_master_out;
     signal wishbone_debug_in : wishbone_slave_out;
     signal wishbone_debug_out : wishbone_master_out;
@@ -49,8 +64,8 @@ architecture behaviour of soc is
     signal wb_masters_in  : wishbone_slave_out_vector(0 to NUM_WB_MASTERS-1);
 
     -- Wishbone master (output of arbiter):
-    signal wb_master_in : wishbone_slave_out;
-    signal wb_master_out : wishbone_master_out;
+    signal wb_master_in       : wishbone_slave_out;
+    signal wb_master_out      : wishbone_master_out;
 
     -- UART0 signals:
     signal wb_uart0_in   : wishbone_master_out;
@@ -130,25 +145,35 @@ 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
-               slave := SLAVE_ICP_0;
-           end if;
+       -- 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;
 
        -- Wishbone muxing. Defaults:
@@ -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 =>