Share soc.vhdl between FPGA and sim
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 10 Sep 2019 15:40:11 +0000 (16:40 +0100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 10 Sep 2019 15:57:47 +0000 (16:57 +0100)
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Makefile
core_tb.vhdl
fpga/soc.vhdl [deleted file]
fpga/toplevel.vhdl
microwatt.core
sim_uart.vhdl
simple_ram_behavioural.vhdl
simple_ram_behavioural_tb.vhdl
soc.vhdl [new file with mode: 0644]

index 506cb29352adde74d8090c99cee6a21f462fe2d1..02d3416227b57e262d9a34079f2cc6df08953456 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ all: $(all)
        $(GHDL) -a $(GHDLFLAGS) $<
 
 common.o: decode_types.o
-core_tb.o: common.o wishbone_types.o core.o simple_ram_behavioural.o sim_uart.o
+core_tb.o: common.o core.o soc.o
 core.o: common.o wishbone_types.o fetch1.o fetch2.o decode1.o decode2.o register_file.o cr_file.o execute1.o execute2.o loadstore1.o loadstore2.o multiply.o writeback.o wishbone_arbiter.o
 cr_file.o: common.o
 crhelpers.o: common.o
@@ -41,6 +41,7 @@ simple_ram_behavioural.o: wishbone_types.o simple_ram_behavioural_helpers.o
 wishbone_arbiter.o: wishbone_types.o
 wishbone_types.o:
 writeback.o: common.o
+soc.o: wishbone_types.o simple_ram_behavioural.o sim_uart.o
 
 fpga/soc_reset_tb.o: fpga/soc_reset.o
 
index 501cbfb2f1ab88c4f75fc767e175937a95c05835..cb11d08b07ecbe98f88d8d19cdbc17b0acd0e9fe 100644 (file)
@@ -13,88 +13,23 @@ end core_tb;
 architecture behave of core_tb is
        signal clk, rst: std_logic;
 
-       signal wishbone_dcore_in : wishbone_slave_out;
-       signal wishbone_dcore_out : wishbone_master_out;
-
-       signal wishbone_icore_in : wishbone_slave_out;
-       signal wishbone_icore_out : wishbone_master_out;
-
-       signal wishbone_core_in : wishbone_slave_out;
-       signal wishbone_core_out : wishbone_master_out;
-
-       signal wishbone_ram_in : wishbone_slave_out;
-       signal wishbone_ram_out : wishbone_master_out;
-
-       signal wishbone_uart_in : wishbone_slave_out;
-       signal wishbone_uart_out : wishbone_master_out;
-
-       signal registers : regfile;
-       signal terminate : std_ulogic;
-
        -- testbench signals
        constant clk_period : time := 10 ns;
 begin
-       core_0: entity work.core
-               generic map (SIM => true)
-           port map (clk => clk, rst => rst,
-                     wishbone_insn_in => wishbone_icore_in,
-                     wishbone_insn_out => wishbone_icore_out,
-                     wishbone_data_in => wishbone_dcore_in,
-                     wishbone_data_out => wishbone_dcore_out,
-                     registers => registers, terminate_out => terminate);
-
-       simple_ram_0: entity work.simple_ram_behavioural
-               generic map ( filename => "simple_ram_behavioural.bin", size => 524288)
-               port map (clk => clk, rst => rst, wishbone_in => wishbone_ram_out, wishbone_out => wishbone_ram_in);
-
-       simple_uart_0: entity work.sim_uart
-               port map ( clk => clk, reset => rst, wishbone_in => wishbone_uart_out, wishbone_out => wishbone_uart_in);
 
-
-       wishbone_arbiter_0: entity work.wishbone_arbiter
-               port map (clk => clk, rst => rst,
-                         wb1_in => wishbone_dcore_out, wb1_out => wishbone_dcore_in,
-                         wb2_in => wishbone_icore_out, wb2_out => wishbone_icore_in,
-                         wb_out => wishbone_core_out, wb_in => wishbone_core_in);
-
-       bus_process: process(wishbone_core_out, wishbone_ram_in, wishbone_uart_in)
-         -- Selected slave
-         type slave_type is (SLAVE_UART, SLAVE_MEMORY, SLAVE_NONE);
-         variable slave : slave_type;
-       begin
-               -- Simple address decoder
-               slave := SLAVE_NONE;
-               if wishbone_core_out.adr(31 downto 24) = x"00" then
-                       slave := SLAVE_MEMORY;
-               elsif wishbone_core_out.adr(31 downto 24) = x"c0" then
-                       if wishbone_core_out.adr(15 downto 12) = x"2" then
-                               slave := SLAVE_UART;
-                       end if;
-               end if;
-
-               -- Wishbone muxing:
-               -- Start with all master signals to all slaves, then override
-               -- cyc and stb accordingly
-               wishbone_ram_out <= wishbone_core_out;
-               wishbone_uart_out <= wishbone_core_out;
-               if slave = SLAVE_MEMORY then
-                       wishbone_core_in <= wishbone_ram_in;
-               else
-                       wishbone_ram_out.cyc <= '0';
-                       wishbone_ram_out.stb <= '0';
-               end if;
-               if slave = SLAVE_UART then
-                       wishbone_core_in <= wishbone_uart_in;
-               else
-                       wishbone_uart_out.cyc <= '0';
-                       wishbone_uart_out.stb <= '0';
-               end if;
-               if slave = SLAVE_NONE then
-                       wishbone_core_in.dat <= (others => '1');
-                       wishbone_core_in.ack <= wishbone_core_out.cyc and
-                                               wishbone_core_out.stb;
-               end if;
-       end process;
+    soc0: entity work.soc
+       generic map(
+           SIM => true,
+           MEMORY_SIZE => 524288,
+           RAM_INIT_FILE => "simple_ram_behavioural.bin",
+           RESET_LOW => false
+           )
+       port map(
+           rst => rst,
+           system_clk => clk,
+           uart0_rxd => '0',
+           uart0_txd => open
+           );
 
        clk_process: process
        begin
@@ -111,14 +46,4 @@ begin
                rst <= '0';
                wait;
        end process;
-
-       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;
diff --git a/fpga/soc.vhdl b/fpga/soc.vhdl
deleted file mode 100644 (file)
index 73907a2..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.math_real.all;
-
-library work;
-use work.wishbone_types.all;
-
-
--- 0x00000000: Main memory (1 MB)
--- 0xc0002000: UART0 (for host communication)
-entity soc is
-    generic (
-       MEMORY_SIZE   : positive;
-       RAM_INIT_FILE : string;
-       RESET_LOW     : boolean
-       );
-    port(
-       rst          : in  std_ulogic;
-       system_clk   : in  std_logic;
-
-       -- UART0 signals:
-       uart0_txd    : out std_logic;
-       uart0_rxd    : in  std_logic
-       );
-end entity soc;
-
-architecture behaviour of soc is
-
-    -- Wishbone master signals:
-    signal wishbone_dcore_in : wishbone_slave_out;
-    signal wishbone_dcore_out : wishbone_master_out;
-    signal wishbone_icore_in : wishbone_slave_out;
-    signal wishbone_icore_out : wishbone_master_out;
-
-    -- Wishbone master (output of arbiter):
-    signal wb_master_in : wishbone_slave_out;
-    signal wb_master_out : wishbone_master_out;
-
-    -- UART0 signals:
-    signal uart0_adr_in  : std_logic_vector(11 downto 0);
-    signal uart0_dat_in  : std_logic_vector( 7 downto 0);
-    signal uart0_dat_out : std_logic_vector( 7 downto 0);
-    signal uart0_cyc_in  : std_logic;
-    signal uart0_stb_in  : std_logic;
-    signal uart0_we_in   : std_logic;
-    signal uart0_ack_out : std_logic;
-
-    -- Main memory signals:
-    signal wb_bram_in     : wishbone_master_out;
-    signal wb_bram_out    : wishbone_slave_out;
-    constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
-
-begin
-
-    -- Processor core
-    processor: entity work.core
-       port map(
-           clk => system_clk,
-           rst => rst,
-           wishbone_insn_in => wishbone_icore_in,
-           wishbone_insn_out => wishbone_icore_out,
-           wishbone_data_in => wishbone_dcore_in,
-           wishbone_data_out => wishbone_dcore_out
-           );
-
-    -- Wishbone bus master arbiter & mux
-    wishbone_arbiter_0: entity work.wishbone_arbiter
-       port map(
-           clk => system_clk,
-           rst => rst,
-           wb1_in => wishbone_dcore_out,
-           wb1_out => wishbone_dcore_in,
-           wb2_in => wishbone_icore_out,
-           wb2_out => wishbone_icore_in,
-           wb_out => wb_master_out,
-           wb_in => wb_master_in
-           );
-
-    -- Wishbone slaves address decoder & mux
-    slave_intercon: process(wb_master_out,  wb_bram_out,
-                           uart0_ack_out, uart0_dat_out)
-       -- Selected slave
-       type slave_type is (SLAVE_UART,
-                           SLAVE_MEMORY,
-                           SLAVE_NONE);
-       variable slave : slave_type;
-    begin
-       -- Simple address decoder
-       slave := SLAVE_NONE;
-       if wb_master_out.adr(63 downto 24) = x"0000000000" 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;
-           end if;
-       end if;
-
-       -- Wishbone muxing. Defaults:
-       wb_bram_in <= wb_master_out;
-       wb_bram_in.cyc  <= '0';
-       uart0_cyc_in <= '0';
-       case slave is
-       when SLAVE_MEMORY =>
-           wb_bram_in.cyc <= wb_master_out.cyc;
-           wb_master_in <= wb_bram_out;
-       when SLAVE_UART =>
-           uart0_cyc_in <= wb_master_out.cyc;
-           wb_master_in.ack <= uart0_ack_out;
-           wb_master_in.dat <= x"00000000000000" & uart0_dat_out;
-       when others =>
-           wb_master_in.dat <= (others => '1');
-           wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc;
-       end case;
-    end process slave_intercon;
-
-    -- UART0 wishbone slave
-    uart0: entity work.pp_soc_uart
-       generic map(
-           FIFO_DEPTH => 32
-           )
-       port map(
-           clk => system_clk,
-           reset => rst,
-           txd => uart0_txd,
-           rxd => uart0_rxd,
-           wb_adr_in => uart0_adr_in,
-           wb_dat_in => uart0_dat_in,
-           wb_dat_out => uart0_dat_out,
-           wb_cyc_in => uart0_cyc_in,
-           wb_stb_in => uart0_stb_in,
-           wb_we_in => uart0_we_in,
-           wb_ack_out => uart0_ack_out
-           );
-    -- Wire it up: XXX FIXME: Need a proper wb64->wb8 adapter that
-    --                 converts SELs into low address bits and muxes
-    --                 data accordingly (either that or rejects large
-    --                 cycles).
-    uart0_adr_in <= wb_master_out.adr(uart0_adr_in'range);
-    uart0_dat_in <= wb_master_out.dat(7 downto 0);
-    uart0_we_in  <= wb_master_out.we;
-    uart0_stb_in <= wb_master_out.stb;
-
-    -- BRAM Memory slave
-    bram0: entity work.mw_soc_memory
-       generic map(
-           MEMORY_SIZE   => MEMORY_SIZE,
-           RAM_INIT_FILE => RAM_INIT_FILE
-           )
-       port map(
-           clk => system_clk,
-           rst => rst,
-           wishbone_in => wb_bram_in,
-           wishbone_out => wb_bram_out
-           );
-
-end architecture behaviour;
index 6ad5c9bb9e57fb21d468f928357e24d8dbd1021e..489080b8b9b689faa0c57143bfb0ee1de6e12e46 100644 (file)
@@ -55,7 +55,8 @@ begin
        generic map(
            MEMORY_SIZE   => MEMORY_SIZE,
            RAM_INIT_FILE => RAM_INIT_FILE,
-           RESET_LOW     => RESET_LOW
+           RESET_LOW     => RESET_LOW,
+           SIM           => false
            )
        port map (
            system_clk        => system_clk,
index f1bd8f0cf96942091407ec55ecc6bc268f8f4108..58485a74f39f6d01278207ffe175f9c26978a498 100644 (file)
@@ -24,19 +24,23 @@ filesets:
       - loadstore2.vhdl
       - multiply.vhdl
       - writeback.vhdl
-      - wishbone_arbiter.vhdl
       - insn_helpers.vhdl
       - core.vhdl
     file_type : vhdlSource-2008
 
   soc:
+    files:
+      - wishbone_arbiter.vhdl
+      - soc.vhdl
+    file_type : vhdlSource-2008
+
+  fpga:
     files:
       - fpga/pp_fifo.vhd
       - fpga/mw_soc_memory.vhdl
       - fpga/soc_reset.vhdl
       - fpga/pp_soc_uart.vhd
       - fpga/pp_utilities.vhd
-      - fpga/soc.vhdl
       - fpga/toplevel.vhdl
       - fpga/firmware.hex : {copyto : firmware.hex, file_type : user}
     file_type : vhdlSource-2008
@@ -64,7 +68,7 @@ filesets:
 targets:
   nexys_a7:
     default_tool: vivado
-    filesets: [core, nexys_a7, soc]
+    filesets: [core, nexys_a7, soc, fpga]
     parameters : [memory_size, ram_init_file]
     tools:
       vivado: {part : xc7a100tcsg324-1}
@@ -72,7 +76,7 @@ targets:
 
   nexys_video:
     default_tool: vivado
-    filesets: [core, nexys_video, soc]
+    filesets: [core, nexys_video, soc, fpga]
     parameters : [memory_size, ram_init_file]
     tools:
       vivado: {part : xc7a200tsbg484-1}
@@ -80,7 +84,7 @@ targets:
 
   arty_a7-35:
     default_tool: vivado
-    filesets: [core, arty_a7-35, soc]
+    filesets: [core, arty_a7-35, soc, fpga]
     parameters : [memory_size, ram_init_file]
     tools:
       vivado: {part : xc7a35ticsg324-1L}
@@ -88,14 +92,14 @@ targets:
 
   cmod_a7-35:
     default_tool: vivado
-    filesets: [core, cmod_a7-35, soc]
+    filesets: [core, cmod_a7-35, soc, fpga]
     parameters : [memory_size, ram_init_file, reset_low=false]
     tools:
       vivado: {part : xc7a35tcpg236-1}
     toplevel : toplevel
 
   synth:
-    filesets: [core]
+    filesets: [core, soc]
     tools:
       vivado: {pnr : none}
     toplevel: core
index c52a8bcab877e75f2d59828df12f2c390e970148..58815608539245b220e3f926a57dfbe9e277af58 100644 (file)
@@ -31,18 +31,30 @@ use work.sim_console.all;
 --! enable register. The following bits are available:
 --! - Bit 0: data received (receive buffer not empty)
 --! - Bit 1: ready to send data (transmit buffer empty)
-entity sim_uart is
+entity pp_soc_uart is
+    generic(
+       FIFO_DEPTH : natural := 64 --Unused
+       );
     port(
        clk : in std_logic;
        reset : in std_logic;
 
+       -- UART ports:
+       txd : out std_logic;
+       rxd : in  std_logic;
+
        -- Wishbone ports:
-       wishbone_in : in wishbone_master_out;
-       wishbone_out : out wishbone_slave_out
+       wb_adr_in  : in  std_logic_vector(11 downto 0);
+       wb_dat_in  : in  std_logic_vector( 7 downto 0);
+       wb_dat_out : out std_logic_vector( 7 downto 0);
+       wb_we_in   : in  std_logic;
+       wb_cyc_in  : in  std_logic;
+       wb_stb_in  : in  std_logic;
+       wb_ack_out : out std_logic
        );
-end entity sim_uart;
+end entity pp_soc_uart;
 
-architecture behaviour of sim_uart is
+architecture behaviour of pp_soc_uart is
 
     signal sample_clk_divisor : std_logic_vector(7 downto 0);
 
@@ -56,7 +68,7 @@ architecture behaviour of sim_uart is
 
 begin
 
-    wishbone_out.ack <= wb_ack and wishbone_in.cyc and wishbone_in.stb;
+    wb_ack_out <= wb_ack and wb_cyc_in and wb_stb_in;
 
     wishbone: process(clk)
        variable sim_tmp : std_logic_vector(63 downto 0);
@@ -71,42 +83,40 @@ begin
            else
                case wb_state is
                when IDLE =>
-                   if wishbone_in.cyc = '1' and wishbone_in.stb = '1' then
-                       if wishbone_in.we = '1' then -- Write to register
-                           if wishbone_in.adr(11 downto 0) = x"000" then
-                               report "FOO !";
-                               sim_console_write(wishbone_in.dat);
-                           elsif wishbone_in.adr(11 downto 0) = x"018" then
-                               sample_clk_divisor <= wishbone_in.dat(7 downto 0);
-                           elsif wishbone_in.adr(11 downto 0) = x"020" then
-                               irq_recv_enable <= wishbone_in.dat(0);
-                               irq_tx_ready_enable <= wishbone_in.dat(1);
+                   if wb_cyc_in = '1' and wb_stb_in = '1' then
+                       if wb_we_in = '1' then -- Write to register
+                           if wb_adr_in(11 downto 0) = x"000" then
+                               sim_console_write(x"00000000000000" & wb_dat_in);
+                           elsif wb_adr_in(11 downto 0) = x"018" then
+                               sample_clk_divisor <= wb_dat_in;
+                           elsif wb_adr_in(11 downto 0) = x"020" then
+                               irq_recv_enable <= wb_dat_in(0);
+                               irq_tx_ready_enable <= wb_dat_in(1);
                            end if;
                            wb_ack <= '1';
                            wb_state <= WRITE_ACK;
                        else -- Read from register
-                           if wishbone_in.adr(11 downto 0) = x"008" then
+                           if wb_adr_in(11 downto 0) = x"008" then
                                sim_console_read(sim_tmp);
-                               wishbone_out.dat <= sim_tmp;
-                           elsif wishbone_in.adr(11 downto 0) = x"010" then
+                               wb_dat_out <= sim_tmp(7 downto 0);
+                           elsif wb_adr_in(11 downto 0) = x"010" then
                                sim_console_poll(sim_tmp);
-                               wishbone_out.dat <= x"000000000000000" & '0' &
-                                                   sim_tmp(0) & '1' & not sim_tmp(0);
-                           elsif wishbone_in.adr(11 downto 0) = x"018" then
-                               wishbone_out.dat <= x"00000000000000" & sample_clk_divisor;
-                           elsif wishbone_in.adr(11 downto 0) = x"020" then
-                               wishbone_out.dat <= (0 => irq_recv_enable,
-                                                    1 => irq_tx_ready_enable,
-                                                    others => '0');
+                               wb_dat_out <= "00000" & sim_tmp(0) & '1' & not sim_tmp(0);
+                           elsif wb_adr_in(11 downto 0) = x"018" then
+                               wb_dat_out <= sample_clk_divisor;
+                           elsif wb_adr_in(11 downto 0) = x"020" then
+                               wb_dat_out <= (0 => irq_recv_enable,
+                                              1 => irq_tx_ready_enable,
+                                              others => '0');
                            else
-                               wishbone_out.dat <= (others => '0');
+                               wb_dat_out <= (others => '0');
                            end if;
                            wb_ack <= '1';
                            wb_state <= READ_ACK;
                        end if;
                    end if;
                when WRITE_ACK|READ_ACK =>
-                   if wishbone_in.stb = '0' then
+                   if wb_stb_in = '0' then
                        wb_ack <= '0';
                        wb_state <= IDLE;
                    end if;
index 6d76d76011f6767cb367a35ffef992e3f2473c82..2ccee7971e9df0438c3910e00faf09b21ae9eb63 100644 (file)
@@ -7,10 +7,10 @@ library work;
 use work.wishbone_types.all;
 use work.simple_ram_behavioural_helpers.all;
 
-entity simple_ram_behavioural is
+entity mw_soc_memory is
        generic (
-               FILENAME : string;
-               SIZE     : integer
+               RAM_INIT_FILE : string;
+               MEMORY_SIZE   : integer
        );
 
        port (
@@ -20,14 +20,14 @@ entity simple_ram_behavioural is
                wishbone_in  : in wishbone_master_out;
                wishbone_out : out wishbone_slave_out
        );
-end simple_ram_behavioural;
+end mw_soc_memory;
 
-architecture behave of simple_ram_behavioural is
+architecture behave of mw_soc_memory is
        type wishbone_state_t is (IDLE, ACK);
 
        signal state      : wishbone_state_t := IDLE;
        signal ret_ack    : std_ulogic := '0';
-       signal identifier : integer := behavioural_initialize(filename => FILENAME, size => SIZE);
+       signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE, size => MEMORY_SIZE);
        signal reload     : integer := 0;
 begin
        wishbone_process: process(clk)
index 823c1b6f27a2711f9205e6ac2354c92bab09e9a3..9523cd1bb84490dcd3194276e3b61c3d8db640e8 100644 (file)
@@ -17,8 +17,8 @@ architecture behave of simple_ram_behavioural_tb is
        signal w_in         : wishbone_slave_out;
        signal w_out        : wishbone_master_out;
 begin
-       simple_ram_0: entity work.simple_ram_behavioural
-               generic map ( filename => "simple_ram_behavioural_tb.bin", size => 16 )
+       simple_ram_0: entity work.mw_soc_memory
+               generic map ( RAM_INIT_FILE => "simple_ram_behavioural_tb.bin", MEMORY_SIZE => 16 )
                port map (clk => clk, rst => rst, wishbone_out => w_in, wishbone_in => w_out);
 
        clock: process
diff --git a/soc.vhdl b/soc.vhdl
new file mode 100644 (file)
index 0000000..0b8614c
--- /dev/null
+++ b/soc.vhdl
@@ -0,0 +1,177 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.math_real.all;
+
+use std.textio.all;
+
+library work;
+use work.common.all;
+use work.wishbone_types.all;
+
+
+-- 0x00000000: Main memory (1 MB)
+-- 0xc0002000: UART0 (for host communication)
+entity soc is
+    generic (
+       MEMORY_SIZE   : positive;
+       RAM_INIT_FILE : string;
+       RESET_LOW     : boolean;
+       SIM           : boolean
+       );
+    port(
+       rst          : in  std_ulogic;
+       system_clk   : in  std_logic;
+
+       -- UART0 signals:
+       uart0_txd    : out std_logic;
+       uart0_rxd    : in  std_logic
+       );
+end entity soc;
+
+architecture behaviour of soc is
+
+    -- Wishbone master signals:
+    signal wishbone_dcore_in : wishbone_slave_out;
+    signal wishbone_dcore_out : wishbone_master_out;
+    signal wishbone_icore_in : wishbone_slave_out;
+    signal wishbone_icore_out : wishbone_master_out;
+
+    -- Wishbone master (output of arbiter):
+    signal wb_master_in : wishbone_slave_out;
+    signal wb_master_out : wishbone_master_out;
+
+    -- UART0 signals:
+    signal wb_uart0_in   : wishbone_master_out;
+    signal wb_uart0_out  : wishbone_slave_out;
+    signal uart_dat8     : std_logic_vector(7 downto 0);
+
+    -- Main memory signals:
+    signal wb_bram_in     : wishbone_master_out;
+    signal wb_bram_out    : wishbone_slave_out;
+    constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
+
+    -- Debug signals (used in SIM only)
+    signal registers     : regfile;
+    signal terminate     : std_ulogic;
+
+begin
+
+    -- Processor core
+    processor: entity work.core
+       generic map(
+           SIM => SIM
+           )
+       port map(
+           clk => system_clk,
+           rst => rst,
+           wishbone_insn_in => wishbone_icore_in,
+           wishbone_insn_out => wishbone_icore_out,
+           wishbone_data_in => wishbone_dcore_in,
+           wishbone_data_out => wishbone_dcore_out,
+           registers => registers,
+           terminate_out => terminate
+           );
+
+    -- Wishbone bus master arbiter & mux
+    wishbone_arbiter_0: entity work.wishbone_arbiter
+       port map(
+           clk => system_clk,
+           rst => rst,
+           wb1_in => wishbone_dcore_out,
+           wb1_out => wishbone_dcore_in,
+           wb2_in => wishbone_icore_out,
+           wb2_out => wishbone_icore_in,
+           wb_out => wb_master_out,
+           wb_in => wb_master_in
+           );
+
+    -- 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,
+                           SLAVE_MEMORY,
+                           SLAVE_NONE);
+       variable slave : slave_type;
+    begin
+       -- Simple address decoder
+       slave := SLAVE_NONE;
+       if wb_master_out.adr(63 downto 24) = x"0000000000" 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;
+           end if;
+       end if;
+
+       -- Wishbone muxing. Defaults:
+       wb_bram_in <= wb_master_out;
+       wb_bram_in.cyc  <= '0';
+       wb_uart0_in <= wb_master_out;
+       wb_uart0_in.cyc <= '0';
+       case slave is
+       when SLAVE_MEMORY =>
+           wb_bram_in.cyc <= wb_master_out.cyc;
+           wb_master_in <= wb_bram_out;
+       when SLAVE_UART =>
+           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;
+       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
+    --            converts SELs into low address bits and muxes
+    --            data accordingly (either that or rejects large
+    --            cycles).
+    uart0: entity work.pp_soc_uart
+       generic map(
+           FIFO_DEPTH => 32
+           )
+       port map(
+           clk => system_clk,
+           reset => rst,
+           txd => uart0_txd,
+           rxd => uart0_rxd,
+           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_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"00000000000000" & uart_dat8;
+
+    -- BRAM Memory slave
+    bram0: entity work.mw_soc_memory
+       generic map(
+           MEMORY_SIZE   => MEMORY_SIZE,
+           RAM_INIT_FILE => RAM_INIT_FILE
+           )
+       port map(
+           clk => system_clk,
+           rst => rst,
+           wishbone_in => wb_bram_in,
+           wishbone_out => wb_bram_out
+           );
+
+end architecture behaviour;