]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blobdiff - hw/core_ctrl.vhd
Connect internal finish_wrb_mem_s to GPRF - gprf_finish_wrb_mem.
[fpga/lx-cpu1/tumbl.git] / hw / core_ctrl.vhd
index b0e19677c92bb5711f03a08440d2190f97b0b433..4bfabbb1a84f149cbf3ab958cd605fdf896098e5 100644 (file)
@@ -52,6 +52,7 @@ ENTITY core_ctrl IS
                delay_bit_o     : OUT STD_LOGIC;
                -- GPRF control
                gprf_clken_o    : OUT STD_LOGIC;
+               gprf_finish_wrb_mem_o : OUT STD_LOGIC;
                -- exeq to fetch feedback registers
                EX2IF_REG_i     :  IN EX2IF_Type;
                EX2IF_REG_o     : OUT EX2IF_Type;
@@ -92,6 +93,8 @@ ARCHITECTURE rtl OF core_ctrl IS
        SIGNAL reset_s         : STD_LOGIC;
        SIGNAL core_clken_s    : STD_LOGIC;
 
+       SIGNAL EX2MEM_REG_r    : EX2MEM_Type;
+       SIGNAL MEM_REG_r       : MEM_REG_Type;
        SIGNAL ID2EX_REG_r     : ID2EX_Type;
        SIGNAL EX2IF_REG_r     : EX2IF_Type;
        SIGNAL IMM_LOCK_r      : IMM_LOCK_Type;
@@ -110,6 +113,9 @@ ARCHITECTURE rtl OF core_ctrl IS
        SIGNAL setup_int_r     : STD_LOGIC;
        SIGNAL int_busy_r      : STD_LOGIC;
 
+       SIGNAL wait_for_mem_s  : STD_LOGIC;
+       SIGNAL finish_wrb_mem_s: STD_LOGIC;
+
 BEGIN
 
        -- static connections
@@ -122,16 +128,22 @@ BEGIN
        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;
+       finish_wrb_mem_s <= NOT MEM2CTRL_i.bus_wait WHEN (MEM_REG_r.wrb_Action = WRB_MEM AND MEM2CTRL_i.bus_taken = '1') ELSE '0';
+       wait_for_mem_s <= MEM2CTRL_i.bus_wait OR MEM2CTRL_i.bus_taken;
+       clken_s        <= NOT wait_for_mem_s OR rst_i;
        clken_pipe_s   <= clken_s AND (NOT HAZARD_WRB_i.hazard);
        imem_clken_o   <= clken_pipe_s;
-       gprf_clken_o   <= clken_s;
+
+       gprf_clken_o   <= clken_s or finish_wrb_mem_s;
+       gprf_finish_wrb_mem_o <= finish_wrb_mem_s;
        -- signals for clearing the ID2EX and EX2MEM registers during branches
        flush_ID2EX_s  <= ((EX2IF_REG_i.take_branch AND (NOT delayBit_r)) OR EX2IF_REG_r.take_branch) WHEN COMPATIBILITY_MODE_g = TRUE
                                                                                ELSE ((EX2IF_REG_i.take_branch AND (NOT delayBit_r)) OR EX2IF_REG_r.take_branch OR EX2CTRL_REG_i.flush_first OR
                                                                                                flush_first_r OR ((NOT EX2CTRL_REG_i.ignore_state) AND (NOT ignore_state_r) AND flush_second_2r));
        flush_EX2MEM_s <= HAZARD_WRB_i.hazard;
        -- outputs that need to be readable too, so needing shadowing signals
+       EX2MEM_REG_o   <= EX2MEM_REG_r;
+       MEM_REG_o      <= MEM_REG_r;
        ID2EX_REG_o    <= ID2EX_REG_r;
        delay_bit_o    <= delayBit_r;
        EX2IF_REG_o    <= EX2IF_REG_r;
@@ -185,12 +197,12 @@ regd_proc:
 
        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');
+               EX2MEM_REG_r.mem_Action  <= NO_MEM;
+               EX2MEM_REG_r.wrb_Action  <= NO_WRB;
+               EX2MEM_REG_r.exeq_result <= (OTHERS => '0');
+               EX2MEM_REG_r.data_rD     <= (OTHERS => '0');
+               EX2MEM_REG_r.byte_Enable <= (OTHERS => '0');
+               EX2MEM_REG_r.wrix_rD     <= (OTHERS => '0');
        END PROCEDURE;
 
        PROCEDURE lp_rst_IMM_LOCK IS
@@ -222,18 +234,18 @@ regd_proc:
 
        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');
+               MEM_REG_r.wrb_Action  <= NO_WRB;
+               MEM_REG_r.exeq_result <= (OTHERS => '0');
+               MEM_REG_r.byte_Enable <= (OTHERS => '0');
+               MEM_REG_r.wrix_rD     <= (OTHERS => '0');
        END PROCEDURE;
 
        BEGIN
 
        WAIT UNTIL clk_i'event AND clk_i = '1';
 
-       IF MEM2CTRL_i.clken = '1' AND halt_i = '0' AND  core_clken_s = '1' THEN
-                       rst_r <= rst_i;
+       IF (wait_for_mem_s = '0' AND  halt_i = '0' AND core_clken_s = '1') OR rst_i = '1' THEN
+               rst_r <= rst_i;
 
                IF (reset_s = '1') THEN     -- synchronous reset ...
                        lp_rst_IF2ID_REG;       -- ... so lasts at least one clock_cycle
@@ -276,7 +288,7 @@ regd_proc:
                                END IF;
                        END IF;
                        HAZARD_WRB_r  <= HAZARD_WRB_i;
-                       MEM_REG_o     <= MEM_REG_i;
+                       MEM_REG_r     <= MEM_REG_i;
                        int_busy_r    <= ID2CTRL_i.int_busy;
                END IF;
                -- decode-to-exeq unit registers
@@ -317,12 +329,21 @@ regd_proc:
                                -- next test to prevent a flush from disrupting
                                -- the write-back pipeline
                                IF (flush_ID2EX_r = '0') THEN
-                                       EX2MEM_REG_o <= EX2MEM_REG_i;
+                                       EX2MEM_REG_r <= EX2MEM_REG_i;
                                END IF;
                                IMM_LOCK_r <= IMM_LOCK_i;
                                MSR_o      <= MSR_i;
                        END IF;
                END IF;
+       ELSE
+               IF finish_wrb_mem_s = '1' THEN
+                       MEM_REG_r.wrb_Action  <= NO_WRB;
+                       MEM_REG_r.wrix_rD     <= (OTHERS => '0');
+                       MEM_REG_r.byte_Enable <= (OTHERS => '0');
+                       IF MEM2CTRL_i.need_keep = '1' THEN
+                               EX2MEM_REG_r.data_rD <= MEM2CTRL_i.read_data;
+                       END IF;
+               END IF;
        END IF;     -- rising edge clk_i ...
        END PROCESS regd_proc;