diff --git a/lib/CPUs/MIPS/src/core/dcache.vhd b/lib/CPUs/MIPS/src/core/dcache.vhd index b9f9f8f..68ff956 100644 --- a/lib/CPUs/MIPS/src/core/dcache.vhd +++ b/lib/CPUs/MIPS/src/core/dcache.vhd @@ -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;