]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blobdiff - hw/core_ctrl.vhd
Separate wait for external bus data and state when external bus is taken by other...
[fpga/lx-cpu1/tumbl.git] / hw / core_ctrl.vhd
index b0e19677c92bb5711f03a08440d2190f97b0b433..7e91261978b0186f83d29829f4f4f180dd72cb2d 100644 (file)
@@ -109,6 +109,9 @@ ARCHITECTURE rtl OF core_ctrl IS
 
        SIGNAL setup_int_r     : STD_LOGIC;
        SIGNAL int_busy_r      : STD_LOGIC;
+       SIGNAL repeat_mem_r    : STD_LOGIC;
+
+       SIGNAL wait_for_mem_s  : STD_LOGIC;
 
 BEGIN
 
@@ -122,7 +125,7 @@ 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;
+       clken_s        <= (NOT MEM2CTRL_i.bus_wait AND NOT MEM2CTRL_i.bus_taken) 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;
@@ -142,6 +145,8 @@ BEGIN
        INT_CTRL_o.rti_target  <= ID2EX_REG_r.program_counter;
        INT_CTRL_o.int_busy    <= int_busy_r;
 
+       wait_for_mem_s <= MEM2CTRL_i.bus_wait OR MEM2CTRL_i.bus_taken;
+
 regd_proc:
        PROCESS
 
@@ -232,9 +237,10 @@ regd_proc:
 
        WAIT UNTIL clk_i'event AND clk_i = '1';
 
-       IF MEM2CTRL_i.clken = '1' AND halt_i = '0' AND  core_clken_s = '1' THEN
+       IF wait_for_mem_s = '0' AND  halt_i = '0' AND core_clken_s = '1' AND repeat_mem_r = '0' THEN
                        rst_r <= rst_i;
 
+               repeat_mem_r  <= '0';
                IF (reset_s = '1') THEN     -- synchronous reset ...
                        lp_rst_IF2ID_REG;       -- ... so lasts at least one clock_cycle
                        lp_rst_MSR;
@@ -323,6 +329,19 @@ regd_proc:
                                MSR_o      <= MSR_i;
                        END IF;
                END IF;
+       ELSE
+               IF MEM_REG_i.wrb_Action = WRB_MEM THEN
+                       IF MEM2CTRL_i.bus_wait = '0' THEN
+                               MEM_REG_o.wrb_Action  <= NO_WRB;
+                               MEM_REG_o.wrix_rD     <= (OTHERS => '0');
+                       ELSIF MEM2CTRL_i.bus_taken = '1' THEN
+                               repeat_mem_r  <= '1';
+                       ELSE
+                               repeat_mem_r  <= '0';
+                       END IF;
+               ELSE
+                       repeat_mem_r  <= '0';
+               END IF;
        END IF;     -- rising edge clk_i ...
        END PROCESS regd_proc;