diff --git a/lib/CPUs/MIPS/src/core/mips_pipeline.vhd b/lib/CPUs/MIPS/src/core/mips_pipeline.vhd index 83be33d..92d2860 100644 --- a/lib/CPUs/MIPS/src/core/mips_pipeline.vhd +++ b/lib/CPUs/MIPS/src/core/mips_pipeline.vhd @@ -150,7 +150,7 @@ architecture Behavioral of pipeline is signal sdu : sdu_t; signal reg_a : word_t; signal reg_b : word_t; - signal branch_ce : STD_LOGIC; + signal branch_taken : STD_LOGIC; signal alu_result : word_t; signal mul_result : word_t; signal mul_busy : STD_LOGIC; @@ -168,6 +168,18 @@ architecture Behavioral of pipeline is signal pipe_rst : STD_LOGIC; signal pc : pc_t; + signal pc_branch : word_t; + signal pc_curr : word_t; + signal pc_last : word_t; + signal pc_nxt : word_t; + signal pc_branch_take : STD_LOGIC; + signal ID_ctrl_branch : STD_LOGIC; + signal EX_ctrl_branch : STD_LOGIC; + signal MEM_ctrl_branch : STD_LOGIC; + signal sdu_ID_stall : STD_LOGIC; + signal sdu_ID_nop : STD_LOGIC; + signal c0_ctrl_in_exc_pending : STD_LOGIC; + signal c0_ctrl_in_exc_inject : STD_LOGIC; -------------------------------------------------------------------------- begin @@ -189,7 +201,19 @@ begin sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en; --------------------------------------------------------------------------- imem_en <= ce and not (sdu.mul_dep or sdu.dmem_dep or c0_ctrl_in.exc_commit); - + pc_branch <= pc.pc_branch; + pc_curr <= pc.curr; + pc_last <= pc.last; + pc_nxt <= pc.nxt; + pc_branch_take <= pc.branch_take; + ID_ctrl_branch <= ID_stage.ctrl.branch; + EX_ctrl_branch <= EX_stage.ctrl.branch; + MEM_ctrl_branch <= MEM_stage.ctrl.branch; + sdu_ID_stall <= sdu.ID_stall; + sdu_ID_nop <= sdu.ID_nop; + c0_ctrl_in_exc_pending <= c0_ctrl_in.exc_pending; + c0_ctrl_in_exc_inject <= c0_ctrl_in.exc_inject; + -------------------------------------------------------------------------- -- Coprocessor assignments -------------------------------------------------------------------------- @@ -263,42 +287,41 @@ proc_stage_pc_next: end if; end process; -proc_stage_branch_ce: - process(clk) +proc_stage_branch: + process(EX_stage, bcu_flags) begin - if rising_edge(clk) then - if pipe_rst = '1' then - branch_ce <= '1'; - else - branch_ce <= c0_ctrl_in.exc_pending; - if sdu.ID_stall = '0' and c0_ctrl_in.exc_inject = '0' then - branch_ce <= '1'; - end if; - end if; + pc.branch_take <= '0'; + if EX_stage.ctrl.branch = '1' then + + case EX_stage.ctrl.bc_src is + + when bc_eq_ne => + pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq; + + when bc_lez_gtz => + pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz); + + when bc_ltz_gez => + pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz; + + when others => null; + end case; end if; end process; -proc_stage_branch: - process(EX_stage, bcu_flags, branch_ce) +proc_stage_branch_taken: + process(clk) begin - if branch_ce = '1' then - pc.branch_take <= '0'; - if EX_stage.ctrl.branch = '1' then - - case EX_stage.ctrl.bc_src is - - when bc_eq_ne => - pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq; - - when bc_lez_gtz => - pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz); - - when bc_ltz_gez => - pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz; - - when others => null; - end case; - end if; + if rising_edge(clk) then + if branch_taken = '0' then + if sdu.ID_stall = '1' or c0_ctrl_in.exc_inject = '1' then + if pc.branch_take = '1' then + branch_taken <= '1'; + end if; + end if; + elsif sdu.ID_stall = '0' then + branch_taken <= '0'; + end if; end if; end process; @@ -306,16 +329,16 @@ proc_stage_pc_branch: process(clk) begin if rising_edge(clk) then - if sdu.ID_stall = '0' then + if sdu.ID_stall = '0' and ID_stage.ctrl.branch = '1' then pc.pc_branch <= pc.curr + ID_stage.bimm18; end if; end if; end process; proc_stage_pc: - process(pc) + process(pc, branch_taken) begin - if pc.branch_take = '1' then + if pc.branch_take = '1' or branch_taken = '1' then pc.curr <= pc.pc_branch; else pc.curr <= pc.nxt;