diff --git a/lib/CPUs/MIPS/src/core/dcache.vhd b/lib/CPUs/MIPS/src/core/dcache.vhd index 1747133..f3d58eb 100644 --- a/lib/CPUs/MIPS/src/core/dcache.vhd +++ b/lib/CPUs/MIPS/src/core/dcache.vhd @@ -41,21 +41,15 @@ ENTITY dcache IS ( rst : in STD_LOGIC; clk : in STD_LOGIC; - - en : in STD_LOGIC; - we : in STD_LOGIC; - be : in unsigned(3 downto 0); - addr : in word_t; - din : in word_t; - dout : out word_t; rdy : out STD_LOGIC; + -- CPU control/data + query_in : in dcache_query_in_t; + query_out : out dcache_query_out_t; + -- Cache control ctrl_in : in cache_ctrl_t; - tlb_query_out : out tlb_query_in_t; - tlb_query_in : in tlb_query_out_t; - -- busmaster data bus_din : in word_t; bus_din_rdy : out std_logic; @@ -194,6 +188,7 @@ END COMPONENT; signal write_rdy : std_logic; signal request_va : word_t; signal request_pa : word_t; + signal request_nc : std_logic; signal tag_match : std_logic; signal cache_hit_inv : std_logic; @@ -291,14 +286,14 @@ begin -- tlb_query_out.vld <= cache_req; -- tlb_query_out.vaddr <= request_va; -- tlb_query_out.write <= cache_req_wr; - tlb_query_out.vld <= req_strobe; - tlb_query_out.vaddr <= addr; - tlb_query_out.idx <= cache_entry_out.idx; - tlb_query_out.write <= we; +-- tlb_query_out.vld <= req_strobe; +-- tlb_query_out.vaddr <= query_in.addr; +-- tlb_query_out.idx <= cache_entry_out.idx; +-- tlb_query_out.write <= query_in.we; - request_pa <= tlb_query_in.paddr; + request_pa <= request_va; - write_hit <= cache_req_wr and cache_hit and not tlb_query_in.exc; + write_hit <= cache_req_wr and cache_hit; -- and not tlb_query_in.exc; debug.req_strobe <= req_strobe; debug.req_read <= cache_req_rd; @@ -312,7 +307,7 @@ begin ------------------------------------------------- -- ctrl ------------------------------------------------- -req_strobe <= cache_rdy and en; +req_strobe <= cache_rdy and query_in.en; request_register: process(clk) @@ -322,11 +317,11 @@ request_register: cache_req_rd <= '0'; cache_req_wr <= '0'; elsif cache_rdy = '1' then - cache_req_rd <= en and not we; - cache_req_wr <= en and we; - cache_req <= en; - if we = '1' then - hit_cache_index <= to_cache_index(addr); + cache_req_rd <= query_in.en and not query_in.we; + cache_req_wr <= query_in.en and query_in.we; + cache_req <= query_in.en; + if query_in.we = '1' then + hit_cache_index <= to_cache_index(query_in.addr); end if; end if; end if; @@ -338,10 +333,12 @@ request_address_register: if rising_edge(clk) then if rst = '1' then request_va <= (others => '0'); + request_nc <= '0'; elsif req_strobe = '1' then - din_reg <= din; - be_reg <= be; - request_va <= addr; + din_reg <= query_in.data; + be_reg <= query_in.be; + request_va <= query_in.addr; + request_nc <= query_in.nc; end if; end if; end process; @@ -351,8 +348,8 @@ instant_raw_logic: begin if rising_edge(clk) then instant_raw <= '0'; - if to_word_index(addr) = fill_word_index and to_cache_index(addr) = hit_cache_index then - instant_raw <= write_hit and en and not we; + if to_word_index(query_in.addr) = fill_word_index and to_cache_index(query_in.addr) = hit_cache_index then + instant_raw <= write_hit and query_in.en and not query_in.we; end if; end if; end process; @@ -392,7 +389,7 @@ fill_address_register: begin if rising_edge(clk) then if req_strobe = '1' then - fill_word_index <= to_word_index(addr); + fill_word_index <= to_word_index(query_in.addr); elsif bus_din_vld = '1' and fill_count_en = '1' then fill_word_index <= fill_word_index + 1; end if; @@ -404,7 +401,7 @@ bus_request_address_register: begin if rising_edge(clk) then if req_strobe = '1' then - req_word_index <= to_word_index(addr); + req_word_index <= to_word_index(query_in.addr); elsif request_count_en = '1' and bus_cmd_rdy = '1' then req_word_index <= req_word_index + 1; end if; @@ -423,7 +420,7 @@ single_read_register: single_read_en <= '1'; end if; elsif single_read_reg_vld = '1' then - if en = '1' then + if query_in.en = '1' then single_read_en <= '0'; single_read_reg_vld <= '0'; end if; @@ -516,10 +513,11 @@ cache_state_next: cache_rdy <= read_rdy and not instant_raw and write_rdy; write_rdy <= not (write_fifo_full and cache_req_wr); + query_out.rdy <= cache_rdy; rdy <= cache_rdy; cache_dout <= single_read_reg when single_read_en = '1' else to_mips_01(data_ram_dout); - dout <= cache_dout; + query_out.data <= cache_dout; -- tag_match <= '1' when to_tag(request_pa) = cache_entry_out.tag else '0'; tag_match <= '1' when ((to_tag(request_pa) xor cache_entry_out.tag) = (tag_width-1 downto 0 => '0')) else '0'; @@ -530,13 +528,13 @@ cache_state_next: 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 to_cache_index(request_va); - tag_ram_addr_rd <= to_cache_index(addr) when (was_miss = '0' and instant_raw = '0') else to_cache_index(request_va); + tag_ram_addr_rd <= to_cache_index(query_in.addr) when (was_miss = '0' and instant_raw = '0') else to_cache_index(request_va); cache_entry_out <= to_dcache_entry(to_mips_01(tag_ram_dout)); cache_entry_out_inv <= to_dcache_entry(to_mips_01(tag_ram_dout_inv)); - ram_read_en <= en or was_miss or fill_count_en; - data_ram_addr <= (to_cache_index(addr) & to_word_index(addr)) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (to_cache_index(request_va) & fill_word_index); + ram_read_en <= query_in.en or was_miss or fill_count_en; + data_ram_addr <= (to_cache_index(query_in.addr) & to_word_index(query_in.addr)) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (to_cache_index(request_va) & fill_word_index); ctrl_data_ram_addr <= to_cache_index(request_va) & fill_word_index; ctrl_data_ram_we <= (others => ram_write_en and bus_din_vld); data_ram_we <= be_reg when (write_hit = '1') else (others => '0'); @@ -544,7 +542,7 @@ cache_state_next: write_through_en <= cache_rdy and cache_req_wr; -- and tlb_query_in.hit and not tlb_query_in.flags.D; cache_busy_state_fsm: - process(cache_busy_state, tlb_query_in, cache_req_rd, cache_hit, mem_fetch_ack, single_read_en, single_read_reg_vld) + process(cache_busy_state, request_nc, cache_req_rd, cache_hit, mem_fetch_ack, single_read_en, single_read_reg_vld) begin read_rdy <= '0'; @@ -563,20 +561,20 @@ cache_busy_state_fsm: else read_rdy <= '1'; if cache_req_rd = '1' then - if tlb_query_in.exc = '0' then - if tlb_query_in.flags.N = '1' or cache_hit = '0' then +-- if tlb_query_in.exc = '0' then + if request_nc = '1' or cache_hit = '0' then -- mem_fetch_req <= '1'; read_rdy <= '0'; cache_busy_state_next <= busy; end if; - end if; +-- end if; end if; end if; when busy => mem_fetch_req <= '1'; if mem_fetch_ack = '1' then - single_read_set <= tlb_query_in.flags.N; + single_read_set <= request_nc; cache_busy_state_next <= ready; end if; @@ -588,7 +586,7 @@ cache_busy_state_fsm: end process; cache_ctrl_state_fsm: - process(cache_ctrl_state, mem_fetch_req, tlb_query_in, flush_count_rdy, fill_count_rdy, request_count_rdy, request_pa, bus_cmd_rdy, bus_din_vld, invalidate_req, invalidate_all, write_through_en, write_data_avail) + process(cache_ctrl_state, mem_fetch_req, request_nc, flush_count_rdy, fill_count_rdy, request_count_rdy, request_pa, bus_cmd_rdy, bus_din_vld, invalidate_req, invalidate_all, write_through_en, write_data_avail) begin tag_ram_we <= '0'; flush_count_en <= '0'; @@ -604,7 +602,6 @@ cache_ctrl_state_fsm: mem_fetch_ack <= '0'; read_write_buffer <= '0'; - cache_entry_in.idx <= tlb_query_in.idx; cache_entry_in.tag <= to_tag(request_pa); cache_entry_in.valid <= '0'; cache_ctrl_state_next <= cache_ctrl_state; @@ -666,7 +663,7 @@ cache_ctrl_state_fsm: read_write_buffer <= '1'; bus_cmd_we <= '1'; elsif mem_fetch_req = '1' then - if tlb_query_in.flags.N = '1' then + if request_nc = '1' then cache_ctrl_state_next <= mem_read_single; else cache_ctrl_state_next <= mem_read; diff --git a/lib/CPUs/MIPS/src/core/icache.vhd b/lib/CPUs/MIPS/src/core/icache.vhd index 7f75e06..04d2cff 100644 --- a/lib/CPUs/MIPS/src/core/icache.vhd +++ b/lib/CPUs/MIPS/src/core/icache.vhd @@ -40,19 +40,15 @@ ENTITY icache IS ( rst : in STD_LOGIC; clk : in STD_LOGIC; + rdy : out STD_LOGIC; -- CPU control/data - en : in STD_LOGIC; - addr : in word_t; - dout : out word_t; - rdy : out STD_LOGIC; + query_in : in icache_query_in_t; + query_out : out icache_query_out_t; -- Cache control ctrl_in : in cache_ctrl_t; - tlb_query_out : out tlb_query_in_t; - tlb_query_in : in tlb_query_out_t; - -- busmaster data bus_din : in word_t; bus_din_rdy : out std_logic; @@ -198,6 +194,7 @@ END COMPONENT; signal cache_hit : std_logic; signal request_va : word_t; signal request_pa : word_t; + signal request_nc : std_logic; signal tag_match : std_logic; signal cache_hit_inv : std_logic; @@ -263,14 +260,14 @@ begin -- tlb_query_out.vld <= cache_req_rd; -- tlb_query_out.vaddr <= request_va; -- tlb_query_out.write <= '0'; - tlb_query_out.vld <= req_strobe; - tlb_query_out.vaddr <= addr; - tlb_query_out.write <= '0'; +-- tlb_query_out.vld <= req_strobe; +-- tlb_query_out.vaddr <= query_in.addr; +-- tlb_query_out.write <= '0'; cache_index_inv <= ctrl_in.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2); tag_inv <= ctrl_in.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2); - request_pa <= tlb_query_in.paddr; + request_pa <= request_va; debug.req_strobe <= req_strobe; debug.req_read <= cache_req_rd; @@ -282,14 +279,14 @@ begin ------------------------------------------------- -- ctrl ------------------------------------------------- -req_strobe <= cache_rdy and en; +req_strobe <= cache_rdy and query_in.en; ctrl_request_register: process(clk) begin if rising_edge(clk) then if cache_rdy = '1' then - cache_req_rd <= en; + cache_req_rd <= query_in.en; end if; end if; end process; @@ -300,10 +297,12 @@ fill_address_register: begin if rising_edge(clk) then if rst = '1' then - request_va <= (others => '0'); + request_va <= (others => '0'); + request_nc <= '0'; elsif req_strobe = '1' then - request_va <= addr; - fill_word_index <= to_word_index(addr); + request_va <= query_in.addr; + request_nc <= query_in.nc; + fill_word_index <= to_word_index(query_in.addr); elsif bus_din_vld = '1' and fill_count_en = '1' then fill_word_index <= fill_word_index + 1; end if; @@ -315,7 +314,7 @@ bus_request_address_register: begin if rising_edge(clk) then if req_strobe = '1' then - req_word_index <= to_word_index(addr); + req_word_index <= to_word_index(query_in.addr); elsif request_count_en = '1' and bus_cmd_rdy = '1' then req_word_index <= req_word_index + 1; end if; @@ -334,7 +333,7 @@ single_read_register: single_read_en <= '1'; end if; elsif single_read_reg_vld = '1' then - if en = '1' then + if query_in.en = '1' then single_read_en <= '0'; single_read_reg_vld <= '0'; end if; @@ -421,10 +420,11 @@ cache_state_next: bus_cmd_out.sel <= (others => '1'); cache_rdy <= read_rdy; + query_out.rdy <= cache_rdy; rdy <= cache_rdy; cache_dout <= single_read_reg when single_read_en = '1' else data_ram_data_rd; - dout <= cache_dout; + query_out.data <= cache_dout; cache_entry_out <= to_icache_entry(to_mips_01(tag_ram_data_rd)); tag_match <= '1' when ((to_tag(request_pa) xor cache_entry_out.tag) = (tag_width-1 downto 0 => '0')) else '0'; @@ -434,17 +434,17 @@ 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; - ram_read_en <= en or was_miss; + ram_read_en <= query_in.en or was_miss; 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 to_cache_index(request_va); - tag_ram_addr_rd <= to_cache_index(addr) when was_miss = '0' else to_cache_index(request_va); - data_ram_addr_rd <= (to_cache_index(addr) & to_word_index(addr)) when was_miss = '0' else (to_cache_index(request_va) & fill_word_index); + tag_ram_addr_rd <= to_cache_index(query_in.addr) when was_miss = '0' else to_cache_index(request_va); + data_ram_addr_rd <= (to_cache_index(query_in.addr) & to_word_index(query_in.addr)) when was_miss = '0' else (to_cache_index(request_va) & fill_word_index); data_ram_addr_wr <= to_cache_index(request_va) & fill_word_index; data_ram_data_wr <= bus_din; data_ram_we <= ram_write_en and bus_din_vld; cache_busy_state_fsm: - process(cache_busy_state, tlb_query_in, cache_req_rd, cache_hit, mem_fetch_ack, single_read_en, single_read_reg_vld) + process(cache_busy_state, request_nc, cache_req_rd, cache_hit, mem_fetch_ack, single_read_en, single_read_reg_vld) begin read_rdy <= '0'; @@ -464,10 +464,10 @@ cache_busy_state_fsm: read_rdy <= '1'; if cache_req_rd = '1' then -- if tlb_query_in.exc = '0' then - if tlb_query_in.flags.N = '1' or cache_hit = '0' then + if request_nc = '1' or cache_hit = '0' then -- mem_fetch_req <= '1'; read_rdy <= '0'; - single_read_set <= tlb_query_in.flags.N; + single_read_set <= request_nc; cache_busy_state_next <= busy; end if; -- end if; @@ -488,7 +488,7 @@ cache_busy_state_fsm: end process; cache_ctrl_state_fsm: - process(cache_ctrl_state, mem_fetch_req, tlb_query_in, bus_din_vld, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, request_pa, bus_cmd_rdy, invalidate_req, invalidate_all) + process(cache_ctrl_state, mem_fetch_req, request_nc, bus_din_vld, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, request_pa, bus_cmd_rdy, invalidate_req, invalidate_all) begin tag_ram_we <= '0'; flush_count_en <= '0'; @@ -554,7 +554,7 @@ cache_ctrl_state_fsm: bus_cmd_cycle_en <= '1'; if bus_cmd_rdy = '1' then cache_ctrl_state_next <= mem_read; - if tlb_query_in.flags.N = '1' then + if request_nc = '1' then cache_ctrl_state_next <= mem_read_single; end if; end if; diff --git a/lib/CPUs/MIPS/src/core/mips_bui.vhd b/lib/CPUs/MIPS/src/core/mips_bui.vhd index 1bedee5..b0ad780 100644 --- a/lib/CPUs/MIPS/src/core/mips_bui.vhd +++ b/lib/CPUs/MIPS/src/core/mips_bui.vhd @@ -39,9 +39,7 @@ entity biu is DCACHE_LINE : natural := 8; -- words WRITE_FIFO_SIZE : natural := 4; -- words WITH_TLB : boolean := true; - TRANSLATE_KSEG0_1 : boolean := true; - ITLB_PIPE : boolean := false; - DTLB_PIPE : boolean := false + TRANSLATE_KSEG0_1 : boolean := true ); Port ( @@ -49,18 +47,7 @@ entity biu is busy : out STD_LOGIC; imem_err : out STD_LOGIC; - imem_rdy : out STD_LOGIC; - imem_en : in STD_LOGIC; - imem_addr : in word_t; - imem_dout : out word_t; dmem_err : out STD_LOGIC; - dmem_rdy : out STD_LOGIC; - dmem_en : in STD_LOGIC; - dmem_we : in STD_LOGIC; - dmem_be : in unsigned(3 downto 0); - dmem_din : in word_t; - dmem_dout : out word_t; - dmem_addr : in word_t; RST_I : in STD_LOGIC; CLK_I : in STD_LOGIC; @@ -117,10 +104,6 @@ architecture behavior of biu is signal i_bus_cmd_cycle_en : std_logic; signal i_bus_cmd : bm_cmd_t; - signal i_tlb_ctrl_in : tlb_ctrl_in_t; - signal i_tlb_ctrl_out : tlb_ctrl_out_t; - signal i_tlb_qry_in : tlb_query_in_t; - signal i_tlb_qry_out : tlb_query_out_t; signal i_tlb_rdy : std_logic; signal i_cache_rdy : std_logic; @@ -130,33 +113,17 @@ architecture behavior of biu is signal d_bus_cmd_cycle_en : std_logic; signal d_bus_cmd : bm_cmd_t; - signal d_tlb_ctrl_in : tlb_ctrl_in_t; - signal d_tlb_ctrl_out : tlb_ctrl_out_t; - signal d_tlb_qry_in : tlb_query_in_t; - signal d_tlb_qry_out : tlb_query_out_t; signal d_tlb_rdy : std_logic; signal d_cache_rdy : std_logic; signal icache_bus_gnt : std_logic; signal dcache_bus_gnt : std_logic; - signal i_cache_tlb_qry_out : tlb_query_in_t; - signal i_cache_tlb_qry_in : tlb_query_out_t; - signal d_cache_tlb_qry_out : tlb_query_in_t; - signal d_cache_tlb_qry_in : tlb_query_out_t; - - begin CPU_CLK <= clk; RST <= RST_I; - imem_rdy <= i_cache_rdy; - dmem_rdy <= d_cache_rdy; - ctrl_out.itlb_ctrl <= i_tlb_ctrl_out; - ctrl_out.dtlb_ctrl <= d_tlb_ctrl_out; - - biu_busy_state: process(clk) begin @@ -217,8 +184,7 @@ inst_i_tlb : entity work.tlb NUM_ENTRIES => TLB_NUM_ENTRIES, CACHE_KSEG1 => false, TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1, - USE_TLB => WITH_TLB, - REGISTERED_OUTPUT => ITLB_PIPE + USE_TLB => WITH_TLB ) PORT MAP ( @@ -229,18 +195,14 @@ inst_i_tlb : entity work.tlb rdy => i_tlb_rdy, - ctrl_in => i_tlb_ctrl_in, - ctrl_out => i_tlb_ctrl_out, + ctrl_in => ctrl_in.itlb_ctrl, + ctrl_out => ctrl_out.itlb_ctrl, - query_in => i_tlb_qry_in, - query_out => i_tlb_qry_out + query_in => ctrl_in.itlb_qry, + query_out => ctrl_out.itlb_qry ); - i_tlb_ctrl_in <= ctrl_in.itlb_ctrl; - i_tlb_qry_in <= ctrl_in.itlb_qry when ITLB_PIPE else i_cache_tlb_qry_out; - i_cache_tlb_qry_in <= i_tlb_qry_out; - inst_icache: entity work.icache GENERIC MAP ( @@ -251,17 +213,14 @@ inst_icache: entity work.icache ( rst => RST, clk => CPU_CLK, + rdy => i_cache_rdy, -- CPU control/data - en => imem_en, - addr => imem_addr, - dout => imem_dout, - rdy => i_cache_rdy, + query_in => ctrl_in.icache_qry, + query_out => ctrl_out.icache_qry, -- Cache control ctrl_in => ctrl_in.icache, - tlb_query_in => i_cache_tlb_qry_in, - tlb_query_out => i_cache_tlb_qry_out, -- busmaster data bus_din => bus_dout, @@ -283,8 +242,7 @@ inst_d_tlb : entity work.tlb NUM_ENTRIES => TLB_NUM_ENTRIES, CACHE_KSEG1 => false, TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1, - USE_TLB => WITH_TLB, - REGISTERED_OUTPUT => DTLB_PIPE + USE_TLB => WITH_TLB ) PORT MAP ( @@ -295,18 +253,14 @@ inst_d_tlb : entity work.tlb rdy => d_tlb_rdy, - ctrl_in => d_tlb_ctrl_in, - ctrl_out => d_tlb_ctrl_out, + ctrl_in => ctrl_in.dtlb_ctrl, + ctrl_out => ctrl_out.dtlb_ctrl, - query_in => d_tlb_qry_in, - query_out => d_tlb_qry_out + query_in => ctrl_in.dtlb_qry, + query_out => ctrl_out.dtlb_qry ); - d_tlb_ctrl_in <= ctrl_in.dtlb_ctrl; - d_tlb_qry_in <= ctrl_in.dtlb_qry when DTLB_PIPE else d_cache_tlb_qry_out; - d_cache_tlb_qry_in <= d_tlb_qry_out; - inst_dcache: entity work.dcache GENERIC MAP ( @@ -318,20 +272,14 @@ inst_dcache: entity work.dcache ( rst => RST, clk => CPU_CLK, + rdy => d_cache_rdy, -- CPU control/data - en => dmem_en, - we => dmem_we, - addr => dmem_addr, - be => dmem_be, - din => dmem_din, - dout => dmem_dout, - rdy => d_cache_rdy, + query_in => ctrl_in.dcache_qry, + query_out => ctrl_out.dcache_qry, -- Cache control ctrl_in => ctrl_in.dcache, - tlb_query_in => d_cache_tlb_qry_in, - tlb_query_out => d_cache_tlb_qry_out, -- busmaster data bus_din => bus_dout, diff --git a/lib/CPUs/MIPS/src/core/mips_pipeline.vhd b/lib/CPUs/MIPS/src/core/mips_pipeline.vhd index c1ec889..30d0f21 100644 --- a/lib/CPUs/MIPS/src/core/mips_pipeline.vhd +++ b/lib/CPUs/MIPS/src/core/mips_pipeline.vhd @@ -32,28 +32,25 @@ use work.mips_util_pkg.all; entity pipeline is Port ( - rst : in STD_LOGIC; - clk : in STD_LOGIC; - ce : in STD_LOGIC; - imem_err : in STD_LOGIC; - imem_rdy : in STD_LOGIC; - imem_en : out STD_LOGIC; - imem_addr : out word_t; - imem_data : in word_t; - dmem_err : in STD_LOGIC; - dmem_rdy : in STD_LOGIC; - dmem_en : out STD_LOGIC; - dmem_we : out STD_LOGIC; - dmem_be : out unsigned(3 downto 0); - dmem_addr : out word_t; - dmem_din : in word_t; - dmem_dout : out word_t; - cop_ir : out word_t; - cop_ir_en : out STD_LOGIC; - cop_din : in word_t; - cop_dout : out word_t; - ctrl_out : out pipe_ctrl_out_t; - ctrl_in : in pipe_ctrl_in_t + rst : in STD_LOGIC; + clk : in STD_LOGIC; + ce : in STD_LOGIC; + imem_err : in STD_LOGIC; + dmem_err : in STD_LOGIC; + cop_ir : out word_t; + cop_ir_en : out STD_LOGIC; + cop_din : in word_t; + cop_dout : out word_t; + ctrl_out : out pipe_ctrl_out_t; + ctrl_in : in pipe_ctrl_in_t; + dtlb_qry_out : out tlb_query_in_t; + dtlb_qry_in : in tlb_query_out_t; + dcache_qry_out : out dcache_query_in_t; + dcache_qry_in : in dcache_query_out_t; + itlb_qry_out : out tlb_query_in_t; + itlb_qry_in : in tlb_query_out_t; + icache_qry_out : out icache_query_in_t; + icache_qry_in : in icache_query_out_t ); end pipeline; @@ -164,17 +161,10 @@ architecture Behavioral of pipeline is signal EX_events_mem : event_t; signal EX_events : event_t; signal MEM_events : event_t; - signal bcu_op_a : word_t; - signal bcu_op_b : word_t; - signal bcu_flags : bcu_flags_t; - signal vaddr1 : word_t; - signal vaddr2 : word_t; - signal dmem_src : word_t; signal stage_rst : unsigned(3 downto 0); signal pipe_rst : STD_LOGIC; signal pc : pc_t; - signal pc_alt : pc_t; -------------------------------------------------------------------------- begin @@ -184,7 +174,7 @@ begin cpu_run <= ce; -- Stall Detection Unit --------------------------------------------------- - sdu.ID_nop <= sdu.imem_dep or ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc; -- or pc_alt.branch_not_taken; + sdu.ID_nop <= sdu.imem_dep or ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc; -- or pc.branch_not_taken; sdu.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc; sdu.MEM_nop <= EX_stage.nop or EX_stage.exc; sdu.WB_nop <= sdu.dmem_dep or MEM_stage.exc or WB_stage.exc or ctrl_in.exc_pending; @@ -196,10 +186,27 @@ begin sdu.WB_stall <= '0'; sdu.mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy); - sdu.imem_dep <= not imem_rdy; - sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en; + sdu.imem_dep <= not icache_qry_in.rdy; + sdu.dmem_dep <= not dcache_qry_in.rdy and MEM_stage.ctrl.dmem_en; --------------------------------------------------------------------------- - imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or ctrl_in.exc_commit); + itlb_qry_out.vld <= (not sdu.ID_stall or ctrl_in.exc_inject); + itlb_qry_out.write <= '0'; + itlb_qry_out.vaddr <= pc.nxt; + + icache_qry_out.addr <= itlb_qry_in.paddr; + icache_qry_out.en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or ctrl_in.exc_commit); + icache_qry_out.nc <= itlb_qry_in.flags.N; + + dtlb_qry_out.vld <= ID_stage.ctrl.dmem_en and not sdu.dmem_dep; + dtlb_qry_out.write <= ID_stage.ctrl.dmem_we; + dtlb_qry_out.vaddr <= ID_stage.va; + + dcache_qry_out.be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_en, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.shift_byp) after 1 ns; + dcache_qry_out.en <= EX_stage.dmem_en; + dcache_qry_out.we <= EX_stage.ctrl.dmem_we; + dcache_qry_out.data <= store_shift(EX_stage.reg_b, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns; + dcache_qry_out.addr <= dtlb_qry_in.paddr; + dcache_qry_out.nc <= dtlb_qry_in.flags.N; -------------------------------------------------------------------------- -- Coprocessor assignments @@ -209,7 +216,7 @@ begin ctrl_out.exc_ack <= '1'; cop_ir <= ID_stage.IR; cop_ir_en <= ID_stage.ctrl.cop_instr_en; - cop_dout <= EX_stage.reg_b; -- dmem_din when MEM_stage.ctrl.dmem_en = '1' else MEM_stage.ex_result; + cop_dout <= EX_stage.reg_b; -------------------------------------------------------------------------- -- Muldiv @@ -233,7 +240,6 @@ inst_muldiv: muldiv -------------------------------------------------------------------------- -- IF stage -------------------------------------------------------------------------- - imem_addr <= pc.curr; pipe_rst <= stage_rst(0); @@ -249,92 +255,9 @@ proc_stage_reset: end if; end process; -proc_stage_pc: - process(pc) - begin - if pc.branch_take = '1' then - pc.curr <= pc.pc_branch after 2 ns; - else - pc.curr <= pc.nxt after 2 ns; - end if; - end process; - -proc_stage_pc_branch: - process(clk_1) - begin - if rising_edge(clk_1) then - if sdu.ID_stall = '0' then - pc.pc_branch <= pc.curr + ID_stage.bimm18; - end if; - end if; - end process; - -proc_stage_branch_ce: - process(clk_1) - begin - if rising_edge(clk_1) then - if pipe_rst = '1' then - branch_ce <= '1'; - else - branch_ce <= ctrl_in.exc_pending; - if sdu.ID_stall = '0' and ctrl_in.exc_inject = '0' then - branch_ce <= '1'; - end if; - end if; - end if; - end process; - -proc_stage_pc_next: - process(clk_1) - begin - if rising_edge(clk_1) then - if ctrl_in.exc_inject = '1' then - pc.nxt <= ctrl_in.exc_vec; - elsif sdu.ID_stall = '0' then - pc.last <= pc.curr; - if ID_stage.ctrl.jump = '1' then - pc.nxt <= ID_stage.jimm32; - elsif ID_stage.ctrl.jump_long = '1' then - pc.nxt <= ID_stage.reg_a; - elsif cpu_run = '1' then - pc.nxt <= pc.curr + 4; - end if; - end if; - end if; - end process; - -proc_stage_branch: - process(clk_2) - begin - if rising_edge(clk_2) and branch_ce = '1' then - pc.branch_take <= '0'; - if EX_stage.ctrl.branch = '1' then - - case EX_stage.ctrl.bc_src is - - when bc_eq_ne => - pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq; - - when bc_lez_gtz => - pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz); - - when bc_ltz_gez => - pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz; - - when others => null; - end case; - end if; - end if; - end process; - -------------------------------------------------------------------------- --- alt pc +-- pc -------------------------------------------------------------------------- -ctrl_out.itlb_qry.vld2 <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or ctrl_in.exc_commit) and imem_rdy; -ctrl_out.itlb_qry.vld <= '1'; -ctrl_out.itlb_qry.write <= '0'; -ctrl_out.itlb_qry.vaddr <= pc_alt.nxt; - inst_bcu_alt_ID: bcu GENERIC MAP ( @@ -359,46 +282,23 @@ inst_bcu_alt_EX: bcu flags => EX_stage.bcu_flags ); -inst_bcu_alt_MEM: bcu - GENERIC MAP - ( - data_width => word_t'length - ) - PORT MAP - ( - op1_in => MEM_stage.reg_a, - op2_in => MEM_stage.reg_b, - flags => MEM_stage.bcu_flags - ); - -inst_bcu_alt_WB: bcu - GENERIC MAP - ( - data_width => word_t'length - ) - PORT MAP - ( - op1_in => WB_stage.reg_a, - op2_in => WB_stage.reg_b, - flags => WB_stage.bcu_flags - ); proc_stage_branch_alt: process(ID_stage) begin - pc_alt.branch_take <= '0'; + pc.branch_take <= '0'; if ID_stage.ctrl.branch = '1' then case ID_stage.ctrl.bc_src is when bc_eq_ne => - pc_alt.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.eq; + pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.eq; when bc_lez_gtz => - pc_alt.branch_take <= ID_stage.ctrl.bc_not xor (ID_stage.bcu_flags.eq or ID_stage.bcu_flags.ltz); + pc.branch_take <= ID_stage.ctrl.bc_not xor (ID_stage.bcu_flags.eq or ID_stage.bcu_flags.ltz); when bc_ltz_gez => - pc_alt.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.ltz; + pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.ltz; when others => null; end case; @@ -425,43 +325,36 @@ proc_stage_branch_not: end case; end process; -proc_stage_pc_next_alt: - process(ctrl_in, sdu, pc_alt, ID_stage, EX_stage) +-- proc_stage_pc_next_alt: + process(ctrl_in, sdu, pc, ID_stage, EX_stage) begin - pc_alt.nxt <= pc_alt.curr; - if sdu.ID_stall = '0' then - pc_alt.nxt <= ctrl_in.exc_vec; - if ctrl_in.exc_inject = '0' then - pc_alt.nxt <= pc_alt.plus4; - if ID_stage.ctrl.jump = '1' then - pc_alt.nxt <= ID_stage.jimm32; - elsif ID_stage.ctrl.jump_long = '1' then - pc_alt.nxt <= ID_stage.reg_a; - elsif pc_alt.branch_take = '1' then - pc_alt.nxt <= pc_alt.pc_branch; - end if; +-- pc.nxt <= ctrl_in.exc_vec; +-- if ctrl_in.exc_inject = '0' then + pc.nxt <= pc.plus4; + if ID_stage.ctrl.jump = '1' then + pc.nxt <= ID_stage.jimm32; + elsif ID_stage.ctrl.jump_long = '1' then + pc.nxt <= ID_stage.reg_a; + elsif pc.branch_take = '1' then + pc.nxt <= pc.pc_branch; end if; - end if; +-- end if; end process; -- always branch in ID and revert in EX -- proc_stage_pc_next_alt: --- process(ctrl_in, sdu, ID_stage, EX_stage, pc_alt) +-- process(ctrl_in, sdu, ID_stage, EX_stage, pc) -- begin --- pc_alt.nxt <= pc_alt.curr; -- if EX_stage.branch_not_taken = '1' then --- pc_alt.nxt <= pc_alt.pc_branch_revert; --- elsif sdu.ID_stall = '0' then --- pc_alt.nxt <= ctrl_in.exc_vec; --- if ctrl_in.exc_inject = '0' then --- pc_alt.nxt <= pc_alt.plus4; --- if ID_stage.ctrl.jump = '1' then --- pc_alt.nxt <= ID_stage.jimm32; --- elsif ID_stage.ctrl.jump_long = '1' then --- pc_alt.nxt <= ID_stage.reg_a; --- elsif D_stage.ctrl.branch = '1' then -- always take branch --- pc_alt.nxt <= pc_alt.pc_branch; --- end if; +-- pc.nxt <= pc.pc_branch_revert; +-- else +-- pc.nxt <= pc.plus4; +-- if ID_stage.ctrl.jump = '1' then +-- pc.nxt <= ID_stage.jimm32; +-- elsif ID_stage.ctrl.jump_long = '1' then +-- pc.nxt <= ID_stage.reg_a; +-- elsif ID_stage.ctrl.branch = '1' then -- always take branch +-- pc.nxt <= pc.pc_branch; -- end if; -- end if; -- end process; @@ -471,9 +364,13 @@ proc_stage_pc_plus_4_alt: begin if rising_edge(clk_2) then if rst = '1' then - pc_alt.plus4 <= ctrl_in.exc_vec; + pc.plus4 <= ctrl_in.exc_vec; elsif cpu_run = '1' then - pc_alt.plus4 <= pc_alt.curr + 4; + if ctrl_in.exc_inject = '1' then + pc.plus4 <= ctrl_in.exc_vec; + else + pc.plus4 <= pc.curr + 4; + end if; end if; end if; end process; @@ -483,7 +380,7 @@ proc_stage_pc_branch_alt: begin if rising_edge(clk_2) then if cpu_run = '1' then - pc_alt.pc_branch <= pc_alt.curr + ID_stage.bimm18; + pc.pc_branch <= pc.curr + ID_stage.bimm18; end if; end if; end process; @@ -493,11 +390,11 @@ proc_stage_pc_curr_alt: begin if rising_edge(clk_1) then if rst = '1' then - pc_alt.curr <= ctrl_in.exc_vec; - pc_alt.last <= ctrl_in.exc_vec; + pc.curr <= ctrl_in.exc_vec; + pc.last <= ctrl_in.exc_vec; elsif cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then - pc_alt.last <= pc_alt.curr; - pc_alt.curr <= pc_alt.nxt; + pc.last <= pc.curr; + pc.curr <= pc.nxt; end if; end if; end process; @@ -508,7 +405,7 @@ proc_stage_pc_revert_alt: if rising_edge(clk_1) then if cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then if ID_stage.ctrl.branch = '1' then - pc_alt.pc_branch_revert <= pc_alt.plus4; + pc.pc_branch_revert <= pc.plus4; end if; end if; end if; @@ -519,7 +416,7 @@ proc_stage_branch_not_taken_alt: begin if rising_edge(clk_1) then if cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then - pc_alt.branch_not_taken <= EX_stage.branch_not_taken; + pc.branch_not_taken <= EX_stage.branch_not_taken; end if; end if; end process; @@ -527,7 +424,7 @@ proc_stage_branch_not_taken_alt: -------------------------------------------------------------------------- -- ID stage -------------------------------------------------------------------------- - ID_stage.IR <= to_01(imem_data); + ID_stage.IR <= to_01(icache_qry_in.data); ID_stage.pcn <= pc.curr; ID_stage.op <= decode_op(ID_stage.IR); ID_stage.jimm32 <= extract_jimm32(ID_stage.IR, ID_stage.pcn); @@ -546,8 +443,8 @@ proc_ID_except: process(ID_stage, ctrl_in, pc) begin ID_stage.events <= events_clr; - ID_stage.events.inst_load_err <= not ctrl_in.exc_pending and (pc.nxt(1) or pc.nxt(0)); - ID_stage.events.inst_priv_addr <= not ctrl_in.exc_pending and (pc.nxt(word_t'left) and ctrl_in.user_mode); + ID_stage.events.inst_load_err <= not ctrl_in.exc_pending and (ID_stage.pcn(1) or ID_stage.pcn(0)); + ID_stage.events.inst_priv_addr <= not ctrl_in.exc_pending and (ID_stage.pcn(word_t'left) and ctrl_in.user_mode); ID_stage.events.ITLB_LOAD <= ctrl_in.ITLB_stat.vld and ctrl_in.ITLB_stat.exc_miss and not ctrl_in.ITLB_stat.write; ID_stage.events.ITLB_STORE <= ctrl_in.ITLB_stat.vld and ctrl_in.ITLB_stat.exc_miss and ctrl_in.ITLB_stat.write; ID_stage.events.ITLB_MOD <= ctrl_in.ITLB_stat.vld and ctrl_in.ITLB_stat.exc_dirty; @@ -752,11 +649,6 @@ proc_stage_EX_mem_except: end if; end process; -ctrl_out.dtlb_qry.vld2 <= EX_stage.dmem_en and dmem_rdy; -ctrl_out.dtlb_qry.vld <= ID_stage.ctrl.dmem_en; -ctrl_out.dtlb_qry.write <= ID_stage.ctrl.dmem_we; -ctrl_out.dtlb_qry.vaddr <= ID_stage.va; - proc_stage_DMEM_ADDR: process(clk_1) begin @@ -774,12 +666,6 @@ proc_stage_DMEM_ADDR: end if; end if; end process; - dmem_src <= cop_din when EX_stage.ctrl.cop_instr_en = '1' else EX_stage.reg_b; - dmem_be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_en, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.shift_byp) after 1 ns; - dmem_en <= EX_stage.dmem_en; - dmem_we <= EX_stage.ctrl.dmem_we; - dmem_dout <= store_shift(dmem_src, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns; - dmem_addr <= EX_stage.va; EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in; EX_stage.exc <= event_is_active(EX_stage.events); @@ -818,14 +704,6 @@ proc_wptr_mux: end process; -------------------------------------------------------------------------- -proc_stage_bcu_op: - process(clk_1) - begin - if rising_edge(clk_1) and sdu.EX_stall = '0' then - bcu_op_a <= ID_stage.reg_a; - bcu_op_b <= ID_stage.reg_b; - end if; - end process; EX_stage.alu_op1 <= EX_stage.reg_a; @@ -914,18 +792,6 @@ inst_alu: alu flags => EX_stage.alu_flags ); -inst_bcu: bcu - GENERIC MAP - ( - data_width => word_t'length - ) - PORT MAP - ( - op1_in => bcu_op_a, - op2_in => bcu_op_b, - flags => bcu_flags - ); - -------------------------------------------------------------------------- -- MEM stage -------------------------------------------------------------------------- @@ -979,7 +845,7 @@ proc_stage_MEM_n: end process; proc_stage_MEM_mux: - process(MEM_stage, dmem_din) + process(MEM_stage, dcache_qry_in.data) variable temp1 : word_t; variable temp2 : word_t; variable data : word_t; @@ -989,7 +855,7 @@ proc_stage_MEM_mux: if MEM_stage.ctrl.reg_link = '1' then data := MEM_stage.epc + 8; elsif MEM_stage.ctrl.dmem_en = '1' then - temp1 := load_shift(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp); + temp1 := load_shift(dcache_qry_in.data, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp); temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en); be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp); if be(0) = '1' then diff --git a/lib/CPUs/MIPS/src/core/mips_tlb.vhd b/lib/CPUs/MIPS/src/core/mips_tlb.vhd index 518fbe8..9a26051 100644 --- a/lib/CPUs/MIPS/src/core/mips_tlb.vhd +++ b/lib/CPUs/MIPS/src/core/mips_tlb.vhd @@ -12,8 +12,7 @@ ENTITY tlb IS NUM_ENTRIES : natural := 8; CACHE_KSEG1 : boolean := false; TRANSLATE_KSEG0_1 : boolean := true; - USE_TLB : boolean := false; - REGISTERED_OUTPUT : boolean := false + USE_TLB : boolean := false ); Port ( @@ -50,8 +49,6 @@ ARCHITECTURE behavior OF tlb IS signal entry_lo_res : tlb_entry_lo_t; signal qry_res : tlb_query_out_t; signal stat_res : tlb_status_t; - signal qry_res_r : tlb_query_out_t; - signal stat_res_r : tlb_status_t; signal pa : word_t; signal hit : STD_LOGIC; @@ -168,8 +165,8 @@ begin qry_res.vld <= vld_r; qry_res.idx <= (hit_umc or hit_umuc) & reg_qry_entry_lo_addr; - query_out <= qry_res_r when REGISTERED_OUTPUT else qry_res; - ctrl_out.stat <= stat_res_r when REGISTERED_OUTPUT else stat_res; + query_out <= qry_res; + ctrl_out.stat <= stat_res; pa <= entry_lo_res.PFN & vaddr_reg(lg2(TLB_PAGE_SIZE)-1 downto 0); @@ -201,19 +198,6 @@ registered_ctrl_out: end if; end process; -registered_qry_out: - process(clk) - begin - if rising_edge(clk) then - qry_res_r.vld <= '0'; - stat_res_r.vld <= '0'; - if query_in.vld2 = '1' then - qry_res_r <= qry_res; - stat_res_r <= stat_res; - end if; - end if; - end process; - inst_reg_entry_lo: entity work.reg_dual GENERIC MAP ( diff --git a/lib/CPUs/MIPS/src/core/mips_top.vhd b/lib/CPUs/MIPS/src/core/mips_top.vhd index a47a8ed..5723475 100644 --- a/lib/CPUs/MIPS/src/core/mips_top.vhd +++ b/lib/CPUs/MIPS/src/core/mips_top.vhd @@ -36,9 +36,7 @@ entity mips_top is dcache_size : natural := 4096; -- words dcache_line : natural := 8; -- words WITH_TLB : boolean := false; - TRANSLATE_KSEG0_1 : boolean := false; - ITLB_PIPE : boolean := false; - DTLB_PIPE : boolean := false + TRANSLATE_KSEG0_1 : boolean := true ); Port ( @@ -71,43 +69,30 @@ architecture rtl of mips_top is COMPONENT pipeline is Port ( - rst : in STD_LOGIC; - clk : in STD_LOGIC; - ce : in STD_LOGIC; - imem_err : in STD_LOGIC; - imem_rdy : in STD_LOGIC; - imem_en : out STD_LOGIC; - imem_addr : out word_t; - imem_data : in word_t; - dmem_err : in STD_LOGIC; - dmem_rdy : in STD_LOGIC; - dmem_en : out STD_LOGIC; - dmem_we : out STD_LOGIC; - dmem_be : out unsigned(3 downto 0); - dmem_addr : out word_t; - dmem_din : in word_t; - dmem_dout : out word_t; - cop_ir : out word_t; - cop_ir_en : out STD_LOGIC; - cop_din : in word_t; - cop_dout : out word_t; - ctrl_out : out pipe_ctrl_out_t; - ctrl_in : in pipe_ctrl_in_t + rst : in STD_LOGIC; + clk : in STD_LOGIC; + ce : in STD_LOGIC; + imem_err : in STD_LOGIC; + dmem_err : in STD_LOGIC; + cop_ir : out word_t; + cop_ir_en : out STD_LOGIC; + cop_din : in word_t; + cop_dout : out word_t; + ctrl_out : out pipe_ctrl_out_t; + ctrl_in : in pipe_ctrl_in_t; + dtlb_qry_out : out tlb_query_in_t; + dtlb_qry_in : in tlb_query_out_t; + dcache_qry_out : out dcache_query_in_t; + dcache_qry_in : in dcache_query_out_t; + itlb_qry_out : out tlb_query_in_t; + itlb_qry_in : in tlb_query_out_t; + icache_qry_out : out icache_query_in_t; + icache_qry_in : in icache_query_out_t ); END COMPONENT; + signal imem_err : std_logic; - signal imem_rdy : std_logic; - signal imem_en : std_logic; - signal imem_addr : word_t; - signal imem_din : word_t; signal dmem_err : std_logic; - signal dmem_rdy : std_logic; - signal dmem_en : std_logic; - signal dmem_we : std_logic; - signal dmem_addr : word_t; - signal dmem_dout : word_t; - signal dmem_din : word_t; - signal dmem_be : unsigned(3 downto 0); signal biu_busy : STD_LOGIC; signal biu_rst : STD_LOGIC; @@ -166,9 +151,7 @@ architecture rtl of mips_top is dcache_line : natural; WRITE_FIFO_SIZE : natural; WITH_TLB : boolean; - TRANSLATE_KSEG0_1 : boolean; - ITLB_PIPE : boolean; - DTLB_PIPE : boolean + TRANSLATE_KSEG0_1 : boolean ); PORT ( @@ -176,18 +159,7 @@ architecture rtl of mips_top is busy : out STD_LOGIC; imem_err : out STD_LOGIC; - imem_rdy : out STD_LOGIC; - imem_en : in STD_LOGIC; - imem_addr : in word_t; - imem_dout : out word_t; dmem_err : out STD_LOGIC; - dmem_rdy : out STD_LOGIC; - dmem_en : in STD_LOGIC; - dmem_we : in STD_LOGIC; - dmem_be : in unsigned(3 downto 0); - dmem_din : in word_t; - dmem_dout : out word_t; - dmem_addr : in word_t; RST_I : in STD_LOGIC; CLK_I : in STD_LOGIC; @@ -238,28 +210,25 @@ begin inst_pipeline: pipeline PORT MAP ( - rst => cpu_rst, - clk => cpu_clk, - ce => cpu_run, - imem_err => imem_err, - imem_rdy => imem_rdy, - imem_en => imem_en, - imem_addr => imem_addr, - imem_data => imem_din, - dmem_err => dmem_err, - dmem_rdy => dmem_rdy, - dmem_en => dmem_en, - dmem_we => dmem_we, - dmem_be => dmem_be, - dmem_addr => dmem_addr, - dmem_din => dmem_din, - dmem_dout => dmem_dout, - cop_ir => pipe_cop_ir, - cop_ir_en => pipe_cop_ir_en, - cop_din => pipe_cop_din, - cop_dout => pipe_cop_dout, - ctrl_out => pipe_ctrl_out, - ctrl_in => pipe_ctrl_in + rst => cpu_rst, + clk => cpu_clk, + ce => cpu_run, + imem_err => imem_err, + dmem_err => dmem_err, + cop_ir => pipe_cop_ir, + cop_ir_en => pipe_cop_ir_en, + cop_din => pipe_cop_din, + cop_dout => pipe_cop_dout, + ctrl_out => pipe_ctrl_out, + ctrl_in => pipe_ctrl_in, + dtlb_qry_out => biu_ctrl_in.dtlb_qry, + dtlb_qry_in => biu_ctrl_out.dtlb_qry, + dcache_qry_out => biu_ctrl_in.dcache_qry, + dcache_qry_in => biu_ctrl_out.dcache_qry, + itlb_qry_out => biu_ctrl_in.itlb_qry, + itlb_qry_in => biu_ctrl_out.itlb_qry, + icache_qry_out => biu_ctrl_in.icache_qry, + icache_qry_in => biu_ctrl_out.icache_qry ); pipe_ctrl_in <= cop0_ctrl_out.pipe; @@ -300,9 +269,7 @@ inst_biu: biu dcache_line => dcache_line, -- words WRITE_FIFO_SIZE => 4, WITH_TLB => WITH_TLB, - TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1, - ITLB_PIPE => ITLB_PIPE, - DTLB_PIPE => DTLB_PIPE + TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1 ) PORT MAP ( @@ -311,18 +278,7 @@ inst_biu: biu busy => biu_busy, imem_err => imem_err, - imem_rdy => imem_rdy, - imem_en => imem_en, - imem_addr => imem_addr, - imem_dout => imem_din, dmem_err => dmem_err, - dmem_rdy => dmem_rdy, - dmem_en => dmem_en, - dmem_we => dmem_we, - dmem_be => dmem_be, - dmem_addr => dmem_addr, - dmem_din => dmem_dout, - dmem_dout => dmem_din, RST_I => biu_rst, CLK_I => CLK_I, @@ -342,12 +298,12 @@ inst_biu: biu ); - biu_ctrl_in.dcache <= cop0_ctrl_out.dcache; biu_ctrl_in.icache <= cop0_ctrl_out.icache; - biu_ctrl_in.dtlb_ctrl <= cop0_ctrl_out.dtlb_ctrl; + biu_ctrl_in.dcache <= cop0_ctrl_out.dcache; biu_ctrl_in.itlb_ctrl <= cop0_ctrl_out.itlb_ctrl; - biu_ctrl_in.dtlb_qry <= pipe_ctrl_out.dtlb_qry; - biu_ctrl_in.itlb_qry <= pipe_ctrl_out.itlb_qry; + biu_ctrl_in.dtlb_ctrl <= cop0_ctrl_out.dtlb_ctrl; +-- biu_ctrl_in.itlb_qry <= pipe_ctrl_out.itlb_qry; +-- biu_ctrl_in.dtlb_qry <= pipe_ctrl_out.dtlb_qry; ------------------------------------------- -- debug @@ -362,16 +318,16 @@ debug_imem_din_register: begin if rising_edge(cpu_clk) then debug.imem_din_vld <= '0'; - if imem_rdy = '1' then + if biu_ctrl_out.icache_qry.rdy = '1' then if en_r = '1' then debug.imem_addr_reg <= addr_r; - debug.imem_din_reg <= imem_din; + debug.imem_din_reg <= biu_ctrl_out.icache_qry.data; debug.imem_din_vld <= '1'; end if; - if imem_en = '1' then - addr_r := imem_addr; + if biu_ctrl_in.icache_qry.en = '1' then + addr_r := biu_ctrl_in.icache_qry.addr; end if; - en_r := imem_en; + en_r := biu_ctrl_in.icache_qry.en; end if; end if; end process; @@ -386,20 +342,20 @@ debug_dmem_din_register: if rising_edge(cpu_clk) then debug.dmem_din_vld <= '0'; debug.dmem_dout_vld <= '0'; - if dmem_rdy = '1' then + if biu_ctrl_out.dcache_qry.rdy = '1' then if en_r = '1' then debug.dmem_addr_reg <= addr_r; - debug.dmem_din_reg <= dmem_din; + debug.dmem_din_reg <= biu_ctrl_out.dcache_qry.data; debug.dmem_din_vld <= not we_r; debug.dmem_dout_reg <= dout_r; debug.dmem_dout_vld <= we_r; end if; - if dmem_en = '1' then - dout_r := dmem_dout; - addr_r := dmem_addr; + if biu_ctrl_in.dcache_qry.en = '1' then + dout_r := biu_ctrl_in.dcache_qry.data; + addr_r := biu_ctrl_in.dcache_qry.addr; end if; - en_r := dmem_en; - we_r := dmem_we; + en_r := biu_ctrl_in.dcache_qry.en; + we_r := biu_ctrl_in.dcache_qry.we; end if; end if; end process; diff --git a/lib/CPUs/MIPS/src/core/mips_types.vhd b/lib/CPUs/MIPS/src/core/mips_types.vhd index 7153a05..e518f07 100644 --- a/lib/CPUs/MIPS/src/core/mips_types.vhd +++ b/lib/CPUs/MIPS/src/core/mips_types.vhd @@ -278,6 +278,31 @@ package mips_types is cause : word_t; end record; + type icache_query_in_t is record + en : std_logic; + nc : std_logic; + addr : word_t; + end record; + + type icache_query_out_t is record + rdy : std_logic; + data : word_t; + end record; + + type dcache_query_in_t is record + en : std_logic; + we : std_logic; + be : unsigned(3 downto 0); + nc : std_logic; + addr : word_t; + data : word_t; + end record; + + type dcache_query_out_t is record + rdy : std_logic; + data : word_t; + end record; + type cache_ctrl_t is record inv_addr : word_t; inv_at : STD_LOGIC; @@ -305,7 +330,6 @@ package mips_types is type tlb_query_in_t is record vld : std_logic; - vld2 : std_logic; write : std_logic; vaddr : word_t; idx : unsigned (lg2(TLB_NUM_ENTRIES) downto 0); @@ -351,6 +375,8 @@ package mips_types is dcache : cache_ctrl_t; itlb_qry : tlb_query_in_t; dtlb_qry : tlb_query_in_t; + icache_qry : icache_query_in_t; + dcache_qry : dcache_query_in_t; end record; type biu_ctrl_out_t is record @@ -358,6 +384,8 @@ package mips_types is dtlb_ctrl : tlb_ctrl_out_t; itlb_qry : tlb_query_out_t; dtlb_qry : tlb_query_out_t; + icache_qry : icache_query_out_t; + dcache_qry : dcache_query_out_t; end record; type pipe_ctrl_in_t is record @@ -372,8 +400,8 @@ package mips_types is exc_vec : word_t; ITLB_stat : tlb_status_t; DTLB_stat : tlb_status_t; - itlb_qry : tlb_query_out_t; - dtlb_qry : tlb_query_out_t; +-- itlb_qry : tlb_query_out_t; +-- dtlb_qry : tlb_query_out_t; end record; type pipe_ctrl_out_t is record @@ -385,8 +413,8 @@ package mips_types is dmem_addr : word_t; exc_req : STD_LOGIC; exc_ack : STD_LOGIC; - itlb_qry : tlb_query_in_t; - dtlb_qry : tlb_query_in_t; +-- itlb_qry : tlb_query_in_t; +-- dtlb_qry : tlb_query_in_t; end record; type cop0_ctrl_in_t is record