📄 icache_gti.vhd
字号:
if Clk'event and Clk = '1' then -- rising clock edge ib_vMode_q <= ib_vMode; valid_tag_addr_q <= valid_tag_addr; valid_TLB_addr_q <= IB_Valid_TLB_Addr; end if; end process Valid_Req_Prev_Virtual_Detect; valid_addr_q <= valid_tag_addr_q when ib_vMode_q = '0' else valid_TLB_addr_q; -- This is what we need to check against the tag memory Check_Tag <= '1' & instr_Tag_Addr_1(30 - CACHELINE_BITS - Tag_Addr_Size - NO_ADDR_TAG_BITS + C_MMU_BITS to 29 - CACHELINE_BITS - Tag_Addr_Size) & mem_PID_1 & ib_VMode_1; addr_Tag_Bits_next <= req_Addr(30 - CACHELINE_BITS - Tag_Addr_Size - NO_ADDR_TAG_BITS + C_MMU_BITS to 29 - CACHELINE_BITS - Tag_Addr_Size) & mem_PID_1 & ib_VMode_1; req_Addr_next <= instr_Tag_Addr_1; end generate Using_Virtual_Memory; Using_Protected_Memory : if (C_USE_MMU = C_MMU_PROTECT) generate signal valid_tag_addr_q : std_logic; begin -- Store address since it's only valid when IB_Tag_Addr_Strobe is '1' Instr_Tag_Addr_Reg : process (Clk) is begin -- process Instr_Tag_Addr_Reg if Clk'event and Clk = '1' then -- rising clock edge if (IB_Tag_Addr_Strobe = '1') then last_Valid_Instr_Tag_Addr <= IB_Tag_Addr; end if; end if; end process Instr_Tag_Addr_Reg; valid_instr_tag_addr <= last_Valid_Instr_Tag_Addr when IB_Tag_Addr_Strobe = '0' else IB_Tag_Addr; -- We need to delay the address one clock cycle, since reading -- the tag memory also takes one clock cycle Instr_Addr_DFF : process (Clk) is begin -- process Instr_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if reset_bool then -- synchronous reset (active true) instr_Addr_1 <= (others => '0'); else instr_Addr_1 <= valid_instr_tag_addr; end if; end if; end process Instr_Addr_DFF; -- Detect previous cache request Valid_Req_Prev_Not_Virtual_Detect : process (Clk) is begin -- process Valid_Req_Prev_Not_Virtual_Detect if Clk'event and Clk = '1' then -- rising clock edge valid_tag_addr_q <= valid_tag_addr; end if; end process Valid_Req_Prev_Not_Virtual_Detect; valid_addr_q <= valid_tag_addr_q; end generate Using_Protected_Memory; Not_Using_Virtual_Memory : if (C_USE_MMU /= C_MMU_VIRTUAL) generate valid_addr <= valid_tag_addr; ICACHE_Valid_Addr <= valid_tag_addr; -- 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); addr_Tag_Bits_next <= req_Addr(30 - CACHELINE_BITS - Tag_Addr_Size - NO_ADDR_TAG_BITS to 29 - CACHELINE_BITS - Tag_Addr_Size); req_Addr_next <= instr_Addr_1; end generate Not_Using_Virtual_Memory; -- Drop other bus access if this access is to be handled by the icache Drop_Other_Request_Handler : process (Clk) is begin -- process Drop_Other_Request_Handler if Clk'event and Clk = '1' then -- rising clock edge if reset_bool then -- synchronous reset (active true) icache_Drop_Request_i <= '0'; elsif valid_addr_strobe = '1' then if (C_ICACHE_ALWAYS_USED = 0) then icache_Drop_Request_i <= valid_addr and ICache_Enabled and not IF_ICache_Inhibit; else icache_Drop_Request_i <= valid_addr; end if; end if; end if; end process Drop_Other_Request_Handler; ICACHE_Drop_Request <= icache_Drop_Request_i; -- Determine if this is a valid request -- valid_req and valid_req_XX are active during the whole access -- valid_req_1st and valid_req_1st_XX are only active one clock cycle Valid_Req_Handle : process (Clk) is begin -- process Valid_Req_Handle if Clk'event and Clk = '1' then -- rising clock edge if reset_bool then -- synchronous reset (active true) valid_Req <= '0'; valid_Req_XX <= '0'; valid_addr_strobe_q <= '0'; else if (valid_addr_strobe = '1') then valid_Req <= valid_addr and ICache_Enabled and not IF_ICache_Inhibit; elsif valid_Req = '1' and icache_hit = '1' then valid_Req <= '0'; end if; if (valid_addr_strobe = '1') then if (C_ICACHE_ALWAYS_USED = 0) then valid_Req_XX <= valid_addr and ICache_Enabled and not IF_ICache_Inhibit; else valid_Req_XX <= valid_addr; end if; elsif valid_Req_XX = '1' and icache_hit = '1' then valid_Req_XX <= '0'; end if; valid_addr_strobe_q <= valid_addr_strobe; end if; end if; end process Valid_Req_Handle; valid_req_1st <= valid_req and valid_addr_strobe_q; valid_req_1st_XX <= valid_req_XX and valid_addr_strobe_q; Use_XX_Accesses : if (C_ICACHE_ALWAYS_USED /= 0) generate signal xx_access : std_logic; signal xx_access_done : std_logic; signal xx_req_with_update : std_logic; begin 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 = '1' 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 (icache_miss = '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_bool then -- synchronous reset (active true) xx_req_with_update <= '0'; elsif (icache_miss) = '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_bool 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'; xx_data <= (others => '0'); end generate No_XX_Accesses; ICACHE_Valid_Req <= (valid_Req_XX = '1'); -- This is the address tag bits for the tag memory tag_bits_addr_part <= tag_bits(C_CACHELINE_SIZE to tag_bits'right); -- The address matches and the tag is valid Using_RTL_1: if (C_TARGET = RTL) generate tag_ok <= valid_Req when tag_bits_addr_part = Check_Tag else '0'; end generate Using_RTL_1; Using_FPGA_FSL_1 : if C_TARGET /= RTL generate tag_hit_comparator : comparator generic map ( C_TARGET => C_TARGET, C_IS_FIRST => true, C_SIZE => tag_bits_addr_part'length) -- [natural] port map ( Carry_IN => valid_Req, -- [in std_logic] DI => '0', -- [ in std_logic] A => tag_bits_addr_part, B => Check_Tag, Carry_OUT => tag_ok); -- [out std_logic] end generate Using_FPGA_FSL_1; Using_RTL_2: if (C_TARGET = RTL) generate -- Need to check if the word within the cacheline is valid Icache_hit_Handle : process (last_Valid_Instr_Tag_Addr, tag_ok, tag_bits) variable temp_Instr_Addr : std_logic_vector(0 to CACHELINE_BITS-1); begin -- process Icache_hit_Handle temp_Instr_Addr := last_Valid_Instr_Tag_Addr(30-cacheline_bits to 29); Icache_hit <= tag_ok and tag_bits(to_integer(unsigned(temp_Instr_Addr))); end process Icache_hit_Handle; end generate Using_RTL_2; --------------------------------------------------------------------------- -- Now we need to add the valid bit check --------------------------------------------------------------------------- Using_FPGA_FSL_2 : if C_TARGET /= RTL generate Using_8word_lines : if (C_CACHELINE_SIZE = 8) generate signal temp_Instr_Addr : std_logic_vector(0 to CACHELINE_BITS-1); begin -- Extract address. temp_Instr_Addr <= Last_valid_instr_tag_addr(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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -