]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blobdiff - hw/core_ctrl.vhd
Customized instruction set (with compatibility mode)
[fpga/lx-cpu1/tumbl.git] / hw / core_ctrl.vhd
index 5e9d5a452bc2ad06a5123bc5b9787079593650cb..a0d714332eff8bf4fbf98c21c7cd80f9c85dc76e 100644 (file)
@@ -21,18 +21,21 @@ LIBRARY IEEE;
 USE IEEE.std_logic_1164.all;
 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_clk_en_o   : OUT 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;
@@ -48,6 +51,8 @@ ENTITY core_ctrl IS
         -- exeq to fetch feedback registers
         EX2IF_REG_i     :  IN EX2IF_Type;
         EX2IF_REG_o     : OUT EX2IF_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;
@@ -70,8 +75,7 @@ ENTITY core_ctrl IS
         MSR_i           :  IN MSR_Type;
         MSR_o           : OUT MSR_Type;
         -- miscellaneous
-        MEM2CTRL_i      :  IN MEM2CTRL_Type;
-        done_o          : OUT STD_LOGIC
+        MEM2CTRL_i      :  IN MEM2CTRL_Type
         );
 END ENTITY core_ctrl;
 
@@ -81,15 +85,13 @@ ARCHITECTURE rtl OF core_ctrl IS
 
     SIGNAL rst_r          : STD_LOGIC;
     SIGNAL reset_s        : STD_LOGIC;
-    SIGNAL core_clk_en_s  : STD_LOGIC;
+    SIGNAL core_clken_s  : STD_LOGIC;
 
     SIGNAL ID2EX_REG_r    : ID2EX_Type;
     SIGNAL EX2IF_REG_r    : EX2IF_Type;
-    SIGNAL delayBit_r     : STD_LOGIC;
-    SIGNAL delayBit_2r    : STD_LOGIC;
     SIGNAL IMM_LOCK_r     : IMM_LOCK_Type;
     SIGNAL HAZARD_WRB_r   : HAZARD_WRB_Type;
-
+    SIGNAL delayBit_r     : STD_LOGIC;
     SIGNAL clken_s        : STD_LOGIC;
     SIGNAL clken_pipe_s   : STD_LOGIC;
     SIGNAL flush_ID2EX_s  : STD_LOGIC;
@@ -99,7 +101,6 @@ ARCHITECTURE rtl OF core_ctrl IS
     SIGNAL setup_int_r    : STD_LOGIC;
     SIGNAL int_busy_r     : STD_LOGIC;
 
-
 BEGIN
 
     -- static connections
@@ -108,16 +109,17 @@ BEGIN
     imem_addr_o    <= IF2ID_REG_i.program_counter;
     -- Tracing
     -- Reset_s is 1 when rst_i is one and then gets deactivated
-    core_clk_en_s <= reset_s OR (NOT trace_i) OR trace_kick_i;
-    core_clk_en_o <= core_clk_en_s;
+    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_r.take_branch;
-    flush_EX2MEM_s <= (flush_ID2EX_s AND (NOT delayBit_2r)) OR HAZARD_WRB_i.hazard;
+    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);
+    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;
@@ -129,12 +131,12 @@ BEGIN
     INT_CTRL_o.int_busy    <= int_busy_r;
 
 regd_proc:
-    PROCESS ( clk_i, rst_i, halt_i, core_clk_en_s,
+    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, delayBit_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
+              int_busy_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
               EX2IF_REG_i, EX_WRB_i, EX2MEM_REG_i )
 
         -- some local procedures
@@ -217,18 +219,22 @@ regd_proc:
     BEGIN
 
         IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
-                                           core_clk_en_s = '1' THEN
+                    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;
-                delayBit_r    <= '0';
+
+                IF (COMPATIBILITY_MODE_g = TRUE) THEN
+                    delayBit_r    <= '0';
+                END IF;
+
                 flush_ID2EX_r <= '0';
                 setup_int_r   <= '0';
                 int_busy_r    <= '0';
-                done_o        <= '0';
                 ID2EX_REG_r.program_counter <= (OTHERS => '0');
             ELSE
                 IF (clken_pipe_s = '1') THEN
@@ -241,15 +247,18 @@ regd_proc:
             END IF;
             -- decode-to-exeq unit registers
             IF ((reset_s = '1') OR (flush_ID2EX_s = '1')) THEN
+                setup_int_r <= '0';
                 lp_rst_ID2EX_REG;
-                delayBit_r <= '0';
+                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
-                                (delayBit_r = '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';
@@ -257,12 +266,10 @@ regd_proc:
                 lp_rst_ID2EX_REG;
             ELSIF (clken_pipe_s = '1') THEN
                 setup_int_r <= '0';
-                if (EX2IF_REG_i.take_branch = '1') THEN
-                    lp_rst_ID2EX_REG;
-                ELSE
-                    ID2EX_REG_r <= ID2EX_REG_i;
+                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
@@ -270,11 +277,9 @@ regd_proc:
                 lp_rst_EX2MEM_REG;
                 lp_rst_EX_WRB;
                 lp_rst_IMM_LOCK;
-                delayBit_2r <= '0';
             ELSE
                 IF (clken_pipe_s = '1') THEN
                     EX2IF_REG_r <= EX2IF_REG_i;
-                    delayBit_2r <= delayBit_r;
                     EX_WRB_o    <= EX_WRB_i;
                 END IF;
                 IF (clken_s = '1') THEN
@@ -287,14 +292,6 @@ regd_proc:
                     MSR_o      <= MSR_i;
                 END IF;
             END IF;
-            -- check on End-Of-Program viz. "bri 0x00"
-            -- use delayBit to distinguish between "bri" and "rtsd/rtid"
-            IF ((ID2EX_REG_r.branch_Action = BR) AND
-                    (ID2EX_REG_r.alu_Op2 = ALU_IN_IMM) AND
-                        (ID2EX_REG_r.IMM16 = C_16_ZEROS) AND
-                            (delayBit_r = '0') AND (flush_EX2MEM_s = '0')) THEN
-                done_o <= '1';
-            END IF;
         END IF;     -- rising edge clk_i ...
     END PROCESS regd_proc;