From 7892b38128f0ffb7e6d822448660d1c8f09a00eb Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 28 Mar 2009 18:24:35 +0000 Subject: [PATCH] - added Cop instructions COP0 32, COP0 33, COP 34, COP0 35: ICACHE_invalidate_at, ICACHE_invalidate_all, DCACHE_invalidate_at, DCACHE_invalidate_all. Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@412 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/src/core/mips_cop.vhd | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/CPUs/MIPS/src/core/mips_cop.vhd b/lib/CPUs/MIPS/src/core/mips_cop.vhd index 34da7f1..357c5a7 100644 --- a/lib/CPUs/MIPS/src/core/mips_cop.vhd +++ b/lib/CPUs/MIPS/src/core/mips_cop.vhd @@ -78,6 +78,7 @@ architecture Behavioral of cop is type cop_pipe_t is record opc : opcode_t; + CO : std_logic; reg_ptr : reg_ptr_t; rs : reg_ptr_t; rd : reg_ptr_t; @@ -116,6 +117,7 @@ begin cop_pipe_ID.rd <= extract_rd(ir); cop_pipe_ID.rt <= extract_rt(ir); cop_pipe_ID.func <= extract_func(ir); + cop_pipe_ID.CO <= ir(25); cop_pipe_ID.re <= cop_pipe_ID.cs when (cop_pipe_ID.opc = "111000" or cop_pipe_ID.rs = "00000") else '0'; cop_pipe_ID.we <= cop_pipe_ID.cs when (cop_pipe_ID.opc = "110000" or cop_pipe_ID.rs = "00100") else '0'; cop_EX_en <= exc_enable and not status_save; @@ -263,6 +265,35 @@ cop_exception_map: status_rest <= exception_end and ctrl_in.exc_left; + + ctrl_out.icache.inv_addr <= test_reg; + ctrl_out.dcache.inv_addr <= test_reg; + +cop_cache_op: + process(clk) + begin + if rising_edge(clk) then + ctrl_out.icache.inv_at <= '0'; + ctrl_out.icache.inv_all <= '0'; + ctrl_out.dcache.inv_at <= '0'; + ctrl_out.dcache.inv_all <= '0'; + if cop_pipe_ID.cs = '1' and cop_pipe_ID.CO = '1' then + case cop_pipe_ID.func is + when "100000" => + ctrl_out.icache.inv_all <= '1'; + when "100001" => + ctrl_out.icache.inv_at <= '1'; + when "100010" => + ctrl_out.dcache.inv_all <= '1'; + when "100011" => + ctrl_out.dcache.inv_at <= '1'; + + when others => null; + end case; + end if; + end if; + end process; + cop_status_restore: process(clk) begin @@ -271,7 +302,7 @@ cop_status_restore: exception_end <= '0'; ctrl_out.exc_exit <= '0'; else - if cop_pipe_ID.func = "10000" and exception_end = '0' then -- RFE + if cop_pipe_ID.CO = '1' and cop_pipe_ID.func = "010000" and exception_end = '0' then -- RFE exception_end <= cop_pipe_ID.cs; ctrl_out.exc_exit <= cop_pipe_ID.cs; elsif exception_end = '1' and ctrl_in.exc_left = '1' then