URL
https://opencores.org/ocsvn/rv01_riscv_core/rv01_riscv_core/trunk
Subversion Repositories rv01_riscv_core
[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_bpu.vhd] - Rev 2
Compare with Previous | Blame | View Log
----------------------------------------------------------------- -- -- ----------------------------------------------------------------- -- -- -- Copyright (C) 2016 Stefano Tonello -- -- -- -- This source file may be used and distributed without -- -- restriction provided that this copyright statement is not -- -- removed from the file and that any derivative work contains -- -- the original copyright notice and the associated disclaimer.-- -- -- -- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY -- -- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -- -- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- -- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR -- -- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -- -- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -- -- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -- -- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -- -- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- -- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -- -- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- -- POSSIBILITY OF SUCH DAMAGE. -- -- -- ----------------------------------------------------------------- --------------------------------------------------------------- -- RV01 Branch Prediction Unit --------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; library work; use work.RV01_CONSTS_PKG.all; use work.RV01_TYPES_PKG.all; use work.RV01_FUNCS_PKG.all; use work.RV01_ARITH_PKG.all; use work.RV01_OP_PKG.all; entity RV01_BPU is generic( BHT_SIZE : natural := 64; PXE : std_logic := '1'; NW : natural := 2 ); port( CLK_i : in std_logic; RST_i : in std_logic; INIT_STRT_i : in std_logic; -- prediction port IF_V_i : in std_logic_vector(NW-1 downto 0); IF_PC_i : in ADR_VEC_T(NW-1 downto 0); IF2_V_i : in std_logic_vector(NW-1 downto 0); IF2_PC_i : in ADR_VEC_T(NW-1 downto 0); -- verification port BHT_BTA_i : in ADR_VEC_T(NW-1 downto 0); BHT_PC_i : in ADR_VEC_T(NW-1 downto 0); BHT_CNT0_i : in std_logic_vector(2-1 downto 0); BHT_CNT1_i : in std_logic_vector(2-1 downto 0); BHT_WE_i : in std_logic_vector(NW-1 downto 0); INIT_END_o : out std_logic; -- prediction port PBX_o : out std_logic; KLL1_o : out std_logic; PBTA_o : out unsigned(ALEN-1 downto 0); -- verification port BPVD0_o : out std_logic_vector(3-1 downto 0); BPVD1_o : out std_logic_vector(3-1 downto 0) ); end RV01_BPU; architecture ARC of RV01_BPU is component RV01_BHT is generic( BHT_SIZE : natural := 64; PXE : std_logic := '1' ); port( CLK_i : in std_logic; RST_i : in std_logic; BHTV_WE_i : in std_logic; BHTV_WADR_i : natural range 0 to BHT_SIZE-1; -- prediction port IF_V_i : std_logic; IF_PC_i : ADR_T; IF2_V_i : std_logic; IF2_PC_i : ADR_T; -- verification port BHT_BTA_i : in ADR_T; BHT_PC_i : in ADR_T; BHT_CNT_i : in std_logic_vector(2-1 downto 0); BHT_WE_i : in std_logic; -- prediction port PBX_o : out std_logic; PBTA_o : out unsigned(ALEN-1 downto 0); -- verification port BPVD_o : out std_logic_vector(3-1 downto 0) ); end component; signal IF_V : std_logic_vector(NW-1 downto 0); signal IF_PC : ADR_VEC_T(NW-1 downto 0); signal IF2_V : std_logic_vector(NW-1 downto 0); signal IF2_PC : ADR_VEC_T(NW-1 downto 0); signal BHT_BTA : ADR_VEC_T(NW-1 downto 0); signal BHT_PC : ADR_VEC_T(NW-1 downto 0); signal BHT_CNT0,BHT_CNT1 : std_logic_vector(2-1 downto 0); signal BHT_WE : std_logic_vector(NW-1 downto 0); signal PBX : std_logic_vector(NW-1 downto 0); signal PBTA : ADR_VEC_T(NW-1 downto 0); signal BHT_CNT_q : natural range 0 to BHT_SIZE-1; signal BHT_INIT_q : std_logic; signal INIT_END : std_logic; signal BPVD0,BPVD1 : std_logic_vector(3-1 downto 0); begin ------------------------------------ -- Note ------------------------------------ -- This module performs branch and jal instructions -- predictions using a branch history table (BHT) -- based on 2-bit saturating counters. -- The module includes two BHT's, one for even -- address instructions and one for odd address -- instructions and is able to predict up to -- two branch/jal instructions per cycle. ------------------------------------ -- BHT initalization ------------------------------------ -- BHT address generator process(CLK_i) begin if(CLK_i = '1' and CLK_i'event) then if(RST_i = '1') then BHT_CNT_q <= 0; elsif(BHT_INIT_q = '1' and BHT_CNT_q < BHT_SIZE-1) then BHT_CNT_q <= BHT_CNT_q + 1; end if; end if; end process; -- Initialization end flag INIT_END <= '1' when BHT_CNT_q = BHT_SIZE-1 else '0'; INIT_END_o <= INIT_END; -- Initialization status process(CLK_i) begin if(CLK_i = '1' and CLK_i'event) then if(RST_i = '1') then BHT_INIT_q <= '0'; elsif(INIT_STRT_i = '1') then BHT_INIT_q <= '1'; elsif(INIT_END = '1') then BHT_INIT_q <= '0'; end if; end if; end process; ------------------------------------ -- BHT's ------------------------------------ -- BHT #0 provides branch prediction for -- even word adresss instructions, while BHT #1 -- provides branch prediction for odd word adresss -- instructions. U_BHT0 : RV01_BHT generic map( BHT_SIZE => BHT_SIZE, PXE => PXE ) port map( CLK_i => CLK_i, RST_i => RST_i, BHTV_WE_i => BHT_INIT_q, BHTV_WADR_i => BHT_CNT_q, IF_V_i => IF_V(0), IF_PC_i => IF_PC(0), IF2_V_i => IF2_V(0), IF2_PC_i => IF2_PC(0), BHT_BTA_i => BHT_BTA(0), BHT_PC_i => BHT_PC(0), BHT_CNT_i => BHT_CNT0, BHT_WE_i => BHT_WE(0), PBX_o => PBX(0), PBTA_o => PBTA(0), BPVD_o => BPVD0 ); GPX_0_1 : if PXE = '1' generate U_BHT1 : RV01_BHT generic map( BHT_SIZE => BHT_SIZE ) port map( CLK_i => CLK_i, RST_i => RST_i, BHTV_WE_i => BHT_INIT_q, BHTV_WADR_i => BHT_CNT_q, IF_V_i => IF_V(1), IF_PC_i => IF_PC(1), IF2_V_i => IF2_V(1), IF2_PC_i => IF2_PC(1), BHT_BTA_i => BHT_BTA(1), BHT_PC_i => BHT_PC(1), BHT_CNT_i => BHT_CNT1, BHT_WE_i => BHT_WE(1), PBX_o => PBX(1), PBTA_o => PBTA(1), BPVD_o => BPVD1 ); end generate; -- GPX_0_1 GPX_0_0 : if PXE = '0' generate PBX(1) <= '0'; PBTA(1) <= (others => '0'); BPVD1 <= (others => '0'); end generate; -- GPX_0_0 ------------------------------------ -- Prediction input data mux ------------------------------------ IF_V(0) <= IF_V_i(0); IF_PC(0) <= IF_PC_i(0); IF_V(1) <= IF_V_i(1); IF_PC(1) <= IF_PC_i(1); IF2_V(0) <= IF2_V_i(0); IF2_V(1) <= IF2_V_i(1); IF2_PC(0) <= IF2_PC_i(0); IF2_PC(1) <= IF2_PC_i(1); BPVD0_o <= BPVD0; BPVD1_o <= BPVD1; -- Predicted branch execute flag PBX_o <= PBX(0) or PBX(1); -- Predicted branch target address -- (slot #0 takes priority over slot #1) PBTA_o <= PBTA(0) when (PBX(0) = '1' or PXE = '0') else PBTA(1); -- If slot #0 instruction is a predicted -- taken branch, slot #1 instruction must -- be nullified. KLL1_o <= PBX(0); ------------------------------------ -- BHT update data mux ------------------------------------ -- Instructions in IX1 stage (where branch -- predictions are verified) can be in -- even-odd or odd-even address order -- requiring proper multiplexing of data -- input to BHT's. process(BHT_PC_i,BHT_BTA_i,BHT_WE_i,BHT_CNT0_i,BHT_CNT1_i) begin if(BHT_PC_i(0)(2) = '0') then -- instructions are in even-odd order BHT_BTA(0) <= BHT_BTA_i(0); BHT_PC(0) <= BHT_PC_i(0); BHT_CNT0 <= BHT_CNT0_i; BHT_WE(0) <= BHT_WE_i(0); BHT_BTA(1) <= BHT_BTA_i(1); BHT_PC(1) <= BHT_PC_i(1); BHT_CNT1 <= BHT_CNT1_i; BHT_WE(1) <= BHT_WE_i(1); else -- instructions are in odd-even order BHT_BTA(0) <= BHT_BTA_i(1); BHT_PC(0) <= BHT_PC_i(1); BHT_CNT0 <= BHT_CNT1_i; BHT_WE(0) <= BHT_WE_i(1); BHT_BTA(1) <= BHT_BTA_i(0); BHT_PC(1) <= BHT_PC_i(0); BHT_CNT1 <= BHT_CNT0_i; BHT_WE(1) <= BHT_WE_i(0); end if; end process; end ARC;