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; COMPATIBILITY_MODE_g : boolean := false ); 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 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_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_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 ); 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_clken_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 delay_bit_r : std_logic; signal ID2GPRF_s : ID2GPRF_Type; signal GPRF2EX_s : GPRF2EX_Type; signal EX2IF_s, EX2IF_r : EX2IF_Type; signal EX2CTRL_s : EX2CTRL_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 HALT_s : HALT_Type; signal ext_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 halted_o <= HALT_s.halt; halt_code_o <= HALT_s.halt_code; 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 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_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 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_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 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, COMPATIBILITY_MODE_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 ); 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, 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, HALT_o => HALT_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 generic map (COMPATIBILITY_MODE_g) port map ( clk_i => clk_i, rst_i => rst_i, halt_i => ext_halt_s, int_i => int_i, trace_i => trace_i, trace_kick_i => trace_kick_i, core_clken_o => core_clken_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, delay_bit_o => delay_bit_r, -- GPRF control gprf_clken_o => gprf_clken_s, -- exeq to fetch feedback registers EX2IF_REG_i => EX2IF_s, EX2IF_REG_o => EX2IF_r, EX2CTRL_REG_i => EX2CTRL_s, -- exeq to core (halting) exeq_halt_i => HALT_s.halt, -- 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 ); 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'; 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; end if; end process regd_proc; end architecture rtl;