]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/commitdiff
Implement ITT conditional execution
authorMartin Meloun <meloumar@cmp.felk.cvut.cz>
Wed, 25 Sep 2013 13:46:41 +0000 (15:46 +0200)
committerMartin Meloun <meloumar@cmp.felk.cvut.cz>
Wed, 25 Sep 2013 13:46:41 +0000 (15:46 +0200)
Signed-off-by: Martin Meloun <meloumar@cmp.felk.cvut.cz>
hw/core_ctrl.vhd
hw/decode.vhd
hw/exeq.vhd
hw/mbl_Pkg.vhd

index a0d714332eff8bf4fbf98c21c7cd80f9c85dc76e..55c5344d40f7169718d41d179b62043e81d1d8e2 100644 (file)
@@ -51,6 +51,7 @@ ENTITY core_ctrl IS
         -- 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
@@ -85,12 +86,13 @@ ARCHITECTURE rtl OF core_ctrl IS
 
     SIGNAL rst_r          : STD_LOGIC;
     SIGNAL reset_s        : STD_LOGIC;
-    SIGNAL core_clken_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;
@@ -118,7 +120,7 @@ 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);
+                      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;
@@ -137,7 +139,7 @@ regd_proc:
               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, EX_WRB_i, EX2MEM_REG_i )
+              EX2IF_REG_i, EX2CTRL_REG_i, EX_WRB_i, EX2MEM_REG_i )
 
         -- some local procedures
         PROCEDURE lp_rst_IF2ID_REG IS
@@ -229,7 +231,9 @@ regd_proc:
                 lp_rst_MEM_REG;
 
                 IF (COMPATIBILITY_MODE_g = TRUE) THEN
-                    delayBit_r    <= '0';
+                    delayBit_r     <= '0';
+                ELSE
+                    flush_second_r <= '0';
                 END IF;
 
                 flush_ID2EX_r <= '0';
@@ -241,6 +245,9 @@ regd_proc:
                     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;
@@ -279,8 +286,8 @@ regd_proc:
                 lp_rst_IMM_LOCK;
             ELSE
                 IF (clken_pipe_s = '1') THEN
-                    EX2IF_REG_r <= EX2IF_REG_i;
-                    EX_WRB_o    <= EX_WRB_i;
+                    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
index 9d02421b452af95b470dd9183e193f961a3b91c6..17c6781f4ab5a9e3c441ee7409cc8f3f18dcec00 100644 (file)
@@ -73,6 +73,8 @@ p_decode:
         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;
@@ -85,6 +87,9 @@ p_decode:
         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;
@@ -179,6 +184,38 @@ p_decode:
                                 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;
@@ -348,9 +385,12 @@ p_decode:
         ID2EX_o.wrb_Action       <= wrb_Action_v;
         --
         IF (COMPATIBILITY_MODE_g = TRUE) THEN
-            ID2CTRL_o.delayBit      <= delayBit_v;
+            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;
+        ID2CTRL_o.int_busy        <= int_busy_v;
 
     END PROCESS;
 
index fc338b8c341b8ea6f7b66fb2e3423d166983dd3e..12357951fb2ec7f59e17c6c60773a3311c136830 100644 (file)
@@ -31,12 +31,14 @@ ENTITY exeq IS
 ----------------------------------------------------------
     GENERIC (
         USE_HW_MUL_g : BOOLEAN := TRUE;
-        USE_BARREL_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;
@@ -79,45 +81,52 @@ p_exeq:
             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_rA_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 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";
+        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
@@ -200,18 +209,49 @@ p_exeq:
             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
-                        result_v(31) := NOT signBit_in1_v;
+                        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
-                        result_v(31) := signBit_in1_v;
+                        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    =>
@@ -281,11 +321,6 @@ p_exeq:
                 NULL;
         END CASE;
 
-        IF (data_rA_v = C_32_ZEROS) THEN
-            isZero_v := '1';
-        ELSE
-            isZero_v := '0';
-        END IF;
         CASE ID2EX_i.branch_Action IS
             WHEN BR     => do_branch_v := '1';
             WHEN BRL    => do_branch_v := '1';
@@ -305,6 +340,26 @@ p_exeq:
             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;
index 2b535858c1387fc6b2c3a5c645a1b2e6e96c1654..c81f642f5098be040cebdcf9bb60969637c9ba02 100644 (file)
@@ -55,6 +55,8 @@ PACKAGE mbl_Pkg IS
     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);
@@ -76,6 +78,8 @@ PACKAGE mbl_Pkg IS
         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
@@ -116,6 +120,11 @@ PACKAGE mbl_Pkg IS
         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);
@@ -223,12 +232,14 @@ PACKAGE mbl_Pkg IS
     COMPONENT exeq IS
         GENERIC (
             USE_HW_MUL_g : BOOLEAN := FALSE;
-            USE_BARREL_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;
@@ -291,6 +302,7 @@ PACKAGE mbl_Pkg IS
             -- 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