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;
+ USE_HW_MUL_g : boolean := true;
+ USE_BARREL_g : boolean := true;
COMPATIBILITY_MODE_g : boolean := false
);
port
int_i : in std_logic;
trace_i : in std_logic;
trace_kick_i : in std_logic;
-
-- Program counter
pc_o : out std_logic_vector(31 downto 0);
-
-- Internal halt (remove with trace kick)
halted_o : out std_logic;
halt_code_o : out std_logic_vector(4 downto 0);
-
-- Internal memory (instruction)
- imem_clk : in std_logic;
- imem_en : in std_logic;
- imem_we : in std_logic_vector(3 downto 0);
- imem_addr : in std_logic_vector(8 downto 0);
- imem_din : in std_logic_vector(31 downto 0);
- imem_dout : out std_logic_vector(31 downto 0);
-
+ imem_clk_i : in std_logic;
+ imem_en_i : in std_logic;
+ imem_we_i : in std_logic_vector(3 downto 0);
+ imem_addr_i : in std_logic_vector(8 downto 0);
+ imem_data_i : in std_logic_vector(31 downto 0);
+ imem_data_o : out std_logic_vector(31 downto 0);
-- Internal memory (data)
- dmem_clk : in std_logic;
- dmem_en : in std_logic;
- dmem_we : in std_logic_vector(3 downto 0);
- dmem_addr : in std_logic_vector(9 downto 0);
- dmem_din : in std_logic_vector(31 downto 0);
- dmem_dout : out std_logic_vector(31 downto 0);
-
+ dmem_clk_i : in std_logic;
+ dmem_en_i : in std_logic;
+ dmem_we_i : in std_logic_vector(3 downto 0);
+ dmem_addr_i : in std_logic_vector(9 downto 0);
+ 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;
- --
- bad_op_o : out std_logic
+ 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;
signal IF2ID_s, IF2ID_r : IF2ID_Type;
signal ID2EX_s, ID2EX_r : ID2EX_Type;
+ signal delay_bit_r : std_logic;
signal ID2GPRF_s : ID2GPRF_Type;
signal GPRF2EX_s : GPRF2EX_Type;
signal EX2IF_s, EX2IF_r : EX2IF_Type;
signal MSR2EX_s : MSR_Type;
signal MEM_REG_s, MEM_REG_r : MEM_REG_Type;
signal dmem_sel_s, dmem_sel_r : std_logic;
- signal bad_op_s : std_logic;
signal HALT_s : HALT_Type;
signal ext_halt_s : std_logic;
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;
halt_code_o <= HALT_s.halt_code;
- bad_op_o <= bad_op_s;
ext_halt_s <= halt_i;
imem_really_clken_s <= imem_clken_s and core_clken_s;
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),
- dat_o => imem_data_s,
+ clk_i => clk_i,
+ cs_i => imem_really_clken_s,
+ adr_i => imem_addr_s((IMEM_ABITS_g-1) downto 0),
+ dat_o => imem_data_s,
- clk_m => imem_clk,
- en_m => imem_en,
- we_m => imem_we,
- addr_m => imem_addr,
- din_m => imem_din,
- dout_m => imem_dout
+ clk_m => imem_clk_i,
+ en_m => imem_en_i,
+ we_m => imem_we_i,
+ addr_m => imem_addr_i,
+ din_m => imem_data_i,
+ 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,
- clk_m => dmem_clk,
- en_m => dmem_en,
- we_m => dmem_we,
- addr_m => dmem_addr,
- din_m => dmem_din,
- dout_m => dmem_dout
+ clk_m => dmem_clk_i,
+ en_m => dmem_en_i,
+ we_m => dmem_we_i,
+ addr_m => dmem_addr_i,
+ din_m => dmem_data_i,
+ dout_m => dmem_data_o
);
- I_FETCH: fetch
+I_FETCH: fetch
port map
(
prog_cntr_i => IF2ID_r.program_counter,
IF2ID_o => IF2ID_s
);
- I_DECODE: decode
+I_DECODE: decode
generic map(USE_HW_MUL_g, USE_BARREL_g, COMPATIBILITY_MODE_g)
port map
(
ID2EX_o => ID2EX_s,
--
INT_CTRL_i => INT_CTRL_s,
- ID2CTRL_o => ID2CTRL_s,
- --
- noLiteOpc_o => bad_op_s
+ ID2CTRL_o => ID2CTRL_s
);
- I_GPRF: lx_rocon_gprf_abd
+I_GPRF: lx_rocon_gprf_abd
port map
(
clk_i => clk_i,
GPRF2EX_o => GPRF2EX_s
);
- I_EXEQ: exeq
+I_EXEQ: exeq
generic map(USE_HW_MUL_g, USE_BARREL_g, COMPATIBILITY_MODE_g)
port map
(
+ IF2ID_i => IF2ID_r,
+ --
ID2EX_i => ID2EX_r,
+ delayBit_i => delay_bit_r,
GPRF2EX_i => GPRF2EX_s,
EX2IF_o => EX2IF_s,
EX2CTRL_o => EX2CTRL_s,
-- 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,
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,
rst_i => rst_i,
halt_i => ext_halt_s,
- bad_op_i => bad_op_s,
int_i => int_i,
trace_i => trace_i,
trace_kick_i => trace_kick_i,
-- decode to exeq pipeline registers
ID2EX_REG_i => ID2EX_s,
ID2EX_REG_o => ID2EX_r,
+ delay_bit_o => delay_bit_r,
-- GPRF control
gprf_clken_o => gprf_clken_s,
-- exeq to fetch feedback registers
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;