-- 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).
--------------------------------------------------------------------------------
ENTITY core_ctrl IS
--------------------------------------------------------------------------------
- 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
- );
+ 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_clken_s : STD_LOGIC;
+ SIGNAL rst_r : STD_LOGIC;
+ SIGNAL reset_s : STD_LOGIC;
+ SIGNAL core_clken_s : 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_second_r : STD_LOGIC;
- 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 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;
+ 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_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_second_r);
- 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;
+ -- 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_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 )
+ 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;
+ -- 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;
- 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;
+ 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_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_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_IMM_LOCK IS
- BEGIN
- IMM_LOCK_r.locked <= '0';
- IMM_LOCK_r.IMM_hi16 <= (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_MSR IS
- BEGIN
- MSR_o.IE <= '0';
- MSR_o.C <= '0';
- END PROCEDURE;
+ PROCEDURE lp_rst_MSR IS
+ BEGIN
+ MSR_o.IE <= '0';
+ MSR_o.C <= '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_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_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_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_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_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;
- BEGIN
+ BEGIN
- IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
- core_clken_s = '1' THEN
- rst_r <= rst_i;
+ IF (RISING_EDGE (clk_i) AND (MEM2CTRL_i.clken = '1')) AND halt_i = '0' AND
+ core_clken_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;
+ 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;
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_r <= '0';
- ELSE
- flush_second_r <= '0';
- END IF;
+ 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;
- 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
- flush_second_r <= EX2CTRL_REG_i.flush_second;
- 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)
- (EX2IF_REG_i.take_branch = '0') AND
- (EX2IF_REG_r.take_branch = '0') AND -- it is still pending a cycle after branching
- (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;
+ 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;
USE IEEE.std_logic_1164.all;
USE WORK.mbl_Pkg.all;
-
--------------------------------------------------------------------------------
ENTITY decode IS
--------------------------------------------------------------------------------
- GENERIC (
- USE_HW_MUL_g : BOOLEAN := TRUE;
- USE_BARREL_g : BOOLEAN := TRUE;
- COMPATIBILITY_MODE_g : BOOLEAN := FALSE
- );
- PORT (
- IF2ID_i : IN IF2ID_Type;
- imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
- --
- ID2GPRF_o : OUT ID2GPRF_Type;
- ID2EX_o : OUT ID2EX_Type;
- --
- INT_CTRL_i : IN INT_CTRL_Type;
- ID2CTRL_o : OUT ID2CTRL_Type;
- --
- noLiteOpc_o : OUT STD_LOGIC
- );
+ GENERIC
+ (
+ USE_HW_MUL_g : BOOLEAN := TRUE;
+ USE_BARREL_g : BOOLEAN := TRUE;
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+ );
+ PORT
+ (
+ IF2ID_i : IN IF2ID_Type;
+ imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ --
+ ID2GPRF_o : OUT ID2GPRF_Type;
+ ID2EX_o : OUT ID2EX_Type;
+ --
+ INT_CTRL_i : IN INT_CTRL_Type;
+ ID2CTRL_o : OUT ID2CTRL_Type;
+ --
+ noLiteOpc_o : OUT STD_LOGIC
+ );
END ENTITY decode;
-
--------------------------------------------------------------------------------
ARCHITECTURE rtl OF decode IS
--------------------------------------------------------------------------------
BEGIN
p_decode:
- PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
-
- VARIABLE prog_counter_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE opcIx_v : STD_LOGIC_VECTOR ( 5 DOWNTO 0);
- VARIABLE instruction_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE rD_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- VARIABLE rA_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- VARIABLE rB_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- VARIABLE IMM16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
- VARIABLE code_x26_v : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
- VARIABLE IMM_Lock_v : STD_LOGIC;
- VARIABLE alu_Action_v : ALU_ACTION_Type;
- VARIABLE alu_Op1_v : ALU_IN1_Type;
- VARIABLE alu_Op2_v : ALU_IN2_Type;
- VARIABLE alu_Cin_v : ALU_CIN_Type;
- VARIABLE msr_Action_v : MSR_ACTION_Type;
- VARIABLE branch_Action_v : BRANCH_ACTION_Type;
- VARIABLE delayBit_v : STD_LOGIC;
- VARIABLE mem_Action_v : MEM_ACTION_Type;
- VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
- VARIABLE wrb_Action_v : WRB_ACTION_Type;
- VARIABLE int_busy_v : STD_LOGIC;
- VARIABLE cmp_Cond_v : CMP_COND_Type;
- VARIABLE cmp_Cond_Type_v : CMP_COND_TYPE_Type;
-
- BEGIN
- prog_counter_v := IF2ID_i.program_counter;
- instruction_v := imem_data_i;
- opcIx_v := instruction_v (31 DOWNTO 26);
- rD_v := instruction_v (25 DOWNTO 21);
- rA_v := instruction_v (20 DOWNTO 16);
- rB_v := instruction_v (15 DOWNTO 11);
- IMM16_v := instruction_v (15 DOWNTO 0);
- IMM_Lock_v := '0';
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_v := '0';
- ELSE
- cmp_cond_v := COND_ALL;
- cmp_cond_type_v := COND_TYPE_ALL;
- END IF;
- alu_Cin_v := CIN_ZERO;
- alu_Action_v := A_NOP;
- msr_Action_v := KEEP_CARRY;
- branch_Action_v := NO_BR;
- mem_Action_v := NO_MEM;
- transfer_Size_v := WORD;
- wrb_Action_v := WRB_EX;
- -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
- code_x26_v := instruction_v(6) & instruction_v(5) & instruction_v(0);
- int_busy_v := INT_CTRL_i.int_busy;
- -- for debugging purposes
- noLiteOpc_o <= '0';
-
- IF (INT_CTRL_i.setup_int = '1') THEN
-
- alu_Op1_v := ALU_IN_ZERO;
- alu_Op2_v := ALU_IN_IMM;
- IMM16_v := X"0010"; -- address of _interrupt_handler vector
- prog_counter_v := INT_CTRL_i.rti_target; -- delayed program counter
- alu_Action_v := A_ADD;
- rD_v := "01110"; -- r14 reserved for storing program_counter
- rA_v := (OTHERS => '0'); -- also set rA and rB to avoid possible ...
- rB_v := (OTHERS => '0'); -- ... erronuous hazard detection in exeq module
- int_busy_v := '1';
- branch_Action_v := BRL;
-
- ELSE
-
- alu_Op1_v := ALU_IN_REGA;
- IF (opcIx_v(3) = '0') THEN
- alu_Op2_v := ALU_IN_REGB;
- ELSE
- alu_Op2_v := ALU_IN_IMM;
- END IF;
-
- CASE opcIx_v (5 DOWNTO 4) IS
-
- WHEN "00" => -- ADD / RSUB
- IF (opcIx_v(0) = '1') THEN -- RSUB
- alu_Op1_v := ALU_IN_NOT_REGA;
- END IF;
- IF (opcIx_v(1) = '0') THEN -- xxx
- IF (opcIx_v(0) = '0') THEN
- alu_Cin_v := CIN_ZERO;
- ELSE
- alu_Cin_v := CIN_ONE;
- END IF;
- ELSE -- xxxC
- alu_Cin_v := FROM_MSR;
- END IF;
- IF ((COMPATIBILITY_MODE_g = TRUE) AND (opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
- -- special CMP(U) and not RSUB(I)K, supported only in compatibility mode
- IF (IMM16_v(1) = '1') THEN -- U-bit set, CMPU
- alu_Action_v := A_CMPU;
- ELSE
- alu_Action_v := A_CMP;
- END IF;
- ELSE
- alu_Action_v := A_ADD;
- IF (opcIx_v(2) = '0') THEN
- msr_Action_v := UPDATE_CARRY;
- END IF;
- END IF;
-
- WHEN "01" => -- MUL / BS
- CASE opcIx_v (2 DOWNTO 0) IS
- WHEN "000" => -- MUL
- IF (USE_HW_MUL_g = TRUE) THEN
- alu_Action_v := A_MUL;
- ELSE
- noLiteOpc_o <= '1';
- END IF;
- WHEN "001" => -- BS
- IF (USE_BARREL_g = TRUE) THEN
- IF (instruction_v(10) = '1') THEN
- alu_Action_v := A_BSLL;
- ELSE
- IF (instruction_v(9) = '1') THEN
- alu_Action_v := A_BSRA;
- ELSE
- alu_Action_v := A_BSRL;
- END IF;
- END IF;
- ELSE
- noLiteOpc_o <= '1';
- END IF;
- WHEN "010" => -- CMP / CMPU / CMPI (new format)
- IF (COMPATIBILITY_MODE_g = FALSE) THEN
- IF (IMM16_v(5) = '1') THEN -- U-bit set, CMPU
- alu_Action_v := A_CMPU;
- ELSE
- alu_Action_v := A_CMP;
- END IF;
-
- IF (opcIx_v(3) = '0') THEN -- IT, ITT, ITE is not available to CMPI
- CASE IMM16_v(4 downto 3) IS
- WHEN "00" =>
- cmp_Cond_Type_v := COND_TYPE_ALL;
- WHEN "01" =>
- cmp_Cond_Type_v := COND_TYPE_IF_THEN;
- WHEN "10" =>
- cmp_Cond_Type_v := COND_TYPE_IF_THEN_THEN;
- WHEN "11" =>
- cmp_Cond_Type_v := COND_TYPE_IF_THEN_ELSE;
- WHEN OTHERS =>
- NULL;
- END CASE;
-
- CASE IMM16_v(2 downto 0) IS
- WHEN "001" =>
- cmp_Cond_v := COND_EQ;
- WHEN "010" =>
- cmp_Cond_v := COND_NE;
- WHEN "011" =>
- cmp_Cond_v := COND_LT;
- WHEN "100" =>
- cmp_Cond_v := COND_LE;
- WHEN "101" =>
- cmp_Cond_v := COND_GT;
- WHEN "110" =>
- cmp_Cond_v := COND_GE;
- WHEN OTHERS =>
- NULL;
- END CASE;
- END IF;
- ELSE
- noLiteOpc_o <= '1';
- END IF;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
-
- WHEN "10" =>
- IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
- CASE code_x26_v IS
- WHEN "001" | "011" | "101" =>
- CASE code_x26_v(2 DOWNTO 1) IS
- WHEN "00" => -- SRA
- alu_Cin_v := FROM_IN1;
- WHEN "01" => -- SRC
- alu_Cin_v := FROM_MSR;
- WHEN "10" => -- SRL
- alu_Cin_v := CIN_ZERO;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- alu_Action_v := A_SHIFT;
- msr_Action_v := UPDATE_CARRY;
- WHEN "110" => -- SEXT8
- alu_Action_v := A_SEXT8;
- WHEN "111" => -- SEXT16
- alu_Action_v := A_SEXT16;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN -- IMM
- IMM_Lock_v := '1';
- -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
- alu_Action_v := A_NOP;
- wrb_Action_v := NO_WRB;
- ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
- CASE rD_v (3 DOWNTO 0) IS
- WHEN "0001" => -- RTI(D)
- int_busy_v := '0';
- WHEN "0000" => -- RTS(D)
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- alu_Action_v := A_ADD;
- branch_Action_v := BR;
- wrb_Action_v := NO_WRB;
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_v := rD_v(4);
- END IF;
- ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
- CASE IMM16_v IS
- WHEN X"8001" => -- MFS (MSR only)
- alu_Action_v := A_MFS;
- WHEN X"C001" => -- MTS (MSR only)
- alu_Action_v := A_MTS;
- wrb_Action_v := NO_WRB;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- rB_v := (OTHERS => '0'); -- in order to prevent occasional hazards (r16, r24)
- ELSE
- CASE opcIx_v (2 DOWNTO 0) IS
- WHEN "000" =>
- alu_Action_v := A_OR;
- WHEN "001" =>
- alu_Action_v := A_AND;
- WHEN "010" =>
- alu_Action_v := A_XOR;
- WHEN "011" =>
- alu_Action_v := A_AND;
- IF (opcIx_v(3) = '0') THEN
- alu_Op2_v := ALU_IN_NOT_REGB;
- ELSE
- alu_Op2_v := ALU_IN_NOT_IMM;
- END IF;
- WHEN "110" => -- BR(I)(D)
- IF (rA_v(2) = '1') THEN
- branch_Action_v := BRL;
- ELSE
- branch_Action_v := BR;
- wrb_Action_v := NO_WRB;
- END IF;
- IF (rA_v(3) = '1') THEN
- alu_Op1_v := ALU_IN_ZERO;
- ELSE
- alu_Op1_v := ALU_IN_PC;
- END IF;
- alu_Action_v := A_ADD;
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_v := rA_v(4);
- END IF;
- WHEN "111" =>
- CASE rD_v(3 DOWNTO 0) IS
- WHEN "0000" => -- BEQ
- branch_Action_v := BEQ;
- WHEN "0001" => -- BNE
- branch_Action_v := BNE;
- WHEN "0010" => -- BLT
- branch_Action_v := BLT;
- WHEN "0011" => -- BLE
- branch_Action_v := BLE;
- WHEN "0100" => -- BGT
- branch_Action_v := BGT;
- WHEN "0101" => -- BGE
- branch_Action_v := BGE;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- alu_Action_v := A_ADD;
- alu_Op1_v := ALU_IN_PC;
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_v := rD_v(4);
- END IF;
- wrb_Action_v := NO_WRB; -- evaluate and update/overwrite in exeq
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- END IF;
-
- WHEN "11" =>
- IF (opcIx_v (3 DOWNTO 0) = "1111") THEN -- HALT
- alu_Action_v := A_HALT;
- wrb_Action_v := NO_WRB;
- ELSE
- alu_Action_v := A_ADD;
- CASE opcIx_v (1 DOWNTO 0) IS
- WHEN "00" => transfer_Size_v := BYTE;
- WHEN "01" => transfer_Size_v := HALFWORD;
- WHEN "10" => transfer_Size_v := WORD;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- IF (opcIx_v(2) = '0') THEN
- mem_Action_v := RD_MEM;
- wrb_Action_v := WRB_MEM;
- ELSE
- mem_Action_v := WR_MEM;
- wrb_Action_v := NO_WRB;
- END IF;
- END IF;
-
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
-
- END CASE;
-
- END IF; -- interrupt test
-
- ID2GPRF_o.rdix_rA <= rA_v;
- ID2GPRF_o.rdix_rB <= rB_v;
- ID2GPRF_o.rdix_rD <= rD_v;
-
- ID2EX_o.program_counter <= prog_counter_v;
- ID2EX_o.rdix_rA <= rA_v;
- ID2EX_o.rdix_rB <= rB_v;
- ID2EX_o.curr_rD <= rD_v;
- ID2EX_o.alu_Action <= alu_Action_v;
- ID2EX_o.alu_Op1 <= alu_Op1_v;
- ID2EX_o.alu_Op2 <= alu_Op2_v;
- ID2EX_o.alu_Cin <= alu_Cin_v;
- ID2EX_o.IMM16 <= IMM16_v;
- ID2EX_o.IMM_Lock <= IMM_Lock_v;
- ID2EX_o.msr_Action <= msr_Action_v;
- ID2EX_o.branch_Action <= branch_Action_v;
- ID2EX_o.mem_Action <= mem_Action_v;
- ID2EX_o.transfer_Size <= transfer_Size_v;
- ID2EX_o.wrb_Action <= wrb_Action_v;
- --
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- ID2CTRL_o.delayBit <= delayBit_v;
- ELSE
- ID2EX_o.cmp_Cond <= cmp_Cond_v;
- ID2EX_o.cmp_Cond_Type <= cmp_Cond_Type_v;
- END IF;
- ID2CTRL_o.int_busy <= int_busy_v;
-
- END PROCESS;
+ PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
+
+ VARIABLE prog_counter_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE opcIx_v : STD_LOGIC_VECTOR ( 5 DOWNTO 0);
+ VARIABLE instruction_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE rD_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ VARIABLE rA_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ VARIABLE rB_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ VARIABLE IMM16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
+ VARIABLE code_x26_v : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
+ VARIABLE IMM_Lock_v : STD_LOGIC;
+ VARIABLE alu_Action_v : ALU_ACTION_Type;
+ VARIABLE alu_Op1_v : ALU_IN1_Type;
+ VARIABLE alu_Op2_v : ALU_IN2_Type;
+ VARIABLE alu_Cin_v : ALU_CIN_Type;
+ VARIABLE msr_Action_v : MSR_ACTION_Type;
+ VARIABLE branch_Action_v : BRANCH_ACTION_Type;
+ VARIABLE it_Action_v : IT_ACTION_Type;
+ VARIABLE delayBit_v : STD_LOGIC;
+ VARIABLE mem_Action_v : MEM_ACTION_Type;
+ VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
+ VARIABLE wrb_Action_v : WRB_ACTION_Type;
+ VARIABLE int_busy_v : STD_LOGIC;
+ VARIABLE condition_raw_v : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
+ VARIABLE halt_v : STD_LOGIC;
+
+ BEGIN
+
+ prog_counter_v := IF2ID_i.program_counter;
+ instruction_v := imem_data_i;
+ opcIx_v := instruction_v (31 DOWNTO 26);
+ rD_v := instruction_v (25 DOWNTO 21);
+ rA_v := instruction_v (20 DOWNTO 16);
+ rB_v := instruction_v (15 DOWNTO 11);
+ IMM16_v := instruction_v (15 DOWNTO 0);
+ IMM_Lock_v := '0';
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_v := '0';
+ ELSE
+ it_Action_v := NO_IT;
+ END IF;
+ condition_raw_v := (others => '1');
+ alu_Cin_v := CIN_ZERO;
+ alu_Action_v := A_NOP;
+ msr_Action_v := KEEP_CARRY;
+ branch_Action_v := NO_BR;
+ mem_Action_v := NO_MEM;
+ transfer_Size_v := WORD;
+ wrb_Action_v := WRB_EX;
+ halt_v := '0';
+ -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
+ code_x26_v := instruction_v(6) & instruction_v(5) & instruction_v(0);
+ int_busy_v := INT_CTRL_i.int_busy;
+ -- for debugging purposes
+ noLiteOpc_o <= '0';
+
+ IF (INT_CTRL_i.setup_int = '1') THEN
+
+ alu_Op1_v := ALU_IN_ZERO;
+ alu_Op2_v := ALU_IN_IMM;
+ IMM16_v := X"0010"; -- address of _interrupt_handler vector
+ prog_counter_v := INT_CTRL_i.rti_target; -- delayed program counter
+ alu_Action_v := A_ADD;
+ rD_v := "01110"; -- r14 reserved for storing program_counter
+ rA_v := (OTHERS => '0'); -- also set rA and rB to avoid possible ...
+ rB_v := (OTHERS => '0'); -- ... erronuous hazard detection in exeq module
+ int_busy_v := '1';
+ branch_Action_v := BRL;
+
+ ELSE
+
+ alu_Op1_v := ALU_IN_REGA;
+ IF (opcIx_v(3) = '0') THEN
+ alu_Op2_v := ALU_IN_REGB;
+ ELSE
+ alu_Op2_v := ALU_IN_IMM;
+ END IF;
+
+ CASE opcIx_v (5 DOWNTO 4) IS
+
+ WHEN "00" => -- ADD / RSUB
+ IF (opcIx_v(0) = '1') THEN -- RSUB
+ alu_Op1_v := ALU_IN_NOT_REGA;
+ END IF;
+ IF (opcIx_v(1) = '0') THEN -- xxx
+ IF (opcIx_v(0) = '0') THEN
+ alu_Cin_v := CIN_ZERO;
+ ELSE
+ alu_Cin_v := CIN_ONE;
+ END IF;
+ ELSE -- xxxC
+ alu_Cin_v := FROM_MSR;
+ END IF;
+ IF ((COMPATIBILITY_MODE_g = TRUE) AND (opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
+ -- special CMP(U) and not RSUB(I)K, supported only in compatibility mode
+ IF (IMM16_v(1) = '1') THEN -- U-bit set, CMPU
+ alu_Action_v := A_CMPU;
+ ELSE
+ alu_Action_v := A_CMP;
+ END IF;
+ ELSE
+ alu_Action_v := A_ADD;
+ IF (opcIx_v(2) = '0') THEN
+ msr_Action_v := UPDATE_CARRY;
+ END IF;
+ END IF;
+
+ WHEN "01" => -- MUL / BS
+
+ CASE opcIx_v (2 DOWNTO 0) IS
+ WHEN "000" => -- MUL
+ IF (USE_HW_MUL_g = TRUE) THEN
+ alu_Action_v := A_MUL;
+ ELSE
+ noLiteOpc_o <= '1';
+ END IF;
+
+ WHEN "001" => -- BS
+ IF (USE_BARREL_g = TRUE) THEN
+ IF (instruction_v(10) = '1') THEN
+ alu_Action_v := A_BSLL;
+ ELSIF (instruction_v(9) = '1') THEN
+ alu_Action_v := A_BSRA;
+ ELSE
+ alu_Action_v := A_BSRL;
+ END IF;
+ ELSE
+ noLiteOpc_o <= '1';
+ END IF;
+
+ WHEN "010" | "011" => -- CMP(U)
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ IF (opcIx_v(0) = '1') THEN
+ alu_Action_v := A_CMPU;
+ ELSE
+ alu_Action_v := A_CMP;
+ END IF;
+ ELSE
+ noLiteOpc_o <= '1';
+ END IF;
+
+ WHEN "100" | "101" => -- IT(U) / ITT(U) / ITE(U)
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ IF (opcIx_v(0) = '1') THEN
+ alu_Action_v := A_CMPU;
+ ELSE
+ alu_Action_v := A_CMP;
+ END IF;
+
+ CASE rD_v(4 downto 3) IS
+ WHEN "00" =>
+ it_Action_v := IT;
+ WHEN "01" =>
+ it_Action_v := ITT;
+ WHEN "10" =>
+ it_Action_v := ITE;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ condition_raw_v := rD_v(2 downto 0);
+ -- IT instruction isn't writing to anything
+ wrb_Action_v := NO_WRB;
+ ELSE
+ noLiteOpc_o <= '1';
+ END IF;
+
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+
+ WHEN "10" =>
+ IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
+ CASE code_x26_v IS
+
+ WHEN "001" | "011" | "101" =>
+ CASE code_x26_v(2 DOWNTO 1) IS
+ WHEN "00" => -- SRA
+ alu_Cin_v := FROM_IN1;
+ WHEN "01" => -- SRC
+ alu_Cin_v := FROM_MSR;
+ WHEN "10" => -- SRL
+ alu_Cin_v := CIN_ZERO;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ alu_Action_v := A_SHIFT;
+ msr_Action_v := UPDATE_CARRY;
+
+ WHEN "110" => -- SEXT8
+ alu_Action_v := A_SEXT8;
+ WHEN "111" => -- SEXT16
+ alu_Action_v := A_SEXT16;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+
+ ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN -- IMM
+ IMM_Lock_v := '1';
+ -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
+ alu_Action_v := A_NOP;
+ wrb_Action_v := NO_WRB;
+ ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
+
+ CASE rD_v (3 DOWNTO 0) IS
+ WHEN "0001" => -- RTI(D)
+ int_busy_v := '0';
+ WHEN "0000" => -- RTS(D)
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+
+ alu_Action_v := A_ADD;
+ branch_Action_v := BR;
+ wrb_Action_v := NO_WRB;
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_v := rD_v(4);
+ END IF;
+
+ ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
+
+ CASE IMM16_v IS
+ WHEN X"8001" => -- MFS (MSR only)
+ alu_Action_v := A_MFS;
+ WHEN X"C001" => -- MTS (MSR only)
+ alu_Action_v := A_MTS;
+ wrb_Action_v := NO_WRB;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ rB_v := (OTHERS => '0'); -- in order to prevent occasional hazards (r16, r24)
+
+ ELSE
+
+ CASE opcIx_v (2 DOWNTO 0) IS
+ WHEN "000" =>
+ alu_Action_v := A_OR;
+ WHEN "001" =>
+ alu_Action_v := A_AND;
+ WHEN "010" =>
+ alu_Action_v := A_XOR;
+ WHEN "011" =>
+ alu_Action_v := A_AND;
+ IF (opcIx_v(3) = '0') THEN
+ alu_Op2_v := ALU_IN_NOT_REGB;
+ ELSE
+ alu_Op2_v := ALU_IN_NOT_IMM;
+ END IF;
+
+ WHEN "110" => -- BR(I)(D)
+ IF (rA_v(2) = '1') THEN
+ branch_Action_v := BRL;
+ ELSE
+ branch_Action_v := BR;
+ wrb_Action_v := NO_WRB;
+ END IF;
+
+ IF (rA_v(3) = '1') THEN
+ alu_Op1_v := ALU_IN_ZERO;
+ ELSE
+ alu_Op1_v := ALU_IN_PC;
+ END IF;
+ alu_Action_v := A_ADD;
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_v := rA_v(4);
+ END IF;
+
+ WHEN "111" =>
+ condition_raw_v := rD_v(2 downto 0); -- Conditional branching
+ branch_Action_v := BR;
+ alu_Action_v := A_ADD;
+ alu_Op1_v := ALU_IN_PC;
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_v := rD_v(4);
+ END IF;
+ wrb_Action_v := NO_WRB; -- evaluate and update/overwrite in exeq
+
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ END IF;
+
+ WHEN "11" =>
+ IF (opcIx_v (3 DOWNTO 0) = "1111") THEN -- HALT
+ alu_Action_v := A_NOP;
+ wrb_Action_v := NO_WRB;
+ halt_v := '1';
+ ELSE
+ alu_Action_v := A_ADD;
+ CASE opcIx_v (1 DOWNTO 0) IS
+ WHEN "00" => transfer_Size_v := BYTE;
+ WHEN "01" => transfer_Size_v := HALFWORD;
+ WHEN "10" => transfer_Size_v := WORD;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ IF (opcIx_v(2) = '0') THEN
+ mem_Action_v := RD_MEM;
+ wrb_Action_v := WRB_MEM;
+ ELSE
+ mem_Action_v := WR_MEM;
+ wrb_Action_v := NO_WRB;
+ END IF;
+ END IF;
+
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+
+ END CASE;
+
+ END IF; -- interrupt test
+
+ ID2GPRF_o.rdix_rA <= rA_v;
+ ID2GPRF_o.rdix_rB <= rB_v;
+ ID2GPRF_o.rdix_rD <= rD_v;
+
+ ID2EX_o.program_counter <= prog_counter_v;
+ ID2EX_o.rdix_rA <= rA_v;
+ ID2EX_o.rdix_rB <= rB_v;
+ ID2EX_o.curr_rD <= rD_v;
+ ID2EX_o.alu_Action <= alu_Action_v;
+ ID2EX_o.alu_Op1 <= alu_Op1_v;
+ ID2EX_o.alu_Op2 <= alu_Op2_v;
+ ID2EX_o.alu_Cin <= alu_Cin_v;
+ ID2EX_o.IMM16 <= IMM16_v;
+ ID2EX_o.IMM_Lock <= IMM_Lock_v;
+ ID2EX_o.msr_Action <= msr_Action_v;
+ ID2EX_o.branch_Action <= branch_Action_v;
+ ID2EX_o.it_Action <= it_Action_v;
+ ID2EX_o.mem_Action <= mem_Action_v;
+ ID2EX_o.transfer_Size <= transfer_Size_v;
+ ID2EX_o.wrb_Action <= wrb_Action_v;
+ ID2EX_o.halt <= halt_v;
+ --
+ CASE condition_raw_v IS
+ WHEN "000" =>
+ ID2EX_o.condition <= COND_EQ;
+ WHEN "001" =>
+ ID2EX_o.condition <= COND_NE;
+ WHEN "010" =>
+ ID2EX_o.condition <= COND_LT;
+ WHEN "011" =>
+ ID2EX_o.condition <= COND_LE;
+ WHEN "100" =>
+ ID2EX_o.condition <= COND_GT;
+ WHEN "101" =>
+ ID2EX_o.condition <= COND_GE;
+ WHEN "111" =>
+ ID2EX_o.condition <= COND_ALL;
+ WHEN OTHERS =>
+ ID2EX_o.condition <= COND_ALL;
+ noLiteOpc_o <= '1';
+ END CASE;
+ --
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ ID2CTRL_o.delayBit <= delayBit_v;
+ END IF;
+ ID2CTRL_o.int_busy <= int_busy_v;
+
+ END PROCESS;
END ARCHITECTURE rtl;
-- Faculty EEMCS, Department ME&CE, Circuits and Systems
-- Date: September, 2010
--
--- Modified: Septemper, 2013: FSL scratched (Meloun)
+-- Modified: Septemper, 2013: FSL scratched, core customized (Meloun)
-- December, 2010: FSL added (Huib)
-- June, 2011: added code for MUL and BARREL (Huib)
-- Adapted to work with separate fsl_M-
----------------------------------------------------------
ENTITY exeq IS
----------------------------------------------------------
- GENERIC (
- USE_HW_MUL_g : BOOLEAN := TRUE;
- USE_BARREL_g : BOOLEAN := TRUE;
- COMPATIBILITY_MODE_g : BOOLEAN := FALSE
- );
- PORT (
- ID2EX_i : IN ID2EX_Type;
- GPRF2EX_i : IN GPRF2EX_Type;
- EX2IF_o : OUT EX2IF_Type;
- EX2CTRL_o : OUT EX2CTRL_Type;
- HALT_o : OUT HALT_Type;
- --
- EX_WRB_i : IN WRB_Type;
- EX_WRB_o : OUT WRB_Type;
- MEM_WRB_i : IN WRB_Type;
- --
- HAZARD_WRB_i : IN HAZARD_WRB_Type;
- HAZARD_WRB_o : OUT HAZARD_WRB_Type;
- --
- IMM_LOCK_i : IN IMM_LOCK_Type;
- IMM_LOCK_o : OUT IMM_LOCK_Type;
- --
- MSR_i : IN MSR_Type;
- MSR_o : OUT MSR_Type;
- --
- EX2MEM_o : OUT EX2MEM_Type
- );
+ GENERIC
+ (
+ USE_HW_MUL_g : BOOLEAN := TRUE;
+ USE_BARREL_g : BOOLEAN := TRUE;
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+ );
+ PORT
+ (
+ ID2EX_i : IN ID2EX_Type;
+ GPRF2EX_i : IN GPRF2EX_Type;
+ EX2IF_o : OUT EX2IF_Type;
+ EX2CTRL_o : OUT EX2CTRL_Type;
+ HALT_o : OUT HALT_Type;
+ --
+ EX_WRB_i : IN WRB_Type;
+ EX_WRB_o : OUT WRB_Type;
+ MEM_WRB_i : IN WRB_Type;
+ --
+ HAZARD_WRB_i : IN HAZARD_WRB_Type;
+ HAZARD_WRB_o : OUT HAZARD_WRB_Type;
+ --
+ IMM_LOCK_i : IN IMM_LOCK_Type;
+ IMM_LOCK_o : OUT IMM_LOCK_Type;
+ --
+ MSR_i : IN MSR_Type;
+ MSR_o : OUT MSR_Type;
+ --
+ EX2MEM_o : OUT EX2MEM_Type
+ );
END ENTITY exeq;
-
----------------------------------------------------------
ARCHITECTURE rtl OF exeq IS
----------------------------------------------------------
BEGIN
p_exeq:
- PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
- IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
-
- -- function needed by BSLL (only if USE_BARREL_g = TRUE)
- FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
- RETURN STD_LOGIC_VECTOR IS
- VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- BEGIN
- f_rev:
- FOR i IN 0 TO 31 LOOP
- reversed_v(31-i) := word32(i);
- END LOOP;
- RETURN reversed_v;
- END;
-
- VARIABLE data_rA_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE data_rB_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE data_rD_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE in1_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE in2_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE hi16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
- VARIABLE IMM32_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE carry_i_v : STD_LOGIC;
- VARIABLE result_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE carry_o_v : STD_LOGIC;
- VARIABLE isZero_v : STD_LOGIC;
- VARIABLE cmpResZero_v : STD_LOGIC;
- VARIABLE signBit_in1_v : STD_LOGIC;
- VARIABLE signBit_in2_v : STD_LOGIC;
- VARIABLE signBit_rA_v : STD_LOGIC;
- VARIABLE signBit_rD_v : STD_LOGIC;
- VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
- VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
- VARIABLE hazard_v : STD_LOGIC;
- VARIABLE save_rX_v : SAVE_REG_Type;
- VARIABLE data_rX_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE do_branch_v : STD_LOGIC;
- VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
- VARIABLE tmp64_v : STD_LOGIC_VECTOR (63 DOWNTO 0);
- VARIABLE padVec_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
- VARIABLE halt_v : STD_LOGIC;
- VARIABLE halt_code_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- VARIABLE do_cmp_cond_v : STD_LOGIC;
- VARIABLE cmp_cond_type_v : CMP_COND_TYPE_Type;
-
- BEGIN
-
- rA_eq_ex_rD_v := '0';
- rB_eq_ex_rD_v := '0';
- hazard_v := '0';
- save_rX_v := NO_SAVE;
- data_rX_v := data_rB_v; -- default value for data_rX_v
- result_v := (OTHERS => '0');
- carry_o_v := '0';
- do_branch_v := '0';
- byte_Enable_v := "0000";
- halt_v := '0';
- halt_code_v := "00000";
- do_cmp_cond_v := '0';
- cmp_cond_type_v := COND_TYPE_ALL;
- signBit_rD_v := '0';
-
- -- create some helper variables
- IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
- rA_eq_ex_rD_v := '1';
- END IF;
- IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
- rB_eq_ex_rD_v := '1';
- END IF;
- -- test where to obtain data_rA from
- IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
- data_rA_v := EX_WRB_i.data_rD;
- ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
- data_rA_v := MEM_WRB_i.data_rD;
- ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
- data_rA_v := HAZARD_WRB_i.data_rX;
- ELSE
- data_rA_v := GPRF2EX_i.data_rA;
- END IF;
- -- test where to obtain data_rB from
- IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
- data_rB_v := EX_WRB_i.data_rD;
- ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
- data_rB_v := MEM_WRB_i.data_rD;
- ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
- data_rB_v := HAZARD_WRB_i.data_rX;
- ELSE
- data_rB_v := GPRF2EX_i.data_rB;
- END IF;
- -- .... or, isn't all necessary data available yet being still in the pipeline ?
- data_rX_v := data_rB_v; -- default value for data_rX_v
- IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
- IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
- hazard_v := '1';
--- always?? IF (MEM_WRB_i.wrb_Action = WRB_MEM) THEN
- -- handle situations in which both rA and rB needed
- IF (rA_eq_ex_rD_v = '1') THEN
- save_rX_v := SAVE_RB; -- already by default data_rX_v = data_rB_v
- ELSE
- save_rX_v := SAVE_RA;
- data_rX_v := data_rA_v;
- END IF;
--- END IF;
- END IF;
- END IF;
-
- IF (IMM_LOCK_i.locked = '1') THEN
- hi16_v := IMM_LOCK_i.IMM_hi16;
- ELSIF (ID2EX_i.IMM16(15) = '0') THEN
- hi16_v := C_16_ZEROS;
- ELSE
- hi16_v := C_16_ONES;
- END IF;
- IMM32_v := hi16_v & ID2EX_i.IMM16;
-
- CASE ID2EX_i.alu_Op1 IS
- WHEN ALU_IN_REGA => in1_v := data_rA_v;
- WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v;
- WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter;
- WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS;
- WHEN OTHERS => NULL;
- END CASE;
-
- CASE ID2EX_i.alu_Op2 IS
- WHEN ALU_IN_REGB => in2_v := data_rB_v;
- WHEN ALU_IN_NOT_REGB => in2_v := NOT data_rB_v;
- WHEN ALU_IN_IMM => in2_v := IMM32_v;
- WHEN ALU_IN_NOT_IMM => in2_v := NOT IMM32_v;
- WHEN OTHERS => NULL;
- END CASE;
-
- signBit_in1_v := in1_v(31);
- signBit_in2_v := in2_v(31);
- signBit_rA_v := data_rA_v(31);
-
- CASE ID2EX_i.alu_Cin IS
- WHEN CIN_ZERO => carry_i_v := '0';
- WHEN CIN_ONE => carry_i_v := '1';
- WHEN FROM_MSR => carry_i_v := MSR_i.C;
- WHEN FROM_IN1 => carry_i_v := in1_v(31);
- WHEN OTHERS => carry_i_v := '0';
- END CASE;
-
- IF (data_rA_v = C_32_ZEROS) THEN
- isZero_v := '1';
- ELSE
- isZero_v := '0';
- END IF;
-
- CASE ID2EX_i.alu_Action IS
- WHEN A_ADD | A_CMP | A_CMPU =>
- ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
- IF (id2ex_i.alu_Action = A_CMPU) THEN
- IF (signBit_in1_v = signBit_in2_v) THEN
- signBit_rD_v := NOT signBit_in1_v;
- END IF;
- ELSIF (id2ex_i.alu_Action = A_CMP) THEN
- IF (signBit_in1_v = signBit_in2_v) THEN
- signBit_rD_v := signBit_in1_v;
- END IF;
- END IF;
-
- result_v(31) := signBit_rD_v;
-
- IF (COMPATIBILITY_MODE_g = FALSE) THEN
- IF (ID2EX_i.cmp_Cond /= COND_ALL) THEN
- IF (result_v = C_32_ZEROS) THEN
- cmpResZero_v := '1';
- ELSE
- cmpResZero_v := '0';
- END IF;
-
- CASE ID2EX_i.cmp_Cond IS
- WHEN COND_EQ => do_cmp_cond_v := cmpResZero_v;
- WHEN COND_NE => do_cmp_cond_v := NOT cmpResZero_v;
- WHEN COND_LT => do_cmp_cond_v := signBit_rD_v;
- WHEN COND_LE => do_cmp_cond_v := signBit_rD_v OR cmpResZero_v;
- WHEN COND_GT => do_cmp_cond_v := NOT (signBit_rD_v OR cmpResZero_v);
- WHEN COND_GE => do_cmp_cond_v := NOT signBit_rD_v;
- WHEN OTHERS => NULL;
- END CASE;
-
- cmp_cond_type_v := ID2EX_i.cmp_Cond_Type;
- END IF;
- END IF;
-
- WHEN A_OR =>
- result_v := in1_v OR in2_v;
- WHEN A_AND =>
- result_v := in1_v AND in2_v;
- WHEN A_XOR =>
- result_v := in1_v XOR in2_v;
- WHEN A_SHIFT =>
- result_v := carry_i_v & in1_v(31 DOWNTO 1);
- carry_o_v := in1_v(0);
- WHEN A_SEXT8 =>
- IF (in1_v(7) = '0') THEN
- result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
- ELSE
- result_v := C_24_ONES & in1_v( 7 DOWNTO 0);
- END IF;
- WHEN A_SEXT16 =>
- IF (in1_v(15) = '0') THEN
- result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
- ELSE
- result_v := C_16_ONES & in1_v(15 DOWNTO 0);
- END IF;
- WHEN A_MFS =>
- result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
- WHEN A_MTS =>
- MSR_o.IE <= data_Ra_v(1);
- MSR_o.C <= data_Ra_v(2);
- WHEN A_MUL =>
- IF (USE_HW_MUL_g = TRUE) THEN
- tmp64_v := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
- result_v := tmp64_v(31 DOWNTO 0);
- END IF;
- WHEN A_BSLL | A_BSRL | A_BSRA =>
- IF (USE_BARREL_g = TRUE) THEN
- IF (ID2EX_i.alu_Action = A_BSLL) THEN
- result_v := reverse_bits (in1_v);
- ELSE
- result_v := in1_v;
- END IF;
- IF (ID2EX_i.alu_Action = A_BSRA) THEN
- padVec_v := (OTHERS => in1_v(31));
- ELSE
- padVec_v := (OTHERS => '0');
- END IF;
- IF (in2_v(4) = '1') THEN
- result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
- END IF;
- IF (in2_v(3) = '1') THEN
- result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO 8);
- END IF;
- IF (in2_v(2) = '1') THEN
- result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO 4);
- END IF;
- IF (in2_v(1) = '1') THEN
- result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO 2);
- END IF;
- IF (in2_v(0) = '1') THEN
- result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO 1);
- END IF;
- IF (ID2EX_i.alu_Action = A_BSLL) THEN
- result_v := reverse_bits (result_v);
- END IF;
- END IF; -- (USE_BARREL_g = TRUE)
- WHEN A_HALT =>
- halt_v := '1';
- halt_code_v := ID2EX_i.IMM16(4 DOWNTO 0);
- WHEN OTHERS =>
- NULL;
- END CASE;
-
- CASE ID2EX_i.branch_Action IS
- WHEN BR => do_branch_v := '1';
- WHEN BRL => do_branch_v := '1';
- WHEN BEQ => do_branch_v := isZero_v;
- WHEN BNE => do_branch_v := NOT isZero_v;
- WHEN BLT => do_branch_v := signBit_rA_v;
- WHEN BLE => do_branch_v := signBit_rA_v OR isZero_v;
- WHEN BGT => do_branch_v := NOT (signBit_rA_v OR isZero_v);
- WHEN BGE => do_branch_v := NOT signBit_rA_v;
- WHEN OTHERS => NULL;
- END CASE;
- IF (do_branch_v = '1') THEN
- EX2IF_o.take_branch <= '1';
- EX2IF_o.branch_target <= result_v;
- ELSE
- EX2IF_o.take_branch <= '0';
- EX2IF_o.branch_target <= C_32_ZEROS;
- END IF;
-
- -- CMP conditioning
- IF (COMPATIBILITY_MODE_g = FALSE) THEN
- CASE cmp_cond_type_v IS
- WHEN COND_TYPE_ALL =>
- EX2CTRL_o.flush_first <= '0';
- EX2CTRL_o.flush_second <= '0';
- WHEN COND_TYPE_IF_THEN =>
- EX2CTRL_o.flush_first <= not do_cmp_cond_v;
- EX2CTRL_o.flush_second <= '0';
- WHEN COND_TYPE_IF_THEN_THEN =>
- EX2CTRL_o.flush_first <= not do_cmp_cond_v;
- EX2CTRL_o.flush_second <= not do_cmp_cond_v;
- WHEN COND_TYPE_IF_THEN_ELSE =>
- EX2CTRL_o.flush_first <= not do_cmp_cond_v;
- EX2CTRL_o.flush_second <= do_cmp_cond_v;
- WHEN OTHERS =>
- NULL;
- END CASE;
- END IF;
-
- -- Halting
- HALT_o.halt <= halt_v;
- HALT_o.halt_code <= halt_code_v;
-
- -- WR_MEM/RD_MEM: result_v --> exeq_result --> mem_address,
- -- WR_MEM: data_rD --> data_out_to_mem
- -- BRL: prog_counter --> exeq_result
- -- else result_v --> exeq_result (data_rD not used)
- EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
- IF (ID2EX_i.branch_Action = BRL) THEN
- EX2MEM_o.wrb_Action <= WRB_EX;
- EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
- EX2MEM_o.data_rD <= ID2EX_i.program_counter;
- -- set data_rD_v, although unused, to prevent an inferred latch
- data_rD_v := GPRF2EX_i.data_rD;
- ELSE
- EX2MEM_o.wrb_Action <= ID2EX_i.wrb_Action;
- EX2MEM_o.exeq_result <= result_v;
- -- test where to obtain data_rD from
- IF (HAZARD_WRB_i.hazard = '1') THEN
- data_rD_v := HAZARD_WRB_i.data_rD;
- ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
- -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
- data_rD_v := EX_WRB_i.data_rD;
- ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
- data_rD_v := MEM_WRB_i.data_rD;
- ELSE
- data_rD_v := GPRF2EX_i.data_rD;
- END IF;
- END IF;
- IF (ID2EX_i.mem_Action /= NO_MEM) THEN
- CASE ID2EX_i.transfer_Size IS
- WHEN BYTE =>
- CASE result_v( 1 DOWNTO 0) IS
- WHEN "00" => byte_Enable_v := "1000";
- WHEN "01" => byte_Enable_v := "0100";
- WHEN "10" => byte_Enable_v := "0010";
- WHEN "11" => byte_Enable_v := "0001";
- WHEN OTHERS => NULL;
- END CASE;
- WHEN HALFWORD =>
- CASE result_v( 1 DOWNTO 0) IS
- WHEN "00" => byte_Enable_v := "1100";
- WHEN "10" => byte_Enable_v := "0011";
- WHEN OTHERS => NULL;
- END CASE;
- WHEN OTHERS => byte_Enable_v := "1111";
- END CASE;
- END IF;
-
- -- update MSR[IE] and/or MSR[C] if needed
- IF (ID2EX_i.alu_Action /= A_MTS) THEN
- MSR_o.IE <= MSR_i.IE;
- IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
- MSR_o.C <= carry_o_v;
- ELSE
- MSR_o.C <= MSR_i.C;
- END IF;
- END IF;
-
- -- pass remaining data to mem
- EX2MEM_o.mem_Action <= ID2EX_i.mem_Action;
- EX2MEM_o.data_rD <= data_rD_v;
- EX2MEM_o.byte_Enable <= byte_Enable_v;
- EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
- --
- IMM_LOCK_o.locked <= ID2EX_i.IMM_Lock;
- IMM_LOCK_o.IMM_hi16 <= ID2EX_i.IMM16;
- --
- EX_WRB_o.wrb_Action <= ID2EX_i.wrb_Action;
- EX_WRB_o.wrix_rD <= ID2EX_i.curr_rD;
- EX_WRB_o.data_rD <= result_v;
- --
- HAZARD_WRB_o.hazard <= hazard_v;
- HAZARD_WRB_o.save_rX <= save_rX_v;
- HAZARD_WRB_o.data_rX <= data_rX_v;
- HAZARD_WRB_o.data_rD <= data_rD_v;
-
- END PROCESS;
+ PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i,
+ IMM_LOCK_i, MSR_i, HAZARD_WRB_i)
+
+ -- function needed by BSLL (only if USE_BARREL_g = TRUE)
+ FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) )
+ RETURN STD_LOGIC_VECTOR IS
+ VARIABLE reversed_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ BEGIN
+ f_rev:
+ FOR i IN 0 TO 31 LOOP
+ reversed_v(31-i) := word32(i);
+ END LOOP;
+ RETURN reversed_v;
+ END;
+
+ VARIABLE data_rA_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE data_rB_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE data_rD_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE in1_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE in2_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE hi16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
+ VARIABLE IMM32_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE carry_i_v : STD_LOGIC;
+ VARIABLE result_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE carry_o_v : STD_LOGIC;
+ VARIABLE isZero_v : STD_LOGIC;
+ VARIABLE signBit_in1_v : STD_LOGIC;
+ VARIABLE signBit_in2_v : STD_LOGIC;
+ VARIABLE signBit_r_v : STD_LOGIC;
+ VARIABLE rA_eq_ex_rD_v : STD_LOGIC;
+ VARIABLE rB_eq_ex_rD_v : STD_LOGIC;
+ VARIABLE hazard_v : STD_LOGIC;
+ VARIABLE save_rX_v : SAVE_REG_Type;
+ VARIABLE data_rX_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE do_branch_v : STD_LOGIC;
+ VARIABLE byte_Enable_v : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+ VARIABLE tmp64_v : STD_LOGIC_VECTOR (63 DOWNTO 0);
+ VARIABLE padVec_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
+ VARIABLE do_cond_v : STD_LOGIC;
+
+ BEGIN
+
+ rA_eq_ex_rD_v := '0';
+ rB_eq_ex_rD_v := '0';
+ hazard_v := '0';
+ save_rX_v := NO_SAVE;
+ data_rX_v := data_rB_v; -- default value for data_rX_v
+ result_v := (OTHERS => '0');
+ carry_o_v := '0';
+ do_branch_v := '0';
+ byte_Enable_v := (OTHERS => '0');
+ do_cond_v := '0';
+ --
+ MSR_o <= MSR_i; -- pass MSR by default
+
+ -- create some helper variables
+ IF (ID2EX_i.rdix_rA = EX_WRB_i.wrix_rD) THEN
+ rA_eq_ex_rD_v := '1';
+ END IF;
+ IF (ID2EX_i.rdix_rB = EX_WRB_i.wrix_rD) THEN
+ rB_eq_ex_rD_v := '1';
+ END IF;
+ -- test where to obtain data_rA from
+ IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rA_eq_ex_rD_v = '1')) THEN
+ data_rA_v := EX_WRB_i.data_rD;
+ ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rA = MEM_WRB_i.wrix_rD)) THEN
+ data_rA_v := MEM_WRB_i.data_rD;
+ ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RA)) THEN
+ data_rA_v := HAZARD_WRB_i.data_rX;
+ ELSE
+ data_rA_v := GPRF2EX_i.data_rA;
+ END IF;
+ -- test where to obtain data_rB from
+ IF ((EX_WRB_i.wrb_Action = WRB_EX) AND (rB_eq_ex_rD_v = '1')) THEN
+ data_rB_v := EX_WRB_i.data_rD;
+ ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.rdix_rB = MEM_WRB_i.wrix_rD)) THEN
+ data_rB_v := MEM_WRB_i.data_rD;
+ ELSIF ((HAZARD_WRB_i.hazard = '1') AND (HAZARD_WRB_i.save_rX = SAVE_RB)) THEN
+ data_rB_v := HAZARD_WRB_i.data_rX;
+ ELSE
+ data_rB_v := GPRF2EX_i.data_rB;
+ END IF;
+ -- .... or, isn't all necessary data available yet being still in the pipeline ?
+ data_rX_v := data_rB_v; -- default value for data_rX_v
+ IF (EX_WRB_i.wrb_Action = WRB_MEM) THEN
+ IF ((rA_eq_ex_rD_v = '1') OR (rB_eq_ex_rD_v = '1')) THEN
+ hazard_v := '1';
+ IF (rA_eq_ex_rD_v = '1') THEN
+ save_rX_v := SAVE_RB; -- already by default data_rX_v = data_rB_v
+ ELSE
+ save_rX_v := SAVE_RA;
+ data_rX_v := data_rA_v;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (IMM_LOCK_i.locked = '1') THEN
+ hi16_v := IMM_LOCK_i.IMM_hi16;
+ ELSIF (ID2EX_i.IMM16(15) = '0') THEN
+ hi16_v := C_16_ZEROS;
+ ELSE
+ hi16_v := C_16_ONES;
+ END IF;
+ IMM32_v := hi16_v & ID2EX_i.IMM16;
+
+ CASE ID2EX_i.alu_Op1 IS
+ WHEN ALU_IN_REGA => in1_v := data_rA_v;
+ WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v;
+ WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter;
+ WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS;
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ CASE ID2EX_i.alu_Op2 IS
+ WHEN ALU_IN_REGB => in2_v := data_rB_v;
+ WHEN ALU_IN_NOT_REGB => in2_v := NOT data_rB_v;
+ WHEN ALU_IN_IMM => in2_v := IMM32_v;
+ WHEN ALU_IN_NOT_IMM => in2_v := NOT IMM32_v;
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ signBit_in1_v := in1_v(31);
+ signBit_in2_v := in2_v(31);
+ signBit_r_v := data_rA_v(31); -- Init with Op1, then possibly override
+
+ CASE ID2EX_i.alu_Cin IS
+ WHEN CIN_ZERO => carry_i_v := '0';
+ WHEN CIN_ONE => carry_i_v := '1';
+ WHEN FROM_MSR => carry_i_v := MSR_i.C;
+ WHEN FROM_IN1 => carry_i_v := in1_v(31);
+ WHEN OTHERS => carry_i_v := '0';
+ END CASE;
+
+ IF (data_rA_v = C_32_ZEROS) THEN
+ isZero_v := '1';
+ ELSE
+ isZero_v := '0';
+ END IF;
+
+ CASE ID2EX_i.alu_Action IS
+
+ WHEN A_ADD | A_CMP | A_CMPU =>
+ ep_add32 ( in1_v, in2_v, carry_i_v, result_v, carry_o_v);
+ CASE ID2EX_i.alu_Action IS
+
+ WHEN A_CMPU =>
+ IF (signBit_in1_v = signBit_in2_v) THEN
+ signBit_r_v := NOT signBit_in1_v;
+ END IF;
+ IF (COMPATIBILITY_MODE_g = FALSE) AND (ID2EX_i.it_Action /= NO_IT) THEN
+ -- have to update zero flag with current result
+ IF (result_v = C_32_ZEROS) THEN
+ isZero_v := '1';
+ ELSE
+ isZero_v := '0';
+ END IF;
+ END IF;
+
+ WHEN A_CMP =>
+ IF (signBit_in1_v = signBit_in2_v) THEN
+ signBit_r_v := signBit_in1_v;
+ END IF;
+ IF (COMPATIBILITY_MODE_g = FALSE) AND (ID2EX_i.it_Action /= NO_IT) THEN
+ -- have to update zero flag with current result
+ IF (result_v = C_32_ZEROS) THEN
+ isZero_v := '1';
+ ELSE
+ isZero_v := '0';
+ END IF;
+ END IF;
+
+ WHEN OTHERS =>
+ NULL;
+
+ END CASE;
+
+ WHEN A_OR =>
+ result_v := in1_v OR in2_v;
+
+ WHEN A_AND =>
+ result_v := in1_v AND in2_v;
+
+ WHEN A_XOR =>
+ result_v := in1_v XOR in2_v;
+
+ WHEN A_SHIFT =>
+ result_v := carry_i_v & in1_v(31 DOWNTO 1);
+ carry_o_v := in1_v(0);
+
+ WHEN A_SEXT8 =>
+ IF (in1_v(7) = '0') THEN
+ result_v := C_24_ZEROS & in1_v( 7 DOWNTO 0);
+ ELSE
+ result_v := C_24_ONES & in1_v( 7 DOWNTO 0);
+ END IF;
+
+ WHEN A_SEXT16 =>
+ IF (in1_v(15) = '0') THEN
+ result_v := C_16_ZEROS & in1_v(15 DOWNTO 0);
+ ELSE
+ result_v := C_16_ONES & in1_v(15 DOWNTO 0);
+ END IF;
+
+ WHEN A_MFS =>
+ result_v := MSR_i.C & C_24_ZEROS & "0000" & MSR_i.C & MSR_i.IE & '0';
+
+ WHEN A_MTS =>
+ MSR_o.IE <= data_Ra_v(1);
+ MSR_o.C <= data_Ra_v(2);
+
+ WHEN A_MUL =>
+ IF (USE_HW_MUL_g = TRUE) THEN
+ tmp64_v := STD_LOGIC_VECTOR( UNSIGNED(in1_v) * UNSIGNED(in2_v) );
+ result_v := tmp64_v(31 DOWNTO 0);
+ END IF;
+
+ WHEN A_BSLL | A_BSRL | A_BSRA =>
+ IF (USE_BARREL_g = TRUE) THEN
+ IF (ID2EX_i.alu_Action = A_BSLL) THEN
+ result_v := reverse_bits (in1_v);
+ ELSE
+ result_v := in1_v;
+ END IF;
+ IF (ID2EX_i.alu_Action = A_BSRA) THEN
+ padVec_v := (OTHERS => in1_v(31));
+ ELSE
+ padVec_v := (OTHERS => '0');
+ END IF;
+ IF (in2_v(4) = '1') THEN
+ result_v := padVec_v (15 DOWNTO 0) & result_v (31 DOWNTO 16);
+ END IF;
+ IF (in2_v(3) = '1') THEN
+ result_v := padVec_v ( 7 DOWNTO 0) & result_v (31 DOWNTO 8);
+ END IF;
+ IF (in2_v(2) = '1') THEN
+ result_v := padVec_v ( 3 DOWNTO 0) & result_v (31 DOWNTO 4);
+ END IF;
+ IF (in2_v(1) = '1') THEN
+ result_v := padVec_v ( 1 DOWNTO 0) & result_v (31 DOWNTO 2);
+ END IF;
+ IF (in2_v(0) = '1') THEN
+ result_v := padVec_v ( 0 DOWNTO 0) & result_v (31 DOWNTO 1);
+ END IF;
+ IF (ID2EX_i.alu_Action = A_BSLL) THEN
+ result_v := reverse_bits (result_v);
+ END IF;
+ END IF; -- (USE_BARREL_g = TRUE)
+
+ WHEN OTHERS =>
+ NULL;
+
+ END CASE;
+
+ CASE ID2EX_i.condition IS
+ WHEN COND_EQ => do_cond_v := isZero_v;
+ WHEN COND_NE => do_cond_v := NOT isZero_v;
+ WHEN COND_LT => do_cond_v := signBit_r_v;
+ WHEN COND_LE => do_cond_v := signBit_r_v OR isZero_v;
+ WHEN COND_GT => do_cond_v := NOT (signBit_r_v OR isZero_v);
+ WHEN COND_GE => do_cond_v := NOT signBit_r_v;
+ WHEN COND_ALL => do_cond_v := '1';
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ CASE ID2EX_i.branch_Action IS
+ WHEN BR => do_branch_v := do_cond_v;
+ WHEN BRL => do_branch_v := '1';
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ IF (do_branch_v = '1') THEN
+ EX2IF_o.take_branch <= '1';
+ EX2IF_o.branch_target <= result_v;
+ ELSE
+ EX2IF_o.take_branch <= '0';
+ EX2IF_o.branch_target <= C_32_ZEROS;
+ END IF;
+
+ -- IT / ITE / ITT conditioning
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ CASE ID2EX_i.it_Action IS
+ WHEN IT =>
+ EX2CTRL_o.flush_first <= not do_cond_v;
+ EX2CTRL_o.flush_second <= '0';
+ EX2CTRL_o.ignore_state <= '1';
+ WHEN ITT =>
+ EX2CTRL_o.flush_first <= not do_cond_v;
+ EX2CTRL_o.flush_second <= not do_cond_v;
+ EX2CTRL_o.ignore_state <= '1';
+ WHEN ITE =>
+ EX2CTRL_o.flush_first <= not do_cond_v;
+ EX2CTRL_o.flush_second <= do_cond_v;
+ EX2CTRL_o.ignore_state <= '1';
+ WHEN OTHERS =>
+ EX2CTRL_o.flush_first <= '0';
+ EX2CTRL_o.flush_second <= '0';
+ EX2CTRL_o.ignore_state <= '0';
+ END CASE;
+ END IF;
+
+ -- Halting, the instruction parsing is separate
+ HALT_o.halt <= ID2EX_i.halt;
+ IF (ID2EX_i.halt = '1') THEN
+ HALT_o.halt_code <= ID2EX_i.IMM16(4 DOWNTO 0);
+ ELSE
+ HALT_o.halt_code <= (others => '0');
+ END IF;
+
+ -- WR_MEM/RD_MEM: result_v --> exeq_result --> mem_address,
+ -- WR_MEM: data_rD --> data_out_to_mem
+ -- BRL: prog_counter --> exeq_result
+ -- else result_v --> exeq_result (data_rD not used)
+ EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
+ IF (ID2EX_i.branch_Action = BRL) THEN
+ EX2MEM_o.wrb_Action <= WRB_EX;
+ EX2MEM_o.exeq_result <= ID2EX_i.program_counter;
+ EX2MEM_o.data_rD <= ID2EX_i.program_counter;
+ -- set data_rD_v, although unused, to prevent an inferred latch
+ data_rD_v := GPRF2EX_i.data_rD;
+ ELSE
+ EX2MEM_o.wrb_Action <= ID2EX_i.wrb_Action;
+ EX2MEM_o.exeq_result <= result_v;
+ -- test where to obtain data_rD from
+ IF (HAZARD_WRB_i.hazard = '1') THEN
+ data_rD_v := HAZARD_WRB_i.data_rD;
+ ELSIF ((EX_WRB_i.wrb_Action = WRB_EX) AND (ID2EX_i.curr_rD = EX_WRB_i.wrix_rD)) THEN
+ -- forward rD_data just calculated, to handle e.g. addi rD,rA,Imm; sw rD,mem[y]; ...
+ data_rD_v := EX_WRB_i.data_rD;
+ ELSIF ((MEM_WRB_i.wrb_Action /= NO_WRB) AND (ID2EX_i.curr_rD = MEM_WRB_i.wrix_rD)) THEN
+ data_rD_v := MEM_WRB_i.data_rD;
+ ELSE
+ data_rD_v := GPRF2EX_i.data_rD;
+ END IF;
+ END IF;
+
+ IF (ID2EX_i.mem_Action /= NO_MEM) THEN
+ CASE ID2EX_i.transfer_Size IS
+
+ WHEN BYTE =>
+ CASE result_v( 1 DOWNTO 0) IS
+ WHEN "00" => byte_Enable_v := "1000";
+ WHEN "01" => byte_Enable_v := "0100";
+ WHEN "10" => byte_Enable_v := "0010";
+ WHEN "11" => byte_Enable_v := "0001";
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ WHEN HALFWORD =>
+ CASE result_v( 1 DOWNTO 0) IS
+ WHEN "00" => byte_Enable_v := "1100";
+ WHEN "10" => byte_Enable_v := "0011";
+ WHEN OTHERS => NULL;
+ END CASE;
+
+ WHEN OTHERS => byte_Enable_v := "1111";
+
+ END CASE;
+ END IF;
+
+ -- update MSR[C] if needed
+ IF (ID2EX_i.msr_Action = UPDATE_CARRY) THEN
+ MSR_o.C <= carry_o_v;
+ END IF;
+
+ -- pass remaining data to mem
+ EX2MEM_o.mem_Action <= ID2EX_i.mem_Action;
+ EX2MEM_o.data_rD <= data_rD_v;
+ EX2MEM_o.byte_Enable <= byte_Enable_v;
+ EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD;
+ --
+ IMM_LOCK_o.locked <= ID2EX_i.IMM_Lock;
+ IMM_LOCK_o.IMM_hi16 <= ID2EX_i.IMM16;
+ --
+ EX_WRB_o.wrb_Action <= ID2EX_i.wrb_Action;
+ EX_WRB_o.wrix_rD <= ID2EX_i.curr_rD;
+ EX_WRB_o.data_rD <= result_v;
+ --
+ HAZARD_WRB_o.hazard <= hazard_v;
+ HAZARD_WRB_o.save_rX <= save_rX_v;
+ HAZARD_WRB_o.data_rX <= data_rX_v;
+ HAZARD_WRB_o.data_rD <= data_rD_v;
+
+ END PROCESS;
END ARCHITECTURE rtl;
-- Faculty EEMCS, Department ME&CE, Circuits and Systems
-- Date: September, 2010
--
--- Modified: September, 2013: Removed FSL
+-- Modified: September, 2013: Removed FSL, core customization
-- June, 2011: ALU_ACTION_Type extended to incorporate
-- MUL and BS instructions (Huib)
-- Adapted to work with separate fsl_M-
USE IEEE.std_logic_unsigned.all;
USE IEEE.numeric_std.all;
-
--------------------------------------------------------------------------------
PACKAGE mbl_Pkg IS
--------------------------------------------------------------------------------
- CONSTANT C_8_ZEROS : STD_LOGIC_VECTOR ( 7 DOWNTO 0) := X"00";
- CONSTANT C_16_ZEROS : STD_LOGIC_VECTOR (15 DOWNTO 0) := X"0000";
- CONSTANT C_24_ZEROS : STD_LOGIC_VECTOR (23 DOWNTO 0) := X"000000";
- CONSTANT C_32_ZEROS : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000";
+ CONSTANT C_8_ZEROS : STD_LOGIC_VECTOR ( 7 DOWNTO 0) := X"00";
+ CONSTANT C_16_ZEROS : STD_LOGIC_VECTOR (15 DOWNTO 0) := X"0000";
+ CONSTANT C_24_ZEROS : STD_LOGIC_VECTOR (23 DOWNTO 0) := X"000000";
+ CONSTANT C_32_ZEROS : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000";
- CONSTANT C_16_ONES : STD_LOGIC_VECTOR (15 DOWNTO 0) := X"FFFF";
- CONSTANT C_24_ONES : STD_LOGIC_VECTOR (23 DOWNTO 0) := X"FFFFFF";
+ CONSTANT C_16_ONES : STD_LOGIC_VECTOR (15 DOWNTO 0) := X"FFFF";
+ CONSTANT C_24_ONES : STD_LOGIC_VECTOR (23 DOWNTO 0) := X"FFFFFF";
----------------------------------------------------------------------------------------------
-- TYPE DEFINITIONS
----------------------------------------------------------------------------------------------
- TYPE ALU_ACTION_Type IS (A_NOP, A_ADD, A_CMP, A_CMPU, A_OR, A_AND, A_XOR,
- A_SHIFT, A_SEXT8, A_SEXT16, A_MFS, A_MTS,
- A_MUL, A_BSLL, A_BSRL, A_BSRA, A_HALT);
- TYPE ALU_IN1_Type IS (ALU_IN_REGA, ALU_IN_NOT_REGA, ALU_IN_PC, ALU_IN_ZERO);
- TYPE ALU_IN2_Type IS (ALU_IN_REGB, ALU_IN_NOT_REGB, ALU_IN_IMM, ALU_IN_NOT_IMM);
- TYPE ALU_CIN_Type IS (CIN_ZERO, CIN_ONE, FROM_MSR, FROM_IN1);
- TYPE MSR_ACTION_Type IS (UPDATE_CARRY, KEEP_CARRY);
- TYPE BRANCH_ACTION_Type IS (NO_BR, BR, BRL, BEQ, BNE, BLT, BLE, BGT, BGE);
- TYPE WRB_ACTION_Type IS (NO_WRB, WRB_EX, WRB_MEM);
- TYPE MEM_ACTION_Type IS (NO_MEM, WR_MEM, RD_MEM);
- TYPE TRANSFER_SIZE_Type IS (WORD, HALFWORD, BYTE);
- TYPE SAVE_REG_Type IS (NO_SAVE, SAVE_RA, SAVE_RB);
- TYPE CMP_COND_Type IS (COND_ALL, COND_EQ, COND_NE, COND_LT, COND_LE, COND_GT, COND_GE);
- TYPE CMP_COND_TYPE_Type IS (COND_TYPE_ALL, COND_TYPE_IF_THEN, COND_TYPE_IF_THEN_THEN, COND_TYPE_IF_THEN_ELSE);
- --
- TYPE IF2ID_Type IS RECORD
- program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
- END RECORD;
-
- TYPE ID2EX_Type IS RECORD
- program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
- rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- curr_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- alu_Action : ALU_ACTION_Type;
- alu_Op1 : ALU_IN1_Type;
- alu_Op2 : ALU_IN2_Type;
- alu_Cin : ALU_CIN_Type;
- IMM16 : STD_LOGIC_VECTOR (15 DOWNTO 0);
- IMM_Lock : STD_LOGIC;
- msr_Action : MSR_ACTION_Type;
- branch_Action : BRANCH_ACTION_Type;
- mem_Action : MEM_ACTION_Type; -- rd_mem implies writeback
- transfer_Size : TRANSFER_SIZE_Type;
- wrb_Action : WRB_ACTION_Type;
- cmp_Cond : CMP_COND_Type;
- cmp_Cond_Type : CMP_COND_TYPE_Type;
- END RECORD;
-
- TYPE ID2GPRF_Type IS RECORD
- rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- rdix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- END RECORD;
-
- TYPE INT_CTRL_Type IS RECORD
- setup_int : STD_LOGIC;
- rti_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
- int_busy : STD_LOGIC;
- END RECORD;
-
- TYPE ID2CTRL_Type IS RECORD
- delayBit : STD_LOGIC;
- int_busy : STD_LOGIC;
- END RECORD;
-
- TYPE GPRF2EX_Type IS RECORD
- data_rA : STD_LOGIC_VECTOR (31 DOWNTO 0);
- data_rB : STD_LOGIC_VECTOR (31 DOWNTO 0);
- data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
- END RECORD;
-
- TYPE IMM_LOCK_Type IS RECORD
- locked : STD_LOGIC;
- IMM_hi16 : STD_LOGIC_VECTOR (15 DOWNTO 0);
- END RECORD;
-
- TYPE MSR_Type IS RECORD
- IE : STD_LOGIC; -- MSR[VHDL b1] = [MicroBlaze b30]
- C : STD_LOGIC; -- MSR[VHDL b2 and b31] = [MicroBlaze b29 and b0]
- END RECORD;
-
- TYPE EX2IF_Type IS RECORD
- take_branch : STD_LOGIC;
- branch_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
- END RECORD;
-
- TYPE EX2CTRL_Type IS RECORD
- flush_first : STD_LOGIC;
- flush_second : STD_LOGIC;
- END RECORD;
-
- TYPE HALT_Type IS RECORD
- halt : STD_LOGIC;
- halt_code : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- END RECORD;
-
- TYPE EX2MEM_Type IS RECORD
- mem_Action : MEM_ACTION_Type; -- RD_MEM implies writeback
- wrb_Action : WRB_ACTION_Type;
- exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0);
- data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
- byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
- wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- END RECORD;
-
- TYPE WRB_Type IS RECORD
- wrb_Action : WRB_ACTION_Type;
- wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
- END RECORD;
-
- TYPE HAZARD_WRB_Type IS RECORD
- hazard : STD_LOGIC;
- save_rX : SAVE_REG_Type;
- data_rX : STD_LOGIC_VECTOR (31 DOWNTO 0);
- data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
- END RECORD;
-
- TYPE MEM_REG_Type IS RECORD
- wrb_Action : WRB_ACTION_Type;
- exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0);
- byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
- wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- END RECORD;
-
- TYPE MEM2CTRL_Type IS RECORD
- clken : STD_LOGIC;
- int : STD_LOGIC;
- END RECORD;
-
- TYPE CORE2DMEMB_Type IS RECORD
- ena : STD_LOGIC;
- addr : STD_LOGIC_VECTOR (31 DOWNTO 0);
- bSel : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
- wre : STD_LOGIC;
- data : STD_LOGIC_VECTOR (31 DOWNTO 0);
- END RECORD;
-
- TYPE DMEMB2CORE_Type IS RECORD
- clken : STD_LOGIC;
- data : STD_LOGIC_VECTOR (31 DOWNTO 0);
- int : STD_LOGIC;
- END RECORD;
-
- TYPE MEMORY_MAP_Type IS ARRAY(NATURAL RANGE <>) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
- -- NOTE: Use the named association format xxxx := ( 0 => X"A0010000" );
- -- in case the array has to contain only one element !!
+ TYPE ALU_ACTION_Type IS (A_NOP, A_ADD, A_CMP, A_CMPU, A_OR, A_AND, A_XOR,
+ A_SHIFT, A_SEXT8, A_SEXT16, A_MFS, A_MTS, A_MUL,
+ A_BSLL, A_BSRL, A_BSRA);
+ TYPE ALU_IN1_Type IS (ALU_IN_REGA, ALU_IN_NOT_REGA, ALU_IN_PC, ALU_IN_ZERO);
+ TYPE ALU_IN2_Type IS (ALU_IN_REGB, ALU_IN_NOT_REGB, ALU_IN_IMM, ALU_IN_NOT_IMM);
+ TYPE ALU_CIN_Type IS (CIN_ZERO, CIN_ONE, FROM_MSR, FROM_IN1);
+ TYPE MSR_ACTION_Type IS (UPDATE_CARRY, KEEP_CARRY);
+ TYPE BRANCH_ACTION_Type IS (NO_BR, BR, BRL);
+ TYPE IT_ACTION_Type IS (NO_IT, IT, ITT, ITE);
+ TYPE WRB_ACTION_Type IS (NO_WRB, WRB_EX, WRB_MEM);
+ TYPE MEM_ACTION_Type IS (NO_MEM, WR_MEM, RD_MEM);
+ TYPE TRANSFER_SIZE_Type IS (WORD, HALFWORD, BYTE);
+ TYPE SAVE_REG_Type IS (NO_SAVE, SAVE_RA, SAVE_RB);
+ TYPE COND_Type IS (COND_ALL, COND_EQ, COND_NE, COND_LT, COND_LE, COND_GT, COND_GE);
+ --
+ TYPE IF2ID_Type IS RECORD
+ program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ END RECORD;
+
+ TYPE ID2EX_Type IS RECORD
+ program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ curr_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ alu_Action : ALU_ACTION_Type;
+ alu_Op1 : ALU_IN1_Type;
+ alu_Op2 : ALU_IN2_Type;
+ alu_Cin : ALU_CIN_Type;
+ IMM16 : STD_LOGIC_VECTOR (15 DOWNTO 0);
+ IMM_Lock : STD_LOGIC;
+ msr_Action : MSR_ACTION_Type;
+ branch_Action : BRANCH_ACTION_Type;
+ it_Action : IT_ACTION_Type;
+ mem_Action : MEM_ACTION_Type; -- rd_mem implies writeback
+ transfer_Size : TRANSFER_SIZE_Type;
+ wrb_Action : WRB_ACTION_Type;
+ condition : COND_Type;
+ halt : STD_LOGIC;
+ END RECORD;
+
+ TYPE ID2GPRF_Type IS RECORD
+ rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ rdix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ END RECORD;
+
+ TYPE INT_CTRL_Type IS RECORD
+ setup_int : STD_LOGIC;
+ rti_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ int_busy : STD_LOGIC;
+ END RECORD;
+
+ TYPE ID2CTRL_Type IS RECORD
+ delayBit : STD_LOGIC;
+ int_busy : STD_LOGIC;
+ END RECORD;
+
+ TYPE GPRF2EX_Type IS RECORD
+ data_rA : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ data_rB : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ END RECORD;
+
+ TYPE IMM_LOCK_Type IS RECORD
+ locked : STD_LOGIC;
+ IMM_hi16 : STD_LOGIC_VECTOR (15 DOWNTO 0);
+ END RECORD;
+
+ TYPE MSR_Type IS RECORD
+ IE : STD_LOGIC; -- MSR[VHDL b1] = [MicroBlaze b30]
+ C : STD_LOGIC; -- MSR[VHDL b2 and b31] = [MicroBlaze b29 and b0]
+ END RECORD;
+
+ TYPE EX2IF_Type IS RECORD
+ take_branch : STD_LOGIC;
+ branch_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ END RECORD;
+
+ TYPE EX2CTRL_Type IS RECORD
+ flush_first : STD_LOGIC;
+ flush_second : STD_LOGIC;
+ ignore_state : STD_LOGIC;
+ END RECORD;
+
+ TYPE HALT_Type IS RECORD
+ halt : STD_LOGIC;
+ halt_code : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ END RECORD;
+
+ TYPE EX2MEM_Type IS RECORD
+ mem_Action : MEM_ACTION_Type; -- RD_MEM implies writeback
+ wrb_Action : WRB_ACTION_Type;
+ exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+ wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ END RECORD;
+
+ TYPE WRB_Type IS RECORD
+ wrb_Action : WRB_ACTION_Type;
+ wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ END RECORD;
+
+ TYPE HAZARD_WRB_Type IS RECORD
+ hazard : STD_LOGIC;
+ save_rX : SAVE_REG_Type;
+ data_rX : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ END RECORD;
+
+ TYPE MEM_REG_Type IS RECORD
+ wrb_Action : WRB_ACTION_Type;
+ exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+ wrix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ END RECORD;
+
+ TYPE MEM2CTRL_Type IS RECORD
+ clken : STD_LOGIC;
+ int : STD_LOGIC;
+ END RECORD;
+
+ TYPE CORE2DMEMB_Type IS RECORD
+ ena : STD_LOGIC;
+ addr : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ bSel : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
+ wre : STD_LOGIC;
+ data : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ END RECORD;
+
+ TYPE DMEMB2CORE_Type IS RECORD
+ clken : STD_LOGIC;
+ data : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ int : STD_LOGIC;
+ END RECORD;
+
+ TYPE MEMORY_MAP_Type IS ARRAY(NATURAL RANGE <>) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
+ -- NOTE: Use the named association format xxxx := ( 0 => X"A0010000" );
+ -- in case the array has to contain only one element !!
----------------------------------------------------------------------------------------------
-- COMPONENTS
----------------------------------------------------------------------------------------------
- COMPONENT fetch IS
- PORT (
- prog_cntr_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
- inc_pc_i : IN STD_LOGIC;
- EX2IF_i : IN EX2IF_Type;
- IF2ID_o : OUT IF2ID_Type
- );
- END COMPONENT;
-
- COMPONENT decode IS
- GENERIC (
- USE_HW_MUL_g : BOOLEAN := TRUE;
- USE_BARREL_g : BOOLEAN := TRUE;
- COMPATIBILITY_MODE_g : BOOLEAN := FALSE
- );
- PORT (
- IF2ID_i : IN IF2ID_Type;
- imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
- --
- ID2GPRF_o : OUT ID2GPRF_Type;
- ID2EX_o : OUT ID2EX_Type;
- --
- INT_CTRL_i : IN INT_CTRL_Type;
- ID2CTRL_o : OUT ID2CTRL_Type;
- --
- noLiteOpc_o : OUT STD_LOGIC
- );
- END COMPONENT;
-
- COMPONENT adder IS
- GENERIC (
- DW_g : POSITIVE := 32;
- LW_g : POSITIVE := 15
- );
- PORT (
- in1 : IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
- in2 : IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
- cin : IN STD_LOGIC;
- sum : OUT STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
- cout : OUT STD_LOGIC
- );
- END COMPONENT;
-
- COMPONENT exeq IS
- GENERIC (
- USE_HW_MUL_g : BOOLEAN := FALSE;
- USE_BARREL_g : BOOLEAN := FALSE;
- COMPATIBILITY_MODE_g : BOOLEAN := FALSE
- );
- PORT (
- ID2EX_i : IN ID2EX_Type;
- GPRF2EX_i : IN GPRF2EX_Type;
- EX2IF_o : OUT EX2IF_Type;
- EX2CTRL_o : OUT EX2CTRL_Type;
- HALT_o : OUT HALT_Type;
- --
- EX_WRB_i : IN WRB_Type;
- EX_WRB_o : OUT WRB_Type;
- MEM_WRB_i : IN WRB_Type;
- --
- HAZARD_WRB_i : IN HAZARD_WRB_Type;
- HAZARD_WRB_o : OUT HAZARD_WRB_Type;
- --
- IMM_LOCK_i : IN IMM_LOCK_Type;
- IMM_LOCK_o : OUT IMM_LOCK_Type;
- --
- MSR_i : IN MSR_Type;
- MSR_o : OUT MSR_Type;
- --
- EX2MEM_o : OUT EX2MEM_Type
- );
- END COMPONENT;
-
- COMPONENT mem IS
- PORT (
- EX2MEM_i : IN EX2MEM_Type;
- --
- DMEMB_i : IN DMEMB2CORE_Type;
- DMEMB_o : OUT CORE2DMEMB_Type;
- --
- MEM_REG_i : IN MEM_REG_Type;
- MEM_REG_o : OUT MEM_REG_Type;
- --
- MEM_WRB_o : OUT WRB_Type;
- MEM2CTRL_o : OUT MEM2CTRL_Type
- );
- END COMPONENT;
-
- COMPONENT core_ctrl IS
- 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 COMPONENT;
+ COMPONENT fetch IS
+ PORT
+ (
+ prog_cntr_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ inc_pc_i : IN STD_LOGIC;
+ EX2IF_i : IN EX2IF_Type;
+ IF2ID_o : OUT IF2ID_Type
+ );
+ END COMPONENT;
+
+ COMPONENT decode IS
+ GENERIC
+ (
+ USE_HW_MUL_g : BOOLEAN := TRUE;
+ USE_BARREL_g : BOOLEAN := TRUE;
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+ );
+ PORT
+ (
+ IF2ID_i : IN IF2ID_Type;
+ imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ --
+ ID2GPRF_o : OUT ID2GPRF_Type;
+ ID2EX_o : OUT ID2EX_Type;
+ --
+ INT_CTRL_i : IN INT_CTRL_Type;
+ ID2CTRL_o : OUT ID2CTRL_Type;
+ --
+ noLiteOpc_o : OUT STD_LOGIC
+ );
+ END COMPONENT;
+
+ COMPONENT exeq IS
+ GENERIC
+ (
+ USE_HW_MUL_g : BOOLEAN := FALSE;
+ USE_BARREL_g : BOOLEAN := FALSE;
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+ );
+ PORT
+ (
+ ID2EX_i : IN ID2EX_Type;
+ GPRF2EX_i : IN GPRF2EX_Type;
+ EX2IF_o : OUT EX2IF_Type;
+ EX2CTRL_o : OUT EX2CTRL_Type;
+ HALT_o : OUT HALT_Type;
+ --
+ EX_WRB_i : IN WRB_Type;
+ EX_WRB_o : OUT WRB_Type;
+ MEM_WRB_i : IN WRB_Type;
+ --
+ HAZARD_WRB_i : IN HAZARD_WRB_Type;
+ HAZARD_WRB_o : OUT HAZARD_WRB_Type;
+ --
+ IMM_LOCK_i : IN IMM_LOCK_Type;
+ IMM_LOCK_o : OUT IMM_LOCK_Type;
+ --
+ MSR_i : IN MSR_Type;
+ MSR_o : OUT MSR_Type;
+ --
+ EX2MEM_o : OUT EX2MEM_Type
+ );
+ END COMPONENT;
+
+ COMPONENT mem IS
+ PORT
+ (
+ EX2MEM_i : IN EX2MEM_Type;
+ --
+ DMEMB_i : IN DMEMB2CORE_Type;
+ DMEMB_o : OUT CORE2DMEMB_Type;
+ --
+ MEM_REG_i : IN MEM_REG_Type;
+ MEM_REG_o : OUT MEM_REG_Type;
+ --
+ MEM_WRB_o : OUT WRB_Type;
+ MEM2CTRL_o : OUT MEM2CTRL_Type
+ );
+ END COMPONENT;
+
+ COMPONENT core_ctrl IS
+ 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 COMPONENT;
----------------------------------------------------------------------------------------------
-- FUNCTION, PROCEDURE DECLARATIONS
----------------------------------------------------------------------------------------------
- PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
- ci : IN STD_LOGIC;
- VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE co : OUT STD_LOGIC );
-
- PROCEDURE ep_add32nc ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
- ci : IN STD_LOGIC;
- VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
+ PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ ci : IN STD_LOGIC;
+ VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE co : OUT STD_LOGIC );
--- PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC;
--- VARIABLE s : OUT STD_LOGIC_VECTOR;
--- VARIABLE co : OUT STD_LOGIC );
+ PROCEDURE ep_add32nc ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ ci : IN STD_LOGIC;
+ VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
- FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE;
+ FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE;
END PACKAGE mbl_Pkg;
-
----------------------------------------------------------
PACKAGE BODY mbl_Pkg IS
----------------------------------------------------------
- PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
- ci : IN STD_LOGIC;
- VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE co : OUT STD_LOGIC ) IS
-
- CONSTANT NBITS_LO_c : POSITIVE := 17;
- CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
- VARIABLE tmp_lo_v : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
- VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
- VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
- BEGIN
- tmp_lo_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO 0) & '1' ) +
- UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO 0) & ci ));
- tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
- UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
- tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
- UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
- IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
- s := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
- co := tmp_hi0_v(NBITS_HI_c +1);
- ELSE
- s := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
- co := tmp_hi1_v(NBITS_HI_c +1);
- END IF;
- END PROCEDURE;
-
- PROCEDURE ep_add32nc ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
- ci : IN STD_LOGIC;
- VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ) IS
-
- CONSTANT NBITS_LO_c : POSITIVE := 17;
- CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
- VARIABLE tmp_lo_v : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
- VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
- VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
- BEGIN
- tmp_lo_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO 0) & '1' ) +
- UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO 0) & ci ));
- tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
- UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
- tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
- UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
- IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
- s := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
- ELSE
- s := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
- END IF;
- END PROCEDURE;
-
--- PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC;
--- VARIABLE s : OUT STD_LOGIC_VECTOR;
--- VARIABLE co : OUT STD_LOGIC ) IS
--- VARIABLE tmp_lo_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
--- VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
--- VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
--- BEGIN
--- tmp_lo_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH/2 -1 DOWNTO 0) & '1' ) +
--- UNSIGNED( '0' & b(a'LENGTH/2 -1 DOWNTO 0) & ci ));
--- tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') +
--- UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '0'));
--- tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') +
--- UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1'));
--- IF (tmp_lo_v(a'LENGTH/2 +1) = '0') THEN
--- s := tmp_hi0_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1);
--- co := tmp_hi0_v(a'LENGTH/2 +1);
--- ELSE
--- s := tmp_hi1_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1);
--- co := tmp_hi1_v(a'LENGTH/2 +1);
--- END IF;
--- END PROCEDURE;
-
--- Function ef_nbits returns the minimum number of binary bits to represent
--- a value N with:
--- so N = 0,1 NBITS = 1
--- N = 2,3 NBITS = 2
--- N = 4,5,6,7 NBITS = 3
--- N = 8..15 NBITS = 4
--- N = 16..31 NBITS = 5
--- etc.
-
- FUNCTION ef_nbits( value : NATURAL ) RETURN POSITIVE IS
- VARIABLE temp_v : POSITIVE;
- BEGIN
- temp_v := 1;
- FOR i IN 1 TO INTEGER'HIGH LOOP
- temp_v := 2*temp_v;
- IF (temp_v > value) THEN
- RETURN i;
- END IF;
- END LOOP;
- RETURN 32;
- END FUNCTION;
-
-END PACKAGE BODY mbl_Pkg;
\ No newline at end of file
+ PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ ci : IN STD_LOGIC;
+ VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE co : OUT STD_LOGIC ) IS
+
+ CONSTANT NBITS_LO_c : POSITIVE := 17;
+ CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
+ VARIABLE tmp_lo_v : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
+ VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
+ VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
+ BEGIN
+ tmp_lo_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO 0) & '1' ) +
+ UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO 0) & ci ));
+ tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
+ UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
+ tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
+ UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
+ IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
+ s := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
+ co := tmp_hi0_v(NBITS_HI_c +1);
+ ELSE
+ s := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
+ co := tmp_hi1_v(NBITS_HI_c +1);
+ END IF;
+ END PROCEDURE;
+
+ PROCEDURE ep_add32nc ( a, b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ ci : IN STD_LOGIC;
+ VARIABLE s : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ) IS
+
+ CONSTANT NBITS_LO_c : POSITIVE := 17;
+ CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
+ VARIABLE tmp_lo_v : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
+ VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
+ VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
+ BEGIN
+ tmp_lo_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO 0) & '1' ) +
+ UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO 0) & ci ));
+ tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
+ UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
+ tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
+ UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
+ IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
+ s := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
+ ELSE
+ s := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
+ END IF;
+ END PROCEDURE;
+
+
+ FUNCTION ef_nbits( value : NATURAL ) RETURN POSITIVE IS
+ VARIABLE temp_v : POSITIVE;
+ BEGIN
+ temp_v := 1;
+ FOR i IN 1 TO INTEGER'HIGH LOOP
+ temp_v := 2*temp_v;
+ IF (temp_v > value) THEN
+ RETURN i;
+ END IF;
+ END LOOP;
+ RETURN 32;
+ END FUNCTION;
+
+END PACKAGE BODY mbl_Pkg;
-- Remarks:
--------------------------------------------------------------------------------
-
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE work.mbl_Pkg.all;
-
--------------------------------------------------------------------------------
ENTITY mem IS
--------------------------------------------------------------------------------
- PORT (
- EX2MEM_i : IN EX2MEM_Type;
- --
- DMEMB_i : IN DMEMB2CORE_Type;
- DMEMB_o : OUT CORE2DMEMB_Type;
- --
- MEM_REG_i : IN MEM_REG_Type;
- MEM_REG_o : OUT MEM_REG_Type;
- --
- MEM_WRB_o : OUT WRB_Type;
- MEM2CTRL_o : OUT MEM2CTRL_Type
- );
+ PORT
+ (
+ EX2MEM_i : IN EX2MEM_Type;
+ --
+ DMEMB_i : IN DMEMB2CORE_Type;
+ DMEMB_o : OUT CORE2DMEMB_Type;
+ --
+ MEM_REG_i : IN MEM_REG_Type;
+ MEM_REG_o : OUT MEM_REG_Type;
+ --
+ MEM_WRB_o : OUT WRB_Type;
+ MEM2CTRL_o : OUT MEM2CTRL_Type
+ );
END ENTITY mem;
-
--------------------------------------------------------------------------------
ARCHITECTURE rtl OF mem IS
--------------------------------------------------------------------------------
BEGIN
- -- writeback in case of reads from the data memory bus:
- -- delay wrb-ctrl signals (see core_ctrl) to stay in sync
- -- with synchronous dmem data output
- -- Following are only the unconditional pass-through signals. More are in the p_mem process.
- MEM_REG_o.wrb_Action <= EX2MEM_i.wrb_Action;
- MEM_REG_o.exeq_result <= EX2MEM_i.exeq_result;
- MEM_REG_o.byte_Enable <= EX2MEM_i.byte_Enable;
- MEM_REG_o.wrix_rD <= EX2MEM_i.wrix_rD;
- --
- 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.int <= DMEMB_i.int;
- -- pass byte_select signal (NOTE: BIG ENDIAN)
- DMEMB_o.bSel <= EX2MEM_i.byte_Enable;
+ -- writeback in case of reads from the data memory bus:
+ -- delay wrb-ctrl signals (see core_ctrl) to stay in sync
+ -- with synchronous dmem data output
+ -- Following are only the unconditional pass-through signals. More are in the p_mem process.
+ MEM_REG_o.wrb_Action <= EX2MEM_i.wrb_Action;
+ MEM_REG_o.exeq_result <= EX2MEM_i.exeq_result;
+ MEM_REG_o.byte_Enable <= EX2MEM_i.byte_Enable;
+ MEM_REG_o.wrix_rD <= EX2MEM_i.wrix_rD;
+ --
+ 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.int <= DMEMB_i.int;
+ -- pass byte_select signal (NOTE: BIG ENDIAN)
+ DMEMB_o.bSel <= EX2MEM_i.byte_Enable;
p_mem:
- PROCESS (EX2MEM_i, DMEMB_i, MEM_REG_i)
- VARIABLE exeq_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE dmem_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ PROCESS (EX2MEM_i, DMEMB_i, MEM_REG_i)
+ VARIABLE exeq_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE dmem_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+
+ BEGIN
+
+ -- always align Big Endian input data from memory(-bus)
+ CASE MEM_REG_i.byte_Enable IS
+ WHEN "1000" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(31 DOWNTO 24);
+ WHEN "0100" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(23 DOWNTO 16);
+ WHEN "0010" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(15 DOWNTO 8);
+ WHEN "0001" => dmem_data_v := C_24_ZEROS & DMEMB_i.data( 7 DOWNTO 0);
+ WHEN "1100" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(31 DOWNTO 16);
+ WHEN "0011" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(15 DOWNTO 0);
+ WHEN OTHERS => dmem_data_v := DMEMB_i.data;
+ END CASE;
+
+ -- output to dmem-bus
+ CASE EX2MEM_i.mem_Action IS
- BEGIN
+ WHEN WR_MEM =>
+ -- write (or forward) to data memory bus
+ DMEMB_o.addr <= EX2MEM_i.exeq_result;
+ DMEMB_o.ena <= '1';
+ DMEMB_o.wre <= '1';
+ -- Note: use MEM_REG_i here, since MEM_WRB_o (output) cannot be read
+ IF ((MEM_REG_i.wrb_Action /= NO_WRB) AND
+ (EX2MEM_i.wrix_rD = MEM_REG_i.wrix_rD)) THEN
+ CASE MEM_REG_i.wrb_Action IS
+ WHEN WRB_EX =>
+ -- forward exeq output, to handle e.g. add rD,rA,xx; sw rD,mem[y]; ...
+ exeq_data_v := MEM_REG_i.exeq_result;
+ WHEN OTHERS =>
+ -- forward mem_data just read, to handle e.g. lhu rD,mem[x]; sh rD,mem[y]; ...
+ exeq_data_v := dmem_data_v;
+ END CASE;
+ ELSE
+ exeq_data_v := EX2MEM_i.data_rD;
+ END IF;
+ -- output data will be in Big Endian format
+ CASE EX2MEM_i.byte_Enable IS
+ WHEN "1000" => DMEMB_o.data <= exeq_data_v( 7 DOWNTO 0) & C_24_ZEROS;
+ WHEN "0100" => DMEMB_o.data <= C_8_ZEROS & exeq_data_v( 7 DOWNTO 0) & C_16_ZEROS;
+ WHEN "0010" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v( 7 DOWNTO 0) & C_8_ZEROS;
+ WHEN "0001" => DMEMB_o.data <= C_24_ZEROS & exeq_data_v( 7 DOWNTO 0);
+ WHEN "1100" => DMEMB_o.data <= exeq_data_v(15 DOWNTO 0) & C_16_ZEROS;
+ WHEN "0011" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v(15 DOWNTO 0);
+ WHEN OTHERS => DMEMB_o.data <= exeq_data_v;
+ END CASE;
- -- always align Big Endian input data from memory(-bus)
- CASE MEM_REG_i.byte_Enable IS
- WHEN "1000" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(31 DOWNTO 24);
- WHEN "0100" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(23 DOWNTO 16);
- WHEN "0010" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(15 DOWNTO 8);
- WHEN "0001" => dmem_data_v := C_24_ZEROS & DMEMB_i.data( 7 DOWNTO 0);
- WHEN "1100" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(31 DOWNTO 16);
- WHEN "0011" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(15 DOWNTO 0);
- WHEN OTHERS => dmem_data_v := DMEMB_i.data;
- END CASE;
+ WHEN RD_MEM =>
+ -- read from data memory bus
+ DMEMB_o.addr <= EX2MEM_i.exeq_result;
+ DMEMB_o.ena <= '1';
+ DMEMB_o.wre <= '0';
+ DMEMB_o.data <= EX2MEM_i.data_rD; -- (OTHERS => 'Z');
- -- output to dmem-bus
--- DMEMB_o.addr <= EX2MEM_i.exeq_result;
- CASE EX2MEM_i.mem_Action IS
- WHEN WR_MEM =>
- -- write (or forward) to data memory bus
- DMEMB_o.addr <= EX2MEM_i.exeq_result;
- DMEMB_o.ena <= '1';
- DMEMB_o.wre <= '1';
- -- Note: use MEM_REG_i here, since MEM_WRB_o (output) cannot be read
- IF ((MEM_REG_i.wrb_Action /= NO_WRB) AND
- (EX2MEM_i.wrix_rD = MEM_REG_i.wrix_rD)) THEN
- CASE MEM_REG_i.wrb_Action IS
- WHEN WRB_EX =>
- -- forward exeq output, to handle e.g. add rD,rA,xx; sw rD,mem[y]; ...
- exeq_data_v := MEM_REG_i.exeq_result;
- WHEN OTHERS =>
- -- forward mem_data just read, to handle e.g. lhu rD,mem[x]; sh rD,mem[y]; ...
- exeq_data_v := dmem_data_v;
- END CASE;
- ELSE
- exeq_data_v := EX2MEM_i.data_rD;
- END IF;
- -- output data will be in Big Endian format
- CASE EX2MEM_i.byte_Enable IS
- WHEN "1000" => DMEMB_o.data <= exeq_data_v( 7 DOWNTO 0) & C_24_ZEROS;
- WHEN "0100" => DMEMB_o.data <= C_8_ZEROS & exeq_data_v( 7 DOWNTO 0) & C_16_ZEROS;
- WHEN "0010" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v( 7 DOWNTO 0) & C_8_ZEROS;
- WHEN "0001" => DMEMB_o.data <= C_24_ZEROS & exeq_data_v( 7 DOWNTO 0);
- WHEN "1100" => DMEMB_o.data <= exeq_data_v(15 DOWNTO 0) & C_16_ZEROS;
- WHEN "0011" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v(15 DOWNTO 0);
- WHEN OTHERS => DMEMB_o.data <= exeq_data_v;
- END CASE;
- WHEN RD_MEM =>
- -- read from data memory bus
- DMEMB_o.addr <= EX2MEM_i.exeq_result;
- DMEMB_o.ena <= '1';
- DMEMB_o.wre <= '0';
- DMEMB_o.data <= EX2MEM_i.data_rD; -- (OTHERS => 'Z');
- WHEN OTHERS => -- NO_MEM
- DMEMB_o.addr <= C_32_ZEROS;
- DMEMB_o.ena <= '0';
- DMEMB_o.wre <= '0';
- DMEMB_o.data <= EX2MEM_i.data_rD; -- (OTHERS => 'Z');
- END CASE;
+ WHEN OTHERS => -- NO_MEM
+ DMEMB_o.addr <= C_32_ZEROS;
+ DMEMB_o.ena <= '0';
+ DMEMB_o.wre <= '0';
+ DMEMB_o.data <= EX2MEM_i.data_rD; -- (OTHERS => 'Z');
+ END CASE;
- -- additional wrb signals
- CASE MEM_REG_i.wrb_Action IS
- WHEN WRB_MEM => MEM_WRB_o.data_rD <= dmem_data_v;
- WHEN OTHERS => MEM_WRB_o.data_rD <= MEM_REG_i.exeq_result;
- END CASE;
+ -- additional wrb signals
+ CASE MEM_REG_i.wrb_Action IS
+ WHEN WRB_MEM => MEM_WRB_o.data_rD <= dmem_data_v;
+ WHEN OTHERS => MEM_WRB_o.data_rD <= MEM_REG_i.exeq_result;
+ END CASE;
- END PROCESS;
+ END PROCESS;
END ARCHITECTURE rtl;