[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
This commit is contained in:
@@ -118,7 +118,7 @@ END COMPONENT;
|
|||||||
return result;
|
return result;
|
||||||
end to_tag_ram_data;
|
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 s, sn : cache_state_t;
|
||||||
|
|
||||||
signal cache_req : std_logic;
|
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 : natural range 0 to 2**word_index_width-1;
|
||||||
signal fill_count_en : std_logic;
|
signal fill_count_en : std_logic;
|
||||||
signal fill_count_rdy : 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_addr_preset : unsigned(cache_index_width-1 downto 0);
|
||||||
signal flush_count_preset : natural range 0 to 2**cache_index_width-1;
|
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_addr : unsigned(cache_index_width-1 downto 0);
|
||||||
@@ -375,6 +376,7 @@ cache_state:
|
|||||||
invalidate_en <= '0';
|
invalidate_en <= '0';
|
||||||
invalidate_ack <= '0';
|
invalidate_ack <= '0';
|
||||||
|
|
||||||
|
flush_load_en <= '0';
|
||||||
flush_count_en <= '0';
|
flush_count_en <= '0';
|
||||||
flush_addr_preset <= (others=>'0'); -- all
|
flush_addr_preset <= (others=>'0'); -- all
|
||||||
flush_count_preset <= 2**cache_index_width-1;
|
flush_count_preset <= 2**cache_index_width-1;
|
||||||
@@ -389,8 +391,16 @@ cache_state:
|
|||||||
sn <= ready;
|
sn <= ready;
|
||||||
when ready =>
|
when ready =>
|
||||||
if invalidate_req = '1' then
|
if invalidate_req = '1' then
|
||||||
sn <= invalidate;
|
sn <= invalidate_init;
|
||||||
invalidate_en <= '1';
|
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
|
else
|
||||||
if cache_req = '1' then
|
if cache_req = '1' then
|
||||||
if cache_hit = '0' and cpu_we_reg = '0' then
|
if cache_hit = '0' and cpu_we_reg = '0' then
|
||||||
@@ -402,17 +412,17 @@ cache_state:
|
|||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
when invalidate_init =>
|
||||||
|
invalidate_en <= '1';
|
||||||
|
sn <= invalidate;
|
||||||
|
|
||||||
when invalidate =>
|
when invalidate =>
|
||||||
sn <= flush;
|
sn <= rd_cache;
|
||||||
invalidate_en <= '1';
|
invalidate_en <= '1';
|
||||||
invalidate_ack <= '1';
|
invalidate_ack <= '1';
|
||||||
|
if cache_hit_inv = '1' or invalidate_all = '1' then
|
||||||
if invalidate_all = '1' then
|
sn <= flush;
|
||||||
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;
|
end if;
|
||||||
|
|
||||||
when flush =>
|
when flush =>
|
||||||
@@ -461,11 +471,11 @@ flush_counter:
|
|||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if flush_count_en = '0' then
|
if flush_load_en = '1' then
|
||||||
flush_count_rdy <= '0';
|
flush_count_rdy <= '0';
|
||||||
flush_count <= flush_count_preset;
|
flush_count <= flush_count_preset;
|
||||||
flush_addr <= flush_addr_preset;
|
flush_addr <= flush_addr_preset;
|
||||||
else
|
elsif flush_count_en = '1' then
|
||||||
if flush_count /= 0 then
|
if flush_count /= 0 then
|
||||||
flush_count <= flush_count - 1;
|
flush_count <= flush_count - 1;
|
||||||
flush_addr <= flush_addr + 1;
|
flush_addr <= flush_addr + 1;
|
||||||
|
|||||||
@@ -132,15 +132,15 @@ END COMPONENT;
|
|||||||
return result;
|
return result;
|
||||||
end to_tag_ram_data;
|
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 s, sn : cache_state_t;
|
||||||
|
|
||||||
signal cache_req : std_logic;
|
signal cache_req : std_logic;
|
||||||
signal cache_ack : std_logic;
|
signal cache_ack : std_logic;
|
||||||
signal cache_busy : std_logic;
|
signal cache_busy : std_logic;
|
||||||
signal cache_miss : std_logic;
|
signal cache_hit : std_logic;
|
||||||
signal tag_match : 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 tag_match_inv : std_logic;
|
||||||
signal request_addr : unsigned(addr_width-1 downto 0);
|
signal request_addr : unsigned(addr_width-1 downto 0);
|
||||||
signal fill_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 : natural range 0 to 2**word_index_width-1;
|
||||||
signal fill_count_en : std_logic;
|
signal fill_count_en : std_logic;
|
||||||
signal fill_count_rdy : 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_addr_preset : unsigned(cache_index_width-1 downto 0);
|
||||||
signal flush_count_preset : natural range 0 to 2**cache_index_width-1;
|
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_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);
|
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
||||||
tag_match <= '1' when fill_tag = cache_entry_out.tag else '0';
|
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);
|
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';
|
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_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;
|
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_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;
|
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;
|
-- tag_ram_re <= (cpu_en or was_miss) and not data_ram_we;
|
||||||
|
|
||||||
cache_state:
|
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
|
begin
|
||||||
cache_busy <= cache_req;
|
cache_busy <= cache_req;
|
||||||
cache_ack <= '0';
|
cache_ack <= '0';
|
||||||
@@ -353,6 +354,7 @@ cache_state:
|
|||||||
invalidate_en <= '0';
|
invalidate_en <= '0';
|
||||||
invalidate_ack <= '0';
|
invalidate_ack <= '0';
|
||||||
|
|
||||||
|
flush_load_en <= '0';
|
||||||
flush_count_en <= '0';
|
flush_count_en <= '0';
|
||||||
flush_addr_preset <= (others=>'0'); -- all
|
flush_addr_preset <= (others=>'0'); -- all
|
||||||
flush_count_preset <= 2**cache_index_width-1;
|
flush_count_preset <= 2**cache_index_width-1;
|
||||||
@@ -367,10 +369,18 @@ cache_state:
|
|||||||
sn <= ready;
|
sn <= ready;
|
||||||
when ready =>
|
when ready =>
|
||||||
if invalidate_req = '1' then
|
if invalidate_req = '1' then
|
||||||
sn <= invalidate;
|
sn <= invalidate_init;
|
||||||
invalidate_en <= '1';
|
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
|
elsif cache_req = '1' then
|
||||||
if cache_miss = '1' then
|
if cache_hit = '0' then
|
||||||
sn <= mem_request;
|
sn <= mem_request;
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
else
|
else
|
||||||
@@ -378,17 +388,17 @@ cache_state:
|
|||||||
cache_ack <= '1';
|
cache_ack <= '1';
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
when invalidate_init =>
|
||||||
|
invalidate_en <= '1';
|
||||||
|
sn <= invalidate;
|
||||||
|
|
||||||
when invalidate =>
|
when invalidate =>
|
||||||
sn <= flush;
|
sn <= rd_cache;
|
||||||
invalidate_en <= '1';
|
invalidate_en <= '1';
|
||||||
invalidate_ack <= '1';
|
invalidate_ack <= '1';
|
||||||
|
if cache_hit_inv = '1' or invalidate_all = '1' then
|
||||||
if invalidate_all = '1' then
|
sn <= flush;
|
||||||
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;
|
end if;
|
||||||
|
|
||||||
when flush =>
|
when flush =>
|
||||||
@@ -436,11 +446,11 @@ flush_counter:
|
|||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if flush_count_en = '0' then
|
if flush_load_en = '1' then
|
||||||
flush_count_rdy <= '0';
|
flush_count_rdy <= '0';
|
||||||
flush_count <= flush_count_preset;
|
flush_count <= flush_count_preset;
|
||||||
flush_addr <= flush_addr_preset;
|
flush_addr <= flush_addr_preset;
|
||||||
else
|
elsif flush_count_en = '1' then
|
||||||
if flush_count /= 0 then
|
if flush_count /= 0 then
|
||||||
flush_count <= flush_count - 1;
|
flush_count <= flush_count - 1;
|
||||||
flush_addr <= flush_addr + 1;
|
flush_addr <= flush_addr + 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user