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
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;
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
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;
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;
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
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;
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: