- removed stall during instant_raw on same word_index (improves performance)

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@312 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2009-02-04 20:13:32 +00:00
parent eebb15e773
commit 9e43596a76
+73 -57
View File
@@ -134,6 +134,7 @@ END COMPONENT;
signal cache_hit : std_logic;
signal tag_match : std_logic;
signal word_index_reg : unsigned(word_index_width-1 downto 0);
signal addr_windex_reg : unsigned(word_index_width-1 downto 0);
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
signal tag_index_reg : unsigned(tag_width-1 downto 0);
@@ -161,16 +162,16 @@ END COMPONENT;
signal tram_re : std_logic;
signal tram_we : std_logic;
signal ram_index_count : natural range 0 to 2**word_index_width-1;
signal ram_index_count_rst : std_logic;
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
signal cache_index_count_en : std_logic;
signal mem_index_count : natural range 0 to 2**word_index_width-1;
signal mem_index_count_en : std_logic;
signal mem_index_count_rst : std_logic;
signal fill_count : natural range 0 to 2**word_index_width-1;
signal fill_count_rst : std_logic;
signal flush_index_count : natural range 0 to 2**cache_index_width-1;
signal flush_index_count_en : std_logic;
signal request_count : natural range 0 to 2**word_index_width-1;
signal request_count_en : std_logic;
signal request_count_rst : std_logic;
signal cpu_reg_en : std_logic;
signal was_miss : std_logic;
signal data_write : std_logic;
signal cache_fill : std_logic;
signal cpu_hit_we : std_logic;
signal instant_raw : std_logic;
@@ -182,9 +183,10 @@ cpu_index_register:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
cache_index_reg <= (others => '0');
tag_index_reg <= (others => '0');
if cache_fill = '1' then
if ACK_I = '1' then
word_index_reg <= word_index_reg + 1;
end if;
elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then
word_index_reg <= cpu_word_index;
cache_index_reg <= cpu_cache_index;
@@ -193,6 +195,18 @@ cpu_index_register:
end if;
end process;
addr_windex_register:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if request_count_en = '1' and SRDY_I = '1' then
addr_windex_reg <= addr_windex_reg + 1;
elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then
addr_windex_reg <= cpu_word_index;
end if;
end if;
end process;
cpu_data_register:
process(CLK_I)
begin
@@ -225,7 +239,10 @@ instant_raw_logic:
process(CLK_I)
begin
if rising_edge(CLK_I) then
instant_raw <= cpu_hit_we and cpu_en and en and not cpu_we;
instant_raw <= '0';
if cpu_word_index = word_index_reg then
instant_raw <= cpu_hit_we and cpu_en and en and not cpu_we;
end if;
end if;
end process;
@@ -258,14 +275,14 @@ gen_data_ram:
PORT MAP (
clk_a => CLK_I,
clk_b => CLK_I,
en_a => ctrl_dram_en,
en_a => '1',
en_b => '1',
we_a => ctrl_dram_we(i),
we_b => cpu_dram_we(i),
we_a => cpu_dram_we(i),
we_b => ctrl_dram_we(i),
addr_a => ctrl_dram_addr,
addr_b => cpu_dram_addr,
din_a => ctrl_dram_din(8*(i+1)-1 downto 8*i),
din_b => cpu_dram_din(8*(i+1)-1 downto 8*i),
din_a => cpu_data_reg(8*(i+1)-1 downto 8*i),
din_b => DAT_I(8*(i+1)-1 downto 8*i),
dout_a => open,
dout_b => cpu_dram_dout(8*(i+1)-1 downto 8*i)
);
@@ -291,30 +308,29 @@ cache_state_next:
tram_din <= to_tram_data(cache_entry_in);
tram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
cache_entry_out <= to_dcache_entry(tram_dout);
cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and cpu_hit_we = '0' and instant_raw = '0') else (cache_index_reg & word_index_reg);
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
ctrl_dram_addr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
ctrl_dram_din <= DAT_I;
ctrl_dram_we <= (others => '1');
ctrl_dram_en <= data_write and ACK_I;
cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0'and instant_raw = '0' and cache_fill = '0') else (cache_index_reg & word_index_reg);
ADDR_O <= tag_index_reg & cache_index_reg & addr_windex_reg & "00";
ctrl_dram_addr <= cache_index_reg & word_index_reg;
ctrl_dram_we <= (others => cache_fill and ACK_I);
cpu_dram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
cache_state:
process(s, instant_raw, cache_hit, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, cpu_en2, cpu_we_reg)
process(s, instant_raw, cache_hit, flush_index_count, fill_count, request_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, cpu_en2, cpu_we_reg)
begin
cpu_reg_en <= '0';
cache_busy <= '1';
tram_we <= '0';
cache_index_count_en <= '0';
ram_index_count_rst <= '0';
mem_index_count_en <= '0';
mem_index_count_rst <= '0';
flush_index_count_en <= '0';
fill_count_rst <= '0';
request_count_en <= '0';
request_count_rst <= '0';
CYC_O <= '0';
STB_O <= '0';
tram_re <= '0';
was_miss <= '0';
data_write <= '0';
tram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
cache_fill <= '0';
tram_addr_wr <= to_unsigned(flush_index_count, cache_index_width);
cache_entry_in.tv_p <= (others => '0');
cache_entry_in.tag <= tag_index_reg;
cache_entry_in.valid <= '0';
@@ -336,12 +352,12 @@ cache_state:
end if;
end if;
when flush =>
cache_index_count_en <= '1';
tram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
flush_index_count_en <= '1';
tram_addr_wr <= to_unsigned(flush_index_count, cache_index_width);
tram_we <= '1';
cache_entry_in.valid <= '0';
cache_entry_in.tag <= (others => '0');
if cache_index_count = 0 then
if flush_index_count = 0 then
sn <= ready;
if cpu_en = '1' then
cpu_reg_en <= '1';
@@ -349,26 +365,26 @@ cache_state:
end if;
end if;
when mem_request =>
ram_index_count_rst <= '1';
mem_index_count_rst <= '1';
fill_count_rst <= '1';
request_count_rst <= '1';
CYC_O <= '1';
if SRDY_I = '1' then
sn <= mem_access;
end if;
when mem_access =>
data_write <= '1';
mem_index_count_en <= '1';
cache_fill <= '1';
request_count_en <= '1';
CYC_O <= '1';
STB_O <= '1';
if mem_index_count = 2**word_index_width-1 then
if request_count = 0 then
if SRDY_I = '1' then
sn <= mem_data;
end if;
end if;
when mem_data =>
CYC_O <= '1';
data_write <= '1';
if ram_index_count = 2**word_index_width-1 then
cache_fill <= '1';
if fill_count = 0 then
if ACK_I = '1' then
sn <= upd_cache;
end if;
@@ -388,41 +404,41 @@ cache_state:
end case;
end process;
cache_index_counter:
flush_index_counter:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if cache_index_count_en = '0' then
cache_index_count <= 2**cache_index_width-1;
elsif cache_index_count /= 0 then
cache_index_count <= cache_index_count - 1;
if flush_index_count_en = '0' then
flush_index_count <= 2**cache_index_width-1;
elsif flush_index_count /= 0 then
flush_index_count <= flush_index_count - 1;
end if;
end if;
end process;
ram_index_counter:
fill_counter:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if ram_index_count_rst = '1' then
ram_index_count <= 0;
elsif data_write = '1' and ACK_I = '1' then
if ram_index_count /= 2**word_index_width-1 then
ram_index_count <= ram_index_count + 1;
if fill_count_rst = '1' then
fill_count <= 2**word_index_width-1;
elsif cache_fill = '1' and ACK_I = '1' then
if fill_count /= 0 then
fill_count <= fill_count - 1;
end if;
end if;
end if;
end process;
mem_index_counter:
request_counter:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if mem_index_count_rst = '1' then
mem_index_count <= 0;
elsif mem_index_count_en = '1' and SRDY_I = '1' then
if mem_index_count /= 2**word_index_width-1 then
mem_index_count <= mem_index_count + 1;
if request_count_rst = '1' then
request_count <= 2**word_index_width-1;
elsif request_count_en = '1' and SRDY_I = '1' then
if request_count /= 0 then
request_count <= request_count - 1;
end if;
end if;
end if;