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

Subversion Repositories rv01_riscv_core

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

Compare with Previous | Blame | View Log

-----------------------------------------------------------------
--                                                             --
-----------------------------------------------------------------
--                                                             --
-- Copyright (C) 2015 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 Exception processing 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_OP_PKG.all;
use work.RV01_IDEC_PKG.all;
use work.RV01_CSR_PKG.all;
--use work.RV01_CFG_PKG.all;
 
entity RV01_EXCPLOG_IX2 is
  generic(
    NW : natural := 2
  );
  port(
    V_i : in std_logic_vector(2-1 downto 0); -- slot #0,1 valid flag
    INSTR_i : in DEC_INSTR_VEC_T(NW-1 downto 0); -- slot #0/1 inst.
    PC0_i : in ADR_T; -- slot #0 pc
    PC1_i : in ADR_T; -- slot #1 pc
    DADR0_i : in ADR_T; -- slot #0 L/S addr.
    DADR1_i : in ADR_T; -- slot #1 L/S addr.
    HALT_i : in std_logic_vector(2-1 downto 0); -- halt request flag
    RSM_i : in std_logic; -- resume flag
    DRSM_i : in std_logic; -- debug resume flag
    EXT_INT_i : in std_logic; -- external int. flag
    SFT_INT_i : in std_logic; -- soft int. flag
    TMR_INT_i : in std_logic; -- timer int. flag
    ETVA_i : in ADR_T; -- exc. target vector addr.
    MEPC_i : in ADR_T; -- mepc CSR
    DADR0_ERR_i : in std_logic; -- 
    DADR1_ERR_i : in std_logic; --
    CSR_ILLG_i : in std_logic; 
    IE_i : in std_logic;
    STEP_i : in std_logic;
 
    V_o : out std_logic_vector(2-1 downto 0); -- slot #0,1 valid flag
    EV_o : out std_logic_vector(2-1 downto 0); -- slot #0,1 excp. valid flag
    INSTR_o : out DEC_INSTR_VEC_T(NW-1 downto 0); -- slot #0/1 inst.
    EERTA_o : out ADR_T -- exception, eret and re-fetch target addr.
  );
end RV01_EXCPLOG_IX2;
 
architecture ARC of RV01_EXCPLOG_IX2 is
 
  signal INSTR : DEC_INSTR_VEC_T(NW-1 downto 0); 
  signal EER0 : std_logic;
 
  function is_store(OP : LS_OP_T) return std_logic is
    variable S : std_logic;
  begin
    if(OP = LS_SB or OP = LS_SH or OP = LS_SW) then
      S := '1';
    else
      S := '0';
    end if;
    return(S);
  end function;
 
  function is_load(OP : LS_OP_T) return std_logic is
    variable S : std_logic;
  begin
    if(OP = LS_LB or OP = LS_LH or OP = LS_LW) then
      S := '1';
    else
      S := '0';
    end if;
    return(S);
  end function;
 
begin
 
  ------------------------------------
  -- Notes
  ------------------------------------
 
  -- This module handles exceptions generated in stage IX2.
  -- Exceptions:
  -- 1) L/S access fault.
  -- 2) timer interrupt.
 
  -- This module also pre-calculate some signal needed
  -- by exception processing in stage IX3.
 
  -- Soft, Timer and external interrups are implicitly
  -- associated to instruction #0.
 
  -- Re-fetching of an instructions is given priority
  -- over raising an exception on the same instruction, so
  -- that exception flag gets cleared if re-fetch one is set.
 
  -- In-order execution constraint requires, in addition,
  -- than instruction #1 exception flag is cleared even when
  -- instruction #0 re-fetch flag is set.
 
  -- Instructions triggering exception or re-fetching are 
  -- prevented from altering arch. state be clearing their
  -- valid bits. Their ab-normal state is recorded by setting
  -- exception valid bits (EV).
 
  process(INSTR_i,DADR0_ERR_i,DADR1_ERR_i,TMR_INT_i,SFT_INT_i,
    EXT_INT_i,CSR_ILLG_i,V_i,IE_i)
  begin
    INSTR(0) <= INSTR_i(0);
    if(INSTR_i(0).RFTCH = '1') then
      INSTR(0).EXCP <= '0';
    elsif(EXT_INT_i = '1') then
        INSTR(0).EXCP <= '1';
        INSTR(0).ECAUSE <= EXTINT;
    elsif(SFT_INT_i = '1') then
        INSTR(0).EXCP <= '1';
        INSTR(0).ECAUSE <= SOFTINT;
    elsif(TMR_INT_i = '1') then
        INSTR(0).EXCP <= '1';
        INSTR(0).ECAUSE <= TIMRINT;
    elsif(INSTR_i(0).EXCP = '0') then
      if(CSR_ILLG_i = '1') then
        INSTR(0).EXCP <= IE_i;
        INSTR(0).ECAUSE <= ILLGINS;
      elsif(DADR0_ERR_i = '1') then
        if(is_store(INSTR_i(0).LS_OP) = '1') then
          INSTR(0).EXCP <= IE_i;
          INSTR(0).ECAUSE <= SACCFLT;
        elsif(is_load(INSTR_i(0).LS_OP) = '1') then
          INSTR(0).EXCP <= IE_i;
          INSTR(0).ECAUSE <= LACCFLT;
        end if;
      end if;
    end if;
    INSTR(1) <= INSTR_i(1);
    if((INSTR_i(0).RFTCH = '1' and V_i(0) = '1') or INSTR_i(1).RFTCH = '1') then
      INSTR(1).EXCP <= '0';
    elsif(INSTR_i(1).EXCP = '0') then
      if(DADR1_ERR_i = '1') then
        if(is_store(INSTR_i(1).LS_OP) = '1') then
          INSTR(1).EXCP <= IE_i;
          INSTR(1).ECAUSE <= SACCFLT;        
        elsif(is_load(INSTR_i(1).LS_OP) = '1') then
          INSTR(1).EXCP <= IE_i;
          INSTR(1).ECAUSE <= LACCFLT;
        end if;
      end if;
    end if;
  end process;
 
  INSTR_o <= INSTR;
 
  -- Instruction #0 valid flag keeps IX1 value unless:
  -- 1) instruction #0 has to raise an exception, OR
  -- 2) instruction #0 has to be re-fetched, OR
  -- 3) instruction #0 has to be halted
 
  V_o(0) <= '0' when (
    (INSTR(0).EXCP = '1') or
    (INSTR(0).RFTCH = '1') or
    (HALT_i(0) = '1' and STEP_i = '0')
  ) else V_i(0);
 
  -- Instruction #1 valid flag keeps IX1 value unless:
  -- 1) instruction #0 has to raise an exception, OR
  -- 2) instruction #0 is a valid eret one, OR
  -- 3) instruction #0 has to be re-fetched, OR
  -- 4) instruction #0 has to be halted, OR
  -- 5) instruction #1 has to raise an exception, OR
  -- 6) instruction #1 has to be re-fetched, OR
  -- 7) instruction #1 has to be halted.
 
  -- Conditions 1-4 are imposed by program order
  -- issue constraint.
 
  V_o(1) <= '0' when (
    (V_i(0) = '1' and INSTR(0).EXCP = '1') or
    (V_i(0) = '1' and INSTR_i(0).IMNMC = IM_ERET) or
    (V_i(0) = '1' and INSTR(0).RFTCH = '1') or
    (V_i(0) = '1' and HALT_i(0) = '1') or
    (INSTR(1).EXCP = '1') or
    (INSTR(1).RFTCH = '1') or
    (HALT_i(1) = '1' and (STEP_i = '0' or V_i(0) = '1'))
  ) else V_i(1);
 
  -- Instruction #0 excp. valid flag value is '0' unless:
  -- 1) instruction #0 has to raise an exception, OR
  -- 2) instruction #0 has to be re-fetched, OR
  -- 3) instruction #0 has to be halted
 
  EV_o(0) <= V_i(0) when (
    (INSTR(0).EXCP = '1') or
    (INSTR(0).RFTCH = '1') or
    (HALT_i(0) = '1')
  ) else '0';
 
  -- Value of EER0 flag is '0' unless:
  -- 1) instruction #0 has to raise an exception, OR
  -- 2) instruction #0 is a valid eret one, OR
  -- 3) instruction #0 has to be re-fetched, OR
  -- 4) instruction #0 has to be halted
 
  EER0 <= V_i(0) when (
    (INSTR(0).EXCP = '1') or
    (INSTR_i(0).IMNMC = IM_ERET) or
    (INSTR(0).RFTCH = '1') or
    (HALT_i(0) = '1')
  ) else '0';
 
  -- Instruction #1 excp. valid flag value is '0' unless:
  -- [
  --   1) instruction #1 has to raise an exception, OR
  --   2) instruction #1 has to be re-fetched, OR
  --   3) instruction #1 has to be halted
  -- ] AND
  -- 4) EER0 is negated
 
  -- Condition 4 is imposed by program order
  -- issue constraint.
 
  EV_o(1) <= V_i(1) when (
    (
      (INSTR(1).EXCP = '1') or
      (INSTR(1).RFTCH = '1') or
      (HALT_i(1) = '1' and (STEP_i = '0' or V_i(0) = '1'))
      --(HALT_i(1) = '1')
    ) and (
      EER0 = '0'
    )
  ) else '0';
 
  -- Exception, ERET & Re-fetch target address
  -- (pre-calculated in IX2 to save time in IX3)
 
  EERTA_o <=
    MEPC_i when (
      (V_i(0) = '1' and INSTR_i(0).IMNMC = IM_ERET) or
      (RSM_i = '1') or (DRSM_i = '1')
    ) else
    PC0_i when (V_i(0) = '1' and INSTR(0).RFTCH = '1') else
    ETVA_i when (V_i(0) = '1' and INSTR(0).EXCP = '1') else
    PC1_i when (V_i(1) = '1' and INSTR(1).RFTCH = '1') else
    ETVA_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.