📄 dcache_gti.vhd
字号:
signal Req_Addr : std_logic_vector(0 to 31); signal new_cacheline_addr : std_logic_vector(0 to 31); signal new_data_data : std_logic_vector(0 to C_DATA_SIZE-1); signal new_data_write : std_logic_vector(0 to 3); signal new_data_addr : DATA_ADDR_TYPE; signal ex_data_addr_lookup : DATA_ADDR_TYPE; signal mem_data_write : std_logic := '0'; signal mem_Write_Allowed_on_miss_hold : std_logic := '0'; signal mem_Write_Allowed_on_miss : std_logic := '0'; signal mem_Write_Allowed_on_hit : std_logic := '0'; signal mem_Write_Allowed : std_logic := '0'; signal mem_Address_Written : std_logic := '0'; signal mem_Data_Written : std_logic := '0'; signal dcache_data_strobe_ii : std_logic; signal dcache_data_strobe_i : std_logic; signal ex_piperun_i : std_logic; subtype word_type is std_logic_vector(0 to 31); type small_memory is array (natural range 0 to C_CACHELINE_SIZE-1) of word_type; signal cacheline_copy : small_memory; signal cacheline_copy_valid : std_logic_vector(0 to C_CACHELINE_SIZE-1); signal use_cacheline_copy_i : std_logic; signal use_cacheline_copy : std_logic; signal cacheline_copy_hit : std_logic; signal cacheline_copy_hit_hold : std_logic; signal cacheline_copy_data : word_type; constant null4 : std_logic_vector(0 to 3) := (others => '0'); constant null32 : std_logic_vector(0 to 31) := (others => '0'); signal reset_b : boolean; signal mem_data_updated : std_logic; signal mem_write_data_be : std_logic_vector(0 to 3); signal mem_mch_byte_access : std_logic; signal mem_mch_addr : std_logic_vector(0 to 31); signal mem_mch_be : std_logic_vector(0 to 3); signal mem_mch_data : std_logic_vector(0 to 31); signal dcache_FSL_OUT_Write_i : std_logic; signal dcache_fsl_request : std_logic; signal dcache_fsl_request_hold : std_logic; signal ram_enable : std_logic;-- signal update_cache_conflict : std_logic; signal update_cache_posted_write_done : std_logic; signal mem_read_cache_hit_direct_sel : std_logic; signal mem_read_cache_hit_sel : std_logic; signal dcache_data_strobe_sel : std_logic; signal dcache_fsl_request_part1 : std_logic; signal dcache_fsl_request_sel : std_logic; signal dcache_fsl_out_write_sel1 : std_logic; signal dcache_fsl_out_write_part1 : std_logic; signal dcache_fsl_out_write_sel2 : std_logic; signal comp1_A : std_logic_vector(0 to NO_ADDR_TAG_BITS+1); signal comp1_B : std_logic_vector(0 to NO_ADDR_TAG_BITS+1); begin -- global settings ex_piperun_i <= '1' when Ex_piperun else '0'; reset_b <= (reset = '1'); ram_enable <= ex_piperun_i; --****************************** -- 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_b then -- synchronous reset (active high) Trace_Cache_Req <= '0'; Trace_Cache_Hit <= '0'; else -- only valid 1 clock cycle for a valid cache access Trace_Cache_Req <= mem_Valid_Req and mem_first_cycle; Trace_Cache_Hit <= mem_cache_hit; end if; end if; end process Trace_Signals_DFF; --*************************************************************************** --*************************************************************************** -- -- Cache hit detection -- --*************************************************************************** --*************************************************************************** --------------------------------------------------------------------------- -- First we need to detect if the address is within the cacheable range --------------------------------------------------------------------------- Valid_Addr_Detect : process (EX_DataBus_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 (EX_DataBus_Addr(I) /= C_DCACHE_BASEADDR(I)) then valid := '0'; end if; end loop; -- I end if; ex_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_b then -- synchronous reset (active true) mem_valid_req <= '0'; mem_valid_req_XX <= '0'; mem_first_cycle <= '0'; mem_write_req <= '0'; elsif (Ex_piperun) then -- Moved to a DFF for better DataBus request since this signal will -- mask any DataBus request signal mem_valid_req <= ex_valid_addr and EX_DataBus_Access and EX_DCache_Enable and not EX_DCache_Inhibit; if (C_DCACHE_ALWAYS_USED = 0) then mem_valid_req_XX <= ex_valid_addr and EX_DataBus_Access and EX_DCache_Enable and not EX_DCache_Inhibit; else mem_valid_req_XX <= ex_valid_addr and EX_DataBus_Access; end if; mem_write_req <= EX_DataBus_Write; mem_first_cycle <= '1'; else mem_first_cycle <= '0'; end if; end if; end process Valid_Req_Handle; Use_XX_Accesses : if (C_DCACHE_ALWAYS_USED /= 0) generate signal xx_req_with_update : std_logic; signal xx_access_done : std_logic; begin xx_access <= mem_valid_Req_XX and not mem_valid_Req; 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 (mem_first_cycle = '1') then-- end if; if ((xx_access = '1') and (xx_access_done = '1') and (DCACHE_FSL_IN_Exists = '1')) then xx_data <= DCACHE_FSL_IN_Data; xx_valid_data <= '1'; xx_access_done <= '0';-- xx_access <= '0'; end if; if (DCACHE_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; ------------------------------------------------------------------------------------------------ -- Need more intelligience on this signal 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_b then -- synchronous reset (active true) xx_req_with_update <= '0'; elsif (mem_Valid_Req_XX and mem_tag_miss) = '1' then xx_req_with_update <= mem_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_b 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; -- cache_updated_allowed <= EX_DCache_Enable and not EX_DCache_Inhibit; end generate Use_XX_Accesses; No_XX_Accesses : if (C_DCACHE_ALWAYS_USED = 0) generate xx_access <= '0'; xx_valid_data <= '0'; cache_updated_allowed <= '1'; xx_data <= (others => '0'); end generate No_XX_Accesses; ----------------------------------------------------------------------------- -- Tell DOPB to drop this transfer since the cache will handle it ----------------------------------------------------------------------------- MEM_DCache_Drop_request <= mem_valid_req_XX; -- This is what we need to check against the tag memory Check_tag_addr_part <= '1' & mem_mch_addr(30 - CACHELINE_BITS - Tag_Addr_Size - NO_ADDR_TAG_BITS to 29 - CACHELINE_BITS - Tag_Addr_Size); -- This is the bits from the tag memory Mem_tag_bits_addr_part <= mem_tag_bits(C_CACHELINE_SIZE to mem_tag_bits'right); -- Check to see if the tag matches (not checking individual words yet) -- mem_tag_hit <= mem_Valid_Req when Mem_tag_bits_addr_part = Check_tag_addr_part else '0'; -- Instatiating a comparator to be sure that it is implemented as a -- carry-chain comparator comp1_A <= mem_Valid_Req & Mem_tag_bits_addr_part; comp1_B <= '1' & Check_tag_addr_part; mem_tag_hit_comparator : comparator generic map ( C_TARGET => C_TARGET, C_IS_FIRST => false, C_SIZE => Check_tag_addr_part'length+1) -- [natural] port map ( Carry_IN => '1', -- [in std_logic] DI => '0', -- [ in std_logic] A => comp1_A, B => comp1_B, Carry_OUT => mem_tag_hit); -- [out std_logic] mem_tag_miss_comparator : comparator generic map ( C_TARGET => C_TARGET, C_IS_FIRST => false, C_SIZE => Check_tag_addr_part'length) -- [natural] port map ( Carry_IN => '0', -- [in std_logic] DI => mem_valid_req_XX, -- [ in std_logic] A => Mem_tag_bits_addr_part, -- [in std_logic_vector(0 to C_SIZE-1)] B => Check_tag_addr_part, -- [in std_logic_vector(0 to C_SIZE-1)] Carry_OUT => mem_tag_miss); -- [out std_logic] -- Can be implemented with a XORCY-- mem_tag_miss <= not mem_tag_hit; ---------------------------------------------------------------------------------- -- Now we need to check the each valid bit for each data word within the cacheline ---------------------------------------------------------------------------------- Valid_check_with_8word_cacheline : if (C_CACHELINE_SIZE = 8) generate signal temp_Data_Addr : std_logic_vector(0 to CACHELINE_BITS-1); begin temp_Data_Addr <= mem_mch_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_Data_Addr) is begin -- process Gen_Addr_Decoder addr_dec <= (others => '0'); addr_dec(to_integer(unsigned(temp_Data_Addr))) <= '1'; end process Gen_Addr_Decoder; valid_check_carry(4) <= mem_tag_hit; 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 (mem_tag_bits(2*I+1) = '1') else '1' when (addr_dec(2*I) = '1') and (mem_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; mem_cache_hit <= 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) <= mem_tag_hit; valid_check_sel(0) <= mem_tag_bits(0) when ( temp_Data_Addr = "000" ) else mem_tag_bits(1) when ( temp_Data_Addr = "001" ) else mem_tag_bits(2) when ( temp_Data_Addr = "010" ) else '1'; -- Bypass valid_check_sel(1) <= mem_tag_bits(3) when ( temp_Data_Addr = "011" ) else mem_tag_bits(4) when ( temp_Data_Addr = "100" ) else mem_tag_bits(5) when ( temp_Data_Addr = "101" ) else '1'; -- Bypass valid_check_sel(2) <= mem_tag_bits(6) when ( temp_Data_Addr = "110" ) else mem_tag_bits(7) when ( temp_Data_Addr = "111" ) else '1'; -- Bypass valid_check_cacheline : for I in 2 downto 0 generate begin valid_check_carry_and_I : carry_and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -