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

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_ftchlog_2w.vhd] - Rev 2

Compare with Previous | Blame | View Log

-----------------------------------------------------------------
--                                                             --
-----------------------------------------------------------------
--                                                             --
-- Copyright (C) 2017 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 Instruction Fecthing Logic
---------------------------------------------------------------
 
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_CSR_PKG.all;
 
entity RV01_FTCHLOG_2W is
  port(
    CLK_i : in std_logic;
    RST_i : in std_logic;
    STRT_i : in std_logic;
    STRTPC_i : in ADR_T;
    HALT_i : in std_logic;
    BJX_i : in std_logic;
    BJTA_i : in ADR_T;
    PBX_i : in std_logic;
    PBTA_i : in ADR_T;
    KLL1_i : in std_logic;
    PJRX_i : std_logic;
    PJRTA_i : in ADR_T;
    EXCP_i : in std_logic;
    ERET_i : in std_logic;
    RFTCH_i : in std_logic;
    ETVA_i : in ADR_T;
    PSTALL_i : in std_logic;
    -- Debug interface
    DHALT_i : in std_logic;
 
    IFV_o : out std_logic_vector(2-1 downto 0);
    IADR0_o : out ADR_T;
    IADR1_o : out ADR_T;
    IADR_MIS_o : out std_logic
  );
end RV01_FTCHLOG_2W;
 
architecture ARC of RV01_FTCHLOG_2W is
 
  signal SZERO : ADR_T := (others => '0');
  signal ONE : std_logic := '1';
  signal PC,PC_q : unsigned(ALEN-4 downto 0);
  signal PC_NS : unsigned(ALEN-4 downto 0);
  signal PCP8,PCP8_q : unsigned(ALEN-4 downto 0);
  signal HALT_q : std_logic;
  signal EVEN_PC : std_logic;
  signal EVEN_PC_NS : std_logic;
  signal FC : std_logic;
  signal PC_NS_FC : unsigned(ALEN-4 downto 0);
  signal EVEN_PC_NS_FC : std_logic;
 
begin
 
  -- Halt flag register
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1' or HALT_i = '1') then
        HALT_q <= '1';
      elsif(STRT_i = '1') then
        HALT_q <= '0';
      end if;
    end if;
  end process;
 
  -- Instructions are always fetched in pair from an address
  -- aligned on a two-word boundary, so that PC LS 3 bits are
  -- guaranteed to be zero and are therefore not physically
  -- implemented.
 
  -- When start or B/J address is an odd word address, fetch
  -- address is still an even word address, but instruction #0
  -- gets nullified. 
 
  -- Fetched instruction #0 is always valid, unless processor is
  -- halted or fetch address is odd.
 
  IFV_o(0) <= (not(HALT_q) or STRT_i) and EVEN_PC;
 
  -- Fetched instruction #1 is always valid, unless processor is
  -- halted.
 
  IFV_o(1) <= (not(HALT_q) or STRT_i);
 
  -- PC register reset value is set to reset exception vector
  -- "low" address.
 
  -- PC register is incremented only if pipeline is not
  -- stalled (i.e. when PSTALL_i = '0').
 
  -- PC+8 value is pre-calculated in current cycle and stored
  -- into PCP8 to remove addition from address critical path.
 
  -- Program Counter register
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        PC_q <= to_unsigned(0,SDLEN-3);
        PCP8_q <= to_unsigned(1,SDLEN-3);
      elsif((HALT_q = '0') or (STRT_i = '1')) then
        PC_q <= PC;
        PCP8_q <= PCP8;
      end if;
    end if;
  end process;
 
  -- PC plus 8
  PCP8 <= PC_NS + 1 when (
    PSTALL_i = '0' or 
    EXCP_i = '1' or 
    ERET_i = '1' or 
    RFTCH_i = '1'
  ) else PCP8_q;
 
  -- Flow change flag
  FC <= EXCP_i or ERET_i or RFTCH_i or BJX_i;
 
  -- PC no-stall value
  process(PBX_i,PJRX_i,FC,PC_NS_FC,PBTA_i,PJRTA_i,PSTALL_i,PC_q,KLL1_i)
  begin
    if(PBX_i = '1' and FC = '0' and PSTALL_i = '0' and KLL1_i = '0') then
      PC_NS <= PBTA_i(ALEN-1 downto 3); 
    elsif(PJRX_i = '1' and FC = '0' and PSTALL_i = '0') then
      PC_NS <= PJRTA_i(ALEN-1 downto 3);   
    elsif(FC = '1' or PSTALL_i = '0') then
      PC_NS <= PC_NS_FC;
    else
      PC_NS <= PC_q;
    end if;
  end process;
 
  -- PC no-stall even flag
  process(PBX_i,PJRX_i,FC,EVEN_PC_NS_FC,PBTA_i,PJRTA_i,PSTALL_i,PC_q,KLL1_i)
  begin
    if(PBX_i = '1' and FC = '0' and PSTALL_i = '0' and KLL1_i = '0') then
      EVEN_PC_NS <= not(PBTA_i(2));
    elsif(PJRX_i = '1' and FC = '0' and PSTALL_i = '0') then
      EVEN_PC_NS <= not(PJRTA_i(2));
    elsif(FC = '1' or PSTALL_i = '0') then
      EVEN_PC_NS <= EVEN_PC_NS_FC;
    else
      EVEN_PC_NS <= '1';
    end if;
  end process;
 
  -- Current cycle PC value mux.
 
  -- ETVA_i can be true exception vector, an address from CSR MEPC,
  -- a re-fetch address, debug memory address or a resume address.
  -- STRTPC_i can be the reset vector or an address from CSR MRV01HA.
 
  process(STRT_i,EXCP_i,ERET_i,RFTCH_i,ETVA_i,BJX_i,BJTA_i,PBX_i,PBTA_i,
    PCP8_q,DHALT_i,STRTPC_i)
  begin
    if(
      BJX_i = '1' and 
      (EXCP_i = '0' and ERET_i = '0' and RFTCH_i = '0' and DHALT_i = '0')
    ) then
      -- Note: the complicated if-condition allows to remove one
      -- muxing level on BJTA_i path.
      PC_NS_FC <= BJTA_i(ALEN-1 downto 3);
      EVEN_PC_NS_FC <= not(BJTA_i(2));
    elsif(
      EXCP_i = '1' or ERET_i = '1' or RFTCH_i = '1' or DHALT_i = '1'
    ) then
      PC_NS_FC <= ETVA_i(ALEN-1 downto 3);
      EVEN_PC_NS_FC <= not(ETVA_i(2));
    elsif(STRT_i = '1') then
      PC_NS_FC <= STRTPC_i(ALEN-1 downto 3);
      EVEN_PC_NS_FC <= not(STRTPC_i(2));
    else
      PC_NS_FC <= PCP8_q;
      EVEN_PC_NS_FC <= '1';
    end if;
  end process;
 
  -- Current cycle PC
  PC <= PC_NS;
 
  -- Even PC flag
  EVEN_PC <= EVEN_PC_NS;
 
  -- Fetch addresses
 
  -- instruction #0 address is always an even word address, while
  -- instruction #1 address is always an odd word one.
 
  IADR0_o <= PC & "000";
  IADR1_o <= PC & "100";
 
  -- A misaligned instruction address can be generated only
  -- by a B/J instruction.
 
  process(BJX_i,PBX_i,PJRX_i,BJTA_i,PJRTA_i,PBTA_i,KLL1_i)
  begin
    IADR_MIS_o <= '0';
    if(BJX_i = '1' and BJTA_i(1 downto 0) /= "00") then
      IADR_MIS_o <= '1';
    elsif(PBX_i = '1' and PBTA_i(1 downto 0) /= "00" and KLL1_i = '0') then
      IADR_MIS_o <= '1';
    elsif(PJRX_i = '1' and PJRTA_i(1 downto 0) /= "00") then
      IADR_MIS_o <= '1';
    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.