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

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.