From b182c161b0b4ab93af9074efd5da430bf6917cad Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Mon, 23 Jan 2017 05:14:05 +0000 Subject: [PATCH] [J-MIPS] - fixed D-Cache invalidate-at - D-Cache improved flush - I-Cache improved flush git-svn-id: http://moon:8086/svn/vhdl/trunk@1376 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/src/core/mips_dcache.vhd | 48 ++++++----- lib/CPUs/MIPS/src/core/mips_icache.vhd | 106 +++++++++++++------------ 2 files changed, 81 insertions(+), 73 deletions(-) diff --git a/lib/CPUs/MIPS/src/core/mips_dcache.vhd b/lib/CPUs/MIPS/src/core/mips_dcache.vhd index f1cf792..bb888f3 100644 --- a/lib/CPUs/MIPS/src/core/mips_dcache.vhd +++ b/lib/CPUs/MIPS/src/core/mips_dcache.vhd @@ -158,9 +158,11 @@ 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 fill_count_rdy : 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); signal flush_count : natural range 0 to 2**cache_index_width-1; - signal flush_count_rst : std_logic; signal flush_count_en : std_logic; signal flush_count_rdy : std_logic; signal request_count : natural range 0 to 2**word_index_width-1; @@ -347,7 +349,7 @@ cache_state_next: tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0'; cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid; tag_ram_din <= 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' and instant_raw = '0') else fill_cache_index; cache_entry_out <= to_dcache_entry(tag_ram_dout); @@ -359,20 +361,23 @@ cache_state_next: cpu_data_ram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0'); cache_state: - process(s, cache_req, instant_raw, cache_hit, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all) + process(s, cache_req, instant_raw, cache_hit, cache_hit_inv, cache_index_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all) begin cache_busy <= cache_req; cache_ack <= '0'; tag_ram_we <= '0'; - flush_count_en <= '0'; - flush_count_rst <= '0'; - invalidate_en <= '0'; request_count_en <= '0'; fill_count_en <= '0'; CYC_O <= '0'; STB_O <= '0'; was_miss <= '0'; + + invalidate_en <= '0'; invalidate_ack <= '0'; + + flush_count_en <= '0'; + flush_addr_preset <= (others=>'0'); -- all + flush_count_preset <= 2**cache_index_width-1; cache_entry_in.tv_p <= (others => '0'); cache_entry_in.tag <= fill_tag; @@ -398,17 +403,16 @@ cache_state: end if; end if; when invalidate => - sn <= rd_cache; + sn <= flush; invalidate_en <= '1'; - invalidate_ack <= '1'; + invalidate_ack <= '1'; + if invalidate_all = '1' then - sn <= flush; - flush_count_rst <= '1'; + flush_addr_preset <= (others=>'0'); -- all + flush_count_preset <= 2**cache_index_width-1; elsif cache_hit_inv = '1' then - tag_ram_we <= '1'; - cache_entry_in.valid <= '0'; - cache_entry_in.tag <= (others => '0'); - sn <= rd_cache; + flush_addr_preset <= cache_index_inv; -- at + flush_count_preset <= 0; end if; when flush => @@ -452,19 +456,19 @@ cache_state: end case; end process; - + flush_counter: process(CLK_I) begin if rising_edge(CLK_I) then - if ctrl.inv_at = '1' then - flush_count <= to_integer(cache_index_inv); - elsif flush_count_rst = '1' then + if flush_count_en = '0' then flush_count_rdy <= '0'; - flush_count <= 2**cache_index_width-1; - elsif flush_count_en = '1' then + flush_count <= flush_count_preset; + flush_addr <= flush_addr_preset; + else if flush_count /= 0 then - flush_count <= flush_count - 1; + flush_count <= flush_count - 1; + flush_addr <= flush_addr + 1; else flush_count_rdy <= '1'; end if; diff --git a/lib/CPUs/MIPS/src/core/mips_icache.vhd b/lib/CPUs/MIPS/src/core/mips_icache.vhd index f66cdf0..f02c174 100644 --- a/lib/CPUs/MIPS/src/core/mips_icache.vhd +++ b/lib/CPUs/MIPS/src/core/mips_icache.vhd @@ -170,10 +170,12 @@ 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_count : natural range 0 to 2**cache_index_width-1; - signal flush_count_rst : std_logic; - signal flush_count_en : std_logic; - signal flush_count_rdy : 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); + signal flush_count : natural range 0 to 2**cache_index_width-1; + signal flush_count_en : std_logic; + signal flush_count_rdy : std_logic; signal request_count : natural range 0 to 2**word_index_width-1; signal request_count_en : std_logic; signal request_count_rdy : std_logic; @@ -337,21 +339,24 @@ 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, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, invalidate_req, invalidate_all) + 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) begin cache_busy <= cache_req; cache_ack <= '0'; tag_ram_we <= '0'; - flush_count_en <= '0'; - flush_count_rst <= '0'; - invalidate_en <= '0'; request_count_en <= '0'; fill_count_en <= '0'; CYC_O <= '0'; STB_O <= '0'; was_miss <= '0'; + + invalidate_en <= '0'; invalidate_ack <= '0'; - + + flush_count_en <= '0'; + flush_addr_preset <= (others=>'0'); -- all + flush_count_preset <= 2**cache_index_width-1; + cache_entry_in.tv_p <= (others => '0'); cache_entry_in.tag <= fill_tag; cache_entry_in.valid <= '0'; @@ -373,30 +378,29 @@ cache_state: cache_ack <= '1'; end if; end if; - when invalidate => - sn <= rd_cache; - invalidate_en <= '1'; - invalidate_ack <= '1'; - if invalidate_all = '1' then - sn <= flush; - flush_count_rst <= '1'; - elsif cache_miss_inv = '0' then - tag_ram_we <= '1'; - cache_entry_in.valid <= '0'; - cache_entry_in.tag <= (others => '0'); - sn <= rd_cache; - end if; - - when flush => - flush_count_en <= '1'; - invalidate_en <= '1'; - tag_ram_we <= '1'; - cache_entry_in.valid <= '0'; - cache_entry_in.tag <= (others => '0'); - if flush_count_rdy = '1' then - tag_ram_we <= '0'; - sn <= rd_cache; - end if; + when invalidate => + sn <= flush; + 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; + end if; + + when flush => + flush_count_en <= '1'; + invalidate_en <= '1'; + tag_ram_we <= '1'; + cache_entry_in.valid <= '0'; + cache_entry_in.tag <= (others => '0'); + if flush_count_rdy = '1' then + tag_ram_we <= '0'; + sn <= rd_cache; + end if; when mem_request => CYC_O <= '1'; if SRDY_I = '1' then @@ -428,24 +432,24 @@ cache_state: end process; -flush_counter: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if ctrl.inv_at = '1' then - flush_count <= to_integer(cache_index_inv); - elsif flush_count_rst = '1' then - flush_count_rdy <= '0'; - flush_count <= 2**cache_index_width-1; - elsif flush_count_en = '1' then - if flush_count /= 0 then - flush_count <= flush_count - 1; - else - flush_count_rdy <= '1'; - end if; - end if; - end if; - 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_addr <= flush_addr_preset; + else + 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; request_counter: process(CLK_I)