]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/commitdiff
Add back support for delay slot, but with writing PC+4 when linking and using delay...
authorMartin Meloun <meloumar@cmp.felk.cvut.cz>
Wed, 2 Oct 2013 09:59:07 +0000 (11:59 +0200)
committerMartin Meloun <meloumar@cmp.felk.cvut.cz>
Wed, 2 Oct 2013 09:59:07 +0000 (11:59 +0200)
Signed-off-by: Martin Meloun <meloumar@cmp.felk.cvut.cz>
hw/core_ctrl.vhd
hw/decode.vhd
hw/exeq.vhd
hw/fetch.vhd
hw/mbl_Pkg.vhd

index 991a1c2aa27dab380b24a8ac2ff0f0c3ccfc72a7..897a9411607f83118c500993db3b27ca42512e9f 100644 (file)
@@ -34,7 +34,6 @@ ENTITY core_ctrl IS
                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;
@@ -49,6 +48,7 @@ ENTITY core_ctrl IS
                -- decode to exeq pipeline registers
                ID2EX_REG_i     :  IN ID2EX_Type;
                ID2EX_REG_o     : OUT ID2EX_Type;
+               delay_bit_o     : OUT STD_LOGIC;
                -- GPRF control
                gprf_clken_o    : OUT STD_LOGIC;
                -- exeq to fetch feedback registers
@@ -117,7 +117,7 @@ BEGIN
        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_s  <= reset_s OR (((NOT trace_i) AND (NOT exeq_halt_i)) OR trace_kick_i);
        core_clken_o  <= core_clken_s;
        -- clock/wait control lines
        clken_s        <= MEM2CTRL_i.clken OR rst_i;
@@ -126,11 +126,12 @@ BEGIN
        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));
+                                                                               ELSE ((EX2IF_REG_i.take_branch AND (NOT delayBit_r)) OR EX2IF_REG_r.take_branch OR EX2CTRL_REG_i.flush_first OR
+                                                                                               flush_first_r OR ((NOT EX2CTRL_REG_i.ignore_state) AND (NOT ignore_state_r) AND flush_second_2r));
        flush_EX2MEM_s <= HAZARD_WRB_i.hazard;
        -- outputs that need to be readable too, so needing shadowing signals
        ID2EX_REG_o    <= ID2EX_REG_r;
+       delay_bit_o    <= delayBit_r;
        EX2IF_REG_o    <= EX2IF_REG_r;
        IMM_LOCK_o     <= IMM_LOCK_r;
        HAZARD_WRB_o   <= HAZARD_WRB_r;
@@ -242,10 +243,9 @@ regd_proc:
                        lp_rst_MSR;
                        lp_rst_HAZARD_WRB;
                        lp_rst_MEM_REG;
+                       delayBit_r        <= '0';
 
-                       IF (COMPATIBILITY_MODE_g = TRUE) THEN
-                               delayBit_r      <= '0';
-                       ELSE
+                       IF (COMPATIBILITY_MODE_g = FALSE) THEN
                                flush_first_r   <= '0';
                                flush_second_r  <= '0';
                                flush_second_2r <= '0';
@@ -286,9 +286,7 @@ regd_proc:
                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;
+                       delayBit_r <= '0';
                -- check for the need and possibility to handle active interrupt requests
                ELSIF (((int_i = '1') OR (MEM2CTRL_i.int = '1')) AND (MSR_i.IE = '1') AND
                                        (ID2CTRL_i.int_busy = '0') AND (int_busy_r = '0') AND
@@ -305,9 +303,7 @@ regd_proc:
                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;
+                       delayBit_r  <= ID2CTRL_i.delayBit;
                END IF;
                -- exeq-to-mem unit registers
                IF ((reset_s = '1') OR (flush_EX2MEM_s = '1')) THEN
index cf681e0e33fbad900a932280ce02f7e9da9877b1..67e207c5c02f0cc8e5df70a13d36362a0d093c3f 100644 (file)
@@ -38,9 +38,7 @@ ENTITY decode IS
                ID2EX_o     : OUT ID2EX_Type;
                --
                INT_CTRL_i  :  IN INT_CTRL_Type;
-               ID2CTRL_o   : OUT ID2CTRL_Type;
-               --
-               noLiteOpc_o : OUT STD_LOGIC
+               ID2CTRL_o   : OUT ID2CTRL_Type
        );
 END ENTITY decode;
 
@@ -87,9 +85,8 @@ p_decode:
                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
+               delayBit_v      := '0';
+               IF (COMPATIBILITY_MODE_g = FALSE) THEN
                        it_Action_v   :=  NO_IT;
                END IF;
                condition_raw_v := (others => '1');
@@ -104,8 +101,6 @@ p_decode:
                -- 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
 
@@ -164,8 +159,6 @@ p_decode:
                                                WHEN "000" =>                                     -- MUL
                                                        IF (USE_HW_MUL_g = TRUE) THEN
                                                                alu_Action_v := A_MUL;
-                                                       ELSE
-                                                               noLiteOpc_o <= '1';
                                                        END IF;
 
                                                WHEN "001" =>                                     -- BS
@@ -177,8 +170,6 @@ p_decode:
                                                                ELSE
                                                                        alu_Action_v := A_BSRL;
                                                                END IF;
-                                                       ELSE
-                                                               noLiteOpc_o <= '1';
                                                        END IF;
 
                                                WHEN "010" | "011" =>                             -- CMP(U)
@@ -188,8 +179,6 @@ p_decode:
                                                                ELSE
                                                                        alu_Action_v := A_CMP;
                                                                END IF;
-                                                       ELSE
-                                                               noLiteOpc_o <= '1';
                                                        END IF;
 
                                                WHEN "100" | "101" =>                             -- IT(U) / ITT(U) / ITE(U)
@@ -201,24 +190,18 @@ p_decode:
                                                                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';
+                                                                       WHEN "00"   =>  it_Action_v := IT;
+                                                                       WHEN "01"   =>  it_Action_v := ITT;
+                                                                       WHEN "10"   =>  it_Action_v := ITE;
+                                                                       WHEN OTHERS =>  NULL;
                                                                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';
+                                                               NULL;
                                        END CASE;
 
                                WHEN "10" =>
@@ -234,7 +217,7 @@ p_decode:
                                                                        WHEN "10" =>                                -- SRL
                                                                                alu_Cin_v := CIN_ZERO;
                                                                        WHEN OTHERS =>
-                                                                               noLiteOpc_o <= '1';
+                                                                               NULL;
                                                                        END CASE;
                                                                alu_Action_v := A_SHIFT;
                                                                msr_Action_v := UPDATE_CARRY;
@@ -244,7 +227,7 @@ p_decode:
                                                        WHEN "111" =>                                   -- SEXT16
                                                                alu_Action_v := A_SEXT16;
                                                        WHEN OTHERS  =>
-                                                               noLiteOpc_o  <= '1';
+                                                               NULL;
                                                END CASE;
 
                                        ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN          -- IMM
@@ -257,17 +240,14 @@ p_decode:
                                                CASE rD_v (3 DOWNTO 0) IS
                                                        WHEN "0001" =>                                  -- RTI(D)
                                                                int_busy_v := '0';
-                                                       WHEN "0000" =>                                  -- RTS(D)
-                                                               WHEN OTHERS  =>
-                                                       noLiteOpc_o <= '1';
+                                                       WHEN OTHERS =>                                  -- RTS(D)
+                                                               NULL;
                                                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;
+                                               delayBit_v      := rD_v(4);
 
                                        ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
 
@@ -278,7 +258,7 @@ p_decode:
                                                                alu_Action_v := A_MTS;
                                                                wrb_Action_v := NO_WRB;
                                                        WHEN OTHERS  =>
-                                                               noLiteOpc_o  <= '1';
+                                                               NULL;
                                                END CASE;
                                                rB_v := (OTHERS => '0');    -- in order to prevent occasional hazards (r16, r24)
 
@@ -300,35 +280,31 @@ p_decode:
                                                                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);
+
+                                                               IF (rA_v(2) = '1') THEN
+                                                                       branch_Action_v := BRL;
+                                                               ELSE
+                                                                       branch_Action_v := BR;
+                                                                       wrb_Action_v    := NO_WRB;
                                                                END IF;
+                                                               alu_Action_v := A_ADD;
+                                                               delayBit_v   := rA_v(4);
 
                                                        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
+                                                               alu_Action_v    := A_ADD;
+                                                               alu_Op1_v       := ALU_IN_PC;
+                                                               delayBit_v      := rD_v(4);
+                                                               wrb_Action_v    := NO_WRB;     -- evaluate and update/overwrite in exeq
 
                                                        WHEN OTHERS =>
-                                                               noLiteOpc_o  <= '1';
+                                                               NULL;
                                                END CASE;
                                        END IF;
 
@@ -343,8 +319,7 @@ p_decode:
                                                        WHEN "00"   => transfer_Size_v := BYTE;
                                                        WHEN "01"   => transfer_Size_v := HALFWORD;
                                                        WHEN "10"   => transfer_Size_v := WORD;
-                                                       WHEN OTHERS =>
-                                                               noLiteOpc_o <= '1';
+                                                       WHEN OTHERS => NULL;
                                                END CASE;
                                                IF (opcIx_v(2) = '0') THEN
                                                        mem_Action_v := RD_MEM;
@@ -356,7 +331,7 @@ p_decode:
                                        END IF;
 
                                WHEN OTHERS =>
-                                       noLiteOpc_o  <= '1';
+                                       NULL;
 
                        END CASE;
 
@@ -401,13 +376,10 @@ p_decode:
                                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;
+               ID2CTRL_o.delayBit       <= delayBit_v;
+               ID2CTRL_o.int_busy       <= int_busy_v;
 
        END PROCESS;
 
index 03477128f2c0390bfa9720906e908b417c462468..39214226cf201005f2f79b510121bdf5a3cd0926 100644 (file)
@@ -37,7 +37,10 @@ ENTITY exeq IS
        );
        PORT
        (
+               IF2ID_i      :  IN IF2ID_Type;
+               --
                ID2EX_i      :  IN ID2EX_Type;
+               delayBit_i   :  IN STD_LOGIC;
                GPRF2EX_i    :  IN GPRF2EX_Type;
                EX2IF_o      : OUT EX2IF_Type;
                EX2CTRL_o    : OUT EX2CTRL_Type;
@@ -68,7 +71,7 @@ BEGIN
 
 p_exeq:
        PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
-                                               IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
+                                               IF2ID_i, delayBit_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) )
@@ -173,11 +176,11 @@ p_exeq:
                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;
+                       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
@@ -382,8 +385,13 @@ p_exeq:
                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;
+                       IF (COMPATIBILITY_MODE_g = TRUE) OR (delayBit_i = '0') THEN
+                               EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
+                               EX2MEM_o.data_rD     <= ID2EX_i.program_counter;
+                       ELSE
+                               EX2MEM_o.exeq_result <= IF2ID_i.program_counter;
+                               EX2MEM_o.data_rD     <= IF2ID_i.program_counter;
+                       END IF;
                        -- set data_rD_v, although unused, to prevent an inferred latch
                        data_rD_v := GPRF2EX_i.data_rD;
                ELSE
index 359f8164527db6d4ce162f160793150da7e95ee3..e9a0a3018da9a3aec1e3f030a97849219006fb8e 100644 (file)
@@ -21,15 +21,15 @@ USE WORK.mbl_Pkg.all;
 --------------------------------------------------------------------------------
 ENTITY 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
-     );
+       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 ENTITY fetch;
 
-
 --------------------------------------------------------------------------------
 ARCHITECTURE rtl OF fetch IS
 --------------------------------------------------------------------------------
@@ -37,17 +37,17 @@ ARCHITECTURE rtl OF fetch IS
 BEGIN
 
 p_fetch:
-    PROCESS ( prog_cntr_i, inc_pc_i, EX2IF_i )
-        VARIABLE next_pc_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
-        VARIABLE incVal_v  : STD_LOGIC_VECTOR (31 DOWNTO 0);
-    BEGIN
-        incVal_v := X"0000000" & '0' & inc_pc_i & "00";
-        ep_add32nc ( prog_cntr_i, incVal_v, '0', next_pc_v );
-        IF (EX2IF_i.take_branch = '0') THEN
-            IF2ID_o.program_counter <= next_pc_v;
-        ELSE
-            IF2ID_o.program_counter <= EX2IF_i.branch_target;
-        END IF;
-    END PROCESS;
+       PROCESS ( prog_cntr_i, inc_pc_i, EX2IF_i )
+               VARIABLE next_pc_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+               VARIABLE incVal_v  : STD_LOGIC_VECTOR (31 DOWNTO 0);
+       BEGIN
+               incVal_v := X"0000000" & '0' & inc_pc_i & "00";
+               ep_add32nc ( prog_cntr_i, incVal_v, '0', next_pc_v );
+               IF (EX2IF_i.take_branch = '0') THEN
+                       IF2ID_o.program_counter <= next_pc_v;
+               ELSE
+                       IF2ID_o.program_counter <= EX2IF_i.branch_target;
+               END IF;
+       END PROCESS;
 
 END ARCHITECTURE rtl;
index 0f48b09c203e4d1ce645c25aa0bb1c05dab19fe4..ec7c25bc3559d2afce3b52857f271f72fff54557 100644 (file)
@@ -213,9 +213,7 @@ PACKAGE mbl_Pkg IS
                ID2EX_o     : OUT ID2EX_Type;
                --
                INT_CTRL_i  :  IN INT_CTRL_Type;
-               ID2CTRL_o   : OUT ID2CTRL_Type;
-               --
-               noLiteOpc_o : OUT STD_LOGIC
+               ID2CTRL_o   : OUT ID2CTRL_Type
        );
        END COMPONENT;
 
@@ -228,7 +226,10 @@ PACKAGE mbl_Pkg IS
        );
        PORT
        (
+               IF2ID_i      :  IN IF2ID_Type;
+               --
                ID2EX_i      :  IN ID2EX_Type;
+               delayBit_i   :  IN STD_LOGIC;
                GPRF2EX_i    :  IN GPRF2EX_Type;
                EX2IF_o      : OUT EX2IF_Type;
                EX2CTRL_o    : OUT EX2CTRL_Type;
@@ -277,7 +278,6 @@ PACKAGE mbl_Pkg IS
                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;
@@ -292,6 +292,7 @@ PACKAGE mbl_Pkg IS
                -- decode to exeq pipeline registers
                ID2EX_REG_i     :  IN ID2EX_Type;
                ID2EX_REG_o     : OUT ID2EX_Type;
+               delay_bit_o     : OUT STD_LOGIC;
                -- GPRF control
                gprf_clken_o    : OUT STD_LOGIC;
                -- exeq to fetch feedback registers