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;