From 3fdaeaed4883ec2c3577e5c763cb82603142b69e Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 4 Feb 2017 10:16:49 +0000 Subject: [PATCH] [J-MIPS] - D-Cache improved flush - I-Cache improved flush git-svn-id: http://moon:8086/svn/vhdl/trunk@1380 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/src/core/mips_dcache.vhd | 68 +++++++++++++++----------- lib/CPUs/MIPS/src/core/mips_icache.vhd | 48 +++++++++++------- 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/lib/CPUs/MIPS/src/core/mips_dcache.vhd b/lib/CPUs/MIPS/src/core/mips_dcache.vhd index bb888f3..2b2787f 100644 --- a/lib/CPUs/MIPS/src/core/mips_dcache.vhd +++ b/lib/CPUs/MIPS/src/core/mips_dcache.vhd @@ -118,7 +118,7 @@ END COMPONENT; return result; end to_tag_ram_data; - type cache_state_t is (init, ready, invalidate, flush, mem_request, mem_access, mem_data, rd_cache); + type cache_state_t is (init, ready, invalidate_init, invalidate, flush, mem_request, mem_access, mem_data, rd_cache); signal s, sn : cache_state_t; signal cache_req : std_logic; @@ -159,6 +159,7 @@ END COMPONENT; signal fill_count : natural range 0 to 2**word_index_width-1; signal fill_count_en : std_logic; signal fill_count_rdy : std_logic; + signal flush_load_en : std_logic; signal flush_addr_preset : unsigned(cache_index_width-1 downto 0); signal flush_count_preset : natural range 0 to 2**cache_index_width-1; signal flush_addr : unsigned(cache_index_width-1 downto 0); @@ -375,6 +376,7 @@ cache_state: invalidate_en <= '0'; invalidate_ack <= '0'; + flush_load_en <= '0'; flush_count_en <= '0'; flush_addr_preset <= (others=>'0'); -- all flush_count_preset <= 2**cache_index_width-1; @@ -389,8 +391,16 @@ cache_state: sn <= ready; when ready => if invalidate_req = '1' then - sn <= invalidate; - invalidate_en <= '1'; + sn <= invalidate_init; + invalidate_en <= '1'; + flush_load_en <= '1'; + if invalidate_all = '1' then + flush_addr_preset <= (others=>'0'); -- all + flush_count_preset <= 2**cache_index_width-1; + else + flush_addr_preset <= cache_index_inv; -- at + flush_count_preset <= 0; + end if; else if cache_req = '1' then if cache_hit = '0' and cpu_we_reg = '0' then @@ -402,18 +412,18 @@ cache_state: end if; end if; end if; + + when invalidate_init => + invalidate_en <= '1'; + sn <= invalidate; + when invalidate => - sn <= flush; - invalidate_en <= '1'; + sn <= rd_cache; + invalidate_en <= '1'; invalidate_ack <= '1'; - - if invalidate_all = '1' then - flush_addr_preset <= (others=>'0'); -- all - flush_count_preset <= 2**cache_index_width-1; - elsif cache_hit_inv = '1' then - flush_addr_preset <= cache_index_inv; -- at - flush_count_preset <= 0; - end if; + if cache_hit_inv = '1' or invalidate_all = '1' then + sn <= flush; + end if; when flush => flush_count_en <= '1'; @@ -457,24 +467,24 @@ cache_state: end process; -flush_counter: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if flush_count_en = '0' then - flush_count_rdy <= '0'; - flush_count <= flush_count_preset; +flush_counter: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if flush_load_en = '1' then + flush_count_rdy <= '0'; + flush_count <= flush_count_preset; flush_addr <= flush_addr_preset; - else - if flush_count /= 0 then + elsif flush_count_en = '1' then + if flush_count /= 0 then flush_count <= flush_count - 1; - flush_addr <= flush_addr + 1; - else - flush_count_rdy <= '1'; - end if; - end if; - end if; - end process; + flush_addr <= flush_addr + 1; + else + flush_count_rdy <= '1'; + end if; + end if; + end if; + end process; request_counter: process(CLK_I) diff --git a/lib/CPUs/MIPS/src/core/mips_icache.vhd b/lib/CPUs/MIPS/src/core/mips_icache.vhd index f02c174..f9d07ff 100644 --- a/lib/CPUs/MIPS/src/core/mips_icache.vhd +++ b/lib/CPUs/MIPS/src/core/mips_icache.vhd @@ -132,15 +132,15 @@ END COMPONENT; return result; end to_tag_ram_data; - type cache_state_t is (init, ready, invalidate, flush, mem_request, mem_access, mem_data, rd_cache, upd_cache); + type cache_state_t is (init, ready, invalidate_init, invalidate, flush, mem_request, mem_access, mem_data, rd_cache, upd_cache); signal s, sn : cache_state_t; signal cache_req : std_logic; signal cache_ack : std_logic; signal cache_busy : std_logic; - signal cache_miss : std_logic; + signal cache_hit : std_logic; signal tag_match : std_logic; - signal cache_miss_inv : std_logic; + signal cache_hit_inv : std_logic; signal tag_match_inv : std_logic; signal request_addr : unsigned(addr_width-1 downto 0); signal fill_addr : unsigned(addr_width-1 downto 0); @@ -170,6 +170,7 @@ END COMPONENT; signal fill_count : natural range 0 to 2**word_index_width-1; signal fill_count_en : std_logic; signal fill_count_rdy : std_logic; + signal flush_load_en : std_logic; signal flush_addr_preset : unsigned(cache_index_width-1 downto 0); signal flush_count_preset : natural range 0 to 2**cache_index_width-1; signal flush_addr : unsigned(cache_index_width-1 downto 0); @@ -322,14 +323,14 @@ cache_state_next: cache_entry_out <= to_icache_entry(tag_ram_data_rd); tag_match <= '1' when fill_tag = cache_entry_out.tag else '0'; - cache_miss <= not (tag_match and cache_entry_out.valid); + cache_hit <= tag_match and cache_entry_out.valid; cache_entry_out_inv <= to_icache_entry(tag_ram_data_rd_inv); tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0'; - cache_miss_inv <= not (tag_match_inv and cache_entry_out_inv.valid); + cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid; tag_ram_data_wr <= to_tag_ram_data(cache_entry_in); - tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else fill_cache_index; + tag_ram_addr_wr <= flush_addr when invalidate_en = '1' else fill_cache_index; tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else fill_cache_index; data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (fill_cache_index & fill_word_index); data_ram_addr_wr <= fill_cache_index & fill_word_index; @@ -339,7 +340,7 @@ cache_state_next: -- tag_ram_re <= (cpu_en or was_miss) and not data_ram_we; cache_state: - process(s, cache_req, cache_miss, cache_miss_inv, cache_index_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, invalidate_req, invalidate_all) + process(s, cache_req, cache_hit, cache_hit_inv, cache_index_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, invalidate_req, invalidate_all) begin cache_busy <= cache_req; cache_ack <= '0'; @@ -353,6 +354,7 @@ cache_state: invalidate_en <= '0'; invalidate_ack <= '0'; + flush_load_en <= '0'; flush_count_en <= '0'; flush_addr_preset <= (others=>'0'); -- all flush_count_preset <= 2**cache_index_width-1; @@ -367,10 +369,18 @@ cache_state: sn <= ready; when ready => if invalidate_req = '1' then - sn <= invalidate; + sn <= invalidate_init; invalidate_en <= '1'; + flush_load_en <= '1'; + if invalidate_all = '1' then + flush_addr_preset <= (others=>'0'); -- all + flush_count_preset <= 2**cache_index_width-1; + else + flush_addr_preset <= cache_index_inv; -- at + flush_count_preset <= 0; + end if; elsif cache_req = '1' then - if cache_miss = '1' then + if cache_hit = '0' then sn <= mem_request; CYC_O <= '1'; else @@ -378,17 +388,17 @@ cache_state: cache_ack <= '1'; end if; end if; + + when invalidate_init => + invalidate_en <= '1'; + sn <= invalidate; + when invalidate => - sn <= flush; + sn <= rd_cache; invalidate_en <= '1'; invalidate_ack <= '1'; - - if invalidate_all = '1' then - flush_addr_preset <= (others=>'0'); -- all - flush_count_preset <= 2**cache_index_width-1; - elsif cache_miss_inv = '0' then - flush_addr_preset <= cache_index_inv; -- at - flush_count_preset <= 0; + if cache_hit_inv = '1' or invalidate_all = '1' then + sn <= flush; end if; when flush => @@ -436,11 +446,11 @@ flush_counter: process(CLK_I) begin if rising_edge(CLK_I) then - if flush_count_en = '0' then + if flush_load_en = '1' then flush_count_rdy <= '0'; flush_count <= flush_count_preset; flush_addr <= flush_addr_preset; - else + elsif flush_count_en = '1' then if flush_count /= 0 then flush_count <= flush_count - 1; flush_addr <= flush_addr + 1;