URL
https://opencores.org/ocsvn/rv01_riscv_core/rv01_riscv_core/trunk
Subversion Repositories rv01_riscv_core
[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_bht.vhd] - Rev 4
Go to most recent revision | 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 History Table (Branch Prediction Sub-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_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 : unsigned(ALEN-1 downto 0); IF2_V_i : std_logic; IF2_PC_i : unsigned(ALEN-1 downto 0); -- 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 RV01_BHT; architecture ARC of RV01_BHT is function to_natural(B : std_logic) return natural is begin if(B = '1') then return(1); else return(0); end if; end function; constant FIX : natural := 1-to_natural(PXE); constant L2BHT_SIZE : natural := log2(BHT_SIZE); constant TAG_SIZE : natural := ALEN - (L2BHT_SIZE+3-FIX); constant CNT_SIZE : natural := 2; -- Each BHT entry holds: -- 1) branch target address (ALEN bits) -- 2) address tag (ALEN-L2BHT_SIZE bits) -- 3) saturating counter(2 bits) constant BHT_WIDTH : natural := ALEN + TAG_SIZE + CNT_SIZE; component RV01_RAM_1RW1R is generic( -- I/O data bus width DWIDTH : integer := 16; -- word count WCOUNT : integer := 256; STYLE : string := "auto" ); port( CLK_i : in std_logic; A_i : in unsigned(log2(WCOUNT)-1 downto 0); DPRA_i : in unsigned(log2(WCOUNT)-1 downto 0); D_i : in std_logic_vector(DWIDTH-1 downto 0); WE_i : in std_logic; Q_o : out std_logic_vector(DWIDTH-1 downto 0); DPQ_o : out std_logic_vector(DWIDTH-1 downto 0) ); end component ; signal BHT_V : std_logic; signal BHT_BTA : unsigned(ALEN-1 downto 0); signal BHT_PADR,BHT_VADR : unsigned(L2BHT_SIZE-1 downto 0); signal BHT_TAG : unsigned(TAG_SIZE-1 downto 0); signal BHT_CNT : std_logic_vector(CNT_SIZE-1 downto 0); signal BHT_TKN : std_logic; signal BHT_HIT : std_logic; signal BHT_D,BHT_Q : std_logic_vector(BHT_WIDTH-1 downto 0); signal BHTV_D,BHTV_Q : std_logic_vector(0 downto 0); signal BHTV_WE,BHT_INIT_q : std_logic; signal BHTV_VADR : unsigned(L2BHT_SIZE-1 downto 0); signal TAG_MTCH : std_logic; begin ------------------------------------ -- Notes ------------------------------------ -- This module implements a simple branch history -- table (BHT) based on 2-bit saturating counters. -- Each BHT entry stores branch prediction info -- for an instruction -- Prediction logic doesn't explicitly check if a -- fetched instruction is a branch, it just -- searches BHT for an entry matching fetch -- address. -- BHT entry valid bits are stored in a separated -- RAM allowing them to be cleared when BHT is -- initialized. A true RAM is used instead of a -- BHT_SIZE-bit register to reduce logic resource -- utlization for large BHT's. -- When parallel execution is enabled, BHT RAM -- address make reference to an instruction pair -- and therefore LS 3b are removed from fetch -- address. -- When parallel execution is NOT enabled, BHT RAM -- address make reference to a single instruction -- and therefore LS 2b only are removed from fetch -- address (this accomplished using FIX constant -- which is derived from PXE generic). -- BHT RAM size is doubled to keep the total entry -- count unchanged. ------------------------------------ -- BHT data RAM ------------------------------------ U_BHT : RV01_RAM_1RW1R generic map( DWIDTH => BHT_WIDTH, WCOUNT => BHT_SIZE, --*(1+FIX) STYLE => "BLOCK" ) port map( CLK_i => CLK_i, A_i => BHT_VADR, DPRA_i => BHT_PADR, D_i => BHT_D, WE_i => BHT_WE_i, Q_o => open, DPQ_o => BHT_Q ); ------------------------------------ -- BHT valid bits RAM ------------------------------------ U_BHTV : RV01_RAM_1RW1R generic map( DWIDTH => 1, WCOUNT => BHT_SIZE --*(1+FIX) ) port map( CLK_i => CLK_i, A_i => BHTV_VADR, DPRA_i => BHT_PADR, D_i => BHTV_D, WE_i => BHTV_WE, Q_o => open, DPQ_o => BHTV_Q ); -- Valid bits are cleared during BHT initialization -- by explicitly writing '0' to each BHTV entry. -- The value written to valid bit is '0' during -- initialization and '1' during normal operations -- (i.e. entries are never invalidated during -- normal operations, they can only be overwritten -- with data related to a aliased branch/jal). BHTV_D(0) <= not(BHTV_WE_i); BHTV_WE <= BHT_WE_i or BHTV_WE_i; BHTV_VADR <= BHT_VADR when BHTV_WE_i = '0' else to_unsigned(BHTV_WADR_i,L2BHT_SIZE); ------------------------------------ -- Branch prediction logic ------------------------------------ BHT_V <= BHTV_Q(0); -- BHT prediction address (PC LS bits) BHT_PADR <= IF_PC_i(L2BHT_SIZE+3-FIX-1 downto 3-FIX); -- BHT verification address (PC LS bits) BHT_VADR <= BHT_PC_i(L2BHT_SIZE+3-FIX-1 downto 3-FIX); -- Extract BTA, address tag, counter value and istruction -- selecting flag from BHT output BHT_BTA <= to_unsigned(BHT_Q(BHT_WIDTH-1 downto TAG_SIZE+CNT_SIZE)); BHT_TAG <= to_unsigned(BHT_Q(TAG_SIZE+CNT_SIZE-1 downto CNT_SIZE)); BHT_CNT <= BHT_Q(CNT_SIZE-1 downto 0); -- BHT tag match flag TAG_MTCH <= '1' when(BHT_TAG = IF2_PC_i(ALEN-1 downto L2BHT_SIZE+3-FIX)) else '0'; -- Prediction "hits" if: -- 1) target BHT entry is valid, AND -- 2) IF2 stage valid bit is set, AND -- 3) address tag matches. -- BHT prediction hit flag BHT_HIT <= BHT_V and IF2_V_i and TAG_MTCH; -- Predicted branch execute flag PBX_o <= TAG_MTCH and ( not(BHT_CNT(1)) and BHT_V and IF2_V_i ); -- Predicted branch target address (BHT BTA). PBTA_o <= BHT_BTA; ------------------------------------ -- BHT updating logic ------------------------------------ -- BHT updating data consists of: -- 1) prediction hit flag, -- 2) prediction count (this avoid to -- re-read BHT). -- 3) branch fetch address. -- Only items 1) and 2) need to be -- actually provided, as fetch address is -- available for each instruction. BPVD_o <= (BHT_CNT & '1') when (BHT_HIT = '1') else "110"; -- BHT updated data and valid bit BHT_D <= to_std_logic_vector(BHT_BTA_i) & to_std_logic_vector(BHT_PC_i(ALEN-1 downto L2BHT_SIZE+3-FIX)) & BHT_CNT_i; end ARC;
Go to most recent revision | Compare with Previous | Blame | View Log