]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blobdiff - hw/core_ctrl.vhd
Attempt to fix forward from memory read to write over when Tumbl is being to stop.
[fpga/lx-cpu1/tumbl.git] / hw / core_ctrl.vhd
index 5e9d5a452bc2ad06a5123bc5b9787079593650cb..9cd778d297ffe187d72bceeaf1701d086dffea82 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).
 LIBRARY IEEE;
 
 USE IEEE.std_logic_1164.all;
-USE WORK.mbl_Pkg.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;
-        trace_i         :  IN STD_LOGIC;
-        trace_kick_i    :  IN STD_LOGIC;
-        core_clk_en_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;
-        -- 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;
-        done_o          : OUT STD_LOGIC
-        );
+       GENERIC
+       (
+               IMEM_ABITS_g         : positive := 9;
+               COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+       );
+       PORT
+       (
+               clk_i           :  IN STD_LOGIC;
+               rst_i           :  IN STD_LOGIC;
+               halt_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 ((IMEM_ABITS_g-1) 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;
+               delay_bit_o     : OUT STD_LOGIC;
+               -- 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 core_clk_en_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 rst_r           : STD_LOGIC;
+       SIGNAL reset_s         : STD_LOGIC;
+       SIGNAL core_clken_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 EX2MEM_REG_r    : EX2MEM_Type;
+       SIGNAL MEM_REG_r       : MEM_REG_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 setup_int_r    : STD_LOGIC;
-    SIGNAL int_busy_r     : STD_LOGIC;
+       SIGNAL setup_int_r     : STD_LOGIC;
+       SIGNAL int_busy_r      : STD_LOGIC;
 
+       SIGNAL wait_for_mem_s  : STD_LOGIC;
+       SIGNAL finish_wrb_mem_s: STD_LOGIC;
 
 BEGIN
 
-    -- 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_clk_en_s <= reset_s OR (NOT trace_i) OR trace_kick_i;
-    core_clk_en_o <= core_clk_en_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_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;
+       -- static connections
+       reset_s        <= rst_i OR rst_r;
+       pc_ctrl_o      <= NOT rst_r;
+       -- Addressing is 32-bit, so omit two lowest bytes from PC
+       imem_addr_o    <= IF2ID_REG_i.program_counter((IMEM_ABITS_g+1) DOWNTO 2);
+       -- Tracing
+       -- Reset_s is 1 when rst_i is one and then gets deactivated
+       core_clken_s  <= reset_s OR (((NOT trace_i) AND (NOT exeq_halt_i)) OR trace_kick_i);
+       core_clken_o  <= core_clken_s;
+       -- clock/wait control lines
+       finish_wrb_mem_s <= NOT MEM2CTRL_i.bus_wait WHEN (MEM_REG_r.wrb_Action = WRB_MEM AND MEM2CTRL_i.bus_taken = '1') ELSE '0';
+       wait_for_mem_s <= MEM2CTRL_i.bus_wait OR MEM2CTRL_i.bus_taken;
+       clken_s        <= NOT wait_for_mem_s 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 OR finish_wrb_mem_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 AND (NOT delayBit_r)) 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
+       EX2MEM_REG_o   <= EX2MEM_REG_r;
+       MEM_REG_o      <= MEM_REG_r;
+       ID2EX_REG_o    <= ID2EX_REG_r;
+       delay_bit_o    <= delayBit_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_clk_en_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, delayBit_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
-              EX2IF_REG_i, EX_WRB_i, EX2MEM_REG_i )
+       PROCESS
+
+       -- some local procedures
+       PROCEDURE lp_rst_IF2ID_REG IS
+       BEGIN
+               IF2ID_REG_o.program_counter <= (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.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;
+
+       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_EX2MEM_REG IS
+       BEGIN
+               EX2MEM_REG_r.mem_Action  <= NO_MEM;
+               EX2MEM_REG_r.wrb_Action  <= NO_WRB;
+               EX2MEM_REG_r.exeq_result <= (OTHERS => '0');
+               EX2MEM_REG_r.data_rD     <= (OTHERS => '0');
+               EX2MEM_REG_r.byte_Enable <= (OTHERS => '0');
+               EX2MEM_REG_r.wrix_rD     <= (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_IMM_LOCK IS
+       BEGIN
+               IMM_LOCK_r.locked   <= '0';
+               IMM_LOCK_r.IMM_hi16 <= (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;
-        END PROCEDURE;
+       PROCEDURE lp_rst_MSR IS
+       BEGIN
+               MSR_o.IE  <= '0';
+               MSR_o.C   <= '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_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_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_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_r.wrb_Action  <= NO_WRB;
+               MEM_REG_r.exeq_result <= (OTHERS => '0');
+               MEM_REG_r.byte_Enable <= (OTHERS => '0');
+               MEM_REG_r.wrix_rD     <= (OTHERS => '0');
+       END PROCEDURE;
 
-        PROCEDURE lp_rst_MSR IS
-        BEGIN
-            MSR_o.IE  <= '0';
-            MSR_o.C   <= '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;
+       WAIT UNTIL clk_i'event AND clk_i = '1';
 
-        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 (wait_for_mem_s = '0' AND  halt_i = '0' AND core_clken_s = '1') OR rst_i = '1' THEN
+               rst_r <= rst_i;
 
-        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 (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;
+                       delayBit_r        <= '0';
 
-    BEGIN
+                       IF (COMPATIBILITY_MODE_g = FALSE) THEN
+                               flush_first_r   <= '0';
+                               flush_second_r  <= '0';
+                               flush_second_2r <= '0';
+                               ignore_state_r  <= '0';
+                       END IF;
 
-        IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
-                                           core_clk_en_s = '1' 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;
-                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';
-                if (EX2IF_REG_i.take_branch = '1') THEN
-                    lp_rst_ID2EX_REG;
-                ELSE
-                    ID2EX_REG_r <= ID2EX_REG_i;
-                END IF;
-                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;
-                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_r     <= 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;
+                       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)
+                                       --
+                                       -- 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;
+                       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;
+               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_r <= EX2MEM_REG_i;
+                               END IF;
+                               IMM_LOCK_r <= IMM_LOCK_i;
+                               MSR_o      <= MSR_i;
+                       END IF;
+               END IF;
+       ELSE
+               IF finish_wrb_mem_s = '1' THEN
+                       MEM_REG_r.wrb_Action  <= NO_WRB;
+                       MEM_REG_r.wrix_rD     <= (OTHERS => '0');
+                       MEM_REG_r.byte_Enable <= (OTHERS => '0');
+                       IF MEM2CTRL_i.need_keep = '1' THEN
+                               EX2MEM_REG_r.data_rD <= MEM2CTRL_i.read_data;
+                       END IF;
+               END IF;
+       END IF;     -- rising edge clk_i ...
+       END PROCESS regd_proc;
 
 END ARCHITECTURE rtl;