]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/commitdiff
Separate wait for external bus data and state when external bus is taken by other...
authorPavel Pisa <ppisa@pikron.com>
Tue, 30 Dec 2014 14:02:20 +0000 (15:02 +0100)
committerPavel Pisa <ppisa@pikron.com>
Tue, 30 Dec 2014 14:02:20 +0000 (15:02 +0100)
Original design reuses external bus clock enable/ready indication
for external master wait. This solution is broken because
external master leaves other data on the bus when clocks
are re-enabled than Tumbl expects. When external master
requests bus at/after end of the Tumbl external memory cycle
there is no need to do anything special in such case.

Signed-off-by: Pavel Pisa <ppisa@pikron.com>
hw/core_ctrl.vhd
hw/mbl_pkg.vhd
hw/mem.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;
 
index 43838e9a437ebd3e9d8267706a4d70fbab84603e..944ac52e6d681a3b5368b7ef7c91e7f8455ace20 100644 (file)
@@ -161,8 +161,9 @@ PACKAGE mbl_pkg IS
        END RECORD;
 
        TYPE MEM2CTRL_Type IS RECORD
-               clken : STD_LOGIC;
-               int   : STD_LOGIC;
+               bus_taken   : STD_LOGIC;
+               bus_wait    : STD_LOGIC;
+               int         : STD_LOGIC;
        END RECORD;
 
        TYPE CORE2DMEMB_Type IS RECORD
@@ -173,7 +174,8 @@ PACKAGE mbl_pkg IS
        END RECORD;
 
        TYPE DMEMB2CORE_Type IS RECORD
-               clken : STD_LOGIC;
+               bus_taken   : STD_LOGIC;
+               bus_wait    : STD_LOGIC;
                data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
                int   : STD_LOGIC;
        END RECORD;
index 411e069fd7073f3d8ed124df8f2dc432b7d240f9..4e0c848a6bb4b3c7d048a1e8a3ab418cb86cb4ec 100644 (file)
@@ -54,7 +54,8 @@ BEGIN
        MEM_WRB_o.wrb_Action <= MEM_REG_i.wrb_Action;
        MEM_WRB_o.wrix_rD    <= MEM_REG_i.wrix_rD;
        -- also signal 'slow memory decices' and interrupts from devices
-       MEM2CTRL_o.clken <= DMEMB_i.clken;
+       MEM2CTRL_o.bus_taken <= '0' WHEN EX2MEM_i.mem_Action = NO_MEM ELSE DMEMB_i.bus_taken;
+       MEM2CTRL_o.bus_wait  <= '0' WHEN EX2MEM_i.mem_Action = NO_MEM ELSE DMEMB_i.bus_wait;
        MEM2CTRL_o.int   <= DMEMB_i.int;
 
 p_mem: