diff --git a/lib/CPUs/MIPS/src/core/mips_pipeline.vhd b/lib/CPUs/MIPS/src/core/mips_pipeline.vhd index 079c1b3..940d559 100644 --- a/lib/CPUs/MIPS/src/core/mips_pipeline.vhd +++ b/lib/CPUs/MIPS/src/core/mips_pipeline.vhd @@ -47,7 +47,15 @@ entity pipeline is dmem_be : out unsigned(3 downto 0); dmem_addr : out word_t; dmem_din : in word_t; - dmem_dout : out word_t + dmem_dout : out word_t; + cop_ir : out word_t; + cop_ir_en : out STD_LOGIC; + cop_reg_rd : in STD_LOGIC; + cop_din : in word_t; + cop_dout : out word_t; + c0_ctrl_out : out cop0_ctrl_in_t; + c0_ctrl_in : in cop0_ctrl_out_t + ); end pipeline; @@ -129,23 +137,6 @@ architecture Behavioral of pipeline is ); END COMPONENT; --------------------------------------------------------------------------- - COMPONENT cop is - Port - ( - rst : in STD_LOGIC; - clk : in STD_LOGIC; - sdu : in sdu_t; - IR_valid : in STD_LOGIC; - IR : in word_t; - events : in event_t; - ctrl_in : in cop_ctrl_in_t; - ctrl_out : out cop_ctrl_out_t; - din : in word_t; - dout : out word_t - ); - END COMPONENT; - -------------------------------------------------------------------------- COMPONENT muldiv is Port @@ -179,10 +170,6 @@ architecture Behavioral of pipeline is signal ctrl_lines : ctrl_lines_t; signal branch_ce : STD_LOGIC; signal cpu_run : STD_LOGIC; - signal cop_ctrl : cop_ctrl_in_t; - signal cop_stat : cop_ctrl_out_t; - signal cop_din : word_t; - signal cop_dout : word_t; signal alu_result : word_t; signal mul_result : word_t; signal mul_busy : STD_LOGIC; @@ -211,7 +198,7 @@ begin cpu_run <= ce; -- Stall Detection Unit --------------------------------------------------- - sdu.ID_nop <= sdu.imem_dep or cop_stat.exc_pending or EX_stage.exc or MEM_stage.exc; + sdu.ID_nop <= sdu.imem_dep or c0_ctrl_in.exc_pending or EX_stage.exc or MEM_stage.exc; sdu.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc; sdu.MEM_nop <= EX_stage.nop or EX_stage.exc; sdu.WB_nop <= sdu.dmem_dep or MEM_stage.nop; @@ -225,7 +212,20 @@ begin sdu.imem_dep <= not imem_rdy; sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en; --------------------------------------------------------------------------- - imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or cop_stat.exc_commit); + imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or c0_ctrl_in.exc_commit); + +-------------------------------------------------------------------------- +-- Coprocessor assignments +-------------------------------------------------------------------------- + c0_ctrl_out.bd_wb <= WB_stage.bd; + c0_ctrl_out.epc_mem <= MEM_stage.pcn; + c0_ctrl_out.epc_wb <= MEM_stage.epc; + c0_ctrl_out.imem_addr <= pc.nxt; + c0_ctrl_out.dmem_addr <= MEM_stage.va; + c0_ctrl_out.sdu <= sdu; + c0_ctrl_out.events <= MEM_stage.events; + cop_ir <= ID_stage.IR; + cop_ir_en <= ID_stage.ctrl.cop_instr_en; -------------------------------------------------------------------------- -- Muldiv @@ -246,42 +246,18 @@ inst_muldiv: muldiv dout => mul_result ); --------------------------------------------------------------------------- --- Coprocessor --------------------------------------------------------------------------- -inst_cop: cop - PORT MAP - ( - rst => rst, - clk => clk, - sdu => sdu, - events => MEM_stage.events, - IR_valid => ID_stage.ctrl.cop_instr_en, - IR => ID_stage.IR, - ctrl_in => cop_ctrl, - ctrl_out => cop_stat, - dout => cop_dout, - din => cop_din - ); - - cop_ctrl.bd_wb <= WB_stage.bd; - cop_ctrl.epc_mem <= MEM_stage.pcn; - cop_ctrl.epc_wb <= MEM_stage.epc; - cop_ctrl.imem_addr <= pc.nxt; - cop_ctrl.dmem_addr <= MEM_stage.va; - -------------------------------------------------------------------------- -- IF stage -------------------------------------------------------------------------- imem_addr <= pc.curr; proc_stage_pc: - process(pc, rst, cop_stat) + process(pc, rst, c0_ctrl_in) begin if rst = '1' then pc.curr <= RESET_VECTOR after 2 ns; else - if pc.is_branch and cop_stat.exc_pending = '0' then + if pc.is_branch and c0_ctrl_in.exc_pending = '0' then pc.curr <= pc.pc_branch after 2 ns; else pc.curr <= pc.nxt after 2 ns; @@ -303,17 +279,17 @@ proc_stage_pc_next: process(clk_1) begin if rising_edge(clk_1) then - cop_ctrl.exc_left <= '0'; + c0_ctrl_out.exc_left <= '0'; if rst = '1' then pc.nxt <= pc.curr; pc.last <= pc.curr; branch_ce <= '1'; else branch_ce <= '0'; - if cop_stat.exc_commit = '1' then - pc.nxt <= cop_stat.exc_vec; + if c0_ctrl_in.exc_commit = '1' then + pc.nxt <= c0_ctrl_in.exc_vec; elsif sdu.ID_stall = '0' then - cop_ctrl.exc_left <= cop_stat.exc_exit; + c0_ctrl_out.exc_left <= c0_ctrl_in.exc_exit; branch_ce <= '1'; pc.last <= pc.curr; if ID_stage.ctrl.jump = '1' then @@ -370,17 +346,18 @@ proc_stage_branch: ID_stage.reg_a_rptr <= extract_rs(ID_stage.IR); ID_stage.reg_b_rptr <= extract_rt(ID_stage.IR); ID_stage.ctrl <= ctrl_lines; - ID_stage.reg_write <= ID_stage.ctrl.reg_write or cop_stat.reg_write; + ID_stage.reg_write <= ID_stage.ctrl.reg_write; + ID_stage.cop_read <= cop_reg_rd; ID_stage.epc <= pc.last; ID_stage.exc <= event_is_active(ID_stage.events); -- Todo: works ID_stage.nop <= sdu.ID_nop; proc_ID_except: - process(ID_stage, cop_stat, pc) + process(ID_stage, c0_ctrl_in, pc) begin ID_stage.events <= events_clr; ID_stage.events.inst_load_err <= pc.nxt(1) or pc.nxt(0); - ID_stage.events.inst_priv_addr <= pc.nxt(word_t'left) and cop_stat.user_mode; + ID_stage.events.inst_priv_addr <= pc.nxt(word_t'left) and c0_ctrl_in.user_mode; end process; proc_stage_hdu: @@ -518,7 +495,8 @@ proc_stage_ID_EX_1: EX_stage.events_in <= ID_stage.events; EX_stage.op <= ID_stage.op; EX_stage.ctrl <= ID_stage.ctrl; - EX_stage.reg_write <= ID_stage.reg_write; + EX_stage.reg_write <= ID_stage.reg_write or ID_stage.cop_read; + EX_stage.cop_read <= ID_stage.cop_read; EX_stage.nop <= sdu.EX_nop; EX_stage.IR <= ID_stage.IR; EX_stage.pcn <= ID_stage.pcn; @@ -594,7 +572,7 @@ proc_stage_DMEM_ADDR: if rising_edge(clk_1) then if sdu.EX_stall = '0' then EX_stage.va <= vaddr; - if cop_stat.RE = '1' then + if c0_ctrl_in.RE = '1' then EX_stage.pa_off <= not vaddr(1 downto 0); else EX_stage.pa_off <= vaddr(1 downto 0); @@ -606,7 +584,7 @@ proc_stage_DMEM_ADDR: dmem_we <= EX_stage.ctrl.dmem_we; dmem_dout <= store_shift(EX_stage.reg_b, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns; dmem_addr <= EX_stage.va; - cop_din <= EX_stage.reg_b; + cop_dout <= EX_stage.reg_b; EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in; EX_stage.exc <= event_is_active(EX_stage.events); @@ -779,8 +757,8 @@ proc_stage_MEM_n: MEM_stage.ex_result <= EX_stage.reg_b; else MEM_stage.ex_result <= EX_stage.result; - if cop_stat.cop_read = '1' then - MEM_stage.ex_result <= cop_dout; + if EX_stage.cop_read = '1' then + MEM_stage.ex_result <= cop_din; end if; end if; if sdu.MEM_nop = '1' then @@ -833,7 +811,7 @@ proc_stage_MEM_except: MEM_stage.events.Int <= int; end process; - MEM_stage.exc <= cop_stat.int or event_is_active(MEM_stage.events_in); + MEM_stage.exc <= c0_ctrl_in.int or event_is_active(MEM_stage.events_in); -------------------------------------------------------------------------- -- WB stage