📄 icache_gti.vhd
字号:
-- Calculate Data types constant Nr_Of_Data_Words : natural := (C_CACHE_BYTE_SIZE/4); constant Data_Addr_Size : natural := log2(Nr_Of_Data_Words); subtype DATA_ADDR_TYPE is std_logic_vector(0 to Data_Addr_Size-1); subtype DATA_WORD_TYPE is std_logic_vector(0 to 31); -- Always use BRAM for tag if data RAM is >= 2048 bits constant Tag_Force_BRAM : boolean := Data_Addr_Size >= 9; signal reset_bool : boolean; signal last_Valid_Instr_Tag_Addr : std_logic_vector(0 to 31); signal valid_instr_tag_addr : std_logic_vector(0 to 31); signal valid_addr_strobe : std_logic; signal valid_addr_strobe_q : std_logic; signal icache_Drop_Request_i : std_logic; signal valid_addr : std_logic; signal valid_addr_q : std_logic; signal valid_tag_addr : std_logic; signal valid_Req : std_logic; signal valid_Req_XX : std_logic; signal valid_req_1st : std_logic; signal valid_req_1st_XX : std_logic; signal xx_valid_data : std_logic; signal xx_data : std_logic_vector(0 to 31); signal cache_updated_allowed : std_logic; signal tag_write_cache : std_logic_vector(0 to 3); signal data_write_cache : std_logic_vector(0 to 3); signal tag_ok : std_logic; signal word_is_valid : std_logic; signal icache_hit : std_logic; signal icache_miss : std_logic; signal instr_Addr_1 : std_logic_vector(0 to 31); signal req_Addr : std_logic_vector(0 to 31); signal req_Addr_next : std_logic_vector(0 to 31); signal tag_bits : TAG_WORD_TYPE; signal check_tag : std_logic_vector(0 to NO_ADDR_TAG_BITS); signal tag_bits_addr_part : std_logic_vector(0 to NO_ADDR_TAG_BITS); signal addr_Tag_Bits : std_logic_vector(0 to NO_ADDR_TAG_BITS-1); signal addr_Tag_Bits_next : std_logic_vector(0 to NO_ADDR_TAG_BITS-1); signal new_tag_bits : TAG_WORD_TYPE; signal tag_addr_lookup : TAG_ADDR_TYPE; signal new_tag_addr : TAG_ADDR_TYPE; signal real_new_tag_addr : TAG_ADDR_TYPE; signal cacheline_cnt : std_logic_vector(0 to CACHELINE_BITS-1); signal cacheline_cnt2 : std_logic_vector(0 to CACHELINE_BITS-1); constant cacheline_cnt_Low : std_logic_vector(0 to CACHELINE_BITS-1) := (others => '0'); constant cacheline_cnt_High : std_logic_vector(0 to CACHELINE_BITS-1) := (others => '1'); 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 new_data_addr1 : std_logic_vector(0 to Data_Addr_Size-CACHELINE_BITS-1); signal new_data_addr : DATA_ADDR_TYPE; signal data_addr_lookup : DATA_ADDR_TYPE; signal iCACHE_Data_i : std_logic_vector(0 to C_DATA_SIZE-1); constant null4 : std_logic_vector(0 to 3) := (others => '0'); constant null32 : std_logic_vector(0 to 31) := (others => '0'); signal ram_enable : std_logic;begin reset_bool <= (reset = '1'); --****************************** -- Trace Signals --****************************** -- Using DFFs to minimize the impact on timing Trace_Signals_DFF: process (Clk) is begin -- process Trace_Signals_DFF if Clk'event and Clk = '1' then -- rising clock edge if reset_bool then -- synchronous reset (active high) Trace_ICache_Req <= '0'; Trace_ICache_Hit <= '0'; else -- only valid 1 clock cycle for a valid cache access Trace_ICache_Req <= valid_req_1st; Trace_ICache_Hit <= Tag_ok; end if; end if; end process Trace_Signals_DFF; --------------------------------------------------------------------------- -- First we need to detect if the address is within the cacheable range --------------------------------------------------------------------------- Valid_Tag_Addr_Detect : process (IB_Tag_Addr) is variable valid : std_logic; begin -- process Valid_Tag_Addr_Detect valid := '1'; if (C_VALID_ADDR_BITS /= 0) then for I in 0 to C_VALID_ADDR_BITS-1 loop if (IB_Tag_Addr(I) /= C_ICACHE_BASEADDR(I)) then valid := '0'; end if; end loop; -- I end if; valid_tag_addr <= valid; end process Valid_Tag_Addr_Detect; Using_TLBS : if (C_USE_MMU >= C_MMU_PROTECT) generate signal icache_req_prev_keep : std_logic; signal ib_Tag_Addr_Strobe_q : std_logic; signal icache_Drop_Request_q : std_logic; signal valid_addr_qq : std_logic; signal icache_req_prev_i : std_logic; signal icache_allow_Data_Strobe : std_logic; signal icache_delayed_Data_Strobe : std_logic; signal icache_hit_carry : std_logic; begin valid_addr_strobe <= IB_Addr_Strobe; -- Detect previous cache request Valid_Req_Prev_Detect : process (Clk) is begin -- process Valid_Req_Prev_Detect if Clk'event and Clk = '1' then -- rising clock edge if reset_bool then -- synchronous reset (active true) icache_req_prev_keep <= '0'; else icache_req_prev_keep <= icache_req_prev_i; end if; ib_Tag_Addr_Strobe_q <= IB_Tag_Addr_Strobe; icache_Drop_Request_q <= icache_drop_request_i; valid_addr_qq <= valid_addr_q; end if; end process Valid_Req_Prev_Detect; icache_req_prev_i <= '1' when valid_addr_q = '0' and valid_addr_qq = '1' and icache_Drop_Request_q = '1' else '0' when ib_Tag_Addr_Strobe_q = '1' or valid_addr_q = '1' or icache_Drop_Request_q = '0' else icache_req_prev_keep; ICACHE_Req_Prev <= icache_req_prev_i; -- Generate data strobe Allow_Data_Strobe : process (Clk) is begin -- process Allow_Data_Strobe if Clk'event and Clk = '1' then -- rising clock edge if reset_bool then -- synchronous reset (active true) icache_allow_Data_Strobe <= '0'; icache_delayed_Data_Strobe <= '0'; else icache_allow_Data_Strobe <= icache_Drop_Request_i and not IB_Block_Ready_MMU; icache_delayed_Data_Strobe <= icache_hit and not icache_allow_Data_Strobe; end if; end if; end process Allow_Data_Strobe; -- ICACHE_Data_Strobe <= (icache_hit and icache_allow_Data_Strobe) or -- (icache_delayed_Data_Strobe); data_strobe_carry_and : carry_and generic map (C_TARGET => C_TARGET) -- [TARGET_FAMILY_TYPE] port map (Carry_IN => icache_hit, -- [in std_logic] A => icache_allow_Data_Strobe, -- [in std_logic] Carry_OUT => icache_hit_carry); -- [out std_logic] data_strobe_carry_or : carry_or generic map (C_TARGET => C_TARGET) -- [TARGET_FAMILY_TYPE] port map (Carry_IN => icache_hit_carry, -- [in std_logic] A => icache_delayed_Data_Strobe, -- [in std_logic] Carry_OUT => ICACHE_Data_Strobe); -- [out std_logic] end generate Using_TLBS; Not_Using_TLBS : if (C_USE_MMU < C_MMU_PROTECT) generate signal last_Valid_Instr_Addr : std_logic_vector(0 to 31); signal valid_instr_addr : std_logic_vector(0 to 31); begin -- Store the instruction address since it's only valid when IB_Addr_Strobe is '1' Instr_Addr_Reg : process (Clk) is begin -- process Instr_Addr_Reg if Clk'event and Clk = '1' then -- rising clock edge if (IB_Addr_Strobe = '1') then last_Valid_Instr_Addr <= IB_Addr; end if; end if; end process Instr_Addr_Reg; last_Valid_Instr_Tag_Addr <= last_Valid_Instr_Addr; valid_instr_tag_addr <= valid_instr_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_addr; end if; end if; end process Instr_Addr_DFF; valid_instr_addr <= last_Valid_Instr_Addr when IB_Addr_Strobe = '0' else IB_Addr; valid_addr_strobe <= IB_Tag_Addr_Strobe; ICACHE_Req_Prev <= '0'; ICACHE_Data_Strobe <= icache_hit; valid_addr_q <= '0'; -- Unused end generate Not_Using_TLBs; Using_Virtual_Memory : if (C_USE_MMU = C_MMU_VIRTUAL) generate signal instr_Tag_Addr_1 : std_logic_vector(0 to 31); signal ib_VMode_1 : std_logic; signal mem_PID_1 : std_logic_vector(0 to 7); signal ib_vMode_q : std_logic; signal valid_tag_addr_q : std_logic; signal valid_TLB_addr_q : std_logic; signal ib_TLB_Addr_MMU_q : std_logic_vector(0 to 31); signal ib_TLB_Addr_Strobe_q : std_logic; signal instr_Addr_1_keep : std_logic_vector(0 to 31); 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_Tag_Addr_1 <= (others => '0'); ib_VMode_1 <= '0'; mem_PID_1 <= (others => '0'); ib_TLB_Addr_MMU_q <= (others => '0'); ib_TLB_Addr_Strobe_q <= '0'; instr_Addr_1_keep <= (others => '0'); else instr_Tag_Addr_1 <= valid_instr_tag_addr; if IB_Tag_Addr_Strobe = '1' then ib_VMode_1 <= IB_VMode; mem_PID_1 <= MEM_PID; end if; ib_TLB_Addr_MMU_q <= IB_TLB_Addr_MMU; ib_TLB_Addr_Strobe_q <= IB_TLB_Addr_Strobe; instr_Addr_1_keep <= instr_Addr_1; end if; end if; end process Instr_Addr_DFF; instr_Addr_1 <= instr_Tag_Addr_1 when ib_VMode_q = '0' else ib_TLB_Addr_MMU_q when ib_TLB_Addr_Strobe_q = '1' else instr_Addr_1_keep; -- First we need to detect if the address is within the cacheable range Valid_Cache_Addr_Detect : process (IB_Cache_Addr_MMU) is variable valid : std_logic; begin -- process Valid_Cache_Addr_Detect valid := '1'; if (C_VALID_ADDR_BITS /= 0) then for I in 0 to C_VALID_ADDR_BITS-1 loop if (IB_Cache_Addr_MMU(I) /= C_ICACHE_BASEADDR(I)) then valid := '0'; end if; end loop; end if; ICACHE_Valid_Addr <= valid; end process Valid_Cache_Addr_Detect; valid_addr <= valid_tag_addr when IB_VMode = '0' else IB_Valid_TLB_Addr; -- Detect previous cache request Valid_Req_Prev_Virtual_Detect : process (Clk) is begin -- process Valid_Req_Prev_Virtual_Detect
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -