OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [riverlib/] [core/] [bp_predic.vhd] - Rev 5

Compare with Previous | Blame | View Log

-----------------------------------------------------------------------------
--! @file
--! @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
--! @brief     Branch predictor.
--! @details   This module gives about 5% of performance improvement (CPI)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
library commonlib;
use commonlib.types_common.all;
--! RIVER CPU specific library.
library riverlib;
--! RIVER CPU configuration constants.
use riverlib.river_cfg.all;
 
 
entity BranchPredictor is
  port (
    i_clk : in std_logic;                              -- CPU clock
    i_nrst : in std_logic;                             -- Reset. Active LOW.
    i_req_mem_fire : in std_logic;                     -- Memory request was accepted
    i_resp_mem_valid : in std_logic;                   -- Memory response from ICache is valid
    i_resp_mem_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- Memory response address
    i_resp_mem_data : in std_logic_vector(31 downto 0);-- Memory response value
    i_f_predic_miss : in std_logic;                    -- Fetch modul detects deviation between predicted and valid pc.
    i_e_npc : in std_logic_vector(31 downto 0);        -- Valid instruction value awaited by 'Executor'
    i_ra : in std_logic_vector(RISCV_ARCH-1 downto 0); -- Return address register value
    o_npc_predict : out std_logic_vector(31 downto 0)  -- Predicted next instruction address
  );
end; 
 
architecture arch_BranchPredictor of BranchPredictor is
 
  type RegistersType is record
      npc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
      resp_mem_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
      resp_mem_data : std_logic_vector(31 downto 0);
  end record;
 
  signal r, rin : RegistersType;
 
begin
 
  comb : process(i_nrst, i_req_mem_fire, i_resp_mem_valid, i_resp_mem_addr,
                 i_resp_mem_data, i_f_predic_miss, i_e_npc, i_ra, r)
    variable v : RegistersType;
    variable wb_tmp : std_logic_vector(31 downto 0);
    variable wb_npc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
    variable wb_jal_off : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
  begin
 
    v := r;
 
    if i_resp_mem_valid = '1' then
        v.resp_mem_addr := i_resp_mem_addr;
        v.resp_mem_data := i_resp_mem_data;
    end if;
 
    wb_tmp := r.resp_mem_data;
    wb_npc := r.npc;
 
    wb_jal_off(BUS_ADDR_WIDTH-1 downto 20) := (others => wb_tmp(31));
    wb_jal_off(19 downto 12) := wb_tmp(19 downto 12);
    wb_jal_off(11) := wb_tmp(20);
    wb_jal_off(10 downto 1) := wb_tmp(30 downto 21);
    wb_jal_off(0) := '0';
 
    if i_f_predic_miss = '1' then
        wb_npc := i_e_npc;
    elsif wb_tmp = X"00008067" then
        -- ret pseudo-instruction: Dhry score 34816 -> 35136
        wb_npc := i_ra(BUS_ADDR_WIDTH-1 downto 0);
    --!elsif wb_tmp(6 downto 0) = "1101111" then
    --!    -- jal instruction: Dhry score 35136 -> 36992
    --!    wb_npc := i_resp_mem_addr + wb_jal_off;
    else
        wb_npc := r.npc + 2;
    end if;
 
 
    if i_req_mem_fire = '1' then
        v.npc := wb_npc;
    end if;
 
    if i_nrst = '0' then
        v.npc := RESET_VECTOR - 2;
        v.resp_mem_addr := RESET_VECTOR;
        v.resp_mem_data := (others => '0');
    end if;
 
    o_npc_predict <= wb_npc;
 
    rin <= v;
  end process;
 
  -- registers:
  regs : process(i_clk)
  begin 
     if rising_edge(i_clk) then 
        r <= rin;
     end if; 
  end process;
 
end;
 

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.