]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blobdiff - hw/lx-rocon_tumbl/lx_rocon_tumbl.vhd
Tumbl: Separate wait for external bus data and state when external bus is taken by...
[fpga/lx-cpu1/lx-rocon.git] / hw / lx-rocon_tumbl / lx_rocon_tumbl.vhd
index a0957ec19aa118a94d42b82e51a4fde28ca12ecb..eafdf59cf66c7d38e1385e298e0d06dc9f3a5166 100644 (file)
@@ -4,17 +4,18 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- Tumbl configured as a coprocessor for lx_rocon
--- Uses 10 bits width address bus with HW barrel and multiplier
+-- Uses 12 bits width address bus with HW barrel and multiplier
 
 entity lx_rocon_tumbl is
        generic
        (
-               IMEM_ABITS_g         : positive := 11;
-               DMEM_ABITS_g         : positive := 12;
+               -- This is for 32-bit addressing
+               IMEM_ABITS_g         : positive := 9;
+               DMEM_ABITS_g         : positive := 10;
                --
                USE_HW_MUL_g         : boolean := true;
                USE_BARREL_g         : boolean := true;
@@ -48,18 +49,18 @@ entity lx_rocon_tumbl is
     dmem_data_i  : in std_logic_vector(31 downto 0);
     dmem_data_o  : out std_logic_vector(31 downto 0);
                -- External memory bus
-               XMEMB_sel_o  : out std_logic;
-               XMEMB_i      : in DMEMB2CORE_Type;
-               XMEMB_o      : out CORE2DMEMB_Type
+               xmemb_sel_o  : out std_logic;
+               xmemb_i      : in DMEMB2CORE_Type;
+               xmemb_o      : out CORE2DMEMB_Type
        );
 end entity lx_rocon_tumbl;
 
 architecture rtl of lx_rocon_tumbl is
 
-       constant DMEM_TEST_c : std_logic_vector((31-DMEM_ABITS_g) downto 0) := (others => '0');
+       constant DMEM_TEST_c : std_logic_vector((14-DMEM_ABITS_g) downto 0) := (others => '0');
 
        signal imem_clken_s  : std_logic;
-       signal imem_addr_s   : std_logic_vector(31 downto 0);
+       signal imem_addr_s   : std_logic_vector((IMEM_ABITS_g-1) downto 0);
        signal imem_data_s   : std_logic_vector(31 downto 0);
        signal gprf_clken_s  : std_logic;
        signal core_clken_s  : std_logic;
@@ -95,12 +96,13 @@ architecture rtl of lx_rocon_tumbl is
        signal dmem_really_sel_s          : std_logic;
        signal gprf_really_clken_s        : std_logic;
 
+
 begin
 
        -- select internal data memory when all address bits above DMEM_ABITS_g are zero
-       dmem_sel_s  <= '1' when (c2dmemb_s.addr(31 downto DMEM_ABITS_g) = DMEM_TEST_c)
+       dmem_sel_s  <= '1' when (c2dmemb_s.addr(14 downto DMEM_ABITS_g) = DMEM_TEST_c)
                                                                        else '0';
-       XMEMB_sel_o <= not dmem_sel_s;
+       XMEMB_sel_o <= (not dmem_sel_s) and core_clken_s;
        XMEMB_o     <= c2dmemb_s;
        pc_o        <= ID2EX_r.program_counter; -- Program counter for EXEQ
        halted_o    <= HALT_s.halt;
@@ -111,12 +113,12 @@ begin
        dmem_really_sel_s   <= dmem_sel_s and core_clken_s;
        gprf_really_clken_s <= gprf_clken_s and core_clken_s;
 
-       I_IMEM: lx_rocon_imem
+I_IMEM: lx_rocon_imem
        port map
        (
                clk_i  => clk_i,
                cs_i   => imem_really_clken_s,
-               adr_i  => imem_addr_s((IMEM_ABITS_g-1) downto 2),
+               adr_i  => imem_addr_s((IMEM_ABITS_g-1) downto 0),
                dat_o  => imem_data_s,
 
                clk_m  => imem_clk_i,
@@ -127,14 +129,13 @@ begin
                dout_m => imem_data_o
        );
 
-       I_DMEM: lx_rocon_dmem
+I_DMEM: lx_rocon_dmem
        port map
        (
                clk_i  => clk_i,
                ce_i   => dmem_really_sel_s,
-               adr_i  => c2dmemb_s.addr((DMEM_ABITS_g-1) downto 2),
-               wre_i  => c2dmemb_s.wre,
-               bsel_i => c2dmemb_s.bSel,
+               adr_i  => c2dmemb_s.addr((DMEM_ABITS_g-1) downto 0),
+               bls_i  => c2dmemb_s.bls,
                dat_i  => c2dmemb_s.data,
                dat_o  => dmem_data_s,
 
@@ -146,7 +147,7 @@ begin
                dout_m => dmem_data_o
        );
 
-       I_FETCH: fetch
+I_FETCH: fetch
        port map
        (
                prog_cntr_i => IF2ID_r.program_counter,
@@ -155,7 +156,7 @@ begin
                IF2ID_o     => IF2ID_s
        );
 
-       I_DECODE: decode
+I_DECODE: decode
        generic map(USE_HW_MUL_g, USE_BARREL_g, COMPATIBILITY_MODE_g)
        port map
        (
@@ -169,7 +170,7 @@ begin
                ID2CTRL_o   => ID2CTRL_s
        );
 
-       I_GPRF: lx_rocon_gprf_abd
+I_GPRF: lx_rocon_gprf_abd
        port map
        (
                clk_i        => clk_i,
@@ -181,7 +182,7 @@ begin
                GPRF2EX_o    => GPRF2EX_s
        );
 
-       I_EXEQ: exeq
+I_EXEQ: exeq
        generic map(USE_HW_MUL_g, USE_BARREL_g, COMPATIBILITY_MODE_g)
        port map
        (
@@ -212,11 +213,12 @@ begin
 
        -- this is a very simple address block decoder, just "internal" dmem or "external"
        -- clken and int hardwired for fast internal data-memory
-       DMEMB_i_s.clken <= '1'          when (dmem_sel_s = '1') else XMEMB_i.clken;
-       DMEMB_i_s.data  <=  dmem_data_s when (dmem_sel_r = '1') else XMEMB_i.data;
+       DMEMB_i_s.bus_wait  <= '0'     when (dmem_sel_s = '1') else XMEMB_i.bus_wait;
+       DMEMB_i_s.bus_taken <= '0'     when (dmem_sel_s = '1') else XMEMB_i.bus_taken;
+       DMEMB_i_s.data  <= dmem_data_s when (dmem_sel_r = '1') else XMEMB_i.data;
        DMEMB_i_s.int   <= XMEMB_i.int;
 
-       I_MEM: mem
+I_MEM: mem
        port map
        (
                EX2MEM_i    => EX2MEM_r,
@@ -231,8 +233,8 @@ begin
                MEM2CTRL_o => MEM2CTRL_s
        );
 
-       I_CTRL: core_ctrl
-       generic map (COMPATIBILITY_MODE_g)
+I_CTRL: core_ctrl
+       generic map (IMEM_ABITS_g, COMPATIBILITY_MODE_g)
        port map
        (
                clk_i           => clk_i,
@@ -286,16 +288,14 @@ begin
                MEM2CTRL_i      => MEM2CTRL_s
        );
 
-       regd_proc: process(clk_i, rst_i)
+regd_proc:
+       process
        begin
-               if clk_i = '1' and clk_i'event then
-                       if (rst_i = '1') then           -- synchronous reset ...
-                               dmem_sel_r <= '1';
-                       else                            -- delay select_external_mem (needed for reading ...)
-                               if (DMEMB_i_s.clken = '1') then
-                                       dmem_sel_r <= dmem_sel_s;   -- OR c2dmemb_s.wre; ??
-                               end if;
-                       end if;
+               wait until clk_i'event and clk_i = '1';
+               if (rst_i = '1') then           -- synchronous reset ...
+                       dmem_sel_r   <= '1';
+               else                            -- delay select_external_mem (needed for reading ...)
+                       dmem_sel_r <= dmem_sel_s;   -- OR c2dmemb_s.wre; ??
                end if;
        end process regd_proc;