]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/commitdiff
Reformat code and restructure decoder to save LUTs and fit critical path
authorMartin Meloun <meloumar@cmp.felk.cvut.cz>
Mon, 30 Sep 2013 12:25:21 +0000 (14:25 +0200)
committerMartin Meloun <meloumar@cmp.felk.cvut.cz>
Mon, 30 Sep 2013 12:25:21 +0000 (14:25 +0200)
Instruction set is also modified, ITxxx are separate from CMP,
do not store the result to a register and are in unsigned / immediate value
variants as well. Added also CMPUI (CMPU has slightly changed encoding).

Signed-off-by: Martin Meloun <meloumar@cmp.felk.cvut.cz>
hw/core_ctrl.vhd
hw/decode.vhd
hw/exeq.vhd
hw/mbl_Pkg.vhd
hw/mem.vhd

index 55c5344d40f7169718d41d179b62043e81d1d8e2..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).
@@ -24,282 +25,312 @@ USE WORK.mbl_Pkg.all;
 --------------------------------------------------------------------------------
 ENTITY core_ctrl IS
 --------------------------------------------------------------------------------
-    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
-        );
+       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 core_clken_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 IMM_LOCK_r     : IMM_LOCK_Type;
-    SIGNAL HAZARD_WRB_r   : HAZARD_WRB_Type;
-    SIGNAL flush_second_r : STD_LOGIC;
-    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 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;
 
 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_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_second_r);
-    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;
+       -- 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 )
+       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 )
 
-        -- some local procedures
-        PROCEDURE lp_rst_IF2ID_REG IS
-        BEGIN
-            IF2ID_REG_o.program_counter <= (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_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_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_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_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_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_IMM_LOCK IS
-        BEGIN
-            IMM_LOCK_r.locked   <= '0';
-            IMM_LOCK_r.IMM_hi16 <= (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_MSR IS
-        BEGIN
-            MSR_o.IE  <= '0';
-            MSR_o.C   <= '0';
-        END PROCEDURE;
+       PROCEDURE lp_rst_MSR IS
+       BEGIN
+               MSR_o.IE  <= '0';
+               MSR_o.C   <= '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_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_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_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_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_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;
 
-    BEGIN
+       BEGIN
 
-        IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
-                    core_clken_s = '1' THEN
-            rst_r <= rst_i;
+       IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
+                               core_clken_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;
+               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;
 
-                IF (COMPATIBILITY_MODE_g = TRUE) THEN
-                    delayBit_r     <= '0';
-                ELSE
-                    flush_second_r <= '0';
-                END IF;
+                       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;
 
-                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
-                    flush_second_r <= EX2CTRL_REG_i.flush_second;
-                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)
-                            (EX2IF_REG_i.take_branch = '0') AND
-                                (EX2IF_REG_r.take_branch = '0') AND -- it is still pending a cycle after branching
-                                    (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;
+                       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;
index 17c6781f4ab5a9e3c441ee7409cc8f3f18dcec00..cf681e0e33fbad900a932280ce02f7e9da9877b1 100644 (file)
@@ -20,30 +20,30 @@ LIBRARY IEEE;
 USE IEEE.std_logic_1164.all;
 USE WORK.mbl_Pkg.all;
 
-
 --------------------------------------------------------------------------------
 ENTITY decode IS
 --------------------------------------------------------------------------------
-    GENERIC (
-        USE_HW_MUL_g : BOOLEAN := TRUE;
-        USE_BARREL_g : BOOLEAN := TRUE;
-        COMPATIBILITY_MODE_g : BOOLEAN := FALSE
-        );
-    PORT (
-        IF2ID_i     :  IN IF2ID_Type;
-        imem_data_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
-        --
-        ID2GPRF_o   : OUT ID2GPRF_Type;
-        ID2EX_o     : OUT ID2EX_Type;
-        --
-        INT_CTRL_i  :  IN INT_CTRL_Type;
-        ID2CTRL_o   : OUT ID2CTRL_Type;
-        --
-        noLiteOpc_o : OUT STD_LOGIC
-        );
+       GENERIC
+       (
+               USE_HW_MUL_g : BOOLEAN := TRUE;
+               USE_BARREL_g : BOOLEAN := TRUE;
+               COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+       );
+       PORT
+       (
+               IF2ID_i     :  IN IF2ID_Type;
+               imem_data_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+               --
+               ID2GPRF_o   : OUT ID2GPRF_Type;
+               ID2EX_o     : OUT ID2EX_Type;
+               --
+               INT_CTRL_i  :  IN INT_CTRL_Type;
+               ID2CTRL_o   : OUT ID2CTRL_Type;
+               --
+               noLiteOpc_o : OUT STD_LOGIC
+       );
 END ENTITY decode;
 
-
 --------------------------------------------------------------------------------
 ARCHITECTURE rtl OF decode IS
 --------------------------------------------------------------------------------
@@ -51,348 +51,365 @@ ARCHITECTURE rtl OF decode IS
 BEGIN
 
 p_decode:
-    PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
-
-        VARIABLE prog_counter_v  : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE opcIx_v         : STD_LOGIC_VECTOR ( 5 DOWNTO 0);
-        VARIABLE instruction_v   : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE rD_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        VARIABLE rA_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        VARIABLE rB_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        VARIABLE IMM16_v         : STD_LOGIC_VECTOR (15 DOWNTO 0);
-        VARIABLE code_x26_v      : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
-        VARIABLE IMM_Lock_v      : STD_LOGIC;
-        VARIABLE alu_Action_v    : ALU_ACTION_Type;
-        VARIABLE alu_Op1_v       : ALU_IN1_Type;
-        VARIABLE alu_Op2_v       : ALU_IN2_Type;
-        VARIABLE alu_Cin_v       : ALU_CIN_Type;
-        VARIABLE msr_Action_v    : MSR_ACTION_Type;
-        VARIABLE branch_Action_v : BRANCH_ACTION_Type;
-        VARIABLE delayBit_v      : STD_LOGIC;
-        VARIABLE mem_Action_v    : MEM_ACTION_Type;
-        VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
-        VARIABLE wrb_Action_v    : WRB_ACTION_Type;
-        VARIABLE int_busy_v      : STD_LOGIC;
-        VARIABLE cmp_Cond_v      : CMP_COND_Type;
-        VARIABLE cmp_Cond_Type_v : CMP_COND_TYPE_Type;
-
-    BEGIN
-        prog_counter_v  := IF2ID_i.program_counter;
-        instruction_v   := imem_data_i;
-        opcIx_v         := instruction_v (31 DOWNTO 26);
-        rD_v            := instruction_v (25 DOWNTO 21);
-        rA_v            := instruction_v (20 DOWNTO 16);
-        rB_v            := instruction_v (15 DOWNTO 11);
-        IMM16_v         := instruction_v (15 DOWNTO  0);
-        IMM_Lock_v      := '0';
-        IF (COMPATIBILITY_MODE_g = TRUE) THEN
-            delayBit_v      := '0';
-        ELSE
-            cmp_cond_v      := COND_ALL;
-            cmp_cond_type_v := COND_TYPE_ALL;
-        END IF;
-        alu_Cin_v       := CIN_ZERO;
-        alu_Action_v    := A_NOP;
-        msr_Action_v    := KEEP_CARRY;
-        branch_Action_v := NO_BR;
-        mem_Action_v    := NO_MEM;
-        transfer_Size_v := WORD;
-        wrb_Action_v    := WRB_EX;
-        -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
-        code_x26_v      := instruction_v(6) & instruction_v(5) & instruction_v(0);
-        int_busy_v      := INT_CTRL_i.int_busy;
-        -- for debugging purposes
-        noLiteOpc_o     <= '0';
-
-        IF (INT_CTRL_i.setup_int = '1') THEN
-
-            alu_Op1_v       := ALU_IN_ZERO;
-            alu_Op2_v       := ALU_IN_IMM;
-            IMM16_v         := X"0010";                 -- address of _interrupt_handler vector
-            prog_counter_v  := INT_CTRL_i.rti_target;   -- delayed program counter
-            alu_Action_v    := A_ADD;
-            rD_v            := "01110";                 -- r14 reserved for storing program_counter
-            rA_v            := (OTHERS => '0');         -- also set rA and rB to avoid possible ...
-            rB_v            := (OTHERS => '0');         -- ... erronuous hazard detection in exeq module
-            int_busy_v      := '1';
-            branch_Action_v := BRL;
-
-        ELSE
-
-            alu_Op1_v := ALU_IN_REGA;
-            IF (opcIx_v(3) = '0') THEN
-                alu_Op2_v := ALU_IN_REGB;
-            ELSE
-                alu_Op2_v := ALU_IN_IMM;
-            END IF;
-
-            CASE opcIx_v (5 DOWNTO 4) IS
-
-                WHEN "00" =>                                            -- ADD / RSUB
-                    IF (opcIx_v(0) = '1') THEN                          -- RSUB
-                        alu_Op1_v := ALU_IN_NOT_REGA;
-                    END IF;
-                    IF (opcIx_v(1) = '0') THEN                          -- xxx
-                        IF (opcIx_v(0) = '0') THEN
-                            alu_Cin_v := CIN_ZERO;
-                        ELSE
-                            alu_Cin_v := CIN_ONE;
-                        END IF;
-                    ELSE                                                -- xxxC
-                        alu_Cin_v := FROM_MSR;
-                    END IF;
-                    IF ((COMPATIBILITY_MODE_g = TRUE) AND (opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
-                    -- special CMP(U) and not RSUB(I)K, supported only in compatibility mode
-                        IF (IMM16_v(1) = '1') THEN                        -- U-bit set, CMPU
-                            alu_Action_v := A_CMPU;
-                        ELSE
-                            alu_Action_v := A_CMP;
-                        END IF;
-                    ELSE
-                        alu_Action_v := A_ADD;
-                        IF (opcIx_v(2) = '0') THEN
-                            msr_Action_v := UPDATE_CARRY;
-                        END IF;
-                    END IF;
-
-                WHEN "01" =>                                            -- MUL / BS
-                    CASE opcIx_v (2 DOWNTO 0) IS
-                        WHEN "000" =>                                   -- MUL
-                            IF (USE_HW_MUL_g = TRUE) THEN
-                                alu_Action_v := A_MUL;
-                            ELSE
-                                noLiteOpc_o <= '1';
-                            END IF;
-                        WHEN "001" =>                                   -- BS
-                            IF (USE_BARREL_g = TRUE) THEN
-                                IF (instruction_v(10) = '1') THEN
-                                    alu_Action_v := A_BSLL;
-                                ELSE
-                                    IF (instruction_v(9) = '1') THEN
-                                        alu_Action_v := A_BSRA;
-                                    ELSE
-                                        alu_Action_v := A_BSRL;
-                                    END IF;
-                                END IF;
-                            ELSE
-                                noLiteOpc_o <= '1';
-                            END IF;
-                        WHEN "010" =>                                             -- CMP / CMPU / CMPI (new format)
-                            IF (COMPATIBILITY_MODE_g = FALSE) THEN
-                                IF (IMM16_v(5) = '1') THEN   -- U-bit set, CMPU
-                                    alu_Action_v := A_CMPU;
-                                ELSE
-                                    alu_Action_v := A_CMP;
-                                END IF;
-
-                                IF (opcIx_v(3) = '0') THEN   -- IT, ITT, ITE is not available to CMPI
-                                    CASE IMM16_v(4 downto 3) IS
-                                        WHEN "00"   =>
-                                            cmp_Cond_Type_v := COND_TYPE_ALL;
-                                        WHEN "01"   =>
-                                            cmp_Cond_Type_v := COND_TYPE_IF_THEN;
-                                        WHEN "10"   =>
-                                            cmp_Cond_Type_v := COND_TYPE_IF_THEN_THEN;
-                                        WHEN "11"   =>
-                                            cmp_Cond_Type_v := COND_TYPE_IF_THEN_ELSE;
-                                        WHEN OTHERS =>
-                                            NULL;
-                                    END CASE;
-
-                                    CASE IMM16_v(2 downto 0) IS
-                                        WHEN "001"  =>
-                                            cmp_Cond_v := COND_EQ;
-                                        WHEN "010"  =>
-                                            cmp_Cond_v := COND_NE;
-                                        WHEN "011"  =>
-                                            cmp_Cond_v := COND_LT;
-                                        WHEN "100"  =>
-                                            cmp_Cond_v := COND_LE;
-                                        WHEN "101"  =>
-                                            cmp_Cond_v := COND_GT;
-                                        WHEN "110"  =>
-                                            cmp_Cond_v := COND_GE;
-                                        WHEN OTHERS =>
-                                            NULL;
-                                    END CASE;
-                                END IF;
-                            ELSE
-                                noLiteOpc_o <= '1';
-                            END IF;
-                        WHEN OTHERS =>
-                            noLiteOpc_o <= '1';
-                    END CASE;
-
-                WHEN "10" =>
-                    IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
-                        CASE code_x26_v IS
-                            WHEN "001" | "011" | "101" =>
-                                CASE code_x26_v(2 DOWNTO 1) IS
-                                    WHEN "00" =>                        -- SRA
-                                        alu_Cin_v := FROM_IN1;
-                                    WHEN "01" =>                        -- SRC
-                                        alu_Cin_v := FROM_MSR;
-                                    WHEN "10" =>                        -- SRL
-                                        alu_Cin_v := CIN_ZERO;
-                                    WHEN OTHERS =>
-                                        noLiteOpc_o <= '1';
-                                END CASE;
-                                alu_Action_v := A_SHIFT;
-                                msr_Action_v := UPDATE_CARRY;
-                            WHEN "110" =>                               -- SEXT8
-                                alu_Action_v := A_SEXT8;
-                            WHEN "111" =>                               -- SEXT16
-                                alu_Action_v := A_SEXT16;
-                            WHEN OTHERS  =>
-                                noLiteOpc_o  <= '1';
-                        END CASE;
-                    ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN          -- IMM
-                        IMM_Lock_v   := '1';
-                        -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
-                        alu_Action_v := A_NOP;
-                        wrb_Action_v := NO_WRB;
-                    ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
-                        CASE rD_v (3 DOWNTO 0) IS
-                            WHEN "0001" =>                              -- RTI(D)
-                                int_busy_v := '0';
-                            WHEN "0000" =>                              -- RTS(D)
-                            WHEN OTHERS  =>
-                                noLiteOpc_o <= '1';
-                        END CASE;
-                        alu_Action_v    := A_ADD;
-                        branch_Action_v := BR;
-                        wrb_Action_v    := NO_WRB;
-                        IF (COMPATIBILITY_MODE_g = TRUE) THEN
-                            delayBit_v  := rD_v(4);
-                        END IF;
-                    ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
-                        CASE IMM16_v IS
-                            WHEN X"8001" =>                             -- MFS (MSR only)
-                                alu_Action_v := A_MFS;
-                            WHEN X"C001" =>                             -- MTS (MSR only)
-                                alu_Action_v := A_MTS;
-                                wrb_Action_v := NO_WRB;
-                            WHEN OTHERS  =>
-                                noLiteOpc_o  <= '1';
-                        END CASE;
-                        rB_v := (OTHERS => '0');    -- in order to prevent occasional hazards (r16, r24)
-                    ELSE
-                        CASE opcIx_v (2 DOWNTO 0) IS
-                            WHEN "000" =>
-                                alu_Action_v := A_OR;
-                            WHEN "001" =>
-                                alu_Action_v := A_AND;
-                            WHEN "010" =>
-                                alu_Action_v := A_XOR;
-                            WHEN "011" =>
-                                alu_Action_v := A_AND;
-                                IF (opcIx_v(3) = '0') THEN
-                                    alu_Op2_v := ALU_IN_NOT_REGB;
-                                ELSE
-                                    alu_Op2_v := ALU_IN_NOT_IMM;
-                                END IF;
-                            WHEN "110" =>                               -- BR(I)(D)
-                                IF (rA_v(2) = '1') THEN
-                                    branch_Action_v := BRL;
-                                ELSE
-                                    branch_Action_v := BR;
-                                    wrb_Action_v    := NO_WRB;
-                                END IF;
-                                IF (rA_v(3) = '1') THEN
-                                    alu_Op1_v := ALU_IN_ZERO;
-                                ELSE
-                                    alu_Op1_v := ALU_IN_PC;
-                                END IF;
-                                alu_Action_v    := A_ADD;
-                                IF (COMPATIBILITY_MODE_g = TRUE) THEN
-                                    delayBit_v  := rA_v(4);
-                                END IF;
-                            WHEN "111" =>
-                                CASE rD_v(3 DOWNTO 0) IS
-                                    WHEN "0000" =>                      -- BEQ
-                                        branch_Action_v := BEQ;
-                                    WHEN "0001" =>                      -- BNE
-                                        branch_Action_v := BNE;
-                                    WHEN "0010" =>                      -- BLT
-                                        branch_Action_v := BLT;
-                                    WHEN "0011" =>                      -- BLE
-                                        branch_Action_v := BLE;
-                                    WHEN "0100" =>                      -- BGT
-                                        branch_Action_v := BGT;
-                                    WHEN "0101" =>                      -- BGE
-                                        branch_Action_v := BGE;
-                                    WHEN OTHERS =>
-                                        noLiteOpc_o <= '1';
-                                END CASE;
-                                alu_Action_v := A_ADD;
-                                alu_Op1_v    := ALU_IN_PC;
-                                IF (COMPATIBILITY_MODE_g = TRUE) THEN
-                                    delayBit_v := rD_v(4);
-                                END IF;
-                                wrb_Action_v := NO_WRB;     -- evaluate and update/overwrite in exeq
-                            WHEN OTHERS =>
-                                noLiteOpc_o  <= '1';
-                        END CASE;
-                    END IF;
-
-                WHEN "11" =>
-                    IF (opcIx_v (3 DOWNTO 0) = "1111") THEN             -- HALT
-                        alu_Action_v :=  A_HALT;
-                        wrb_Action_v := NO_WRB;
-                    ELSE
-                        alu_Action_v :=  A_ADD;
-                        CASE opcIx_v (1 DOWNTO 0) IS
-                            WHEN "00"   => transfer_Size_v := BYTE;
-                            WHEN "01"   => transfer_Size_v := HALFWORD;
-                            WHEN "10"   => transfer_Size_v := WORD;
-                            WHEN OTHERS =>
-                                noLiteOpc_o <= '1';
-                        END CASE;
-                        IF (opcIx_v(2) = '0') THEN
-                            mem_Action_v := RD_MEM;
-                            wrb_Action_v := WRB_MEM;
-                        ELSE
-                            mem_Action_v := WR_MEM;
-                            wrb_Action_v := NO_WRB;
-                        END IF;
-                    END IF;
-
-                WHEN OTHERS =>
-                    noLiteOpc_o  <= '1';
-
-            END CASE;
-
-        END IF;         -- interrupt test
-
-        ID2GPRF_o.rdix_rA  <= rA_v;
-        ID2GPRF_o.rdix_rB  <= rB_v;
-        ID2GPRF_o.rdix_rD  <= rD_v;
-
-        ID2EX_o.program_counter  <= prog_counter_v;
-        ID2EX_o.rdix_rA          <= rA_v;
-        ID2EX_o.rdix_rB          <= rB_v;
-        ID2EX_o.curr_rD          <= rD_v;
-        ID2EX_o.alu_Action       <= alu_Action_v;
-        ID2EX_o.alu_Op1          <= alu_Op1_v;
-        ID2EX_o.alu_Op2          <= alu_Op2_v;
-        ID2EX_o.alu_Cin          <= alu_Cin_v;
-        ID2EX_o.IMM16            <= IMM16_v;
-        ID2EX_o.IMM_Lock         <= IMM_Lock_v;
-        ID2EX_o.msr_Action       <= msr_Action_v;
-        ID2EX_o.branch_Action    <= branch_Action_v;
-        ID2EX_o.mem_Action       <= mem_Action_v;
-        ID2EX_o.transfer_Size    <= transfer_Size_v;
-        ID2EX_o.wrb_Action       <= wrb_Action_v;
-        --
-        IF (COMPATIBILITY_MODE_g = TRUE) THEN
-            ID2CTRL_o.delayBit    <= delayBit_v;
-        ELSE
-            ID2EX_o.cmp_Cond      <= cmp_Cond_v;
-            ID2EX_o.cmp_Cond_Type <= cmp_Cond_Type_v;
-        END IF;
-        ID2CTRL_o.int_busy        <= int_busy_v;
-
-    END PROCESS;
+       PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
+
+               VARIABLE prog_counter_v  : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE opcIx_v         : STD_LOGIC_VECTOR ( 5 DOWNTO 0);
+               VARIABLE instruction_v   : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE rD_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               VARIABLE rA_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               VARIABLE rB_v            : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               VARIABLE IMM16_v         : STD_LOGIC_VECTOR (15 DOWNTO 0);
+               VARIABLE code_x26_v      : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
+               VARIABLE IMM_Lock_v      : STD_LOGIC;
+               VARIABLE alu_Action_v    : ALU_ACTION_Type;
+               VARIABLE alu_Op1_v       : ALU_IN1_Type;
+               VARIABLE alu_Op2_v       : ALU_IN2_Type;
+               VARIABLE alu_Cin_v       : ALU_CIN_Type;
+               VARIABLE msr_Action_v    : MSR_ACTION_Type;
+               VARIABLE branch_Action_v : BRANCH_ACTION_Type;
+               VARIABLE it_Action_v     : IT_ACTION_Type;
+               VARIABLE delayBit_v      : STD_LOGIC;
+               VARIABLE mem_Action_v    : MEM_ACTION_Type;
+               VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
+               VARIABLE wrb_Action_v    : WRB_ACTION_Type;
+               VARIABLE int_busy_v      : STD_LOGIC;
+               VARIABLE condition_raw_v : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
+               VARIABLE halt_v          : STD_LOGIC;
+
+       BEGIN
+
+               prog_counter_v  := IF2ID_i.program_counter;
+               instruction_v   := imem_data_i;
+               opcIx_v         := instruction_v (31 DOWNTO 26);
+               rD_v            := instruction_v (25 DOWNTO 21);
+               rA_v            := instruction_v (20 DOWNTO 16);
+               rB_v            := instruction_v (15 DOWNTO 11);
+               IMM16_v         := instruction_v (15 DOWNTO  0);
+               IMM_Lock_v      := '0';
+               IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                       delayBit_v    := '0';
+               ELSE
+                       it_Action_v   :=  NO_IT;
+               END IF;
+               condition_raw_v := (others => '1');
+               alu_Cin_v       := CIN_ZERO;
+               alu_Action_v    := A_NOP;
+               msr_Action_v    := KEEP_CARRY;
+               branch_Action_v := NO_BR;
+               mem_Action_v    := NO_MEM;
+               transfer_Size_v := WORD;
+               wrb_Action_v    := WRB_EX;
+               halt_v          := '0';
+               -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
+               code_x26_v      := instruction_v(6) & instruction_v(5) & instruction_v(0);
+               int_busy_v      := INT_CTRL_i.int_busy;
+               -- for debugging purposes
+               noLiteOpc_o     <= '0';
+
+               IF (INT_CTRL_i.setup_int = '1') THEN
+
+                       alu_Op1_v       := ALU_IN_ZERO;
+                       alu_Op2_v       := ALU_IN_IMM;
+                       IMM16_v         := X"0010";                 -- address of _interrupt_handler vector
+                       prog_counter_v  := INT_CTRL_i.rti_target;   -- delayed program counter
+                       alu_Action_v    := A_ADD;
+                       rD_v            := "01110";                 -- r14 reserved for storing program_counter
+                       rA_v            := (OTHERS => '0');         -- also set rA and rB to avoid possible ...
+                       rB_v            := (OTHERS => '0');         -- ... erronuous hazard detection in exeq module
+                       int_busy_v      := '1';
+                       branch_Action_v := BRL;
+
+               ELSE
+
+                       alu_Op1_v := ALU_IN_REGA;
+                       IF (opcIx_v(3) = '0') THEN
+                               alu_Op2_v := ALU_IN_REGB;
+                       ELSE
+                               alu_Op2_v := ALU_IN_IMM;
+                       END IF;
+
+                       CASE opcIx_v (5 DOWNTO 4) IS
+
+                               WHEN "00" =>                                          -- ADD / RSUB
+                                       IF (opcIx_v(0) = '1') THEN                          -- RSUB
+                                               alu_Op1_v := ALU_IN_NOT_REGA;
+                                       END IF;
+                                       IF (opcIx_v(1) = '0') THEN                          -- xxx
+                                               IF (opcIx_v(0) = '0') THEN
+                                                       alu_Cin_v := CIN_ZERO;
+                                               ELSE
+                                                       alu_Cin_v := CIN_ONE;
+                                               END IF;
+                                       ELSE                                                -- xxxC
+                                               alu_Cin_v := FROM_MSR;
+                                       END IF;
+                                       IF ((COMPATIBILITY_MODE_g = TRUE) AND (opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
+                                               -- special CMP(U) and not RSUB(I)K, supported only in compatibility mode
+                                               IF (IMM16_v(1) = '1') THEN                        -- U-bit set, CMPU
+                                                       alu_Action_v := A_CMPU;
+                                               ELSE
+                                                       alu_Action_v := A_CMP;
+                                               END IF;
+                                               ELSE
+                                                       alu_Action_v := A_ADD;
+                                               IF (opcIx_v(2) = '0') THEN
+                                                       msr_Action_v := UPDATE_CARRY;
+                                               END IF;
+                                       END IF;
+
+                               WHEN "01" =>                                          -- MUL / BS
+
+                                       CASE opcIx_v (2 DOWNTO 0) IS
+                                               WHEN "000" =>                                     -- MUL
+                                                       IF (USE_HW_MUL_g = TRUE) THEN
+                                                               alu_Action_v := A_MUL;
+                                                       ELSE
+                                                               noLiteOpc_o <= '1';
+                                                       END IF;
+
+                                               WHEN "001" =>                                     -- BS
+                                                       IF (USE_BARREL_g = TRUE) THEN
+                                                               IF (instruction_v(10) = '1') THEN
+                                                                       alu_Action_v := A_BSLL;
+                                                               ELSIF (instruction_v(9) = '1') THEN
+                                                                       alu_Action_v := A_BSRA;
+                                                               ELSE
+                                                                       alu_Action_v := A_BSRL;
+                                                               END IF;
+                                                       ELSE
+                                                               noLiteOpc_o <= '1';
+                                                       END IF;
+
+                                               WHEN "010" | "011" =>                             -- CMP(U)
+                                                       IF (COMPATIBILITY_MODE_g = FALSE) THEN
+                                                               IF (opcIx_v(0) = '1') THEN
+                                                                       alu_Action_v := A_CMPU;
+                                                               ELSE
+                                                                       alu_Action_v := A_CMP;
+                                                               END IF;
+                                                       ELSE
+                                                               noLiteOpc_o <= '1';
+                                                       END IF;
+
+                                               WHEN "100" | "101" =>                             -- IT(U) / ITT(U) / ITE(U)
+                                                       IF (COMPATIBILITY_MODE_g = FALSE) THEN
+                                                               IF (opcIx_v(0) = '1') THEN
+                                                                       alu_Action_v := A_CMPU;
+                                                               ELSE
+                                                                       alu_Action_v := A_CMP;
+                                                               END IF;
+
+                                                               CASE rD_v(4 downto 3) IS
+                                                                       WHEN "00"   =>
+                                                                               it_Action_v := IT;
+                                                                       WHEN "01"   =>
+                                                                               it_Action_v := ITT;
+                                                                       WHEN "10"   =>
+                                                                               it_Action_v := ITE;
+                                                                       WHEN OTHERS =>
+                                                                               noLiteOpc_o <= '1';
+                                                               END CASE;
+                                                               condition_raw_v := rD_v(2 downto 0);
+                                                               -- IT instruction isn't writing to anything
+                                                               wrb_Action_v := NO_WRB;
+                                                       ELSE
+                                                               noLiteOpc_o <= '1';
+                                                       END IF;
+
+                                               WHEN OTHERS =>
+                                                               noLiteOpc_o <= '1';
+                                       END CASE;
+
+                               WHEN "10" =>
+                                       IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
+                                               CASE code_x26_v IS
+
+                                                       WHEN "001" | "011" | "101" =>
+                                                               CASE code_x26_v(2 DOWNTO 1) IS
+                                                                       WHEN "00" =>                                -- SRA
+                                                                               alu_Cin_v := FROM_IN1;
+                                                                       WHEN "01" =>                                -- SRC
+                                                                               alu_Cin_v := FROM_MSR;
+                                                                       WHEN "10" =>                                -- SRL
+                                                                               alu_Cin_v := CIN_ZERO;
+                                                                       WHEN OTHERS =>
+                                                                               noLiteOpc_o <= '1';
+                                                                       END CASE;
+                                                               alu_Action_v := A_SHIFT;
+                                                               msr_Action_v := UPDATE_CARRY;
+
+                                                       WHEN "110" =>                                   -- SEXT8
+                                                               alu_Action_v := A_SEXT8;
+                                                       WHEN "111" =>                                   -- SEXT16
+                                                               alu_Action_v := A_SEXT16;
+                                                       WHEN OTHERS  =>
+                                                               noLiteOpc_o  <= '1';
+                                               END CASE;
+
+                                       ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN          -- IMM
+                                               IMM_Lock_v   := '1';
+                                               -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
+                                               alu_Action_v := A_NOP;
+                                               wrb_Action_v := NO_WRB;
+                                       ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
+
+                                               CASE rD_v (3 DOWNTO 0) IS
+                                                       WHEN "0001" =>                                  -- RTI(D)
+                                                               int_busy_v := '0';
+                                                       WHEN "0000" =>                                  -- RTS(D)
+                                                               WHEN OTHERS  =>
+                                                       noLiteOpc_o <= '1';
+                                               END CASE;
+
+                                               alu_Action_v    := A_ADD;
+                                               branch_Action_v := BR;
+                                               wrb_Action_v    := NO_WRB;
+                                               IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                                                       delayBit_v  := rD_v(4);
+                                               END IF;
+
+                                       ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
+
+                                               CASE IMM16_v IS
+                                                       WHEN X"8001" =>                                 -- MFS (MSR only)
+                                                               alu_Action_v := A_MFS;
+                                                       WHEN X"C001" =>                                 -- MTS (MSR only)
+                                                               alu_Action_v := A_MTS;
+                                                               wrb_Action_v := NO_WRB;
+                                                       WHEN OTHERS  =>
+                                                               noLiteOpc_o  <= '1';
+                                               END CASE;
+                                               rB_v := (OTHERS => '0');    -- in order to prevent occasional hazards (r16, r24)
+
+                                       ELSE
+
+                                               CASE opcIx_v (2 DOWNTO 0) IS
+                                                       WHEN "000" =>
+                                                               alu_Action_v := A_OR;
+                                                       WHEN "001" =>
+                                                               alu_Action_v := A_AND;
+                                                       WHEN "010" =>
+                                                               alu_Action_v := A_XOR;
+                                                       WHEN "011" =>
+                                                               alu_Action_v := A_AND;
+                                                               IF (opcIx_v(3) = '0') THEN
+                                                                       alu_Op2_v := ALU_IN_NOT_REGB;
+                                                               ELSE
+                                                                       alu_Op2_v := ALU_IN_NOT_IMM;
+                                                               END IF;
+
+                                                       WHEN "110" =>                                                                             -- BR(I)(D)
+                                                               IF (rA_v(2) = '1') THEN
+                                                                       branch_Action_v := BRL;
+                                                               ELSE
+                                                                       branch_Action_v := BR;
+                                                                       wrb_Action_v    := NO_WRB;
+                                                               END IF;
+
+                                                               IF (rA_v(3) = '1') THEN
+                                                                       alu_Op1_v := ALU_IN_ZERO;
+                                                               ELSE
+                                                                       alu_Op1_v := ALU_IN_PC;
+                                                               END IF;
+                                                               alu_Action_v    := A_ADD;
+                                                               IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                                                                       delayBit_v  := rA_v(4);
+                                                               END IF;
+
+                                                       WHEN "111" =>
+                                                               condition_raw_v := rD_v(2 downto 0);          -- Conditional branching
+                                                               branch_Action_v := BR;
+                                                               alu_Action_v := A_ADD;
+                                                               alu_Op1_v    := ALU_IN_PC;
+                                                               IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                                                                       delayBit_v := rD_v(4);
+                                                               END IF;
+                                                               wrb_Action_v := NO_WRB;     -- evaluate and update/overwrite in exeq
+
+                                                       WHEN OTHERS =>
+                                                               noLiteOpc_o  <= '1';
+                                               END CASE;
+                                       END IF;
+
+                               WHEN "11" =>
+                                       IF (opcIx_v (3 DOWNTO 0) = "1111") THEN             -- HALT
+                                               alu_Action_v := A_NOP;
+                                               wrb_Action_v := NO_WRB;
+                                               halt_v       := '1';
+                                       ELSE
+                                               alu_Action_v :=  A_ADD;
+                                               CASE opcIx_v (1 DOWNTO 0) IS
+                                                       WHEN "00"   => transfer_Size_v := BYTE;
+                                                       WHEN "01"   => transfer_Size_v := HALFWORD;
+                                                       WHEN "10"   => transfer_Size_v := WORD;
+                                                       WHEN OTHERS =>
+                                                               noLiteOpc_o <= '1';
+                                               END CASE;
+                                               IF (opcIx_v(2) = '0') THEN
+                                                       mem_Action_v := RD_MEM;
+                                                       wrb_Action_v := WRB_MEM;
+                                               ELSE
+                                                       mem_Action_v := WR_MEM;
+                                                       wrb_Action_v := NO_WRB;
+                                               END IF;
+                                       END IF;
+
+                               WHEN OTHERS =>
+                                       noLiteOpc_o  <= '1';
+
+                       END CASE;
+
+               END IF;         -- interrupt test
+
+               ID2GPRF_o.rdix_rA  <= rA_v;
+               ID2GPRF_o.rdix_rB  <= rB_v;
+               ID2GPRF_o.rdix_rD  <= rD_v;
+
+               ID2EX_o.program_counter  <= prog_counter_v;
+               ID2EX_o.rdix_rA          <= rA_v;
+               ID2EX_o.rdix_rB          <= rB_v;
+               ID2EX_o.curr_rD          <= rD_v;
+               ID2EX_o.alu_Action       <= alu_Action_v;
+               ID2EX_o.alu_Op1          <= alu_Op1_v;
+               ID2EX_o.alu_Op2          <= alu_Op2_v;
+               ID2EX_o.alu_Cin          <= alu_Cin_v;
+               ID2EX_o.IMM16            <= IMM16_v;
+               ID2EX_o.IMM_Lock         <= IMM_Lock_v;
+               ID2EX_o.msr_Action       <= msr_Action_v;
+               ID2EX_o.branch_Action    <= branch_Action_v;
+               ID2EX_o.it_Action        <= it_Action_v;
+               ID2EX_o.mem_Action       <= mem_Action_v;
+               ID2EX_o.transfer_Size    <= transfer_Size_v;
+               ID2EX_o.wrb_Action       <= wrb_Action_v;
+               ID2EX_o.halt             <= halt_v;
+               --
+               CASE condition_raw_v IS
+                       WHEN "000"  =>
+                               ID2EX_o.condition    <= COND_EQ;
+                       WHEN "001"  =>
+                               ID2EX_o.condition    <= COND_NE;
+                       WHEN "010"  =>
+                               ID2EX_o.condition    <= COND_LT;
+                       WHEN "011"  =>
+                               ID2EX_o.condition    <= COND_LE;
+                       WHEN "100"  =>
+                               ID2EX_o.condition    <= COND_GT;
+                       WHEN "101"  =>
+                               ID2EX_o.condition    <= COND_GE;
+                       WHEN "111"  =>
+                               ID2EX_o.condition    <= COND_ALL;
+                       WHEN OTHERS =>
+                               ID2EX_o.condition    <= COND_ALL;
+                               noLiteOpc_o            <= '1';
+               END CASE;
+               --
+               IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                       ID2CTRL_o.delayBit   <= delayBit_v;
+               END IF;
+               ID2CTRL_o.int_busy     <= int_busy_v;
+
+       END PROCESS;
 
 END ARCHITECTURE rtl;
 
index 12357951fb2ec7f59e17c6c60773a3311c136830..03477128f2c0390bfa9720906e908b417c462468 100644 (file)
@@ -9,7 +9,7 @@
 --                Faculty EEMCS, Department ME&CE, Circuits and Systems
 --  Date:         September, 2010
 --
---  Modified:     Septemper, 2013: FSL scratched (Meloun)
+--  Modified:     Septemper, 2013: FSL scratched, core customized (Meloun)
 --                 December, 2010: FSL added (Huib)
 --                     June, 2011: added code for MUL and BARREL (Huib)
 --                                 Adapted to work with separate fsl_M-
@@ -29,36 +29,37 @@ USE WORK.mbl_Pkg.all;
 ----------------------------------------------------------
 ENTITY exeq IS
 ----------------------------------------------------------
-    GENERIC (
-        USE_HW_MUL_g : BOOLEAN := TRUE;
-        USE_BARREL_g : BOOLEAN := TRUE;
-        COMPATIBILITY_MODE_g : BOOLEAN := FALSE
-        );
-    PORT (
-        ID2EX_i      :  IN ID2EX_Type;
-        GPRF2EX_i    :  IN GPRF2EX_Type;
-        EX2IF_o      : OUT EX2IF_Type;
-        EX2CTRL_o    : OUT EX2CTRL_Type;
-        HALT_o       : OUT HALT_Type;
-        --
-        EX_WRB_i     :  IN WRB_Type;
-        EX_WRB_o     : OUT WRB_Type;
-        MEM_WRB_i    :  IN WRB_Type;
-        --
-        HAZARD_WRB_i :  IN HAZARD_WRB_Type;
-        HAZARD_WRB_o : OUT HAZARD_WRB_Type;
-        --
-        IMM_LOCK_i   :  IN IMM_LOCK_Type;
-        IMM_LOCK_o   : OUT IMM_LOCK_Type;
-        --
-        MSR_i        :  IN MSR_Type;
-        MSR_o        : OUT MSR_Type;
-        --
-        EX2MEM_o     : OUT EX2MEM_Type
-        );
+       GENERIC
+       (
+               USE_HW_MUL_g : BOOLEAN := TRUE;
+               USE_BARREL_g : BOOLEAN := TRUE;
+               COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+       );
+       PORT
+       (
+               ID2EX_i      :  IN ID2EX_Type;
+               GPRF2EX_i    :  IN GPRF2EX_Type;
+               EX2IF_o      : OUT EX2IF_Type;
+               EX2CTRL_o    : OUT EX2CTRL_Type;
+               HALT_o       : OUT HALT_Type;
+               --
+               EX_WRB_i     :  IN WRB_Type;
+               EX_WRB_o     : OUT WRB_Type;
+               MEM_WRB_i    :  IN WRB_Type;
+               --
+               HAZARD_WRB_i :  IN HAZARD_WRB_Type;
+               HAZARD_WRB_o : OUT HAZARD_WRB_Type;
+               --
+               IMM_LOCK_i   :  IN IMM_LOCK_Type;
+               IMM_LOCK_o   : OUT IMM_LOCK_Type;
+               --
+               MSR_i        :  IN MSR_Type;
+               MSR_o        : OUT MSR_Type;
+               --
+               EX2MEM_o     : OUT EX2MEM_Type
+       );
 END ENTITY exeq;
 
-
 ----------------------------------------------------------
 ARCHITECTURE rtl OF exeq IS
 ----------------------------------------------------------
@@ -66,379 +67,389 @@ ARCHITECTURE rtl OF exeq IS
 BEGIN
 
 p_exeq:
-    PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
-                        IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
-
-        -- function needed by BSLL (only if USE_BARREL_g = TRUE)
-        FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
-                                                        RETURN STD_LOGIC_VECTOR IS
-            VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        BEGIN
-        f_rev:
-            FOR i IN 0 TO 31 LOOP
-                reversed_v(31-i) := word32(i);
-            END LOOP;
-            RETURN reversed_v;
-        END;
-
-        VARIABLE data_rA_v       : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE data_rB_v       : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE data_rD_v       : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE in1_v           : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE in2_v           : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE hi16_v          : STD_LOGIC_VECTOR (15 DOWNTO 0);
-        VARIABLE IMM32_v         : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE carry_i_v       : STD_LOGIC;
-        VARIABLE result_v        : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE carry_o_v       : STD_LOGIC;
-        VARIABLE isZero_v        : STD_LOGIC;
-        VARIABLE cmpResZero_v    : STD_LOGIC;
-        VARIABLE signBit_in1_v   : STD_LOGIC;
-        VARIABLE signBit_in2_v   : STD_LOGIC;
-        VARIABLE signBit_rA_v    : STD_LOGIC;
-        VARIABLE signBit_rD_v    : STD_LOGIC;
-        VARIABLE rA_eq_ex_rD_v   : STD_LOGIC;
-        VARIABLE rB_eq_ex_rD_v   : STD_LOGIC;
-        VARIABLE hazard_v        : STD_LOGIC;
-        VARIABLE save_rX_v       : SAVE_REG_Type;
-        VARIABLE data_rX_v       : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE do_branch_v     : STD_LOGIC;
-        VARIABLE byte_Enable_v   : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
-        VARIABLE tmp64_v         : STD_LOGIC_VECTOR (63 DOWNTO 0);
-        VARIABLE padVec_v        : STD_LOGIC_VECTOR (15 DOWNTO 0);
-        VARIABLE halt_v          : STD_LOGIC;
-        VARIABLE halt_code_v     : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        VARIABLE do_cmp_cond_v   : STD_LOGIC;
-        VARIABLE cmp_cond_type_v : CMP_COND_TYPE_Type;
-
-    BEGIN
-
-        rA_eq_ex_rD_v   := '0';
-        rB_eq_ex_rD_v   := '0';
-        hazard_v        := '0';
-        save_rX_v       := NO_SAVE;
-        data_rX_v       := data_rB_v;         -- default value for data_rX_v
-        result_v        := (OTHERS => '0');
-        carry_o_v       := '0';
-        do_branch_v     := '0';
-        byte_Enable_v   := "0000";
-        halt_v          := '0';
-        halt_code_v     := "00000";
-        do_cmp_cond_v   := '0';
-        cmp_cond_type_v := COND_TYPE_ALL;
-        signBit_rD_v    := '0';
-
-        -- create some helper variables
-        IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
-            rA_eq_ex_rD_v := '1';
-        END IF;
-        IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
-            rB_eq_ex_rD_v := '1';
-        END IF;
-        -- test where to obtain data_rA from
-        IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
-            data_rA_v := EX_WRB_i.data_rD;
-        ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
-            data_rA_v := MEM_WRB_i.data_rD;
-        ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
-            data_rA_v := HAZARD_WRB_i.data_rX;
-        ELSE
-            data_rA_v := GPRF2EX_i.data_rA;
-        END IF;
-        -- test where to obtain data_rB from
-        IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
-            data_rB_v := EX_WRB_i.data_rD;
-        ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
-            data_rB_v := MEM_WRB_i.data_rD;
-        ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
-            data_rB_v := HAZARD_WRB_i.data_rX;
-        ELSE
-            data_rB_v := GPRF2EX_i.data_rB;
-        END IF;
-        -- .... or, isn't all necessary data available yet being still in the pipeline ?
-        data_rX_v := data_rB_v;                 -- default value for data_rX_v
-        IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
-            IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
-                hazard_v  := '1';
--- always??     IF (MEM_WRB_i.wrb_Action = WRB_MEM) THEN
-                    -- handle situations in which both rA and rB needed
-                    IF (rA_eq_ex_rD_v = '1') THEN
-                        save_rX_v := SAVE_RB;   -- already by default data_rX_v = data_rB_v
-                    ELSE
-                        save_rX_v := SAVE_RA;
-                        data_rX_v := data_rA_v;
-                    END IF;
---              END IF;
-            END IF;
-        END IF;
-
-        IF (IMM_LOCK_i.locked = '1') THEN
-            hi16_v := IMM_LOCK_i.IMM_hi16;
-        ELSIF (ID2EX_i.IMM16(15) = '0') THEN
-            hi16_v := C_16_ZEROS;
-        ELSE
-            hi16_v :=  C_16_ONES;
-        END IF;
-        IMM32_v := hi16_v & ID2EX_i.IMM16;
-
-        CASE ID2EX_i.alu_Op1 IS
-            WHEN ALU_IN_REGA     =>  in1_v := data_rA_v;
-            WHEN ALU_IN_NOT_REGA =>  in1_v := NOT data_rA_v;
-            WHEN ALU_IN_PC       =>  in1_v := ID2EX_i.program_counter;
-            WHEN ALU_IN_ZERO     =>  in1_v := C_32_ZEROS;
-            WHEN OTHERS          =>  NULL;
-        END CASE;
-
-        CASE ID2EX_i.alu_Op2 IS
-            WHEN ALU_IN_REGB     =>  in2_v := data_rB_v;
-            WHEN ALU_IN_NOT_REGB =>  in2_v := NOT data_rB_v;
-            WHEN ALU_IN_IMM      =>  in2_v := IMM32_v;
-            WHEN ALU_IN_NOT_IMM  =>  in2_v := NOT IMM32_v;
-            WHEN OTHERS          =>  NULL;
-        END CASE;
-
-        signBit_in1_v := in1_v(31);
-        signBit_in2_v := in2_v(31);
-        signBit_rA_v  := data_rA_v(31);
-
-        CASE ID2EX_i.alu_Cin IS
-            WHEN CIN_ZERO  =>   carry_i_v := '0';
-            WHEN CIN_ONE   =>   carry_i_v := '1';
-            WHEN FROM_MSR  =>   carry_i_v := MSR_i.C;
-            WHEN FROM_IN1  =>   carry_i_v := in1_v(31);
-            WHEN OTHERS    =>   carry_i_v := '0';
-        END CASE;
-
-        IF (data_rA_v = C_32_ZEROS) THEN
-            isZero_v := '1';
-        ELSE
-            isZero_v := '0';
-        END IF;
-
-        CASE ID2EX_i.alu_Action IS
-            WHEN A_ADD | A_CMP | A_CMPU =>
-                ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
-                IF (id2ex_i.alu_Action = A_CMPU) THEN
-                    IF (signBit_in1_v = signBit_in2_v) THEN
-                        signBit_rD_v := NOT signBit_in1_v;
-                    END IF;
-                ELSIF (id2ex_i.alu_Action = A_CMP) THEN
-                    IF (signBit_in1_v = signBit_in2_v) THEN
-                        signBit_rD_v := signBit_in1_v;
-                    END IF;
-                END IF;
-
-                result_v(31) := signBit_rD_v;
-
-                IF (COMPATIBILITY_MODE_g = FALSE) THEN
-                    IF (ID2EX_i.cmp_Cond /= COND_ALL) THEN
-                        IF (result_v = C_32_ZEROS) THEN
-                            cmpResZero_v := '1';
-                        ELSE
-                            cmpResZero_v := '0';
-                        END IF;
-
-                        CASE ID2EX_i.cmp_Cond IS
-                            WHEN COND_EQ => do_cmp_cond_v := cmpResZero_v;
-                            WHEN COND_NE => do_cmp_cond_v := NOT cmpResZero_v;
-                            WHEN COND_LT => do_cmp_cond_v := signBit_rD_v;
-                            WHEN COND_LE => do_cmp_cond_v := signBit_rD_v OR cmpResZero_v;
-                            WHEN COND_GT => do_cmp_cond_v := NOT (signBit_rD_v OR cmpResZero_v);
-                            WHEN COND_GE => do_cmp_cond_v := NOT signBit_rD_v;
-                            WHEN OTHERS  => NULL;
-                        END CASE;
-
-                        cmp_cond_type_v := ID2EX_i.cmp_Cond_Type;
-                    END IF;
-                END IF;
-
-            WHEN A_OR      =>
-                result_v  := in1_v  OR in2_v;
-            WHEN A_AND    =>
-                result_v  := in1_v AND in2_v;
-            WHEN A_XOR    =>
-                result_v  := in1_v XOR in2_v;
-            WHEN A_SHIFT  =>
-                result_v  := carry_i_v & in1_v(31 DOWNTO 1);
-                carry_o_v := in1_v(0);
-            WHEN A_SEXT8   =>
-                IF (in1_v(7) = '0') THEN
-                    result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
-                ELSE
-                    result_v :=  C_24_ONES & in1_v( 7 DOWNTO 0);
-                END IF;
-            WHEN A_SEXT16  =>
-                IF (in1_v(15) = '0') THEN
-                    result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
-                ELSE
-                    result_v :=  C_16_ONES & in1_v(15 DOWNTO 0);
-                END IF;
-            WHEN A_MFS     =>
-                result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
-            WHEN A_MTS     =>
-                MSR_o.IE  <= data_Ra_v(1);
-                MSR_o.C   <= data_Ra_v(2);
-            WHEN A_MUL     =>
-                IF (USE_HW_MUL_g = TRUE) THEN
-                    tmp64_v  := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
-                    result_v := tmp64_v(31 DOWNTO 0);
-                END IF;
-            WHEN A_BSLL | A_BSRL | A_BSRA  =>
-                IF (USE_BARREL_g = TRUE) THEN
-                    IF (ID2EX_i.alu_Action = A_BSLL) THEN
-                        result_v := reverse_bits (in1_v);
-                    ELSE
-                        result_v := in1_v;
-                    END IF;
-                    IF (ID2EX_i.alu_Action = A_BSRA) THEN
-                        padVec_v := (OTHERS => in1_v(31));
-                    ELSE
-                        padVec_v := (OTHERS => '0');
-                    END IF;
-                    IF (in2_v(4) = '1') THEN
-                        result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
-                    END IF;
-                    IF (in2_v(3) = '1') THEN
-                        result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO  8);
-                    END IF;
-                    IF (in2_v(2) = '1') THEN
-                        result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO  4);
-                    END IF;
-                    IF (in2_v(1) = '1') THEN
-                        result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO  2);
-                    END IF;
-                    IF (in2_v(0) = '1') THEN
-                        result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO  1);
-                    END IF;
-                    IF (ID2EX_i.alu_Action = A_BSLL) THEN
-                        result_v := reverse_bits (result_v);
-                    END IF;
-                END IF;     -- (USE_BARREL_g = TRUE)
-            WHEN A_HALT    =>
-                halt_v := '1';
-                halt_code_v := ID2EX_i.IMM16(4 DOWNTO 0);
-            WHEN OTHERS    =>
-                NULL;
-        END CASE;
-
-        CASE ID2EX_i.branch_Action IS
-            WHEN BR     => do_branch_v := '1';
-            WHEN BRL    => do_branch_v := '1';
-            WHEN BEQ    => do_branch_v := isZero_v;
-            WHEN BNE    => do_branch_v := NOT isZero_v;
-            WHEN BLT    => do_branch_v := signBit_rA_v;
-            WHEN BLE    => do_branch_v := signBit_rA_v OR isZero_v;
-            WHEN BGT    => do_branch_v := NOT (signBit_rA_v OR isZero_v);
-            WHEN BGE    => do_branch_v := NOT signBit_rA_v;
-            WHEN OTHERS => NULL;
-        END CASE;
-        IF (do_branch_v = '1') THEN
-            EX2IF_o.take_branch   <= '1';
-            EX2IF_o.branch_target <= result_v;
-        ELSE
-            EX2IF_o.take_branch   <= '0';
-            EX2IF_o.branch_target <= C_32_ZEROS;
-        END IF;
-
-        -- CMP conditioning
-        IF (COMPATIBILITY_MODE_g = FALSE) THEN
-            CASE cmp_cond_type_v IS
-                WHEN COND_TYPE_ALL          =>
-                    EX2CTRL_o.flush_first  <= '0';
-                    EX2CTRL_o.flush_second <= '0';
-                WHEN COND_TYPE_IF_THEN      =>
-                    EX2CTRL_o.flush_first  <= not do_cmp_cond_v;
-                    EX2CTRL_o.flush_second <= '0';
-                WHEN COND_TYPE_IF_THEN_THEN =>
-                    EX2CTRL_o.flush_first  <= not do_cmp_cond_v;
-                    EX2CTRL_o.flush_second <= not do_cmp_cond_v;
-                WHEN COND_TYPE_IF_THEN_ELSE =>
-                    EX2CTRL_o.flush_first  <= not do_cmp_cond_v;
-                    EX2CTRL_o.flush_second <= do_cmp_cond_v;
-                WHEN OTHERS                 =>
-                    NULL;
-            END CASE;
-        END IF;
-
-        -- Halting
-        HALT_o.halt      <= halt_v;
-        HALT_o.halt_code <= halt_code_v;
-
-        -- WR_MEM/RD_MEM:      result_v --> exeq_result --> mem_address,
-        --        WR_MEM:                       data_rD --> data_out_to_mem
-        --           BRL:  prog_counter --> exeq_result
-        --          else       result_v --> exeq_result (data_rD not used)
-        EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
-        IF (ID2EX_i.branch_Action = BRL) THEN
-            EX2MEM_o.wrb_Action  <= WRB_EX;
-            EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
-            EX2MEM_o.data_rD     <= ID2EX_i.program_counter;
-            -- set data_rD_v, although unused, to prevent an inferred latch
-            data_rD_v := GPRF2EX_i.data_rD;
-        ELSE
-            EX2MEM_o.wrb_Action  <= ID2EX_i.wrb_Action;
-            EX2MEM_o.exeq_result <= result_v;
-            -- test where to obtain data_rD from
-            IF (HAZARD_WRB_i.hazard = '1') THEN
-                data_rD_v := HAZARD_WRB_i.data_rD;
-            ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
-                -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
-                data_rD_v := EX_WRB_i.data_rD;
-            ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
-                data_rD_v := MEM_WRB_i.data_rD;
-            ELSE
-                data_rD_v := GPRF2EX_i.data_rD;
-            END IF;
-        END IF;
-        IF (ID2EX_i.mem_Action /= NO_MEM) THEN
-            CASE ID2EX_i.transfer_Size IS
-                WHEN BYTE     =>
-                    CASE result_v( 1 DOWNTO 0) IS
-                        WHEN "00"   => byte_Enable_v := "1000";
-                        WHEN "01"   => byte_Enable_v := "0100";
-                        WHEN "10"   => byte_Enable_v := "0010";
-                        WHEN "11"   => byte_Enable_v := "0001";
-                        WHEN OTHERS => NULL;
-                    END CASE;
-                WHEN HALFWORD =>
-                    CASE result_v( 1 DOWNTO 0) IS
-                        WHEN "00"   => byte_Enable_v := "1100";
-                        WHEN "10"   => byte_Enable_v := "0011";
-                        WHEN OTHERS => NULL;
-                    END CASE;
-                WHEN OTHERS   =>       byte_Enable_v := "1111";
-            END CASE;
-        END IF;
-
-        -- update MSR[IE] and/or MSR[C] if needed
-        IF (ID2EX_i.alu_Action /= A_MTS) THEN
-            MSR_o.IE  <= MSR_i.IE;
-            IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
-                MSR_o.C <= carry_o_v;
-            ELSE
-                MSR_o.C <= MSR_i.C;
-            END IF;
-        END IF;
-
-        -- pass remaining data to mem
-        EX2MEM_o.mem_Action  <= ID2EX_i.mem_Action;
-        EX2MEM_o.data_rD     <= data_rD_v;
-        EX2MEM_o.byte_Enable <= byte_Enable_v;
-        EX2MEM_o.wrix_rD     <= ID2EX_i.curr_rD;
-        --
-        IMM_LOCK_o.locked    <= ID2EX_i.IMM_Lock;
-        IMM_LOCK_o.IMM_hi16  <= ID2EX_i.IMM16;
-        --
-        EX_WRB_o.wrb_Action  <= ID2EX_i.wrb_Action;
-        EX_WRB_o.wrix_rD     <= ID2EX_i.curr_rD;
-        EX_WRB_o.data_rD     <= result_v;
-        --
-        HAZARD_WRB_o.hazard  <= hazard_v;
-        HAZARD_WRB_o.save_rX <= save_rX_v;
-        HAZARD_WRB_o.data_rX <= data_rX_v;
-        HAZARD_WRB_o.data_rD <= data_rD_v;
-
-    END PROCESS;
+       PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
+                                               IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
+
+               -- function needed by BSLL (only if USE_BARREL_g = TRUE)
+               FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
+                       RETURN STD_LOGIC_VECTOR IS
+                               VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               BEGIN
+               f_rev:
+                       FOR i IN 0 TO 31 LOOP
+                               reversed_v(31-i) := word32(i);
+                       END LOOP;
+                       RETURN reversed_v;
+               END;
+
+               VARIABLE data_rA_v     : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE data_rB_v     : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE data_rD_v     : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE in1_v         : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE in2_v         : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE hi16_v        : STD_LOGIC_VECTOR (15 DOWNTO 0);
+               VARIABLE IMM32_v       : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE carry_i_v     : STD_LOGIC;
+               VARIABLE result_v      : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE carry_o_v     : STD_LOGIC;
+               VARIABLE isZero_v      : STD_LOGIC;
+               VARIABLE signBit_in1_v : STD_LOGIC;
+               VARIABLE signBit_in2_v : STD_LOGIC;
+               VARIABLE signBit_r_v   : STD_LOGIC;
+               VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
+               VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
+               VARIABLE hazard_v      : STD_LOGIC;
+               VARIABLE save_rX_v     : SAVE_REG_Type;
+               VARIABLE data_rX_v     : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE do_branch_v   : STD_LOGIC;
+               VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+               VARIABLE tmp64_v       : STD_LOGIC_VECTOR (63 DOWNTO 0);
+               VARIABLE padVec_v      : STD_LOGIC_VECTOR (15 DOWNTO 0);
+               VARIABLE do_cond_v     : STD_LOGIC;
+
+       BEGIN
+
+               rA_eq_ex_rD_v := '0';
+               rB_eq_ex_rD_v := '0';
+               hazard_v      := '0';
+               save_rX_v     := NO_SAVE;
+               data_rX_v     := data_rB_v;         -- default value for data_rX_v
+               result_v      := (OTHERS => '0');
+               carry_o_v     := '0';
+               do_branch_v   := '0';
+               byte_Enable_v := (OTHERS => '0');
+               do_cond_v     := '0';
+               --
+    MSR_o         <= MSR_i;             -- pass MSR by default
+
+               -- create some helper variables
+               IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
+                       rA_eq_ex_rD_v := '1';
+               END IF;
+               IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
+                       rB_eq_ex_rD_v := '1';
+               END IF;
+               -- test where to obtain data_rA from
+               IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
+                       data_rA_v := EX_WRB_i.data_rD;
+               ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
+                       data_rA_v := MEM_WRB_i.data_rD;
+               ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
+                       data_rA_v := HAZARD_WRB_i.data_rX;
+               ELSE
+                       data_rA_v := GPRF2EX_i.data_rA;
+               END IF;
+               -- test where to obtain data_rB from
+               IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
+                       data_rB_v := EX_WRB_i.data_rD;
+               ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
+                       data_rB_v := MEM_WRB_i.data_rD;
+               ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
+                       data_rB_v := HAZARD_WRB_i.data_rX;
+               ELSE
+                       data_rB_v := GPRF2EX_i.data_rB;
+               END IF;
+               -- .... or, isn't all necessary data available yet being still in the pipeline ?
+               data_rX_v := data_rB_v;                 -- default value for data_rX_v
+               IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
+                       IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
+                               hazard_v  := '1';
+                               IF (rA_eq_ex_rD_v = '1') THEN
+                                       save_rX_v := SAVE_RB;   -- already by default data_rX_v = data_rB_v
+                               ELSE
+                                       save_rX_v := SAVE_RA;
+                                       data_rX_v := data_rA_v;
+                               END IF;
+                       END IF;
+               END IF;
+
+               IF (IMM_LOCK_i.locked = '1') THEN
+                       hi16_v := IMM_LOCK_i.IMM_hi16;
+               ELSIF (ID2EX_i.IMM16(15) = '0') THEN
+                       hi16_v := C_16_ZEROS;
+               ELSE
+                       hi16_v :=  C_16_ONES;
+               END IF;
+               IMM32_v := hi16_v & ID2EX_i.IMM16;
+
+               CASE ID2EX_i.alu_Op1 IS
+                       WHEN ALU_IN_REGA     =>  in1_v := data_rA_v;
+                       WHEN ALU_IN_NOT_REGA =>  in1_v := NOT data_rA_v;
+                       WHEN ALU_IN_PC       =>  in1_v := ID2EX_i.program_counter;
+                       WHEN ALU_IN_ZERO     =>  in1_v := C_32_ZEROS;
+                       WHEN OTHERS          =>  NULL;
+               END CASE;
+
+               CASE ID2EX_i.alu_Op2 IS
+                       WHEN ALU_IN_REGB     =>  in2_v := data_rB_v;
+                       WHEN ALU_IN_NOT_REGB =>  in2_v := NOT data_rB_v;
+                       WHEN ALU_IN_IMM      =>  in2_v := IMM32_v;
+                       WHEN ALU_IN_NOT_IMM  =>  in2_v := NOT IMM32_v;
+                       WHEN OTHERS          =>  NULL;
+               END CASE;
+
+               signBit_in1_v := in1_v(31);
+               signBit_in2_v := in2_v(31);
+               signBit_r_v   := data_rA_v(31); -- Init with Op1, then possibly override
+
+               CASE ID2EX_i.alu_Cin IS
+                       WHEN CIN_ZERO  =>   carry_i_v := '0';
+                       WHEN CIN_ONE   =>   carry_i_v := '1';
+                       WHEN FROM_MSR  =>   carry_i_v := MSR_i.C;
+                       WHEN FROM_IN1  =>   carry_i_v := in1_v(31);
+                       WHEN OTHERS    =>   carry_i_v := '0';
+               END CASE;
+
+               IF (data_rA_v = C_32_ZEROS) THEN
+                       isZero_v := '1';
+               ELSE
+                       isZero_v := '0';
+               END IF;
+
+               CASE ID2EX_i.alu_Action IS
+
+                       WHEN A_ADD | A_CMP | A_CMPU =>
+                               ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
+                               CASE ID2EX_i.alu_Action IS
+
+                                       WHEN A_CMPU  =>
+                                               IF (signBit_in1_v = signBit_in2_v) THEN
+                                                       signBit_r_v := NOT signBit_in1_v;
+                                               END IF;
+                                               IF (COMPATIBILITY_MODE_g = FALSE) AND (ID2EX_i.it_Action /= NO_IT) THEN
+                                                       -- have to update zero flag with current result
+                                                       IF (result_v = C_32_ZEROS) THEN
+                                                               isZero_v := '1';
+                                                       ELSE
+                                                               isZero_v := '0';
+                                                       END IF;
+                                               END IF;
+
+                                       WHEN A_CMP  =>
+                                               IF (signBit_in1_v = signBit_in2_v) THEN
+                                                       signBit_r_v := signBit_in1_v;
+                                               END IF;
+                                               IF (COMPATIBILITY_MODE_g = FALSE) AND (ID2EX_i.it_Action /= NO_IT) THEN
+                                                       -- have to update zero flag with current result
+                                                       IF (result_v = C_32_ZEROS) THEN
+                                                               isZero_v := '1';
+                                                       ELSE
+                                                               isZero_v := '0';
+                                                       END IF;
+                                               END IF;
+
+                                       WHEN OTHERS =>
+                                               NULL;
+
+                               END CASE;
+
+                       WHEN A_OR     =>
+                               result_v  := in1_v  OR in2_v;
+
+                       WHEN A_AND    =>
+                               result_v  := in1_v AND in2_v;
+
+                       WHEN A_XOR    =>
+                               result_v  := in1_v XOR in2_v;
+
+                       WHEN A_SHIFT  =>
+                               result_v  := carry_i_v & in1_v(31 DOWNTO 1);
+                               carry_o_v := in1_v(0);
+
+                       WHEN A_SEXT8  =>
+                               IF (in1_v(7) = '0') THEN
+                                       result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
+                               ELSE
+                                       result_v :=  C_24_ONES & in1_v( 7 DOWNTO 0);
+                               END IF;
+
+                       WHEN A_SEXT16 =>
+                               IF (in1_v(15) = '0') THEN
+                                       result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
+                               ELSE
+                                       result_v :=  C_16_ONES & in1_v(15 DOWNTO 0);
+                               END IF;
+
+                       WHEN A_MFS    =>
+                               result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
+
+                       WHEN A_MTS    =>
+                               MSR_o.IE  <= data_Ra_v(1);
+                               MSR_o.C   <= data_Ra_v(2);
+
+                       WHEN A_MUL    =>
+                               IF (USE_HW_MUL_g = TRUE) THEN
+                                       tmp64_v  := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
+                                       result_v := tmp64_v(31 DOWNTO 0);
+                               END IF;
+
+                       WHEN A_BSLL | A_BSRL | A_BSRA  =>
+                               IF (USE_BARREL_g = TRUE) THEN
+                                       IF (ID2EX_i.alu_Action = A_BSLL) THEN
+                                               result_v := reverse_bits (in1_v);
+                                       ELSE
+                                               result_v := in1_v;
+                                       END IF;
+                                       IF (ID2EX_i.alu_Action = A_BSRA) THEN
+                                               padVec_v := (OTHERS => in1_v(31));
+                                       ELSE
+                                               padVec_v := (OTHERS => '0');
+                                       END IF;
+                                       IF (in2_v(4) = '1') THEN
+                                               result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
+                                       END IF;
+                                       IF (in2_v(3) = '1') THEN
+                                               result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO  8);
+                                       END IF;
+                                       IF (in2_v(2) = '1') THEN
+                                               result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO  4);
+                                       END IF;
+                                       IF (in2_v(1) = '1') THEN
+                                               result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO  2);
+                                       END IF;
+                                       IF (in2_v(0) = '1') THEN
+                                               result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO  1);
+                                       END IF;
+                                       IF (ID2EX_i.alu_Action = A_BSLL) THEN
+                                               result_v := reverse_bits (result_v);
+                                       END IF;
+                               END IF;     -- (USE_BARREL_g = TRUE)
+
+                       WHEN OTHERS    =>
+                               NULL;
+
+    END CASE;
+
+               CASE ID2EX_i.condition IS
+                       WHEN COND_EQ  => do_cond_v := isZero_v;
+                       WHEN COND_NE  => do_cond_v := NOT isZero_v;
+                       WHEN COND_LT  => do_cond_v := signBit_r_v;
+                       WHEN COND_LE  => do_cond_v := signBit_r_v OR isZero_v;
+                       WHEN COND_GT  => do_cond_v := NOT (signBit_r_v OR isZero_v);
+                       WHEN COND_GE  => do_cond_v := NOT signBit_r_v;
+                       WHEN COND_ALL => do_cond_v := '1';
+                       WHEN OTHERS   => NULL;
+               END CASE;
+
+               CASE ID2EX_i.branch_Action IS
+                       WHEN BR     => do_branch_v := do_cond_v;
+                       WHEN BRL    => do_branch_v := '1';
+                       WHEN OTHERS => NULL;
+               END CASE;
+
+               IF (do_branch_v = '1') THEN
+                       EX2IF_o.take_branch   <= '1';
+                       EX2IF_o.branch_target <= result_v;
+               ELSE
+                       EX2IF_o.take_branch   <= '0';
+                       EX2IF_o.branch_target <= C_32_ZEROS;
+               END IF;
+
+               -- IT / ITE / ITT conditioning
+               IF (COMPATIBILITY_MODE_g = FALSE) THEN
+                       CASE ID2EX_i.it_Action IS
+                               WHEN IT     =>
+                                       EX2CTRL_o.flush_first  <= not do_cond_v;
+                                       EX2CTRL_o.flush_second <= '0';
+                                       EX2CTRL_o.ignore_state <= '1';
+                               WHEN ITT    =>
+                                       EX2CTRL_o.flush_first  <= not do_cond_v;
+                                       EX2CTRL_o.flush_second <= not do_cond_v;
+                                       EX2CTRL_o.ignore_state <= '1';
+                               WHEN ITE    =>
+                                       EX2CTRL_o.flush_first  <= not do_cond_v;
+                                       EX2CTRL_o.flush_second <= do_cond_v;
+                                       EX2CTRL_o.ignore_state <= '1';
+                               WHEN OTHERS =>
+                                       EX2CTRL_o.flush_first  <= '0';
+                                       EX2CTRL_o.flush_second <= '0';
+                                       EX2CTRL_o.ignore_state <= '0';
+                       END CASE;
+               END IF;
+
+               -- Halting, the instruction parsing is separate
+               HALT_o.halt        <= ID2EX_i.halt;
+               IF (ID2EX_i.halt = '1') THEN
+                       HALT_o.halt_code <= ID2EX_i.IMM16(4 DOWNTO 0);
+               ELSE
+                       HALT_o.halt_code <= (others => '0');
+               END IF;
+
+               -- WR_MEM/RD_MEM:      result_v --> exeq_result --> mem_address,
+               --        WR_MEM:                       data_rD --> data_out_to_mem
+               --           BRL:  prog_counter --> exeq_result
+               --          else       result_v --> exeq_result (data_rD not used)
+               EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
+               IF (ID2EX_i.branch_Action = BRL) THEN
+                       EX2MEM_o.wrb_Action  <= WRB_EX;
+                       EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
+                       EX2MEM_o.data_rD     <= ID2EX_i.program_counter;
+                       -- set data_rD_v, although unused, to prevent an inferred latch
+                       data_rD_v := GPRF2EX_i.data_rD;
+               ELSE
+                       EX2MEM_o.wrb_Action  <= ID2EX_i.wrb_Action;
+                       EX2MEM_o.exeq_result <= result_v;
+                       -- test where to obtain data_rD from
+                       IF (HAZARD_WRB_i.hazard = '1') THEN
+                               data_rD_v := HAZARD_WRB_i.data_rD;
+                       ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
+                       -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
+                               data_rD_v := EX_WRB_i.data_rD;
+                       ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
+                               data_rD_v := MEM_WRB_i.data_rD;
+                       ELSE
+                               data_rD_v := GPRF2EX_i.data_rD;
+                       END IF;
+               END IF;
+
+               IF (ID2EX_i.mem_Action /= NO_MEM) THEN
+                       CASE ID2EX_i.transfer_Size IS
+
+                               WHEN BYTE     =>
+                                       CASE result_v( 1 DOWNTO 0) IS
+                                               WHEN "00"   => byte_Enable_v := "1000";
+                                               WHEN "01"   => byte_Enable_v := "0100";
+                                               WHEN "10"   => byte_Enable_v := "0010";
+                                               WHEN "11"   => byte_Enable_v := "0001";
+                                               WHEN OTHERS => NULL;
+                                       END CASE;
+
+                               WHEN HALFWORD =>
+                                       CASE result_v( 1 DOWNTO 0) IS
+                                               WHEN "00"   => byte_Enable_v := "1100";
+                                               WHEN "10"   => byte_Enable_v := "0011";
+                                               WHEN OTHERS => NULL;
+                                       END CASE;
+
+                               WHEN OTHERS     => byte_Enable_v := "1111";
+
+                       END CASE;
+               END IF;
+
+               -- update MSR[C] if needed
+               IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
+                       MSR_o.C <= carry_o_v;
+               END IF;
+
+               -- pass remaining data to mem
+               EX2MEM_o.mem_Action  <= ID2EX_i.mem_Action;
+               EX2MEM_o.data_rD     <= data_rD_v;
+               EX2MEM_o.byte_Enable <= byte_Enable_v;
+               EX2MEM_o.wrix_rD     <= ID2EX_i.curr_rD;
+               --
+               IMM_LOCK_o.locked    <= ID2EX_i.IMM_Lock;
+               IMM_LOCK_o.IMM_hi16  <= ID2EX_i.IMM16;
+               --
+               EX_WRB_o.wrb_Action  <= ID2EX_i.wrb_Action;
+               EX_WRB_o.wrix_rD     <= ID2EX_i.curr_rD;
+               EX_WRB_o.data_rD     <= result_v;
+               --
+               HAZARD_WRB_o.hazard  <= hazard_v;
+               HAZARD_WRB_o.save_rX <= save_rX_v;
+               HAZARD_WRB_o.data_rX <= data_rX_v;
+               HAZARD_WRB_o.data_rD <= data_rD_v;
+
+       END PROCESS;
 
 END ARCHITECTURE rtl;
 
index c81f642f5098be040cebdcf9bb60969637c9ba02..0f48b09c203e4d1ce645c25aa0bb1c05dab19fe4 100644 (file)
@@ -9,7 +9,7 @@
 --                Faculty EEMCS, Department ME&CE, Circuits and Systems
 --  Date:         September, 2010
 --
---  Modified:     September, 2013: Removed FSL
+--  Modified:     September, 2013: Removed FSL, core customization
 --                     June, 2011: ALU_ACTION_Type extended to incorporate
 --                                 MUL and BS instructions (Huib)
 --                                 Adapted to work with separate fsl_M-
@@ -25,429 +25,389 @@ USE IEEE.std_logic_1164.all;
 USE IEEE.std_logic_unsigned.all;
 USE IEEE.numeric_std.all;
 
-
 --------------------------------------------------------------------------------
 PACKAGE mbl_Pkg IS
 --------------------------------------------------------------------------------
 
-    CONSTANT  C_8_ZEROS : STD_LOGIC_VECTOR ( 7 DOWNTO 0) :=       X"00";
-    CONSTANT C_16_ZEROS : STD_LOGIC_VECTOR (15 DOWNTO 0) :=     X"0000";
-    CONSTANT C_24_ZEROS : STD_LOGIC_VECTOR (23 DOWNTO 0) :=   X"000000";
-    CONSTANT C_32_ZEROS : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000";
+       CONSTANT  C_8_ZEROS : STD_LOGIC_VECTOR ( 7 DOWNTO 0) :=       X"00";
+       CONSTANT C_16_ZEROS : STD_LOGIC_VECTOR (15 DOWNTO 0) :=     X"0000";
+       CONSTANT C_24_ZEROS : STD_LOGIC_VECTOR (23 DOWNTO 0) :=   X"000000";
+       CONSTANT C_32_ZEROS : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000";
 
-    CONSTANT C_16_ONES  : STD_LOGIC_VECTOR (15 DOWNTO 0) :=     X"FFFF";
-    CONSTANT C_24_ONES  : STD_LOGIC_VECTOR (23 DOWNTO 0) :=   X"FFFFFF";
+       CONSTANT C_16_ONES  : STD_LOGIC_VECTOR (15 DOWNTO 0) :=     X"FFFF";
+       CONSTANT C_24_ONES  : STD_LOGIC_VECTOR (23 DOWNTO 0) :=   X"FFFFFF";
 
 
 ----------------------------------------------------------------------------------------------
 -- TYPE DEFINITIONS
 ----------------------------------------------------------------------------------------------
 
-    TYPE ALU_ACTION_Type    IS (A_NOP, A_ADD, A_CMP, A_CMPU, A_OR, A_AND, A_XOR,
-                                        A_SHIFT, A_SEXT8, A_SEXT16, A_MFS, A_MTS,
-                                        A_MUL, A_BSLL, A_BSRL, A_BSRA, A_HALT);
-    TYPE ALU_IN1_Type       IS (ALU_IN_REGA, ALU_IN_NOT_REGA, ALU_IN_PC, ALU_IN_ZERO);
-    TYPE ALU_IN2_Type       IS (ALU_IN_REGB, ALU_IN_NOT_REGB, ALU_IN_IMM, ALU_IN_NOT_IMM);
-    TYPE ALU_CIN_Type       IS (CIN_ZERO, CIN_ONE, FROM_MSR, FROM_IN1);
-    TYPE MSR_ACTION_Type    IS (UPDATE_CARRY, KEEP_CARRY);
-    TYPE BRANCH_ACTION_Type IS (NO_BR, BR, BRL, BEQ, BNE, BLT, BLE, BGT, BGE);
-    TYPE WRB_ACTION_Type    IS (NO_WRB, WRB_EX, WRB_MEM);
-    TYPE MEM_ACTION_Type    IS (NO_MEM, WR_MEM, RD_MEM);
-    TYPE TRANSFER_SIZE_Type IS (WORD, HALFWORD, BYTE);
-    TYPE SAVE_REG_Type      IS (NO_SAVE, SAVE_RA, SAVE_RB);
-    TYPE CMP_COND_Type      IS (COND_ALL, COND_EQ, COND_NE, COND_LT, COND_LE, COND_GT, COND_GE);
-    TYPE CMP_COND_TYPE_Type IS (COND_TYPE_ALL, COND_TYPE_IF_THEN, COND_TYPE_IF_THEN_THEN, COND_TYPE_IF_THEN_ELSE);
-    --
-    TYPE IF2ID_Type IS RECORD
-        program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
-    END RECORD;
-
-    TYPE ID2EX_Type IS RECORD
-        program_counter  : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        rdix_rA          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        rdix_rB          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        curr_rD          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        alu_Action       : ALU_ACTION_Type;
-        alu_Op1          : ALU_IN1_Type;
-        alu_Op2          : ALU_IN2_Type;
-        alu_Cin          : ALU_CIN_Type;
-        IMM16            : STD_LOGIC_VECTOR (15 DOWNTO 0);
-        IMM_Lock         : STD_LOGIC;
-        msr_Action       : MSR_ACTION_Type;
-        branch_Action    : BRANCH_ACTION_Type;
-        mem_Action       : MEM_ACTION_Type;         -- rd_mem implies writeback
-        transfer_Size    : TRANSFER_SIZE_Type;
-        wrb_Action       : WRB_ACTION_Type;
-        cmp_Cond         : CMP_COND_Type;
-        cmp_Cond_Type    : CMP_COND_TYPE_Type;
-    END RECORD;
-
-    TYPE ID2GPRF_Type IS RECORD
-        rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        rdix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-    END RECORD;
-
-    TYPE INT_CTRL_Type IS RECORD
-        setup_int  : STD_LOGIC;
-        rti_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        int_busy   : STD_LOGIC;
-    END RECORD;
-
-    TYPE ID2CTRL_Type IS RECORD
-        delayBit : STD_LOGIC;
-        int_busy : STD_LOGIC;
-    END RECORD;
-
-    TYPE GPRF2EX_Type IS RECORD
-        data_rA : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        data_rB : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
-    END RECORD;
-
-    TYPE IMM_LOCK_Type IS RECORD
-        locked   : STD_LOGIC;
-        IMM_hi16 : STD_LOGIC_VECTOR (15 DOWNTO 0);
-    END RECORD;
-
-    TYPE MSR_Type IS RECORD
-        IE  : STD_LOGIC;        -- MSR[VHDL b1] = [MicroBlaze b30]
-        C   : STD_LOGIC;        -- MSR[VHDL b2 and b31] = [MicroBlaze b29 and b0]
-    END RECORD;
-
-    TYPE EX2IF_Type IS RECORD
-        take_branch   : STD_LOGIC;
-        branch_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
-    END RECORD;
-
-    TYPE EX2CTRL_Type IS RECORD
-        flush_first   : STD_LOGIC;
-        flush_second  : STD_LOGIC;
-    END RECORD;
-
-    TYPE HALT_Type IS RECORD
-        halt          : STD_LOGIC;
-        halt_code     : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-    END RECORD;
-
-    TYPE EX2MEM_Type IS RECORD
-        mem_Action      : MEM_ACTION_Type;                  -- RD_MEM implies writeback
-        wrb_Action      : WRB_ACTION_Type;
-        exeq_result     : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        data_rD         : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        byte_Enable     : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
-        wrix_rD         : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-    END RECORD;
-
-    TYPE WRB_Type IS RECORD
-        wrb_Action : WRB_ACTION_Type;
-        wrix_rD    : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-        data_rD    : STD_LOGIC_VECTOR (31 DOWNTO 0);
-    END RECORD;
-
-    TYPE HAZARD_WRB_Type IS RECORD
-        hazard  : STD_LOGIC;
-        save_rX : SAVE_REG_Type;
-        data_rX : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
-    END RECORD;
-
-    TYPE MEM_REG_Type IS RECORD
-        wrb_Action  : WRB_ACTION_Type;
-        exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
-        wrix_rD     : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
-    END RECORD;
-
-    TYPE MEM2CTRL_Type IS RECORD
-        clken : STD_LOGIC;
-        int   : STD_LOGIC;
-    END RECORD;
-
-    TYPE CORE2DMEMB_Type IS RECORD
-        ena   : STD_LOGIC;
-        addr  : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        bSel  : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
-        wre   : STD_LOGIC;
-        data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
-    END RECORD;
-
-    TYPE DMEMB2CORE_Type IS RECORD
-        clken : STD_LOGIC;
-        data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        int   : STD_LOGIC;
-    END RECORD;
-
-    TYPE MEMORY_MAP_Type IS ARRAY(NATURAL RANGE <>) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
-    -- NOTE: Use the named association format  xxxx := ( 0 => X"A0010000" );
-    --       in case the array has to contain only one element !!
+       TYPE ALU_ACTION_Type    IS (A_NOP, A_ADD, A_CMP, A_CMPU, A_OR, A_AND, A_XOR,
+                                                                                                                       A_SHIFT, A_SEXT8, A_SEXT16, A_MFS, A_MTS, A_MUL,
+                                                                                                                       A_BSLL, A_BSRL, A_BSRA);
+       TYPE ALU_IN1_Type       IS (ALU_IN_REGA, ALU_IN_NOT_REGA, ALU_IN_PC, ALU_IN_ZERO);
+       TYPE ALU_IN2_Type       IS (ALU_IN_REGB, ALU_IN_NOT_REGB, ALU_IN_IMM, ALU_IN_NOT_IMM);
+       TYPE ALU_CIN_Type       IS (CIN_ZERO, CIN_ONE, FROM_MSR, FROM_IN1);
+       TYPE MSR_ACTION_Type    IS (UPDATE_CARRY, KEEP_CARRY);
+       TYPE BRANCH_ACTION_Type IS (NO_BR, BR, BRL);
+       TYPE IT_ACTION_Type     IS (NO_IT, IT, ITT, ITE);
+       TYPE WRB_ACTION_Type    IS (NO_WRB, WRB_EX, WRB_MEM);
+       TYPE MEM_ACTION_Type    IS (NO_MEM, WR_MEM, RD_MEM);
+       TYPE TRANSFER_SIZE_Type IS (WORD, HALFWORD, BYTE);
+       TYPE SAVE_REG_Type      IS (NO_SAVE, SAVE_RA, SAVE_RB);
+       TYPE COND_Type          IS (COND_ALL, COND_EQ, COND_NE, COND_LT, COND_LE, COND_GT, COND_GE);
+       --
+       TYPE IF2ID_Type IS RECORD
+               program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       END RECORD;
+
+       TYPE ID2EX_Type IS RECORD
+               program_counter  : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               rdix_rA          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               rdix_rB          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               curr_rD          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               alu_Action       : ALU_ACTION_Type;
+               alu_Op1          : ALU_IN1_Type;
+               alu_Op2          : ALU_IN2_Type;
+               alu_Cin          : ALU_CIN_Type;
+               IMM16            : STD_LOGIC_VECTOR (15 DOWNTO 0);
+               IMM_Lock         : STD_LOGIC;
+               msr_Action       : MSR_ACTION_Type;
+               branch_Action    : BRANCH_ACTION_Type;
+               it_Action        : IT_ACTION_Type;
+               mem_Action       : MEM_ACTION_Type;         -- rd_mem implies writeback
+               transfer_Size    : TRANSFER_SIZE_Type;
+               wrb_Action       : WRB_ACTION_Type;
+               condition        : COND_Type;
+               halt             : STD_LOGIC;
+       END RECORD;
+
+       TYPE ID2GPRF_Type IS RECORD
+               rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               rdix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+       END RECORD;
+
+       TYPE INT_CTRL_Type IS RECORD
+               setup_int  : STD_LOGIC;
+               rti_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               int_busy   : STD_LOGIC;
+       END RECORD;
+
+       TYPE ID2CTRL_Type IS RECORD
+               delayBit : STD_LOGIC;
+               int_busy : STD_LOGIC;
+       END RECORD;
+
+       TYPE GPRF2EX_Type IS RECORD
+               data_rA : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               data_rB : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       END RECORD;
+
+       TYPE IMM_LOCK_Type IS RECORD
+               locked   : STD_LOGIC;
+               IMM_hi16 : STD_LOGIC_VECTOR (15 DOWNTO 0);
+       END RECORD;
+
+       TYPE MSR_Type IS RECORD
+               IE  : STD_LOGIC;        -- MSR[VHDL b1] = [MicroBlaze b30]
+               C   : STD_LOGIC;        -- MSR[VHDL b2 and b31] = [MicroBlaze b29 and b0]
+       END RECORD;
+
+       TYPE EX2IF_Type IS RECORD
+               take_branch   : STD_LOGIC;
+               branch_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       END RECORD;
+
+       TYPE EX2CTRL_Type IS RECORD
+               flush_first       : STD_LOGIC;
+               flush_second      : STD_LOGIC;
+               ignore_state      : STD_LOGIC;
+       END RECORD;
+
+       TYPE HALT_Type IS RECORD
+               halt          : STD_LOGIC;
+               halt_code     : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+       END RECORD;
+
+       TYPE EX2MEM_Type IS RECORD
+               mem_Action      : MEM_ACTION_Type;                  -- RD_MEM implies writeback
+               wrb_Action      : WRB_ACTION_Type;
+               exeq_result     : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               data_rD         : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               byte_Enable     : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+               wrix_rD         : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+       END RECORD;
+
+       TYPE WRB_Type IS RECORD
+               wrb_Action : WRB_ACTION_Type;
+               wrix_rD    : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+               data_rD    : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       END RECORD;
+
+       TYPE HAZARD_WRB_Type IS RECORD
+               hazard  : STD_LOGIC;
+               save_rX : SAVE_REG_Type;
+               data_rX : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       END RECORD;
+
+       TYPE MEM_REG_Type IS RECORD
+               wrb_Action  : WRB_ACTION_Type;
+               exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+               wrix_rD     : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+       END RECORD;
+
+       TYPE MEM2CTRL_Type IS RECORD
+               clken : STD_LOGIC;
+               int   : STD_LOGIC;
+       END RECORD;
+
+       TYPE CORE2DMEMB_Type IS RECORD
+               ena   : STD_LOGIC;
+               addr  : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               bSel  : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+               wre   : STD_LOGIC;
+               data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       END RECORD;
+
+       TYPE DMEMB2CORE_Type IS RECORD
+               clken : STD_LOGIC;
+               data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               int   : STD_LOGIC;
+       END RECORD;
+
+       TYPE MEMORY_MAP_Type IS ARRAY(NATURAL RANGE <>) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
+       -- NOTE: Use the named association format  xxxx := ( 0 => X"A0010000" );
+       --       in case the array has to contain only one element !!
 
 ----------------------------------------------------------------------------------------------
 -- COMPONENTS
 ----------------------------------------------------------------------------------------------
 
-    COMPONENT fetch IS
-        PORT (
-            prog_cntr_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
-            inc_pc_i    :  IN STD_LOGIC;
-            EX2IF_i     :  IN EX2IF_Type;
-            IF2ID_o     : OUT IF2ID_Type
-            );
-    END COMPONENT;
-
-    COMPONENT decode IS
-        GENERIC (
-            USE_HW_MUL_g : BOOLEAN := TRUE;
-            USE_BARREL_g : BOOLEAN := TRUE;
-            COMPATIBILITY_MODE_g : BOOLEAN := FALSE
-            );
-        PORT (
-            IF2ID_i     :  IN IF2ID_Type;
-            imem_data_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
-            --
-            ID2GPRF_o   : OUT ID2GPRF_Type;
-            ID2EX_o     : OUT ID2EX_Type;
-            --
-            INT_CTRL_i  :  IN INT_CTRL_Type;
-            ID2CTRL_o   : OUT ID2CTRL_Type;
-            --
-            noLiteOpc_o : OUT STD_LOGIC
-            );
-    END COMPONENT;
-
-    COMPONENT adder IS
-        GENERIC (
-            DW_g : POSITIVE := 32;
-            LW_g : POSITIVE := 15
-        );
-        PORT (
-            in1  :  IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
-            in2  :  IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
-            cin  :  IN STD_LOGIC;
-            sum  : OUT STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
-            cout : OUT STD_LOGIC
-            );
-    END COMPONENT;
-
-    COMPONENT exeq IS
-        GENERIC (
-            USE_HW_MUL_g : BOOLEAN := FALSE;
-            USE_BARREL_g : BOOLEAN := FALSE;
-            COMPATIBILITY_MODE_g : BOOLEAN := FALSE
-            );
-        PORT (
-            ID2EX_i      :  IN ID2EX_Type;
-            GPRF2EX_i    :  IN GPRF2EX_Type;
-            EX2IF_o      : OUT EX2IF_Type;
-            EX2CTRL_o    : OUT EX2CTRL_Type;
-            HALT_o       : OUT HALT_Type;
-            --
-            EX_WRB_i     :  IN WRB_Type;
-            EX_WRB_o     : OUT WRB_Type;
-            MEM_WRB_i    :  IN WRB_Type;
-            --
-            HAZARD_WRB_i :  IN HAZARD_WRB_Type;
-            HAZARD_WRB_o : OUT HAZARD_WRB_Type;
-            --
-            IMM_LOCK_i   :  IN IMM_LOCK_Type;
-            IMM_LOCK_o   : OUT IMM_LOCK_Type;
-            --
-            MSR_i        :  IN MSR_Type;
-            MSR_o        : OUT MSR_Type;
-            --
-            EX2MEM_o     : OUT EX2MEM_Type
-            );
-    END COMPONENT;
-
-    COMPONENT mem IS
-        PORT (
-            EX2MEM_i    :  IN EX2MEM_Type;
-            --
-            DMEMB_i     :  IN DMEMB2CORE_Type;
-            DMEMB_o     : OUT CORE2DMEMB_Type;
-            --
-            MEM_REG_i   :  IN MEM_REG_Type;
-            MEM_REG_o   : OUT MEM_REG_Type;
-            --
-            MEM_WRB_o   : OUT WRB_Type;
-            MEM2CTRL_o  : OUT MEM2CTRL_Type
-            );
-    END COMPONENT;
-
-    COMPONENT core_ctrl IS
-        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 COMPONENT;
+       COMPONENT fetch IS
+       PORT
+       (
+               prog_cntr_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+               inc_pc_i    :  IN STD_LOGIC;
+               EX2IF_i     :  IN EX2IF_Type;
+               IF2ID_o     : OUT IF2ID_Type
+       );
+       END COMPONENT;
+
+       COMPONENT decode IS
+       GENERIC
+       (
+               USE_HW_MUL_g : BOOLEAN := TRUE;
+               USE_BARREL_g : BOOLEAN := TRUE;
+               COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+       );
+       PORT
+       (
+               IF2ID_i     :  IN IF2ID_Type;
+               imem_data_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+               --
+               ID2GPRF_o   : OUT ID2GPRF_Type;
+               ID2EX_o     : OUT ID2EX_Type;
+               --
+               INT_CTRL_i  :  IN INT_CTRL_Type;
+               ID2CTRL_o   : OUT ID2CTRL_Type;
+               --
+               noLiteOpc_o : OUT STD_LOGIC
+       );
+       END COMPONENT;
+
+       COMPONENT exeq IS
+       GENERIC
+       (
+               USE_HW_MUL_g : BOOLEAN := FALSE;
+               USE_BARREL_g : BOOLEAN := FALSE;
+               COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+       );
+       PORT
+       (
+               ID2EX_i      :  IN ID2EX_Type;
+               GPRF2EX_i    :  IN GPRF2EX_Type;
+               EX2IF_o      : OUT EX2IF_Type;
+               EX2CTRL_o    : OUT EX2CTRL_Type;
+               HALT_o       : OUT HALT_Type;
+               --
+               EX_WRB_i     :  IN WRB_Type;
+               EX_WRB_o     : OUT WRB_Type;
+               MEM_WRB_i    :  IN WRB_Type;
+               --
+               HAZARD_WRB_i :  IN HAZARD_WRB_Type;
+               HAZARD_WRB_o : OUT HAZARD_WRB_Type;
+               --
+               IMM_LOCK_i   :  IN IMM_LOCK_Type;
+               IMM_LOCK_o   : OUT IMM_LOCK_Type;
+               --
+               MSR_i        :  IN MSR_Type;
+               MSR_o        : OUT MSR_Type;
+               --
+               EX2MEM_o     : OUT EX2MEM_Type
+       );
+       END COMPONENT;
+
+       COMPONENT mem IS
+       PORT
+       (
+               EX2MEM_i    :  IN EX2MEM_Type;
+               --
+               DMEMB_i     :  IN DMEMB2CORE_Type;
+               DMEMB_o     : OUT CORE2DMEMB_Type;
+               --
+               MEM_REG_i   :  IN MEM_REG_Type;
+               MEM_REG_o   : OUT MEM_REG_Type;
+               --
+               MEM_WRB_o   : OUT WRB_Type;
+               MEM2CTRL_o  : OUT MEM2CTRL_Type
+       );
+       END COMPONENT;
+
+       COMPONENT core_ctrl IS
+       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 COMPONENT;
 
 ----------------------------------------------------------------------------------------------
 -- FUNCTION, PROCEDURE DECLARATIONS
 ----------------------------------------------------------------------------------------------
 
-    PROCEDURE ep_add32 ( a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
-                         ci   :  IN STD_LOGIC;
-                         VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
-                         VARIABLE co : OUT STD_LOGIC );
-
-    PROCEDURE ep_add32nc ( a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
-                         ci   :  IN STD_LOGIC;
-                         VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
+       PROCEDURE ep_add32 (    a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+                                                                                               ci   :  IN STD_LOGIC;
+                                                                                       VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
+                                                                                       VARIABLE co : OUT STD_LOGIC );
 
---  PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC;
---                       VARIABLE s  : OUT STD_LOGIC_VECTOR;
---                       VARIABLE co : OUT STD_LOGIC );
+       PROCEDURE ep_add32nc (  a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+                                                                                                       ci   :  IN STD_LOGIC;
+                                                                                               VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
 
-    FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE;
+       FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE;
 
 END PACKAGE mbl_Pkg;
 
-
 ----------------------------------------------------------
 PACKAGE BODY mbl_Pkg IS
 ----------------------------------------------------------
 
-    PROCEDURE ep_add32 (        a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
-                                ci   :  IN STD_LOGIC;
-                         VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
-                         VARIABLE co : OUT STD_LOGIC ) IS
-
-        CONSTANT NBITS_LO_c : POSITIVE := 17;
-        CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
-        VARIABLE tmp_lo_v   : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
-        VARIABLE tmp_hi0_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
-        VARIABLE tmp_hi1_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
-    BEGIN
-        tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO  0) & '1' ) +
-                                       UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO  0) & ci  ));
-        tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
-                                       UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
-        tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
-                                       UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
-        IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
-            s  := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
-            co := tmp_hi0_v(NBITS_HI_c +1);
-        ELSE
-            s  := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
-            co := tmp_hi1_v(NBITS_HI_c +1);
-        END IF;
-    END PROCEDURE;
-
-    PROCEDURE ep_add32nc (        a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
-                                ci   :  IN STD_LOGIC;
-                         VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ) IS
-
-        CONSTANT NBITS_LO_c : POSITIVE := 17;
-        CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
-        VARIABLE tmp_lo_v   : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
-        VARIABLE tmp_hi0_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
-        VARIABLE tmp_hi1_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
-    BEGIN
-        tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO  0) & '1' ) +
-                                       UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO  0) & ci  ));
-        tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
-                                       UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
-        tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
-                                       UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
-        IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
-            s  := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
-        ELSE
-            s  := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
-        END IF;
-    END PROCEDURE;
-
---  PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC;
---                       VARIABLE s  : OUT STD_LOGIC_VECTOR;
---                       VARIABLE co : OUT STD_LOGIC ) IS
---        VARIABLE tmp_lo_v  : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
---        VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
---        VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
---    BEGIN
---      tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH/2 -1 DOWNTO  0) & '1' ) +
---                                     UNSIGNED( '0' & b(a'LENGTH/2 -1 DOWNTO  0) & ci  ));
---      tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') +
---                                     UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '0'));
---      tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') +
---                                     UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1'));
---      IF (tmp_lo_v(a'LENGTH/2 +1) = '0') THEN
---          s  := tmp_hi0_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1);
---          co := tmp_hi0_v(a'LENGTH/2 +1);
---      ELSE
---          s  := tmp_hi1_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1);
---          co := tmp_hi1_v(a'LENGTH/2 +1);
---      END IF;
---  END PROCEDURE;
-
---  Function ef_nbits returns the minimum number of binary bits to represent
---  a value N with:
---  so N =  0,1       NBITS = 1
---     N =  2,3       NBITS = 2
---     N =  4,5,6,7   NBITS = 3
---     N =  8..15     NBITS = 4
---     N = 16..31     NBITS = 5
---       etc.
-
-    FUNCTION ef_nbits( value : NATURAL ) RETURN POSITIVE IS
-        VARIABLE temp_v : POSITIVE;
-    BEGIN
-        temp_v := 1;
-        FOR i IN 1 TO INTEGER'HIGH LOOP
-            temp_v := 2*temp_v;
-            IF (temp_v > value) THEN
-                RETURN i;
-            END IF;
-        END LOOP;
-                               RETURN 32;
-    END FUNCTION;
-
-END PACKAGE BODY mbl_Pkg;
\ No newline at end of file
+       PROCEDURE ep_add32 (    a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+                                                                                               ci   :  IN STD_LOGIC;
+                                                                                       VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
+                                                                                       VARIABLE co : OUT STD_LOGIC ) IS
+
+               CONSTANT NBITS_LO_c : POSITIVE := 17;
+               CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
+               VARIABLE tmp_lo_v   : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
+               VARIABLE tmp_hi0_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
+               VARIABLE tmp_hi1_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
+       BEGIN
+               tmp_lo_v  := STD_LOGIC_VECTOR(  UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO  0) & '1' ) +
+                                                                                                                                               UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO  0) & ci  ));
+               tmp_hi0_v := STD_LOGIC_VECTOR(  UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
+                                                                                                                                               UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
+               tmp_hi1_v := STD_LOGIC_VECTOR(  UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
+                                                                                                                                               UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
+               IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
+                       s  := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
+                       co := tmp_hi0_v(NBITS_HI_c +1);
+               ELSE
+                       s  := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
+                       co := tmp_hi1_v(NBITS_HI_c +1);
+               END IF;
+       END PROCEDURE;
+
+    PROCEDURE ep_add32nc (     a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+                                                                                                               ci   :  IN STD_LOGIC;
+                                                                                                       VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ) IS
+
+               CONSTANT NBITS_LO_c : POSITIVE := 17;
+               CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
+               VARIABLE tmp_lo_v   : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
+               VARIABLE tmp_hi0_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
+               VARIABLE tmp_hi1_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
+       BEGIN
+               tmp_lo_v  := STD_LOGIC_VECTOR(  UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO  0) & '1' ) +
+                                                                                                                                               UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO  0) & ci  ));
+               tmp_hi0_v := STD_LOGIC_VECTOR(  UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
+                                                                                                                                               UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
+               tmp_hi1_v := STD_LOGIC_VECTOR(  UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
+                                                                                                                                               UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
+               IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
+                       s  := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
+               ELSE
+                       s  := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
+               END IF;
+       END PROCEDURE;
+
+
+       FUNCTION ef_nbits( value : NATURAL ) RETURN POSITIVE IS
+               VARIABLE temp_v : POSITIVE;
+       BEGIN
+               temp_v := 1;
+               FOR i IN 1 TO INTEGER'HIGH LOOP
+                       temp_v := 2*temp_v;
+                       IF (temp_v > value) THEN
+                               RETURN i;
+                       END IF;
+               END LOOP;
+               RETURN 32;
+       END FUNCTION;
+
+END PACKAGE BODY mbl_Pkg;
index 6d549820ca90e49b62b7c09910c90a8a11896bf2..139451c0385c04837133479a957b475754eed535 100644 (file)
 --  Remarks:
 --------------------------------------------------------------------------------
 
-
 LIBRARY IEEE;
 USE IEEE.std_logic_1164.all;
 USE work.mbl_Pkg.all;
 
-
 --------------------------------------------------------------------------------
 ENTITY mem IS
 --------------------------------------------------------------------------------
-    PORT (
-        EX2MEM_i    :  IN EX2MEM_Type;
-        --
-        DMEMB_i     :  IN DMEMB2CORE_Type;
-        DMEMB_o     : OUT CORE2DMEMB_Type;
-        --
-        MEM_REG_i   :  IN MEM_REG_Type;
-        MEM_REG_o   : OUT MEM_REG_Type;
-        --
-        MEM_WRB_o   : OUT WRB_Type;
-        MEM2CTRL_o  : OUT MEM2CTRL_Type
-        );
+       PORT
+       (
+               EX2MEM_i    :  IN EX2MEM_Type;
+               --
+               DMEMB_i     :  IN DMEMB2CORE_Type;
+               DMEMB_o     : OUT CORE2DMEMB_Type;
+               --
+               MEM_REG_i   :  IN MEM_REG_Type;
+               MEM_REG_o   : OUT MEM_REG_Type;
+               --
+               MEM_WRB_o   : OUT WRB_Type;
+               MEM2CTRL_o  : OUT MEM2CTRL_Type
+       );
 END ENTITY mem;
 
-
 --------------------------------------------------------------------------------
 ARCHITECTURE rtl OF mem IS
 --------------------------------------------------------------------------------
 
 BEGIN
 
-    -- writeback in case of reads from the data memory bus:
-    -- delay wrb-ctrl signals (see core_ctrl) to stay in sync
-    -- with synchronous dmem data output
-    -- Following are only the unconditional pass-through signals. More are in the p_mem process.
-    MEM_REG_o.wrb_Action  <= EX2MEM_i.wrb_Action;
-    MEM_REG_o.exeq_result <= EX2MEM_i.exeq_result;
-    MEM_REG_o.byte_Enable <= EX2MEM_i.byte_Enable;
-    MEM_REG_o.wrix_rD     <= EX2MEM_i.wrix_rD;
-    --
-    MEM_WRB_o.wrb_Action <= MEM_REG_i.wrb_Action;
-    MEM_WRB_o.wrix_rD    <= MEM_REG_i.wrix_rD;
-    -- also signal 'slow memory decices' and interrupts from devices
-    MEM2CTRL_o.clken <= DMEMB_i.clken;
-    MEM2CTRL_o.int   <= DMEMB_i.int;
-    -- pass byte_select signal (NOTE: BIG ENDIAN)
-    DMEMB_o.bSel     <= EX2MEM_i.byte_Enable;
+       -- writeback in case of reads from the data memory bus:
+       -- delay wrb-ctrl signals (see core_ctrl) to stay in sync
+       -- with synchronous dmem data output
+       -- Following are only the unconditional pass-through signals. More are in the p_mem process.
+       MEM_REG_o.wrb_Action  <= EX2MEM_i.wrb_Action;
+       MEM_REG_o.exeq_result <= EX2MEM_i.exeq_result;
+       MEM_REG_o.byte_Enable <= EX2MEM_i.byte_Enable;
+       MEM_REG_o.wrix_rD     <= EX2MEM_i.wrix_rD;
+       --
+       MEM_WRB_o.wrb_Action <= MEM_REG_i.wrb_Action;
+       MEM_WRB_o.wrix_rD    <= MEM_REG_i.wrix_rD;
+       -- also signal 'slow memory decices' and interrupts from devices
+       MEM2CTRL_o.clken <= DMEMB_i.clken;
+       MEM2CTRL_o.int   <= DMEMB_i.int;
+       -- pass byte_select signal (NOTE: BIG ENDIAN)
+       DMEMB_o.bSel     <= EX2MEM_i.byte_Enable;
 
 p_mem:
-    PROCESS (EX2MEM_i, DMEMB_i, MEM_REG_i)
-        VARIABLE exeq_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE dmem_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       PROCESS (EX2MEM_i, DMEMB_i, MEM_REG_i)
+               VARIABLE exeq_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE dmem_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+
+       BEGIN
+
+               -- always align Big Endian input data from memory(-bus)
+               CASE MEM_REG_i.byte_Enable IS
+                       WHEN "1000" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(31 DOWNTO 24);
+                       WHEN "0100" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(23 DOWNTO 16);
+                       WHEN "0010" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(15 DOWNTO  8);
+                       WHEN "0001" => dmem_data_v := C_24_ZEROS & DMEMB_i.data( 7 DOWNTO  0);
+                       WHEN "1100" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(31 DOWNTO 16);
+                       WHEN "0011" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(15 DOWNTO  0);
+                       WHEN OTHERS => dmem_data_v :=              DMEMB_i.data;
+               END CASE;
+
+               -- output to dmem-bus
+               CASE EX2MEM_i.mem_Action IS
 
-    BEGIN
+                       WHEN WR_MEM =>
+                               -- write (or forward) to data memory bus
+                               DMEMB_o.addr <= EX2MEM_i.exeq_result;
+                               DMEMB_o.ena  <= '1';
+                               DMEMB_o.wre  <= '1';
+                               -- Note: use MEM_REG_i here, since MEM_WRB_o (output) cannot be read
+                               IF ((MEM_REG_i.wrb_Action /= NO_WRB) AND
+                                       (EX2MEM_i.wrix_rD = MEM_REG_i.wrix_rD)) THEN
+                                       CASE MEM_REG_i.wrb_Action IS
+                                               WHEN WRB_EX  =>
+                                                       -- forward exeq output, to handle e.g. add rD,rA,xx; sw rD,mem[y]; ...
+                                                       exeq_data_v := MEM_REG_i.exeq_result;
+                                               WHEN OTHERS  =>
+                                                       -- forward mem_data just read, to handle e.g. lhu rD,mem[x]; sh rD,mem[y]; ...
+                                                       exeq_data_v := dmem_data_v;
+                                       END CASE;
+                               ELSE
+                                       exeq_data_v := EX2MEM_i.data_rD;
+                               END IF;
+                               -- output data will be in Big Endian format
+                               CASE EX2MEM_i.byte_Enable IS
+                                       WHEN "1000" => DMEMB_o.data <=              exeq_data_v( 7 DOWNTO 0) & C_24_ZEROS;
+                                       WHEN "0100" => DMEMB_o.data <=  C_8_ZEROS & exeq_data_v( 7 DOWNTO 0) & C_16_ZEROS;
+                                       WHEN "0010" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v( 7 DOWNTO 0) &  C_8_ZEROS;
+                                       WHEN "0001" => DMEMB_o.data <= C_24_ZEROS & exeq_data_v( 7 DOWNTO 0);
+                                       WHEN "1100" => DMEMB_o.data <=              exeq_data_v(15 DOWNTO 0) & C_16_ZEROS;
+                                       WHEN "0011" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v(15 DOWNTO 0);
+                                       WHEN OTHERS => DMEMB_o.data <=              exeq_data_v;
+                               END CASE;
 
-        -- always align Big Endian input data from memory(-bus)
-        CASE MEM_REG_i.byte_Enable IS
-            WHEN "1000" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(31 DOWNTO 24);
-            WHEN "0100" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(23 DOWNTO 16);
-            WHEN "0010" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(15 DOWNTO  8);
-            WHEN "0001" => dmem_data_v := C_24_ZEROS & DMEMB_i.data( 7 DOWNTO  0);
-            WHEN "1100" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(31 DOWNTO 16);
-            WHEN "0011" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(15 DOWNTO  0);
-            WHEN OTHERS => dmem_data_v :=              DMEMB_i.data;
-        END CASE;
+                       WHEN RD_MEM =>
+                               -- read from data memory bus
+                               DMEMB_o.addr <= EX2MEM_i.exeq_result;
+                               DMEMB_o.ena  <= '1';
+                               DMEMB_o.wre  <= '0';
+                               DMEMB_o.data <= EX2MEM_i.data_rD;   -- (OTHERS => 'Z');
 
-        -- output to dmem-bus
---      DMEMB_o.addr <= EX2MEM_i.exeq_result;
-        CASE EX2MEM_i.mem_Action IS
-            WHEN WR_MEM =>
-                -- write (or forward) to data memory bus
-                DMEMB_o.addr <= EX2MEM_i.exeq_result;
-                DMEMB_o.ena  <= '1';
-                DMEMB_o.wre  <= '1';
-                -- Note: use MEM_REG_i here, since MEM_WRB_o (output) cannot be read
-                IF ((MEM_REG_i.wrb_Action /= NO_WRB) AND
-                        (EX2MEM_i.wrix_rD = MEM_REG_i.wrix_rD)) THEN
-                    CASE MEM_REG_i.wrb_Action IS
-                        WHEN WRB_EX  =>
-                            -- forward exeq output, to handle e.g. add rD,rA,xx; sw rD,mem[y]; ...
-                            exeq_data_v := MEM_REG_i.exeq_result;
-                        WHEN OTHERS  =>
-                            -- forward mem_data just read, to handle e.g. lhu rD,mem[x]; sh rD,mem[y]; ...
-                            exeq_data_v := dmem_data_v;
-                    END CASE;
-                ELSE
-                    exeq_data_v := EX2MEM_i.data_rD;
-                END IF;
-                -- output data will be in Big Endian format
-                CASE EX2MEM_i.byte_Enable IS
-                    WHEN "1000" => DMEMB_o.data <=              exeq_data_v( 7 DOWNTO 0) & C_24_ZEROS;
-                    WHEN "0100" => DMEMB_o.data <=  C_8_ZEROS & exeq_data_v( 7 DOWNTO 0) & C_16_ZEROS;
-                    WHEN "0010" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v( 7 DOWNTO 0) &  C_8_ZEROS;
-                    WHEN "0001" => DMEMB_o.data <= C_24_ZEROS & exeq_data_v( 7 DOWNTO 0);
-                    WHEN "1100" => DMEMB_o.data <=              exeq_data_v(15 DOWNTO 0) & C_16_ZEROS;
-                    WHEN "0011" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v(15 DOWNTO 0);
-                    WHEN OTHERS => DMEMB_o.data <=              exeq_data_v;
-                END CASE;
-            WHEN RD_MEM =>
-                -- read from data memory bus
-                DMEMB_o.addr <= EX2MEM_i.exeq_result;
-                DMEMB_o.ena  <= '1';
-                DMEMB_o.wre  <= '0';
-                DMEMB_o.data <= EX2MEM_i.data_rD;   -- (OTHERS => 'Z');
-            WHEN OTHERS =>      -- NO_MEM
-                DMEMB_o.addr <= C_32_ZEROS;
-                DMEMB_o.ena  <= '0';
-                DMEMB_o.wre  <= '0';
-                DMEMB_o.data <= EX2MEM_i.data_rD;   -- (OTHERS => 'Z');
-        END CASE;
+                       WHEN OTHERS =>      -- NO_MEM
+                               DMEMB_o.addr <= C_32_ZEROS;
+                               DMEMB_o.ena  <= '0';
+                               DMEMB_o.wre  <= '0';
+                               DMEMB_o.data <= EX2MEM_i.data_rD;   -- (OTHERS => 'Z');
+               END CASE;
 
-        -- additional wrb signals
-        CASE MEM_REG_i.wrb_Action IS
-            WHEN WRB_MEM => MEM_WRB_o.data_rD <= dmem_data_v;
-            WHEN OTHERS  => MEM_WRB_o.data_rD <= MEM_REG_i.exeq_result;
-        END CASE;
+               -- additional wrb signals
+               CASE MEM_REG_i.wrb_Action IS
+                       WHEN WRB_MEM => MEM_WRB_o.data_rD <= dmem_data_v;
+                       WHEN OTHERS  => MEM_WRB_o.data_rD <= MEM_REG_i.exeq_result;
+               END CASE;
 
-    END PROCESS;
+       END PROCESS;
 
 END ARCHITECTURE rtl;