+library ieee;
+
+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.lx_rocon_pkg.all;
+
+-- Tumbl configured as a coprocessor for lx_rocon
+-- Uses 10 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;
+ --
+ USE_HW_MUL_g : boolean := true;
+ USE_BARREL_g : boolean := true
+ );
+ port
+ (
+ clk_i : in std_logic;
+ rst_i : in std_logic;
+ halt_i : in std_logic;
+ 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 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);
+
+ -- 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);
+
+ -- 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;
+ done_o : out std_logic
+ );
+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');
+
+ signal imem_clken_s : std_logic;
+ signal imem_addr_s : std_logic_vector(31 downto 0);
+ signal imem_data_s : std_logic_vector(31 downto 0);
+ signal gprf_clken_s : std_logic;
+ signal core_clk_en_s : std_logic;
+ signal pc_ctrl_s : std_logic;
+ signal c2dmemb_s : CORE2DMEMB_Type;
+ signal dmem_data_s : std_logic_vector(31 downto 0);
+ signal DMEMB_i_s : DMEMB2CORE_Type;
+
+ signal MEM2CTRL_s : MEM2CTRL_Type;
+ signal INT_CTRL_s : INT_CTRL_Type;
+ signal ID2CTRL_s : ID2CTRL_Type;
+
+ signal IF2ID_s, IF2ID_r : IF2ID_Type;
+ signal ID2EX_s, ID2EX_r : ID2EX_Type;
+ signal ID2GPRF_s : ID2GPRF_Type;
+ signal GPRF2EX_s : GPRF2EX_Type;
+ signal EX2IF_s, EX2IF_r : EX2IF_Type;
+ signal EX2MEM_s, EX2MEM_r : EX2MEM_Type;
+ signal EX_WRB_s, EX_WRB_r : WRB_Type;
+ signal MEM_WRB_s : WRB_Type;
+ signal IMM_LOCK_s, IMM_LOCK_r : IMM_LOCK_Type;
+ signal HAZARD_WRB_s, HAZARD_WRB_r : HAZARD_WRB_Type;
+ signal EX2MSR_s : MSR_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 BAD_OP_up_s : std_logic;
+ signal halt_s : std_logic;
+
+ signal imem_really_clken_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)
+ else '0';
+ XMEMB_sel_o <= not dmem_sel_s;
+ XMEMB_o <= c2dmemb_s;
+ pc_o <= ID2EX_r.program_counter; -- Program counter for EXEQ
+ bad_op_o <= BAD_OP_s;
+ halt_s <= halt_i or BAD_OP_up_s;
+
+ imem_really_clken_s <= imem_clken_s and core_clk_en_s;
+ dmem_really_sel_s <= dmem_sel_s and core_clk_en_s;
+ gprf_really_clken_s <= gprf_clken_s and core_clk_en_s;
+
+ 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_m => imem_clk,
+ en_m => imem_en,
+ we_m => imem_we,
+ addr_m => imem_addr,
+ din_m => imem_din,
+ dout_m => imem_dout
+ );
+
+ 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,
+ 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
+ );
+
+ I_FETCH: fetch
+ port map
+ (
+ prog_cntr_i => IF2ID_r.program_counter,
+ inc_pc_i => pc_ctrl_s,
+ EX2IF_i => EX2IF_r,
+ IF2ID_o => IF2ID_s
+ );
+
+ I_DECODE: decode
+ generic map(USE_HW_MUL_g, USE_BARREL_g)
+ port map
+ (
+ IF2ID_i => IF2ID_r,
+ imem_data_i => imem_data_s,
+ --
+ ID2GPRF_o => ID2GPRF_s,
+ ID2EX_o => ID2EX_s,
+ --
+ INT_CTRL_i => INT_CTRL_s,
+ ID2CTRL_o => ID2CTRL_s,
+ --
+ noLiteOpc_o => BAD_OP_s
+ );
+
+ I_GPRF: lx_rocon_gprf_abd
+ port map
+ (
+ clk_i => clk_i,
+ rst_i => rst_i,
+ clken_i => gprf_really_clken_s,
+ --
+ ID2GPRF_i => ID2GPRF_s,
+ MEM_WRB_i => MEM_WRB_s,
+ GPRF2EX_o => GPRF2EX_s
+ );
+
+ I_EXEQ: exeq
+ generic map(USE_HW_MUL_g, USE_BARREL_g)
+ port map
+ (
+ ID2EX_i => ID2EX_r,
+ GPRF2EX_i => GPRF2EX_s,
+ EX2IF_o => EX2IF_s,
+ --
+ EX_WRB_i => EX_WRB_r,
+ EX_WRB_o => EX_WRB_s,
+ MEM_WRB_i => MEM_WRB_s,
+ --
+ HAZARD_WRB_i => HAZARD_WRB_r,
+ HAZARD_WRB_o => HAZARD_WRB_s,
+ --
+ IMM_LOCK_i => IMM_LOCK_r,
+ IMM_LOCK_o => IMM_LOCK_s,
+ --
+ MSR_i => MSR2EX_s,
+ MSR_o => EX2MSR_s,
+ --
+ EX2MEM_o => EX2MEM_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.int <= XMEMB_i.int;
+
+ I_MEM: mem
+ port map
+ (
+ EX2MEM_i => EX2MEM_r,
+ MEM_WRB_o => MEM_WRB_s,
+ --
+ DMEMB_i => DMEMB_i_s,
+ DMEMB_o => c2dmemb_s,
+ --
+ MEM_REG_i => MEM_REG_r,
+ MEM_REG_o => MEM_REG_s,
+ --
+ MEM2CTRL_o => MEM2CTRL_s
+ );
+
+ I_CTRL: core_ctrl
+ port map
+ (
+ clk_i => clk_i,
+ rst_i => rst_i,
+ halt_i => halt_s,
+ int_i => int_i,
+ trace_i => trace_i,
+ trace_kick_i => trace_kick_i,
+ core_clk_en_o => core_clk_en_s,
+ -- specific fetch i/o
+ imem_addr_o => imem_addr_s,
+ imem_clken_o => imem_clken_s,
+ pc_ctrl_o => pc_ctrl_s,
+ -- fetch to decode pipeline registers
+ IF2ID_REG_i => IF2ID_s,
+ IF2ID_REG_o => IF2ID_r,
+ -- decode to exeq pipeline registers
+ ID2EX_REG_i => ID2EX_s,
+ ID2EX_REG_o => ID2EX_r,
+ -- GPRF control
+ gprf_clken_o => gprf_clken_s,
+ -- exeq to fetch feedback registers
+ EX2IF_REG_i => EX2IF_s,
+ EX2IF_REG_o => EX2IF_r,
+ -- exeq to mem pipeline registers
+ EX2MEM_REG_i => EX2MEM_s,
+ EX2MEM_REG_o => EX2MEM_r,
+ -- mem pipeline register
+ MEM_REG_i => MEM_REG_s,
+ MEM_REG_o => MEM_REG_r,
+ -- decode control i/o
+ ID2CTRL_i => ID2CTRL_s,
+ INT_CTRL_o => INT_CTRL_s,
+ -- exeq control i/o
+ EX_WRB_i => EX_WRB_s,
+ EX_WRB_o => EX_WRB_r,
+ -- data hazard i/o
+ HAZARD_WRB_i => HAZARD_WRB_s,
+ HAZARD_WRB_o => HAZARD_WRB_r,
+ -- for handling the 'IMM' instruction
+ IMM_LOCK_i => IMM_LOCK_s,
+ IMM_LOCK_o => IMM_LOCK_r,
+ -- for handling the Machine Status Register
+ MSR_i => EX2MSR_s,
+ MSR_o => MSR2EX_s,
+ -- miscellaneous
+ MEM2CTRL_i => MEM2CTRL_s,
+ done_o => done_o
+ );
+
+ regd_proc: process(clk_i, rst_i)
+ begin
+ if clk_i = '1' and clk_i'event then
+ if (rst_i = '1') then -- synchronous reset ...
+ dmem_sel_r <= '1';
+ BAD_OP_up_s <= '0';
+ 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;
+ BAD_OP_up_s <= BAD_OP_up_s or BAD_OP_s;
+ end if;
+ end if;
+ end process regd_proc;
+
+end architecture rtl;