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