icache.vhd
来自「Xilinx软核microblaze源码(VHDL)版本7.10」· VHDL 代码 · 共 916 行 · 第 1/3 页
VHD
916 行
signal Update_Idle : std_logic; signal Valid_Bits : std_logic_vector(0 to C_CACHELINE_SIZE-1); signal Real_Valid_Bits : std_logic_vector(0 to C_CACHELINE_SIZE-1); constant All_False_Bits : std_logic_vector(0 to C_CACHELINE_SIZE-1) := (others => '0'); signal Last_Valid_Instr_Addr : std_logic_vector(0 to 31); signal True_Instr_Addr : std_logic_vector(0 to 31); signal new_data_addr1 : std_logic_vector(0 to Data_Addr_Size-1-CACHELINE_BITS); signal new_data_addr : DATA_ADDR_TYPE; signal data_addr_lookup : DATA_ADDR_TYPE; signal null4 : std_logic_vector(0 to 3); signal null32 : std_logic_vector(0 to 31); signal bram_enable : std_logic; constant null_tag_data : TAG_WORD_TYPE := (others => '0'); constant null_data_data : std_logic_vector(0 to 31) := (others => '0'); signal data_cache_write : std_logic_vector(0 to 3);begin -- XCL Clocks ICACHE_FSL_IN_Clk <= Clk; ICACHE_FSL_OUT_Clk <= Clk; null4 <= (others => '0'); null32 <= (others => '0'); bram_enable <= '1'; True_Instr_Addr <= Last_Valid_Instr_Addr when I_AS = '0' else Instr_Addr; TT : process (Clk) is begin -- process TT if Clk'event and Clk = '1' then -- rising clock edge if (I_AS = '1') then Last_Valid_Instr_Addr <= Instr_Addr; end if; end if; end process TT; --------------------------------------------------------------------------- -- Need to delay the cache enable so that we can stop at the right place --------------------------------------------------------------------------- ICache_Enabled_DFF : process (Clk) is begin -- process ICache_Enabled_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) ICache_Enabled_1 <= '0'; else ICache_Enabled_1 <= ICache_Enabled_i; end if; end if; end process ICache_Enabled_DFF; ICache_Enabled_i <= '1' when ICache_Enabled else '0'; --------------------------------------------------------------------------- -- First we need to detect if the address is within the cacheable range --------------------------------------------------------------------------- Valid_Addr_Detect : process (Instr_Addr) is variable valid : std_logic; begin -- process Valid_Addr_Detect valid := '1'; if (C_VALID_ADDR_BITS /= 0) then for I in 0 to C_VALID_ADDR_BITS-1 loop if (Instr_Addr(I) /= C_ICACHE_BASEADDR(I)) then valid := '0'; end if; end loop; -- I end if; valid_addr <= valid; end process Valid_Addr_Detect; Valid_Req_Handle : process (Clk) is begin -- process Valid_Req_Handle if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) Valid_Req <= '0'; valid_req_1st_cycle <= '0'; Valid_Req_XX <= '0'; Valid_Req_1st_Cycle_XX <= '0'; else if (I_AS = '1') then Valid_Req <= valid_addr and ICache_Enabled_i; elsif (IReady_I = '1') then Valid_Req <= '0'; end if; if (I_AS = '1') then if (C_ICACHE_ALWAYS_USED = 0) then valid_Req_XX <= valid_addr and ICache_Enabled_i; else valid_Req_XX <= valid_addr; end if; elsif (IReady_I = '1') then valid_Req_XX <= '0'; end if; if (C_ICACHE_ALWAYS_USED = 0) then Valid_Req_1st_Cycle_XX <= valid_addr and I_AS and ICache_Enabled_i; else Valid_Req_1st_Cycle_XX <= valid_addr and I_AS; end if; Valid_Req_1st_Cycle <= valid_addr and I_AS and ICache_Enabled_i; end if; end if; end process Valid_Req_Handle; Use_XX_Accesses : if (C_ICACHE_ALWAYS_USED /= 0) generate First_Valid_Data_in_Cacheline : process (Clk) is begin -- process First_Valid_Data_in_Cacheline if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) xx_data <= (others => '0'); xx_valid_data <= '0'; xx_access_done <= '1'; xx_access <= '0'; else xx_valid_data <= '0'; if ((Valid_Req_1st_Cycle_XX and not Tag_Ok) = '1') then xx_access <= valid_Req_XX and not valid_Req; end if; if ((xx_access = '1') and (xx_access_done = '1') and (ICACHE_FSL_IN_Exists = '1')) then xx_data <= ICACHE_FSL_IN_Data; xx_valid_data <= '1'; xx_access_done <= '0'; xx_access <= '0'; end if; if (ICACHE_FSL_IN_Exists = '1') and (Update_Idle = '1') then xx_access_done <= '1'; end if; end if; end if; end process First_Valid_Data_in_Cacheline; Handling_when_to_allow_cache_updating: process (Clk) is begin -- process Handling_when_to_allow_cache_updating if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) xx_req_with_update <= '0'; elsif ((Valid_req_1st_cycle_XX and not Tag_Ok) = '1') then xx_req_with_update <= valid_Req; end if; end if; end process Handling_when_to_allow_cache_updating; Allow_Cache_Write : process (Clk) is begin -- process Allow_Cache_Write if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) cache_updated_allowed <= '0'; elsif (Update_Idle = '1') then cache_updated_allowed <= xx_req_with_update; end if; end if; end process Allow_Cache_Write; end generate Use_XX_Accesses; No_XX_Accesses : if (C_ICACHE_ALWAYS_USED = 0) generate xx_valid_data <= '0'; cache_updated_allowed <= '1'; end generate No_XX_Accesses; Valid_ICache_Access <= valid_Req_XX; --------------------------------------------------------------------------- -- The tag handling -- -- Tag is divided into -- (0 to X-1) word_valid (cacheline bits) -- (X) tag_valid (1 bit) -- (X+1 to Y) tag address (tag_addr bits) --------------------------------------------------------------------------- -- Instruction address is only valid for 1 clock cycle due to the -- pipelining of the instruction fetches -- We need to compare the tag read from the tag with the current instr addr -- The instr address needs to be clocked Instr_Addr_DFF : process (Clk) is begin -- process Instr_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) Instr_Addr_1 <= (others => '0'); else Instr_Addr_1 <= True_Instr_Addr; end if; end if; end process Instr_Addr_DFF; -- This is what we need to check against the tag memory Check_Tag <= '1' & Instr_Addr_1(30 - CACHELINE_BITS - Tag_Addr_Size - NO_ADDR_TAG_BITS to 29 - CACHELINE_BITS - Tag_Addr_Size); -- This is the bits for the tag memory Tag_Bits_C <= tag_bits(C_CACHELINE_SIZE to tag_bits'right); tag_hit_comparator : comparator generic map ( C_TARGET => C_TARGET, C_IS_FIRST => true, C_SIZE => Tag_Bits_C'length) -- [natural] port map ( Carry_IN => Valid_Req, -- [in std_logic] DI => '0', -- [ in std_logic] A => Tag_Bits_C, B => Check_Tag, Carry_OUT => tag_ok); -- [out std_logic] --------------------------------------------------------------------------- -- Now we need to add the valid bit check --------------------------------------------------------------------------- Using_FPGA_FSL_2 : if C_TARGET /= RTL generate signal combined_iready_n : std_logic; begin Using_8word_lines : if (C_CACHELINE_SIZE = 8) generate signal temp_Instr_Addr : std_logic_vector(0 to CACHELINE_BITS-1); begin temp_Instr_Addr <= Instr_Addr_1(30-CACHELINE_BITS to 29); Using_8Line_4LUT : if ( not C_LUT6_OPTIMIZED ) generate signal addr_dec : std_logic_vector(0 to 7); signal valid_check_sel : std_logic_vector(0 to 3); signal valid_check_carry : std_logic_vector(0 to 4); begin Gen_Addr_Decoder : process (temp_Instr_Addr) is begin -- process Gen_Addr_Decoder addr_dec <= (others => '0'); addr_dec(to_integer(unsigned(temp_Instr_Addr))) <= '1'; end process Gen_Addr_Decoder; valid_check_carry(4) <= tag_ok; valid_check_cacheline : for I in 3 downto 0 generate begin -- Pass carry value when no addr_dec is set -- Force a zero when one addr_dec is set and the mem_tag_bits is not set valid_check_sel(I) <= -- Passing when no addr_dec is set '1' when (addr_dec(2*I+1)='0' and (addr_dec(2*I)='0')) else -- Passing if the corresponding mem_tag_bit is set '1' when (addr_dec(2*I+1) = '1') and (tag_bits(2*I+1) = '1') else '1' when (addr_dec(2*I) = '1') and (tag_bits(2*I) = '1') else '0'; valid_check_carry_and_I : carry_and generic map (C_TARGET => C_TARGET) -- [TARGET_FAMILY_TYPE] port map (Carry_IN => valid_check_carry(I+1), -- [in std_logic] A => valid_check_sel(I), -- [in std_logic] Carry_OUT => valid_check_carry(I)); -- [out std_logic] end generate valid_check_cacheline; Word_Is_Valid <= valid_check_carry(0); end generate Using_8Line_4LUT; Using_8Line_6LUT : if ( C_LUT6_OPTIMIZED ) generate signal valid_check_sel : std_logic_vector(0 to 2); signal valid_check_carry : std_logic_vector(0 to 3); begin valid_check_carry(3) <= tag_ok; valid_check_sel(0) <= tag_bits(0) when ( temp_Instr_Addr = "000" ) else tag_bits(1) when ( temp_Instr_Addr = "001" ) else tag_bits(2) when ( temp_Instr_Addr = "010" ) else '1'; -- Bypass valid_check_sel(1) <= tag_bits(3) when ( temp_Instr_Addr = "011" ) else tag_bits(4) when ( temp_Instr_Addr = "100" ) else tag_bits(5) when ( temp_Instr_Addr = "101" ) else '1'; -- Bypass valid_check_sel(2) <= tag_bits(6) when ( temp_Instr_Addr = "110" ) else tag_bits(7) when ( temp_Instr_Addr = "111" ) else '1'; -- Bypass valid_check_cacheline : for I in 2 downto 0 generate begin valid_check_carry_and_I : carry_and generic map (C_TARGET => C_TARGET) -- [TARGET_FAMILY_TYPE] port map (Carry_IN => valid_check_carry(I+1), -- [in std_logic] A => valid_check_sel(I), -- [in std_logic] Carry_OUT => valid_check_carry(I)); -- [out std_logic] end generate valid_check_cacheline; Word_Is_Valid <= valid_check_carry(0); end generate Using_8Line_6LUT; end generate Using_8word_lines; Using_4word_lines : if (C_CACHELINE_SIZE = 4) generate begin Using_4LUT : if ( not C_LUT6_OPTIMIZED ) generate signal sel1 : std_logic; signal sel2 : std_logic; signal carry : std_logic; begin -- Instr_Addr_1(28 to 29) = "11" <=> tag_bits(3) -- Instr_Addr_1(28 to 29) = "10" <=> tag_bits(2) Sel1 <= not(Instr_Addr_1(28)) or ((Instr_Addr_1(29) and tag_bits(3)) or
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?