dcache: Add wishbone pipelining support
[microwatt.git] / soc.vhdl
index 4b0280737593d5452e496ad23117ff0ccba4cc45..950d0ddbc14380466674c02479a5b085e0581201 100644 (file)
--- a/soc.vhdl
+++ b/soc.vhdl
@@ -1,8 +1,9 @@
 library ieee;
 use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
 use ieee.math_real.all;
-
 use std.textio.all;
+use std.env.stop;
 
 library work;
 use work.common.all;
@@ -24,7 +25,10 @@ entity soc is
 
        -- UART0 signals:
        uart0_txd    : out std_ulogic;
-       uart0_rxd    : in  std_ulogic
+       uart0_rxd    : in  std_ulogic;
+
+       -- Misc (to use for things like LEDs)
+       core_terminated : out std_ulogic
        );
 end entity soc;
 
@@ -52,10 +56,6 @@ architecture behaviour of soc is
     signal wb_bram_out    : wishbone_slave_out;
     constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
 
-    -- Core debug signals (used in SIM only)
-    signal registers     : regfile;
-    signal terminate     : std_ulogic;
-
     -- DMI debug bus signals
     signal dmi_addr    : std_ulogic_vector(7 downto 0);
     signal dmi_din     : std_ulogic_vector(63 downto 0);
@@ -85,8 +85,12 @@ begin
            wishbone_insn_out => wishbone_icore_out,
            wishbone_data_in => wishbone_dcore_in,
            wishbone_data_out => wishbone_dcore_out,
-           registers => registers,
-           terminate_out => terminate
+           dmi_addr => dmi_addr(3 downto 0),
+           dmi_dout => dmi_core_dout,
+           dmi_din => dmi_dout,
+           dmi_wr => dmi_wr,
+           dmi_ack => dmi_core_ack,
+           dmi_req => dmi_core_req
            );
 
     -- Wishbone bus master arbiter & mux
@@ -102,18 +106,18 @@ begin
     -- Wishbone slaves address decoder & mux
     slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out)
        -- Selected slave
-       type slave_type is (SLAVE_UART,
+       type slave_type is (SLAVE_UART_0,
                            SLAVE_MEMORY,
                            SLAVE_NONE);
        variable slave : slave_type;
     begin
-       -- Simple address decoder
+       -- Simple address decoder.
        slave := SLAVE_NONE;
-       if wb_master_out.adr(63 downto 24) = x"0000000000" then
+       if wb_master_out.adr(31 downto 24) = x"00" then
            slave := SLAVE_MEMORY;
-       elsif wb_master_out.adr(63 downto 24) = x"00000000c0" then
-           if wb_master_out.adr(15 downto 12) = x"2" then
-               slave := SLAVE_UART;
+       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;
        end if;
 
@@ -126,30 +130,17 @@ begin
        when SLAVE_MEMORY =>
            wb_bram_in.cyc <= wb_master_out.cyc;
            wb_master_in <= wb_bram_out;
-       when SLAVE_UART =>
+       when SLAVE_UART_0 =>
            wb_uart0_in.cyc <= wb_master_out.cyc;
            wb_master_in <= wb_uart0_out;
        when others =>
            wb_master_in.dat <= (others => '1');
            wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc;
+           wb_master_in.stall <= '0';
        end case;
     end process slave_intercon;
 
     -- Simulated memory and UART
-    sim_terminate_test: if SIM generate
-
-       -- Dump registers if core terminates
-       dump_registers: process(all)
-       begin
-           if terminate = '1' then
-               loop_0: for i in 0 to 31 loop
-                   report "REG " & to_hstring(registers(i));
-               end loop loop_0;
-               assert false report "end of test" severity failure;
-           end if;
-       end process;
-
-    end generate;
 
     -- UART0 wishbone slave
     -- XXX FIXME: Need a proper wb64->wb8 adapter that
@@ -174,6 +165,7 @@ begin
            wb_ack_out => wb_uart0_out.ack
            );
     wb_uart0_out.dat <= x"00000000000000" & uart_dat8;
+    wb_uart0_out.stall <= '0' when wb_uart0_in.cyc = '0' else not wb_uart0_out.ack;
 
     -- BRAM Memory slave
     bram0: entity work.mw_soc_memory
@@ -207,8 +199,8 @@ begin
 
     -- DMI interconnect
     dmi_intercon: process(dmi_addr, dmi_req,
-                    dmi_wb_ack, dmi_wb_dout,
-                    dmi_core_ack, dmi_core_dout)
+                         dmi_wb_ack, dmi_wb_dout,
+                         dmi_core_ack, dmi_core_dout)
 
        -- DMI address map (each address is a full 64-bit register)
        --
@@ -222,12 +214,11 @@ begin
        variable slave : slave_type;
     begin
        -- Simple address decoder
-       if dmi_addr(7 downto 0) = "000000--" then
+       slave := SLAVE_NONE;
+       if std_match(dmi_addr, "000000--") then
            slave := SLAVE_WB;
-       elsif dmi_addr(7 downto 0) = "0001----" then
+       elsif std_match(dmi_addr, "0001----") then
            slave := SLAVE_CORE;
-       else
-           slave := SLAVE_NONE;
        end if;
 
        -- DMI muxing
@@ -246,11 +237,12 @@ begin
            dmi_ack <= dmi_req;
            dmi_din <= (others => '1');
        end case;
-    end process;
 
-    -- Core dummy
-    dmi_core_ack <= dmi_core_req;
-    dmi_core_dout <= x"0000000000000000";
+       -- SIM magic exit
+       if SIM and dmi_req = '1' and dmi_addr = "11111111" and dmi_wr = '1' then
+           stop;
+       end if;
+    end process;
 
     -- Wishbone debug master (TODO: Add a DMI address decoder)
     wishbone_debug: entity work.wishbone_debug_master