diff --git a/lib/CPUs/MIPS/src/core/dcache.vhd b/lib/CPUs/MIPS/src/core/dcache.vhd index 6512cbc..a135bee 100644 --- a/lib/CPUs/MIPS/src/core/dcache.vhd +++ b/lib/CPUs/MIPS/src/core/dcache.vhd @@ -127,7 +127,7 @@ END COMPONENT; return result; end to_tram_data; - type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache); + type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_data, rd_cache); signal s, sn : cache_state_t; signal cache_busy : std_logic; @@ -162,17 +162,18 @@ END COMPONENT; signal tram_we : 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 cache_fill : std_logic; - signal cpu_hit_we : std_logic; - signal instant_raw : std_logic; + 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_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; + signal cpu_reg_en : std_logic; + signal was_miss : std_logic; + signal cpu_hit_we : std_logic; + signal instant_raw : std_logic; begin @@ -182,7 +183,7 @@ cpu_index_register: process(CLK_I) begin if rising_edge(CLK_I) then - if cache_fill = '1' then + if fill_count_en = '1' then if ACK_I = '1' then word_index_reg <= word_index_reg + 1; end if; @@ -198,8 +199,10 @@ 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; + if request_count_en = '1'then + if SRDY_I = '1' then + addr_windex_reg <= addr_windex_reg + 1; + end if; elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then addr_windex_reg <= cpu_word_index; end if; @@ -246,11 +249,13 @@ instant_raw_logic: end process; inst_tag_ram : dpram_1w1r - GENERIC MAP ( + GENERIC MAP + ( addr_width => tram_addr_width, data_width => tram_data_width ) - PORT MAP ( + PORT MAP + ( clka => CLK_I, clkb => CLK_I, en_a => '1', @@ -267,11 +272,13 @@ gen_data_ram: begin inst_data_ram : dpram_2w2r - GENERIC MAP ( + GENERIC MAP + ( addr_width => lg2(cache_size), data_width => word_t'length/4 ) - PORT MAP ( + PORT MAP + ( clk_a => CLK_I, clk_b => CLK_I, en_a => '1', @@ -305,30 +312,28 @@ cache_state_next: tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0'; cache_hit <= tag_match and cache_entry_out.valid; tram_din <= to_tram_data(cache_entry_in); + tram_addr_wr <= to_unsigned(flush_count, cache_index_width) when flush_count_en = '1' else cache_index_reg; 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 instant_raw = '0' and cache_fill = '0') else (cache_index_reg & word_index_reg); + cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '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); + ctrl_dram_we <= (others => fill_count_en 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, flush_index_count, fill_count, request_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_count_rdy, fill_count_rdy, request_count_rdy, tag_index_reg, cpu_en, SRDY_I, cpu_en2, cpu_we_reg) begin cpu_reg_en <= '0'; cache_busy <= '1'; tram_we <= '0'; - flush_index_count_en <= '0'; - fill_count_rst <= '0'; + flush_count_en <= '0'; request_count_en <= '0'; - request_count_rst <= '0'; + fill_count_en <= '0'; CYC_O <= '0'; STB_O <= '0'; was_miss <= '0'; - 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'; @@ -349,47 +354,39 @@ cache_state: end if; end if; when flush => - flush_index_count_en <= '1'; - tram_addr_wr <= to_unsigned(flush_index_count, cache_index_width); - tram_we <= '1'; + flush_count_en <= '1'; + tram_we <= '1'; cache_entry_in.valid <= '0'; cache_entry_in.tag <= (others => '0'); - if flush_index_count = 0 then + if flush_count_rdy = '1' then + tram_we <= '0'; sn <= ready; if cpu_en = '1' then cpu_reg_en <= '1'; end if; end if; when mem_request => - fill_count_rst <= '1'; - request_count_rst <= '1'; CYC_O <= '1'; if SRDY_I = '1' then sn <= mem_access; end if; when mem_access => - cache_fill <= '1'; + fill_count_en <= '1'; request_count_en <= '1'; CYC_O <= '1'; STB_O <= '1'; - if request_count = 0 then - if SRDY_I = '1' then - sn <= mem_data; - end if; + if request_count_rdy = '1' then + STB_O <= '0'; + sn <= mem_data; end if; when mem_data => - CYC_O <= '1'; - cache_fill <= '1'; - if fill_count = 0 then - if ACK_I = '1' then - sn <= upd_cache; - end if; + CYC_O <= '1'; + fill_count_en <= '1'; + if fill_count_rdy = '1' then + tram_we <= '1'; + cache_entry_in.valid <= '1'; + sn <= rd_cache; end if; - when upd_cache => - tram_addr_wr <= cache_index_reg; - tram_we <= '1'; - cache_entry_in.valid <= '1'; - sn <= rd_cache; when rd_cache => was_miss <= '1'; sn <= ready; @@ -397,43 +394,59 @@ cache_state: when others => sn <= ready; end case; + end process; -flush_index_counter: +flush_counter: process(CLK_I) begin if rising_edge(CLK_I) then - 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; + if flush_count_en = '0' then + flush_count_rdy <= '0'; + flush_count <= 2**cache_index_width-1; + else + if flush_count /= 0 then + flush_count <= flush_count - 1; + else + flush_count_rdy <= '1'; + end if; end if; end if; end process; -fill_counter: - process(CLK_I) - begin - if rising_edge(CLK_I) then - 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; - request_counter: process(CLK_I) begin if rising_edge(CLK_I) then - 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; + if request_count_en = '0' then + request_count_rdy <= '0'; + request_count <= 2**word_index_width-1; + else + if SRDY_I = '1' then + if request_count /= 0 then + request_count <= request_count - 1; + else + request_count_rdy <= '1'; + end if; + end if; + end if; + end if; + end process; + +fill_counter: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if fill_count_en = '0' then + fill_count_rdy <= '0'; + fill_count <= 2**word_index_width-1; + else + if ACK_I = '1' then + if fill_count /= 0 then + fill_count <= fill_count - 1; + else + fill_count_rdy <= '1'; + end if; end if; end if; end if; diff --git a/lib/CPUs/MIPS/src/core/icache.vhd b/lib/CPUs/MIPS/src/core/icache.vhd index 534ff3a..258c687 100644 --- a/lib/CPUs/MIPS/src/core/icache.vhd +++ b/lib/CPUs/MIPS/src/core/icache.vhd @@ -101,13 +101,14 @@ END COMPONENT; return result; end to_tag_ram_data; - type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache); + type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_data, rd_cache); signal s, sn : cache_state_t; signal cache_busy : std_logic; signal cache_miss : 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); @@ -127,16 +128,17 @@ END COMPONENT; signal tag_ram_re : std_logic; signal tag_ram_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 cpu_reg_en : std_logic; - signal was_miss : std_logic; - signal data_write : std_logic; + 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_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; + signal cpu_reg_en : std_logic; + signal was_miss : std_logic; begin @@ -148,6 +150,10 @@ cpu_index_reg: if RST_I = '1' then cache_index_reg <= (others => '0'); tag_index_reg <= (others => '0'); + elsif fill_count_en = '1' then + if ACK_I = '1' then + word_index_reg <= word_index_reg + 1; + end if; elsif cpu_reg_en = '1' then word_index_reg <= cpu_word_index; cache_index_reg <= cpu_cache_index; @@ -156,12 +162,28 @@ cpu_index_reg: end if; end process; +addr_windex_register: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if request_count_en = '1'then + if SRDY_I = '1' then + addr_windex_reg <= addr_windex_reg + 1; + end if; + elsif cpu_reg_en = '1' then + addr_windex_reg <= cpu_word_index; + end if; + end if; + end process; + inst_tag_ram : dpram_1w1r - GENERIC MAP ( + GENERIC MAP + ( addr_width => tag_ram_addr_width, data_width => tag_ram_data_width ) - PORT MAP ( + PORT MAP + ( clka => CLK_I, clkb => CLK_I, en_a => '1', @@ -174,11 +196,13 @@ inst_tag_ram : dpram_1w1r ); inst_data_ram : dpram_1w1r - GENERIC MAP ( + GENERIC MAP + ( addr_width => lg2(cache_size), data_width => word_t'length ) - PORT MAP ( + PORT MAP + ( clka => CLK_I, clkb => CLK_I, en_a => '1', @@ -209,31 +233,29 @@ cache_state_next: tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0'; cache_miss <= not (tag_match and cache_entry_out.valid); tag_ram_data_wr <= to_tag_ram_data(cache_entry_in); + tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when flush_count_en = '1' else cache_index_reg; tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg; cache_entry_out <= to_icache_entry(tag_ram_data_rd); data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '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"; - data_ram_addr_wr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width); + ADDR_O <= tag_index_reg & cache_index_reg & addr_windex_reg & "00"; + data_ram_addr_wr <= cache_index_reg & word_index_reg; data_ram_data_wr <= DAT_I; - data_ram_we <= data_write and ACK_I; + data_ram_we <= fill_count_en and ACK_I; cache_state: - process(s, cache_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, en) + process(s, cache_miss, flush_count_rdy, fill_count_rdy, request_count_rdy, tag_index_reg, cpu_en, SRDY_I, en) begin cpu_reg_en <= '0'; cache_busy <= '1'; tag_ram_we <= '0'; - cache_index_count_en <= '0'; - ram_index_count_rst <= '0'; - mem_index_count_en <= '0'; - mem_index_count_rst <= '0'; + flush_count_en <= '0'; + request_count_en <= '0'; + fill_count_en <= '0'; CYC_O <= '0'; STB_O <= '0'; data_ram_re <= '0'; tag_ram_re <= '0'; was_miss <= '0'; - data_write <= '0'; - tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width); cache_entry_in.tv_p <= (others => '0'); cache_entry_in.tag <= tag_index_reg; cache_entry_in.valid <= '0'; @@ -257,12 +279,12 @@ cache_state: end if; end if; when flush => - cache_index_count_en <= '1'; - tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width); + flush_count_en <= '1'; tag_ram_we <= '1'; cache_entry_in.valid <= '0'; cache_entry_in.tag <= (others => '0'); - if cache_index_count = 0 then + if flush_count_rdy = '1' then + tag_ram_we <= '0'; sn <= ready; if cpu_en = '1' then cpu_reg_en <= '1'; @@ -271,81 +293,89 @@ cache_state: end if; end if; when mem_request => - ram_index_count_rst <= '1'; - mem_index_count_rst <= '1'; CYC_O <= '1'; if SRDY_I = '1' then sn <= mem_access; end if; when mem_access => - mem_index_count_en <= '1'; - data_write <= '1'; - CYC_O <= '1'; - STB_O <= '1'; - if mem_index_count = 2**word_index_width-1 then - if SRDY_I = '1' then - sn <= mem_data; - end if; + request_count_en <= '1'; + fill_count_en <= '1'; + CYC_O <= '1'; + STB_O <= '1'; + if request_count_rdy = '1' then + STB_O <= '0'; + sn <= mem_data; end if; when mem_data => - CYC_O <= '1'; - data_write <= '1'; - if ram_index_count = 2**word_index_width-1 then - if ACK_I = '1' then - sn <= upd_cache; - end if; + CYC_O <= '1'; + fill_count_en <= '1'; + if fill_count_rdy = '1' then + tag_ram_we <= '1'; + cache_entry_in.valid <= '1'; + sn <= rd_cache; end if; - when upd_cache => - tag_ram_addr_wr <= cache_index_reg; - tag_ram_we <= '1'; - cache_entry_in.valid <= '1'; - sn <= rd_cache; - when rd_cache => tag_ram_re <= '1'; data_ram_re <= '1'; was_miss <= '1'; sn <= ready; + when others => sn <= ready; end case; + end process; -cache_index_counter: +flush_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_count_en = '0' then + flush_count_rdy <= '0'; + flush_count <= 2**cache_index_width-1; + else + if flush_count /= 0 then + flush_count <= flush_count - 1; + else + flush_count_rdy <= '1'; + end if; end if; end if; end process; -ram_index_counter: +request_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; - end if; + if request_count_en = '0' then + request_count_rdy <= '0'; + request_count <= 2**word_index_width-1; + else + if SRDY_I = '1' then + if request_count /= 0 then + request_count <= request_count - 1; + else + request_count_rdy <= '1'; + end if; + end if; end if; end if; end process; -mem_index_counter: +fill_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 fill_count_en = '0' then + fill_count_rdy <= '0'; + fill_count <= 2**word_index_width-1; + else + if ACK_I = '1' then + if fill_count /= 0 then + fill_count <= fill_count - 1; + else + fill_count_rdy <= '1'; + end if; end if; end if; end if;