-- Author: Huib Lincklaen Arriens
-- Delft University of Technology
-- Faculty EEMCS, Department ME&CE, Circuits and Systems
--- Date: December, 2010
--- Modified: September, 2012: interrupt handling corrected to let
+-- Date: December, 2010
+-- Modified: September, 2013: Core customization (Meloun)
+-- September, 2012: interrupt handling corrected to let
-- a pending branch be taken first
-- (with thanks to Matthis Meier, TU Dortmund,
-- for detecting this errror).
USE IEEE.std_logic_1164.all;
USE WORK.mbl_Pkg.all;
-
--------------------------------------------------------------------------------
ENTITY core_ctrl IS
--------------------------------------------------------------------------------
- PORT (
- clk_i : IN STD_LOGIC;
- rst_i : IN STD_LOGIC;
- halt_i : IN STD_LOGIC;
- int_i : IN STD_LOGIC;
- trace_i : IN STD_LOGIC;
- trace_kick_i : IN STD_LOGIC;
- core_clk_en_o : OUT STD_LOGIC;
- -- specific fetch i/o
- imem_addr_o : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
- imem_clken_o : OUT STD_LOGIC;
- pc_ctrl_o : OUT STD_LOGIC;
- -- fetch to decode pipeline registers
- IF2ID_REG_i : IN IF2ID_Type;
- IF2ID_REG_o : OUT IF2ID_Type;
- -- decode to exeq pipeline registers
- ID2EX_REG_i : IN ID2EX_Type;
- ID2EX_REG_o : OUT ID2EX_Type;
- -- GPRF control
- gprf_clken_o : OUT STD_LOGIC;
- -- exeq to fetch feedback registers
- EX2IF_REG_i : IN EX2IF_Type;
- EX2IF_REG_o : OUT EX2IF_Type;
- -- exeq to mem pipeline registers
- EX2MEM_REG_i : IN EX2MEM_Type;
- EX2MEM_REG_o : OUT EX2MEM_Type;
- -- mem pipeline register
- MEM_REG_i : IN MEM_REG_Type;
- MEM_REG_o : OUT MEM_REG_Type;
- -- decode control i/o
- ID2CTRL_i : IN ID2CTRL_Type;
- INT_CTRL_o : OUT INT_CTRL_Type;
- -- exeq control i/o
- EX_WRB_i : IN WRB_Type;
- EX_WRB_o : OUT WRB_Type;
- -- data hazard i/o
- HAZARD_WRB_i : IN HAZARD_WRB_Type;
- HAZARD_WRB_o : OUT HAZARD_WRB_Type;
- -- for handling the 'IMM' instruction
- IMM_LOCK_i : IN IMM_LOCK_Type;
- IMM_LOCK_o : OUT IMM_LOCK_Type;
- -- for handling the Machine Status Register
- MSR_i : IN MSR_Type;
- MSR_o : OUT MSR_Type;
- -- miscellaneous
- MEM2CTRL_i : IN MEM2CTRL_Type;
- done_o : OUT STD_LOGIC
- );
+ GENERIC
+ (
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+ );
+ PORT
+ (
+ clk_i : IN STD_LOGIC;
+ rst_i : IN STD_LOGIC;
+ halt_i : IN STD_LOGIC;
+ bad_op_i : IN STD_LOGIC;
+ int_i : IN STD_LOGIC;
+ trace_i : IN STD_LOGIC;
+ trace_kick_i : IN STD_LOGIC;
+ core_clken_o : OUT STD_LOGIC;
+ -- specific fetch i/o
+ imem_addr_o : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
+ imem_clken_o : OUT STD_LOGIC;
+ pc_ctrl_o : OUT STD_LOGIC;
+ -- fetch to decode pipeline registers
+ IF2ID_REG_i : IN IF2ID_Type;
+ IF2ID_REG_o : OUT IF2ID_Type;
+ -- decode to exeq pipeline registers
+ ID2EX_REG_i : IN ID2EX_Type;
+ ID2EX_REG_o : OUT ID2EX_Type;
+ -- GPRF control
+ gprf_clken_o : OUT STD_LOGIC;
+ -- exeq to fetch feedback registers
+ EX2IF_REG_i : IN EX2IF_Type;
+ EX2IF_REG_o : OUT EX2IF_Type;
+ EX2CTRL_REG_i : IN EX2CTRL_Type;
+ -- exeq to core (halting)
+ exeq_halt_i : IN STD_LOGIC;
+ -- exeq to mem pipeline registers
+ EX2MEM_REG_i : IN EX2MEM_Type;
+ EX2MEM_REG_o : OUT EX2MEM_Type;
+ -- mem pipeline register
+ MEM_REG_i : IN MEM_REG_Type;
+ MEM_REG_o : OUT MEM_REG_Type;
+ -- decode control i/o
+ ID2CTRL_i : IN ID2CTRL_Type;
+ INT_CTRL_o : OUT INT_CTRL_Type;
+ -- exeq control i/o
+ EX_WRB_i : IN WRB_Type;
+ EX_WRB_o : OUT WRB_Type;
+ -- data hazard i/o
+ HAZARD_WRB_i : IN HAZARD_WRB_Type;
+ HAZARD_WRB_o : OUT HAZARD_WRB_Type;
+ -- for handling the 'IMM' instruction
+ IMM_LOCK_i : IN IMM_LOCK_Type;
+ IMM_LOCK_o : OUT IMM_LOCK_Type;
+ -- for handling the Machine Status Register
+ MSR_i : IN MSR_Type;
+ MSR_o : OUT MSR_Type;
+ -- miscellaneous
+ MEM2CTRL_i : IN MEM2CTRL_Type
+ );
END ENTITY core_ctrl;
--------------------------------------------------------------------------------
ARCHITECTURE rtl OF core_ctrl IS
--------------------------------------------------------------------------------
- SIGNAL rst_r : STD_LOGIC;
- SIGNAL reset_s : STD_LOGIC;
- SIGNAL core_clk_en_s : STD_LOGIC;
-
- SIGNAL ID2EX_REG_r : ID2EX_Type;
- SIGNAL EX2IF_REG_r : EX2IF_Type;
- SIGNAL delayBit_r : STD_LOGIC;
- SIGNAL delayBit_2r : STD_LOGIC;
- SIGNAL IMM_LOCK_r : IMM_LOCK_Type;
- SIGNAL HAZARD_WRB_r : HAZARD_WRB_Type;
-
- SIGNAL clken_s : STD_LOGIC;
- SIGNAL clken_pipe_s : STD_LOGIC;
- SIGNAL flush_ID2EX_s : STD_LOGIC;
- SIGNAL flush_ID2EX_r : STD_LOGIC;
- SIGNAL flush_EX2MEM_s : STD_LOGIC;
+ SIGNAL rst_r : STD_LOGIC;
+ SIGNAL reset_s : STD_LOGIC;
+ SIGNAL core_clken_s : STD_LOGIC;
- SIGNAL setup_int_r : STD_LOGIC;
- SIGNAL int_busy_r : STD_LOGIC;
+ SIGNAL ID2EX_REG_r : ID2EX_Type;
+ SIGNAL EX2IF_REG_r : EX2IF_Type;
+ SIGNAL IMM_LOCK_r : IMM_LOCK_Type;
+ SIGNAL HAZARD_WRB_r : HAZARD_WRB_Type;
+ SIGNAL flush_first_r : STD_LOGIC;
+ SIGNAL flush_second_r : STD_LOGIC;
+ SIGNAL flush_second_2r : STD_LOGIC;
+ SIGNAL ignore_state_r : STD_LOGIC; -- Please note: Flushing first is considered immediate!
+ SIGNAL delayBit_r : STD_LOGIC;
+ SIGNAL clken_s : STD_LOGIC;
+ SIGNAL clken_pipe_s : STD_LOGIC;
+ SIGNAL flush_ID2EX_s : STD_LOGIC;
+ SIGNAL flush_ID2EX_r : STD_LOGIC;
+ SIGNAL flush_EX2MEM_s : STD_LOGIC;
+ SIGNAL setup_int_r : STD_LOGIC;
+ SIGNAL int_busy_r : STD_LOGIC;
BEGIN
- -- static connections
- reset_s <= rst_i OR rst_r;
- pc_ctrl_o <= NOT rst_r;
- imem_addr_o <= IF2ID_REG_i.program_counter;
- -- Tracing
- -- Reset_s is 1 when rst_i is one and then gets deactivated
- core_clk_en_s <= reset_s OR (NOT trace_i) OR trace_kick_i;
- core_clk_en_o <= core_clk_en_s;
- -- clock/wait control lines
- clken_s <= MEM2CTRL_i.clken 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;
- -- signals for clearing the ID2EX and EX2MEM registers during branches
- flush_ID2EX_s <= EX2IF_REG_r.take_branch;
- flush_EX2MEM_s <= (flush_ID2EX_s AND (NOT delayBit_2r)) OR HAZARD_WRB_i.hazard;
- -- outputs that need to be readable too, so needing shadowing signals
- ID2EX_REG_o <= ID2EX_REG_r;
- EX2IF_REG_o <= EX2IF_REG_r;
- IMM_LOCK_o <= IMM_LOCK_r;
- HAZARD_WRB_o <= HAZARD_WRB_r;
- --
- INT_CTRL_o.setup_int <= setup_int_r;
- INT_CTRL_o.rti_target <= ID2EX_REG_r.program_counter;
- INT_CTRL_o.int_busy <= int_busy_r;
+ -- static connections
+ reset_s <= rst_i OR rst_r;
+ pc_ctrl_o <= NOT rst_r;
+ imem_addr_o <= IF2ID_REG_i.program_counter;
+ -- Tracing
+ -- Reset_s is 1 when rst_i is one and then gets deactivated
+ core_clken_s <= reset_s OR ((NOT bad_op_i) AND (((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_pipe_s <= clken_s AND (NOT HAZARD_WRB_i.hazard);
+ imem_clken_o <= clken_pipe_s;
+ gprf_clken_o <= clken_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 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
+ ID2EX_REG_o <= ID2EX_REG_r;
+ EX2IF_REG_o <= EX2IF_REG_r;
+ IMM_LOCK_o <= IMM_LOCK_r;
+ HAZARD_WRB_o <= HAZARD_WRB_r;
+ --
+ INT_CTRL_o.setup_int <= setup_int_r;
+ INT_CTRL_o.rti_target <= ID2EX_REG_r.program_counter;
+ INT_CTRL_o.int_busy <= int_busy_r;
regd_proc:
- PROCESS ( clk_i, rst_i, halt_i, core_clk_en_s,
- -- complete sensitivity list for synthesizer
- reset_s, MEM2CTRL_i, clken_pipe_s, IF2ID_REG_i,
- flush_ID2EX_s, flush_EX2MEM_s, HAZARD_WRB_i,
- MEM_REG_i, ID2CTRL_i, int_i, MSR_i,
- int_busy_r, delayBit_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
- EX2IF_REG_i, EX_WRB_i, EX2MEM_REG_i )
+ PROCESS ( clk_i, rst_i, halt_i, core_clken_s,
+ -- complete sensitivity list for synthesizer
+ reset_s, MEM2CTRL_i, clken_pipe_s, IF2ID_REG_i,
+ flush_ID2EX_s, flush_EX2MEM_s, HAZARD_WRB_i,
+ MEM_REG_i, ID2CTRL_i, int_i, MSR_i,
+ int_busy_r, IMM_LOCK_i, ID2EX_REG_i, ID2EX_REG_r,
+ EX2IF_REG_i, EX2CTRL_REG_i, EX_WRB_i, EX2MEM_REG_i )
+
+ -- some local procedures
+ PROCEDURE lp_rst_IF2ID_REG IS
+ BEGIN
+ IF2ID_REG_o.program_counter <= (OTHERS => '0');
+ END PROCEDURE;
+
+ PROCEDURE lp_rst_ID2EX_REG IS
+ BEGIN
+ -- reset and handle ID2EX_REG_r.program_counter separately,
+ -- since it will be needed during interrupt setup
+ ID2EX_REG_r.rdix_rA <= (OTHERS => '0');
+ ID2EX_REG_r.rdix_rB <= (OTHERS => '0');
+ ID2EX_REG_r.curr_rD <= (OTHERS => '0');
+ ID2EX_REG_r.alu_Action <= A_NOP;
+ ID2EX_REG_r.alu_Op1 <= ALU_IN_ZERO;
+ ID2EX_REG_r.alu_Op2 <= ALU_IN_IMM;
+ ID2EX_REG_r.alu_Cin <= CIN_ZERO;
+ ID2EX_REG_r.IMM16 <= (OTHERS => '0');
+ ID2EX_REG_r.IMM_Lock <= '0';
+ ID2EX_REG_r.msr_Action <= KEEP_CARRY;
+ ID2EX_REG_r.branch_Action <= NO_BR;
+ ID2EX_REG_r.mem_Action <= NO_MEM;
+ ID2EX_REG_r.transfer_Size <= WORD;
+ ID2EX_REG_r.wrb_Action <= NO_WRB;
+ ID2EX_REG_r.condition <= COND_ALL;
+ ID2EX_REG_r.halt <= '0';
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ ID2EX_REG_r.it_Action <= NO_IT;
+ ELSE
+ END IF;
+ END PROCEDURE;
+
+ PROCEDURE lp_rst_EX2IF_REG IS
+ BEGIN
+ EX2IF_REG_r.take_branch <= '0';
+ EX2IF_REG_r.branch_target <= (OTHERS => '0');
+ END PROCEDURE;
- -- some local procedures
- PROCEDURE lp_rst_IF2ID_REG IS
- BEGIN
- IF2ID_REG_o.program_counter <= (OTHERS => '0');
- END PROCEDURE;
+ 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');
+ END PROCEDURE;
- PROCEDURE lp_rst_ID2EX_REG IS
- BEGIN
- -- reset and handle ID2EX_REG_r.program_counter separately,
- -- since it will be needed during interrupt setup
- ID2EX_REG_r.rdix_rA <= (OTHERS => '0');
- ID2EX_REG_r.rdix_rB <= (OTHERS => '0');
- ID2EX_REG_r.curr_rD <= (OTHERS => '0');
- ID2EX_REG_r.alu_Action <= A_NOP;
- ID2EX_REG_r.alu_Op1 <= ALU_IN_ZERO;
- ID2EX_REG_r.alu_Op2 <= ALU_IN_IMM;
- ID2EX_REG_r.alu_Cin <= CIN_ZERO;
- ID2EX_REG_r.IMM16 <= (OTHERS => '0');
- ID2EX_REG_r.IMM_Lock <= '0';
- ID2EX_REG_r.msr_Action <= KEEP_CARRY;
- ID2EX_REG_r.branch_Action <= NO_BR;
- ID2EX_REG_r.mem_Action <= NO_MEM;
- ID2EX_REG_r.transfer_Size <= WORD;
- ID2EX_REG_r.wrb_Action <= NO_WRB;
- END PROCEDURE;
+ PROCEDURE lp_rst_IMM_LOCK IS
+ BEGIN
+ IMM_LOCK_r.locked <= '0';
+ IMM_LOCK_r.IMM_hi16 <= (OTHERS => '0');
+ END PROCEDURE;
- PROCEDURE lp_rst_EX2IF_REG IS
- BEGIN
- EX2IF_REG_r.take_branch <= '0';
- EX2IF_REG_r.branch_target <= (OTHERS => '0');
- END PROCEDURE;
+ PROCEDURE lp_rst_MSR IS
+ BEGIN
+ MSR_o.IE <= '0';
+ MSR_o.C <= '0';
+ END PROCEDURE;
- 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');
- END PROCEDURE;
+ PROCEDURE lp_rst_EX_WRB IS
+ BEGIN
+ EX_WRB_o.wrb_Action <= NO_WRB;
+ EX_WRB_o.wrix_rD <= (OTHERS => '0');
+ EX_WRB_o.data_rD <= (OTHERS => '0');
+ END PROCEDURE;
- PROCEDURE lp_rst_IMM_LOCK IS
- BEGIN
- IMM_LOCK_r.locked <= '0';
- IMM_LOCK_r.IMM_hi16 <= (OTHERS => '0');
- END PROCEDURE;
+ PROCEDURE lp_rst_HAZARD_WRB IS
+ BEGIN
+ HAZARD_WRB_r.hazard <= '0';
+ HAZARD_WRB_r.save_rX <= NO_SAVE;
+ HAZARD_WRB_r.data_rX <= (OTHERS => '0');
+ HAZARD_WRB_r.data_rD <= (OTHERS => '0');
+ END PROCEDURE;
- PROCEDURE lp_rst_MSR IS
- BEGIN
- MSR_o.IE <= '0';
- MSR_o.C <= '0';
- END PROCEDURE;
+ 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');
+ END PROCEDURE;
- PROCEDURE lp_rst_EX_WRB IS
- BEGIN
- EX_WRB_o.wrb_Action <= NO_WRB;
- EX_WRB_o.wrix_rD <= (OTHERS => '0');
- EX_WRB_o.data_rD <= (OTHERS => '0');
- END PROCEDURE;
+ BEGIN
- PROCEDURE lp_rst_HAZARD_WRB IS
- BEGIN
- HAZARD_WRB_r.hazard <= '0';
- HAZARD_WRB_r.save_rX <= NO_SAVE;
- HAZARD_WRB_r.data_rX <= (OTHERS => '0');
- HAZARD_WRB_r.data_rD <= (OTHERS => '0');
- END PROCEDURE;
+ IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
+ core_clken_s = '1' THEN
+ rst_r <= rst_i;
- 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');
- END PROCEDURE;
+ IF (reset_s = '1') THEN -- synchronous reset ...
+ lp_rst_IF2ID_REG; -- ... so lasts at least one clock_cycle
+ lp_rst_MSR;
+ lp_rst_HAZARD_WRB;
+ lp_rst_MEM_REG;
- BEGIN
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_r <= '0';
+ ELSE
+ flush_first_r <= '0';
+ flush_second_r <= '0';
+ flush_second_2r <= '0';
+ ignore_state_r <= '0';
+ END IF;
- IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
- core_clk_en_s = '1' THEN
- rst_r <= rst_i;
- IF (reset_s = '1') THEN -- synchronous reset ...
- lp_rst_IF2ID_REG; -- ... so lasts at least one clock_cycle
- lp_rst_MSR;
- lp_rst_HAZARD_WRB;
- lp_rst_MEM_REG;
- delayBit_r <= '0';
- flush_ID2EX_r <= '0';
- setup_int_r <= '0';
- int_busy_r <= '0';
- done_o <= '0';
- ID2EX_REG_r.program_counter <= (OTHERS => '0');
- ELSE
- IF (clken_pipe_s = '1') THEN
- IF2ID_REG_o <= IF2ID_REG_i;
- END IF;
- flush_ID2EX_r <= flush_ID2EX_s;
- HAZARD_WRB_r <= HAZARD_WRB_i;
- MEM_REG_o <= MEM_REG_i;
- int_busy_r <= ID2CTRL_i.int_busy;
- END IF;
- -- decode-to-exeq unit registers
- IF ((reset_s = '1') OR (flush_ID2EX_s = '1')) THEN
- lp_rst_ID2EX_REG;
- delayBit_r <= '0';
- -- check for the need and possibility to handle active interrupt requests
- ELSIF (((int_i = '1') OR (MEM2CTRL_i.int = '1')) AND (MSR_i.IE = '1') AND
- (ID2CTRL_i.int_busy = '0') AND (int_busy_r = '0') AND
- -- pending branch should be taken before interrupt can be executed
- -- dectected by Matthis Meier, TU Dortmund (Sept 2012)
- (EX2IF_REG_i.take_branch = '0') AND
- (delayBit_r = '0') AND
- (IMM_LOCK_i.locked = '0') AND
- (HAZARD_WRB_i.hazard = '0')) THEN
- setup_int_r <= '1';
- ID2EX_REG_r.program_counter <= ID2EX_REG_i.program_counter;
- lp_rst_ID2EX_REG;
- ELSIF (clken_pipe_s = '1') THEN
- setup_int_r <= '0';
- if (EX2IF_REG_i.take_branch = '1') THEN
- lp_rst_ID2EX_REG;
- ELSE
- ID2EX_REG_r <= ID2EX_REG_i;
- END IF;
- delayBit_r <= ID2CTRL_i.delayBit;
- END IF;
- -- exeq-to-mem unit registers
- IF ((reset_s = '1') OR (flush_EX2MEM_s = '1')) THEN
- lp_rst_EX2IF_REG;
- lp_rst_EX2MEM_REG;
- lp_rst_EX_WRB;
- lp_rst_IMM_LOCK;
- delayBit_2r <= '0';
- ELSE
- IF (clken_pipe_s = '1') THEN
- EX2IF_REG_r <= EX2IF_REG_i;
- delayBit_2r <= delayBit_r;
- EX_WRB_o <= EX_WRB_i;
- END IF;
- IF (clken_s = '1') THEN
- -- next test to prevent a flush from disrupting
- -- the write-back pipeline
- IF (flush_ID2EX_r = '0') THEN
- EX2MEM_REG_o <= EX2MEM_REG_i;
- END IF;
- IMM_LOCK_r <= IMM_LOCK_i;
- MSR_o <= MSR_i;
- END IF;
- END IF;
- -- check on End-Of-Program viz. "bri 0x00"
- -- use delayBit to distinguish between "bri" and "rtsd/rtid"
- IF ((ID2EX_REG_r.branch_Action = BR) AND
- (ID2EX_REG_r.alu_Op2 = ALU_IN_IMM) AND
- (ID2EX_REG_r.IMM16 = C_16_ZEROS) AND
- (delayBit_r = '0') AND (flush_EX2MEM_s = '0')) THEN
- done_o <= '1';
- END IF;
- END IF; -- rising edge clk_i ...
- END PROCESS regd_proc;
+ flush_ID2EX_r <= '0';
+ setup_int_r <= '0';
+ int_busy_r <= '0';
+ ID2EX_REG_r.program_counter <= (OTHERS => '0');
+ ELSE
+ IF (clken_pipe_s = '1') THEN
+ IF2ID_REG_o <= IF2ID_REG_i;
+ END IF;
+ flush_ID2EX_r <= flush_ID2EX_s;
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ -- Flushing based on IT / ITE / ITT along with IMM locking
+ IF (ID2EX_REG_i.IMM_Lock = '1') THEN
+ IF (flush_second_2r = '0') THEN
+ flush_second_2r <= flush_second_r;
+ END IF;
+ flush_first_r <= EX2CTRL_REG_i.flush_first;
+ flush_second_r <= EX2CTRL_REG_i.flush_second;
+ ignore_state_r <= EX2CTRL_REG_i.ignore_state;
+ ELSE
+ flush_first_r <= '0';
+ -- Directly to 2r (flushing the following instruction)
+ flush_second_2r <= flush_second_r OR EX2CTRL_REG_i.flush_second;
+ flush_second_r <= '0';
+ ignore_state_r <= '0';
+ END IF;
+ END IF;
+ HAZARD_WRB_r <= HAZARD_WRB_i;
+ MEM_REG_o <= MEM_REG_i;
+ int_busy_r <= ID2CTRL_i.int_busy;
+ END IF;
+ -- decode-to-exeq unit registers
+ IF ((reset_s = '1') OR (flush_ID2EX_s = '1')) THEN
+ setup_int_r <= '0';
+ lp_rst_ID2EX_REG;
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_r <= '0';
+ END IF;
+ -- check for the need and possibility to handle active interrupt requests
+ ELSIF (((int_i = '1') OR (MEM2CTRL_i.int = '1')) AND (MSR_i.IE = '1') AND
+ (ID2CTRL_i.int_busy = '0') AND (int_busy_r = '0') AND
+ -- pending branch should be taken before interrupt can be executed
+ -- dectected by Matthis Meier, TU Dortmund (Sept 2012)
+ --
+ -- Same goes for pending flushing - should be taken before interrupt can be executed
+ (EX2IF_REG_i.take_branch = '0') AND (EX2IF_REG_r.take_branch = '0') AND ((COMPATIBILITY_MODE_g = TRUE)
+ OR ((flush_first_r = '0') AND (flush_second_r = '0') AND (flush_second_2r = '0'))) AND
+ (IMM_LOCK_i.locked = '0') AND (HAZARD_WRB_i.hazard = '0')) THEN
+ setup_int_r <= '1';
+ ID2EX_REG_r.program_counter <= ID2EX_REG_i.program_counter;
+ lp_rst_ID2EX_REG;
+ ELSIF (clken_pipe_s = '1') THEN
+ setup_int_r <= '0';
+ ID2EX_REG_r <= ID2EX_REG_i;
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_r <= ID2CTRL_i.delayBit;
+ END IF;
+ END IF;
+ -- exeq-to-mem unit registers
+ IF ((reset_s = '1') OR (flush_EX2MEM_s = '1')) THEN
+ lp_rst_EX2IF_REG;
+ lp_rst_EX2MEM_REG;
+ lp_rst_EX_WRB;
+ lp_rst_IMM_LOCK;
+ ELSE
+ IF (clken_pipe_s = '1') THEN
+ EX2IF_REG_r <= EX2IF_REG_i;
+ EX_WRB_o <= EX_WRB_i;
+ END IF;
+ IF (clken_s = '1') THEN
+ -- next test to prevent a flush from disrupting
+ -- the write-back pipeline
+ IF (flush_ID2EX_r = '0') THEN
+ EX2MEM_REG_o <= EX2MEM_REG_i;
+ END IF;
+ IMM_LOCK_r <= IMM_LOCK_i;
+ MSR_o <= MSR_i;
+ END IF;
+ END IF;
+ END IF; -- rising edge clk_i ...
+ END PROCESS regd_proc;
END ARCHITECTURE rtl;