OpenCores
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 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 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;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.