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_ix3.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;
 
entity RV01_EXCPLOG_IX3 is
  generic(
    NW : natural := 2
  );
  port(
    V_i : in std_logic_vector(NW-1 downto 0); -- slot #0,1 valid flag
    EV_i : in std_logic_vector(NW-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; -- halt flag
    HIS_i : in std_logic; -- debug halt instruction selector
 
 
    EXCP_o : out std_logic; -- exc. flag
    ERET_o : out std_logic; -- return from exc. flag
    RFTCH_o : out std_logic; -- re-fetch flag
    KPRD_o : out std_logic_vector(NW-1 downto 0); -- slot #0/1 keep pipe reg. data flag
    CLRP_o : out std_logic; -- clear pipe flag
    CLRB_o : out std_logic; -- clear store buffer flag
    CLRD_o : out std_logic; -- clear divider flag
    EPC_o : out ADR_T; -- exc. pc
    ECAUSE_o : out std_logic_vector(5-1 downto 0); -- exc. cause
    EDADR_o : out ADR_T -- exc. L/S addr.
  );
end RV01_EXCPLOG_IX3;
 
architecture ARC of RV01_EXCPLOG_IX3 is
 
  signal EXCP : std_logic;
  signal ERET : std_logic;
  signal RFTCH : std_logic;
  signal EIS : std_logic;
  signal DIV_REM : std_logic;
 
begin
 
  ------------------------------------
  -- Notes
  ------------------------------------
 
  -- This modules generates most part of signals
  -- associated with re-fetching and exception 
  -- processing. Such signals are generated in 
  -- stage IX3 to insure that all instructions
  -- older than the one requiring re-fetching or
  -- raising an exception have complete their
  -- execution.
 
  -- Exception are raised and re-fetching started
  -- only when store buffer is empty of pending
  -- store (which are older than the instructions
  -- in stage IX3) and fetching is not stalled
  -- (to insure change of program flow doesn't get
  -- "ignored" because there's no room for new 
  -- instructions in fetch queue).
 
  -- When an exception is raised or an instruction 
  -- is re-fetched all instructions in the pipeline
  -- are invalidated and store buffer is cleared of
  -- pending store requests.
  -- Divider is also reset (aborting possibly ongoing
  -- operations) in case of exception or re-fetching,
  -- unless re-fetching is triggered by the same 
  -- division instruction which is under processing.
 
  -- EV_i flags are asserted only for instruction
  -- raising an exception. Instruction eret is not
  -- treated an exception-raising instruction and
  -- therefore its valid bit is provided by V_i.
 
  -- Exception flag
  EXCP <= (
    (EV_i(0) and INSTR_i(0).EXCP) or
    (EV_i(1) and INSTR_i(1).EXCP)
  ) and not(HALT_i);
 
  -- Exception is actually raised only when store buffer
  -- is empty because pending stores are older than
  -- instructions in IX3.
 
  EXCP_o <= EXCP;
 
  -- Return from exception flag
  ERET <= V_i(0) when (
    (INSTR_i(0).IMNMC = IM_ERET) and
    HALT_i = '0'
  ) else '0';
 
  -- Return from exception can take place only when
  -- store buffer is empty because pending stores are
  -- older than instructions in IX3.
 
  ERET_o <= ERET;
 
  -- Re-fetch flag
  RFTCH <= (
      (EV_i(0) and INSTR_i(0).RFTCH) or
      (EV_i(1) and INSTR_i(1).RFTCH)
    ) and not(HALT_i);
 
  -- Re-fetching can take place only when
  -- store buffer is empty because pending stores are
  -- older than instructions in IX3.
 
  RFTCH_o <= RFTCH;
 
  -- IX3 instructions must be kept in pipe registers
  -- until store buffer is empty (to be deleted).
 
  KPRD_o(0) <= '0';  
 
  KPRD_o(1) <= '0';  
 
  -- clear pipe flag
  CLRP_o <= EXCP or ERET or RFTCH;
 
  -- clear store buffer flag
  CLRB_o <= (EXCP or ERET or RFTCH);
 
  -- instruction #0 division/reminder flag
 
  DIV_REM <= '1' when (
    (INSTR_i(0).ALU_OP = ALU_DIV) or
    (INSTR_i(0).ALU_OP = ALU_REM)
  ) else '0';
 
  -- clear divider flag
 
  -- a possible division operation in progress must be stopped
  -- (resetting divider) in case exception, return from exception
  -- or re-fetching occurs, unless the re-fetching is triggered
  -- by a division instruction.
 
  CLRD_o <= '1' when ( 
    EXCP = '1' or 
    ERET = '1' or 
    (EV_i(0) = '1' and INSTR_i(0).RFTCH = '1' and DIV_REM = '0') or
    (EV_i(1) = '1' and INSTR_i(1).RFTCH = '1' and INSTR_i(0).RFTCH = '0')
  )else '0';
 
  -- Exception instruction selector
  EIS <= HIS_i when (HALT_i = '1') else not(EV_i(0) and INSTR_i(0).EXCP);
 
  -- Exception PC
  EPC_o <=
    PC0_i when (EIS = '0') else
    PC1_i;
 
  -- Exception cause
  ECAUSE_o <= 
    INSTR_i(0).ECAUSE when (EIS = '0') else
    INSTR_i(1).ECAUSE;
 
  -- Exception L/S address (aka the "bad addr")
  EDADR_o <=
    DADR0_i when (EIS = '0') else
    DADR1_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.