]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blobdiff - hw/core_ctrl.vhd
Reformat code and restructure decoder to save LUTs and fit critical path
[fpga/lx-cpu1/tumbl.git] / hw / core_ctrl.vhd
index 596bc223f0f82760ae34525687f37616f494caf7..991a1c2aa27dab380b24a8ac2ff0f0c3ccfc72a7 100644 (file)
@@ -7,8 +7,9 @@
 --  Author:       Huib Lincklaen Arriens
 --                Delft University of Technology
 --                Faculty EEMCS, Department ME&CE, Circuits and Systems
---  Date:          December, 2010
---  Modified:     September, 2012: interrupt handling corrected to let
+--  Date:         December, 2010
+--  Modified:     September, 2013: Core customization (Meloun)
+--                September, 2012: interrupt handling corrected to let
 --                                 a pending branch be taken first
 --                                 (with thanks to Matthis Meier, TU Dortmund,
 --                                  for detecting this errror).
@@ -21,290 +22,315 @@ LIBRARY IEEE;
 USE IEEE.std_logic_1164.all;
 USE WORK.mbl_Pkg.all;
 
-
 --------------------------------------------------------------------------------
 ENTITY core_ctrl IS
 --------------------------------------------------------------------------------
-    PORT (
-        clk_i           :  IN STD_LOGIC;
-        rst_i           :  IN STD_LOGIC;
-        halt_i          :  IN STD_LOGIC;
-        int_i           :  IN STD_LOGIC;
-        -- specific fetch i/o
-        imem_addr_o     : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
-        imem_clken_o    : OUT STD_LOGIC;
-        pc_ctrl_o       : OUT STD_LOGIC;
-        -- fetch to decode pipeline registers
-        IF2ID_REG_i     :  IN IF2ID_Type;
-        IF2ID_REG_o     : OUT IF2ID_Type;
-        -- decode to exeq pipeline registers
-        ID2EX_REG_i     :  IN ID2EX_Type;
-        ID2EX_REG_o     : OUT ID2EX_Type;
-        -- GPRF control
-        gprf_clken_o    : OUT STD_LOGIC;
-        -- exeq to fetch feedback registers
-        EX2IF_REG_i     :  IN EX2IF_Type;
-        EX2IF_REG_o     : OUT EX2IF_Type;
-        -- exeq to mem pipeline registers
-        EX2MEM_REG_i    :  IN EX2MEM_Type;
-        EX2MEM_REG_o    : OUT EX2MEM_Type;
-        -- mem pipeline register
-        MEM_REG_i       :  IN MEM_REG_Type;
-        MEM_REG_o       : OUT MEM_REG_Type;
-        -- FSL to mem data delay register(s)
-        FSL_S2MEM_REG_i :  IN FSL_S2MEM_Type;
-        FSL_S2MEM_REG_o : OUT FSL_S2MEM_Type;
-        -- decode control i/o
-        ID2CTRL_i       :  IN ID2CTRL_Type;
-        INT_CTRL_o      : OUT INT_CTRL_Type;
-        -- exeq control i/o
-        EX_WRB_i        :  IN WRB_Type;
-        EX_WRB_o        : OUT WRB_Type;
-        -- data hazard i/o
-        HAZARD_WRB_i    :  IN HAZARD_WRB_Type;
-        HAZARD_WRB_o    : OUT HAZARD_WRB_Type;
-        -- for handling the 'IMM' instruction
-        IMM_LOCK_i      :  IN IMM_LOCK_Type;
-        IMM_LOCK_o      : OUT IMM_LOCK_Type;
-        -- for handling the Machine Status Register
-        MSR_i           :  IN MSR_Type;
-        MSR_o           : OUT MSR_Type;
-        -- miscellaneous
-        MEM2CTRL_i      :  IN MEM2CTRL_Type;
-        FSL_nStall_i    :  IN STD_LOGIC;
-        done_o          : OUT STD_LOGIC
-        );
+       GENERIC
+       (
+               COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+       );
+       PORT
+       (
+               clk_i           :  IN STD_LOGIC;
+               rst_i           :  IN STD_LOGIC;
+               halt_i          :  IN STD_LOGIC;
+               bad_op_i        :  IN STD_LOGIC;
+               int_i           :  IN STD_LOGIC;
+               trace_i         :  IN STD_LOGIC;
+               trace_kick_i    :  IN STD_LOGIC;
+               core_clken_o    : OUT STD_LOGIC;
+               -- specific fetch i/o
+               imem_addr_o     : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
+               imem_clken_o    : OUT STD_LOGIC;
+               pc_ctrl_o       : OUT STD_LOGIC;
+               -- fetch to decode pipeline registers
+               IF2ID_REG_i     :  IN IF2ID_Type;
+               IF2ID_REG_o     : OUT IF2ID_Type;
+               -- decode to exeq pipeline registers
+               ID2EX_REG_i     :  IN ID2EX_Type;
+               ID2EX_REG_o     : OUT ID2EX_Type;
+               -- GPRF control
+               gprf_clken_o    : OUT STD_LOGIC;
+               -- exeq to fetch feedback registers
+               EX2IF_REG_i     :  IN EX2IF_Type;
+               EX2IF_REG_o     : OUT EX2IF_Type;
+               EX2CTRL_REG_i   :  IN EX2CTRL_Type;
+               -- exeq to core (halting)
+               exeq_halt_i     :  IN STD_LOGIC;
+               -- exeq to mem pipeline registers
+               EX2MEM_REG_i    :  IN EX2MEM_Type;
+               EX2MEM_REG_o    : OUT EX2MEM_Type;
+               -- mem pipeline register
+               MEM_REG_i       :  IN MEM_REG_Type;
+               MEM_REG_o       : OUT MEM_REG_Type;
+               -- decode control i/o
+               ID2CTRL_i       :  IN ID2CTRL_Type;
+               INT_CTRL_o      : OUT INT_CTRL_Type;
+               -- exeq control i/o
+               EX_WRB_i        :  IN WRB_Type;
+               EX_WRB_o        : OUT WRB_Type;
+               -- data hazard i/o
+               HAZARD_WRB_i    :  IN HAZARD_WRB_Type;
+               HAZARD_WRB_o    : OUT HAZARD_WRB_Type;
+               -- for handling the 'IMM' instruction
+               IMM_LOCK_i      :  IN IMM_LOCK_Type;
+               IMM_LOCK_o      : OUT IMM_LOCK_Type;
+               -- for handling the Machine Status Register
+               MSR_i           :  IN MSR_Type;
+               MSR_o           : OUT MSR_Type;
+               -- miscellaneous
+               MEM2CTRL_i      :  IN MEM2CTRL_Type
+       );
 END ENTITY core_ctrl;
 
 --------------------------------------------------------------------------------
 ARCHITECTURE rtl OF core_ctrl IS
 --------------------------------------------------------------------------------
 
-    SIGNAL rst_r          : STD_LOGIC;
-    SIGNAL reset_s        : STD_LOGIC;
+       SIGNAL rst_r           : STD_LOGIC;
+       SIGNAL reset_s         : STD_LOGIC;
+       SIGNAL core_clken_s    : STD_LOGIC;
 
-    SIGNAL ID2EX_REG_r    : ID2EX_Type;
-    SIGNAL EX2IF_REG_r    : EX2IF_Type;
-    SIGNAL delayBit_r     : STD_LOGIC;
-    SIGNAL delayBit_2r    : STD_LOGIC;
-    SIGNAL IMM_LOCK_r     : IMM_LOCK_Type;
-    SIGNAL HAZARD_WRB_r   : HAZARD_WRB_Type;
+       SIGNAL ID2EX_REG_r     : ID2EX_Type;
+       SIGNAL EX2IF_REG_r     : EX2IF_Type;
+       SIGNAL IMM_LOCK_r      : IMM_LOCK_Type;
+       SIGNAL HAZARD_WRB_r    : HAZARD_WRB_Type;
+       SIGNAL flush_first_r   : STD_LOGIC;
+       SIGNAL flush_second_r  : STD_LOGIC;
+       SIGNAL flush_second_2r : STD_LOGIC;
+       SIGNAL ignore_state_r  : STD_LOGIC; -- Please note: Flushing first is considered immediate!
+       SIGNAL delayBit_r      : STD_LOGIC;
+       SIGNAL clken_s         : STD_LOGIC;
+       SIGNAL clken_pipe_s    : STD_LOGIC;
+       SIGNAL flush_ID2EX_s   : STD_LOGIC;
+       SIGNAL flush_ID2EX_r   : STD_LOGIC;
+       SIGNAL flush_EX2MEM_s  : STD_LOGIC;
 
-    SIGNAL clken_s        : STD_LOGIC;
-    SIGNAL clken_pipe_s   : STD_LOGIC;
-    SIGNAL flush_ID2EX_s  : STD_LOGIC;
-    SIGNAL flush_ID2EX_r  : STD_LOGIC;
-    SIGNAL flush_EX2MEM_s : STD_LOGIC;
+       SIGNAL setup_int_r     : STD_LOGIC;
+       SIGNAL int_busy_r      : STD_LOGIC;
 
-    SIGNAL setup_int_r    : STD_LOGIC;
-    SIGNAL int_busy_r     : STD_LOGIC;
+BEGIN
 
-    SIGNAL S_Data_r       : STD_LOGIC_VECTOR (31 DOWNTO 0);
-    SIGNAL S_Data_2r      : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       -- static connections
+       reset_s        <= rst_i OR rst_r;
+       pc_ctrl_o      <= NOT rst_r;
+       imem_addr_o    <= IF2ID_REG_i.program_counter;
+       -- Tracing
+       -- Reset_s is 1 when rst_i is one and then gets deactivated
+       core_clken_s  <= reset_s OR ((NOT bad_op_i) AND (((NOT trace_i) AND (NOT exeq_halt_i)) OR trace_kick_i));
+       core_clken_o  <= core_clken_s;
+       -- clock/wait control lines
+       clken_s        <= MEM2CTRL_i.clken OR rst_i;
+       clken_pipe_s   <= clken_s AND (NOT HAZARD_WRB_i.hazard);
+       imem_clken_o   <= clken_pipe_s;
+       gprf_clken_o   <= clken_s;
+       -- signals for clearing the ID2EX and EX2MEM registers during branches
+       flush_ID2EX_s  <= ((EX2IF_REG_i.take_branch AND (NOT delayBit_r)) OR EX2IF_REG_r.take_branch) WHEN COMPATIBILITY_MODE_g = TRUE
+                                                                               ELSE (EX2IF_REG_i.take_branch OR EX2IF_REG_r.take_branch OR EX2CTRL_REG_i.flush_first OR flush_first_r OR
+                                                                                               ((NOT EX2CTRL_REG_i.ignore_state) AND (NOT ignore_state_r) AND flush_second_2r));
+       flush_EX2MEM_s <= HAZARD_WRB_i.hazard;
+       -- outputs that need to be readable too, so needing shadowing signals
+       ID2EX_REG_o    <= ID2EX_REG_r;
+       EX2IF_REG_o    <= EX2IF_REG_r;
+       IMM_LOCK_o     <= IMM_LOCK_r;
+       HAZARD_WRB_o   <= HAZARD_WRB_r;
+       --
+       INT_CTRL_o.setup_int   <= setup_int_r;
+       INT_CTRL_o.rti_target  <= ID2EX_REG_r.program_counter;
+       INT_CTRL_o.int_busy    <= int_busy_r;
 
+regd_proc:
+       PROCESS ( clk_i, rst_i, halt_i, core_clken_s,
+                                               -- complete sensitivity list for synthesizer
+                                               reset_s, MEM2CTRL_i, clken_pipe_s, IF2ID_REG_i,
+                                               flush_ID2EX_s, flush_EX2MEM_s, HAZARD_WRB_i,
+                                               MEM_REG_i, ID2CTRL_i, int_i, MSR_i,
+                                               int_busy_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
+                                               EX2IF_REG_i, EX2CTRL_REG_i, EX_WRB_i, EX2MEM_REG_i )
 
-BEGIN
+       -- some local procedures
+       PROCEDURE lp_rst_IF2ID_REG IS
+       BEGIN
+               IF2ID_REG_o.program_counter <= (OTHERS => '0');
+       END PROCEDURE;
 
-    -- static connections
-    reset_s        <= rst_i OR rst_r;
-    pc_ctrl_o      <= NOT rst_r;
-    imem_addr_o    <= IF2ID_REG_i.program_counter;
-    -- clock/wait control lines
-    clken_s        <= (MEM2CTRL_i.clken AND FSL_nStall_i) OR rst_i;
-    clken_pipe_s   <= clken_s AND (NOT HAZARD_WRB_i.hazard);
-    imem_clken_o   <= clken_pipe_s;
-    gprf_clken_o   <= clken_s;
-    -- signals for clearing the ID2EX and EX2MEM registers during branches
-    flush_ID2EX_s  <= EX2IF_REG_r.take_branch;
-    flush_EX2MEM_s <= (flush_ID2EX_s AND (NOT delayBit_2r)) OR HAZARD_WRB_i.hazard;
-    -- outputs that need to be readable too, so needing shadowing signals
-    ID2EX_REG_o    <= ID2EX_REG_r;
-    EX2IF_REG_o    <= EX2IF_REG_r;
-    IMM_LOCK_o     <= IMM_LOCK_r;
-    HAZARD_WRB_o   <= HAZARD_WRB_r;
-    --
-    INT_CTRL_o.setup_int   <= setup_int_r;
-    INT_CTRL_o.rti_target  <= ID2EX_REG_r.program_counter;
-    INT_CTRL_o.int_busy    <= int_busy_r;
-    --
-    FSL_S2MEM_REG_o.S_Data <= S_Data_2r;
+       PROCEDURE lp_rst_ID2EX_REG IS
+       BEGIN
+               -- reset and handle ID2EX_REG_r.program_counter separately,
+               -- since it will be needed during interrupt setup
+               ID2EX_REG_r.rdix_rA          <= (OTHERS => '0');
+               ID2EX_REG_r.rdix_rB          <= (OTHERS => '0');
+               ID2EX_REG_r.curr_rD          <= (OTHERS => '0');
+               ID2EX_REG_r.alu_Action       <= A_NOP;
+               ID2EX_REG_r.alu_Op1          <= ALU_IN_ZERO;
+               ID2EX_REG_r.alu_Op2          <= ALU_IN_IMM;
+               ID2EX_REG_r.alu_Cin          <= CIN_ZERO;
+               ID2EX_REG_r.IMM16            <= (OTHERS => '0');
+               ID2EX_REG_r.IMM_Lock         <= '0';
+               ID2EX_REG_r.msr_Action       <= KEEP_CARRY;
+               ID2EX_REG_r.branch_Action    <= NO_BR;
+               ID2EX_REG_r.mem_Action       <= NO_MEM;
+               ID2EX_REG_r.transfer_Size    <= WORD;
+               ID2EX_REG_r.wrb_Action       <= NO_WRB;
+               ID2EX_REG_r.condition        <= COND_ALL;
+               ID2EX_REG_r.halt             <= '0';
+               IF (COMPATIBILITY_MODE_g = FALSE) THEN
+                       ID2EX_REG_r.it_Action      <= NO_IT;
+               ELSE
+               END IF;
+       END PROCEDURE;
 
-regd_proc:
-    PROCESS ( clk_i, rst_i, halt_i,
-              -- complete sensitivity list for synthesizer
-              reset_s, MEM2CTRL_i, clken_pipe_s, IF2ID_REG_i,
-              flush_ID2EX_s, flush_EX2MEM_s, HAZARD_WRB_i,
-              MEM_REG_i, ID2CTRL_i, int_i, MSR_i,
-              int_busy_r, delayBit_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
-              EX2IF_REG_i, EX_WRB_i, S_Data_r, FSL_S2MEM_REG_i, EX2MEM_REG_i )
+       PROCEDURE lp_rst_EX2IF_REG IS
+       BEGIN
+               EX2IF_REG_r.take_branch   <= '0';
+               EX2IF_REG_r.branch_target <= (OTHERS => '0');
+       END PROCEDURE;
 
-        -- some local procedures
-        PROCEDURE lp_rst_IF2ID_REG IS
-        BEGIN
-            IF2ID_REG_o.program_counter <= (OTHERS => '0');
-        END PROCEDURE;
+       PROCEDURE lp_rst_EX2MEM_REG IS
+       BEGIN
+               EX2MEM_REG_o.mem_Action  <= NO_MEM;
+               EX2MEM_REG_o.wrb_Action  <= NO_WRB;
+               EX2MEM_REG_o.exeq_result <= (OTHERS => '0');
+               EX2MEM_REG_o.data_rD     <= (OTHERS => '0');
+               EX2MEM_REG_o.byte_Enable <= (OTHERS => '0');
+               EX2MEM_REG_o.wrix_rD     <= (OTHERS => '0');
+       END PROCEDURE;
 
-        PROCEDURE lp_rst_ID2EX_REG IS
-        BEGIN
-            -- reset and handle ID2EX_REG_r.program_counter separately,
-            -- since it will be needed during interrupt setup
-            ID2EX_REG_r.rdix_rA          <= (OTHERS => '0');
-            ID2EX_REG_r.rdix_rB          <= (OTHERS => '0');
-            ID2EX_REG_r.curr_rD          <= (OTHERS => '0');
-            ID2EX_REG_r.alu_Action       <= A_NOP;
-            ID2EX_REG_r.alu_Op1          <= ALU_IN_ZERO;
-            ID2EX_REG_r.alu_Op2          <= ALU_IN_IMM;
-            ID2EX_REG_r.alu_Cin          <= CIN_ZERO;
-            ID2EX_REG_r.IMM16            <= (OTHERS => '0');
-            ID2EX_REG_r.IMM_Lock         <= '0';
-            ID2EX_REG_r.msr_Action       <= KEEP_CARRY;
-            ID2EX_REG_r.branch_Action    <= NO_BR;
-            ID2EX_REG_r.mem_Action       <= NO_MEM;
-            ID2EX_REG_r.transfer_Size    <= WORD;
-            ID2EX_REG_r.wrb_Action       <= NO_WRB;
-            ID2EX_REG_r.FSL_Test         <= '1';
-            ID2EX_REG_r.FSL_Non_blocking <= '1';
-            ID2EX_REG_r.FSL_Control      <= '0';
-            ID2EX_REG_r.FSL_Atomic       <= '0';
-        END PROCEDURE;
+       PROCEDURE lp_rst_IMM_LOCK IS
+       BEGIN
+               IMM_LOCK_r.locked   <= '0';
+               IMM_LOCK_r.IMM_hi16 <= (OTHERS => '0');
+       END PROCEDURE;
 
-        PROCEDURE lp_rst_EX2IF_REG IS
-        BEGIN
-            EX2IF_REG_r.take_branch   <= '0';
-            EX2IF_REG_r.branch_target <= (OTHERS => '0');
-        END PROCEDURE;
+       PROCEDURE lp_rst_MSR IS
+       BEGIN
+               MSR_o.IE  <= '0';
+               MSR_o.C   <= '0';
+       END PROCEDURE;
 
-        PROCEDURE lp_rst_EX2MEM_REG IS
-        BEGIN
-            EX2MEM_REG_o.mem_Action  <= NO_MEM;
-            EX2MEM_REG_o.wrb_Action  <= NO_WRB;
-            EX2MEM_REG_o.exeq_result <= (OTHERS => '0');
-            EX2MEM_REG_o.data_rD     <= (OTHERS => '0');
-            EX2MEM_REG_o.byte_Enable <= (OTHERS => '0');
-            EX2MEM_REG_o.wrix_rD     <= (OTHERS => '0');
-        END PROCEDURE;
+       PROCEDURE lp_rst_EX_WRB IS
+       BEGIN
+               EX_WRB_o.wrb_Action <= NO_WRB;
+               EX_WRB_o.wrix_rD    <= (OTHERS => '0');
+               EX_WRB_o.data_rD    <= (OTHERS => '0');
+       END PROCEDURE;
 
-        PROCEDURE lp_rst_FSL2MEM_REG IS
-        BEGIN
-            S_Data_r  <= (OTHERS => '0');
-            S_Data_2r <= (OTHERS => '0');
-        END PROCEDURE;
+       PROCEDURE lp_rst_HAZARD_WRB IS
+       BEGIN
+               HAZARD_WRB_r.hazard  <= '0';
+               HAZARD_WRB_r.save_rX <= NO_SAVE;
+               HAZARD_WRB_r.data_rX <= (OTHERS => '0');
+               HAZARD_WRB_r.data_rD <= (OTHERS => '0');
+       END PROCEDURE;
 
-        PROCEDURE lp_rst_IMM_LOCK IS
-        BEGIN
-            IMM_LOCK_r.locked   <= '0';
-            IMM_LOCK_r.IMM_hi16 <= (OTHERS => '0');
-        END PROCEDURE;
+       PROCEDURE lp_rst_MEM_REG IS
+       BEGIN
+               MEM_REG_o.wrb_Action  <= NO_WRB;
+               MEM_REG_o.exeq_result <= (OTHERS => '0');
+               MEM_REG_o.byte_Enable <= (OTHERS => '0');
+               MEM_REG_o.wrix_rD     <= (OTHERS => '0');
+       END PROCEDURE;
 
-        PROCEDURE lp_rst_MSR IS
-        BEGIN
-            MSR_o.IE  <= '0';
-            MSR_o.C   <= '0';
-            MSR_o.FSL <= '0';
-        END PROCEDURE;
+       BEGIN
 
-        PROCEDURE lp_rst_EX_WRB IS
-        BEGIN
-            EX_WRB_o.wrb_Action <= NO_WRB;
-            EX_WRB_o.wrix_rD    <= (OTHERS => '0');
-            EX_WRB_o.data_rD    <= (OTHERS => '0');
-        END PROCEDURE;
+       IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
+                               core_clken_s = '1' THEN
+                       rst_r <= rst_i;
 
-        PROCEDURE lp_rst_HAZARD_WRB IS
-        BEGIN
-            HAZARD_WRB_r.hazard  <= '0';
-            HAZARD_WRB_r.save_rX <= NO_SAVE;
-            HAZARD_WRB_r.data_rX <= (OTHERS => '0');
-            HAZARD_WRB_r.data_rD <= (OTHERS => '0');
-        END PROCEDURE;
+               IF (reset_s = '1') THEN     -- synchronous reset ...
+                       lp_rst_IF2ID_REG;       -- ... so lasts at least one clock_cycle
+                       lp_rst_MSR;
+                       lp_rst_HAZARD_WRB;
+                       lp_rst_MEM_REG;
 
-        PROCEDURE lp_rst_MEM_REG IS
-        BEGIN
-            MEM_REG_o.wrb_Action  <= NO_WRB;
-            MEM_REG_o.exeq_result <= (OTHERS => '0');
-            MEM_REG_o.byte_Enable <= (OTHERS => '0');
-            MEM_REG_o.wrix_rD     <= (OTHERS => '0');
-        END PROCEDURE;
+                       IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                               delayBit_r      <= '0';
+                       ELSE
+                               flush_first_r   <= '0';
+                               flush_second_r  <= '0';
+                               flush_second_2r <= '0';
+                               ignore_state_r  <= '0';
+                       END IF;
 
-    BEGIN
-        IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' THEN
-            rst_r <= rst_i;
-            IF (reset_s = '1') THEN     -- synchronous reset ...
-                lp_rst_IF2ID_REG;       -- ... so lasts at least one clock_cycle
-                lp_rst_MSR;
-                lp_rst_HAZARD_WRB;
-                lp_rst_MEM_REG;
-                lp_rst_FSL2MEM_REG;
-                delayBit_r    <= '0';
-                flush_ID2EX_r <= '0';
-                setup_int_r   <= '0';
-                int_busy_r    <= '0';
-                done_o        <= '0';
-                ID2EX_REG_r.program_counter <= (OTHERS => '0');
-            ELSE
-                IF (clken_pipe_s = '1') THEN
-                    IF2ID_REG_o <= IF2ID_REG_i;
-                END IF;
-                flush_ID2EX_r <= flush_ID2EX_s;
-                HAZARD_WRB_r  <= HAZARD_WRB_i;
-                MEM_REG_o     <= MEM_REG_i;
-                int_busy_r    <= ID2CTRL_i.int_busy;
-            END IF;
-            -- decode-to-exeq unit registers
-            IF ((reset_s = '1') OR (flush_ID2EX_s = '1')) THEN
-                lp_rst_ID2EX_REG;
-                delayBit_r <= '0';
-            -- check for the need and possibility to handle active interrupt requests
-            ELSIF (((int_i = '1') OR (MEM2CTRL_i.int = '1')) AND (MSR_i.IE = '1') AND
-                        (ID2CTRL_i.int_busy = '0') AND (int_busy_r = '0') AND
-                -- pending branch should be taken before interrupt can be executed
-                -- dectected by Matthis Meier, TU Dortmund (Sept 2012)
-                            (EX2IF_REG_i.take_branch = '0') AND
-                                (delayBit_r = '0') AND
-                                    (IMM_LOCK_i.locked = '0') AND
-                                        (HAZARD_WRB_i.hazard = '0')) THEN
-                setup_int_r <= '1';
-                ID2EX_REG_r.program_counter <= ID2EX_REG_i.program_counter;
-                lp_rst_ID2EX_REG;
-            ELSIF (clken_pipe_s = '1') THEN
-                setup_int_r <= '0';
-                ID2EX_REG_r <= ID2EX_REG_i;
-                delayBit_r  <= ID2CTRL_i.delayBit;
-            END IF;
-            -- exeq-to-mem unit registers
-            IF ((reset_s = '1') OR (flush_EX2MEM_s = '1')) THEN
-                lp_rst_EX2IF_REG;
-                lp_rst_EX2MEM_REG;
-                lp_rst_EX_WRB;
-                lp_rst_IMM_LOCK;
-                delayBit_2r <= '0';
-            ELSE
-                IF (clken_pipe_s = '1') THEN
-                    EX2IF_REG_r <= EX2IF_REG_i;
-                    delayBit_2r <= delayBit_r;
-                    EX_WRB_o    <= EX_WRB_i;
-                    S_Data_2r   <= S_Data_r;
-                    S_Data_r    <= FSL_S2MEM_REG_i.S_Data;
-                END IF;
-                IF (clken_s = '1') THEN
-                    -- next test to prevent a flush from disrupting
-                    -- the write-back pipeline
-                    IF (flush_ID2EX_r = '0') THEN
-                        EX2MEM_REG_o <= EX2MEM_REG_i;
-                    END IF;
-                    IMM_LOCK_r <= IMM_LOCK_i;
-                    MSR_o      <= MSR_i;
-                END IF;
-            END IF;
-            -- check on End-Of-Program viz. "bri 0x00"
-            -- use delayBit to distinguish between "bri" and "rtsd/rtid"
-            IF ((ID2EX_REG_r.branch_Action = BR) AND
-                    (ID2EX_REG_r.alu_Op2 = ALU_IN_IMM) AND
-                        (ID2EX_REG_r.IMM16 = C_16_ZEROS) AND
-                            (delayBit_r = '0') AND (flush_EX2MEM_s = '0')) THEN
-                done_o <= '1';
-            END IF;
-        END IF;     -- rising edge clk_i ...
-    END PROCESS regd_proc;
+                       flush_ID2EX_r <= '0';
+                       setup_int_r   <= '0';
+                       int_busy_r    <= '0';
+                       ID2EX_REG_r.program_counter <= (OTHERS => '0');
+               ELSE
+                       IF (clken_pipe_s = '1') THEN
+                               IF2ID_REG_o <= IF2ID_REG_i;
+                       END IF;
+                       flush_ID2EX_r <= flush_ID2EX_s;
+                       IF (COMPATIBILITY_MODE_g = FALSE) THEN
+                               -- Flushing based on IT / ITE / ITT along with IMM locking
+                               IF (ID2EX_REG_i.IMM_Lock = '1') THEN
+                                       IF (flush_second_2r = '0') THEN
+                                               flush_second_2r <= flush_second_r;
+                                       END IF;
+                                       flush_first_r   <= EX2CTRL_REG_i.flush_first;
+                                       flush_second_r  <= EX2CTRL_REG_i.flush_second;
+                                       ignore_state_r  <= EX2CTRL_REG_i.ignore_state;
+                               ELSE
+                                       flush_first_r   <= '0';
+                                       -- Directly to 2r (flushing the following instruction)
+                                       flush_second_2r <= flush_second_r OR EX2CTRL_REG_i.flush_second;
+                                       flush_second_r  <= '0';
+                                       ignore_state_r  <= '0';
+                               END IF;
+                       END IF;
+                       HAZARD_WRB_r  <= HAZARD_WRB_i;
+                       MEM_REG_o     <= MEM_REG_i;
+                       int_busy_r    <= ID2CTRL_i.int_busy;
+               END IF;
+               -- decode-to-exeq unit registers
+               IF ((reset_s = '1') OR (flush_ID2EX_s = '1')) THEN
+                       setup_int_r <= '0';
+                       lp_rst_ID2EX_REG;
+                       IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                               delayBit_r <= '0';
+                       END IF;
+               -- check for the need and possibility to handle active interrupt requests
+               ELSIF (((int_i = '1') OR (MEM2CTRL_i.int = '1')) AND (MSR_i.IE = '1') AND
+                                       (ID2CTRL_i.int_busy = '0') AND (int_busy_r = '0') AND
+                                       -- pending branch should be taken before interrupt can be executed
+                                       -- dectected by Matthis Meier, TU Dortmund (Sept 2012)
+                                       --
+                                       -- Same goes for pending flushing - should be taken before interrupt can be executed
+                                       (EX2IF_REG_i.take_branch = '0') AND (EX2IF_REG_r.take_branch = '0') AND ((COMPATIBILITY_MODE_g = TRUE)
+                                       OR ((flush_first_r = '0') AND (flush_second_r = '0') AND (flush_second_2r = '0'))) AND
+                                       (IMM_LOCK_i.locked = '0') AND (HAZARD_WRB_i.hazard = '0')) THEN
+                       setup_int_r <= '1';
+                       ID2EX_REG_r.program_counter <= ID2EX_REG_i.program_counter;
+                       lp_rst_ID2EX_REG;
+               ELSIF (clken_pipe_s = '1') THEN
+                       setup_int_r <= '0';
+                       ID2EX_REG_r <= ID2EX_REG_i;
+                       IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                               delayBit_r  <= ID2CTRL_i.delayBit;
+                       END IF;
+               END IF;
+               -- exeq-to-mem unit registers
+               IF ((reset_s = '1') OR (flush_EX2MEM_s = '1')) THEN
+                       lp_rst_EX2IF_REG;
+                       lp_rst_EX2MEM_REG;
+                       lp_rst_EX_WRB;
+                       lp_rst_IMM_LOCK;
+               ELSE
+                       IF (clken_pipe_s = '1') THEN
+                               EX2IF_REG_r   <= EX2IF_REG_i;
+                               EX_WRB_o      <= EX_WRB_i;
+                       END IF;
+                       IF (clken_s = '1') THEN
+                               -- next test to prevent a flush from disrupting
+                               -- the write-back pipeline
+                               IF (flush_ID2EX_r = '0') THEN
+                                       EX2MEM_REG_o <= EX2MEM_REG_i;
+                               END IF;
+                               IMM_LOCK_r <= IMM_LOCK_i;
+                               MSR_o      <= MSR_i;
+                       END IF;
+               END IF;
+       END IF;     -- rising edge clk_i ...
+       END PROCESS regd_proc;
 
 END ARCHITECTURE rtl;