📄 dcache.vhd
字号:
signal Data_Read_I : std_logic_vector(0 to C_DATA_SIZE-1); signal tag_ok : std_logic; signal cache_hit : std_logic; signal valid_cache_hit : std_logic; signal Word_Is_Valid : std_logic; signal Word_Is_Valid_i : std_logic; signal Data_Addr_1 : std_logic_vector(0 to 31); 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 tag_bits : TAG_WORD_TYPE; signal tag_bits_C : std_logic_vector(0 to NO_ADDR_TAG_BITS); constant tag_bits_c_odd : natural := (tag_bits_c'length) mod 2; signal Check_Tag : std_logic_vector(0 to NO_ADDR_TAG_BITS); signal Read_Strobe_1 : std_logic; signal Valid_Read_Access : std_logic; signal DCACHE_FSL_OUT_Write_i : std_logic; 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 write_to_cache : std_logic; signal write_to_cache_be : std_logic_vector(0 to 3); 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 Use_Last_Addr : std_logic; signal Last_Valid_Data_Addr : std_logic_vector(0 to 31); signal Req_Addr : std_logic_vector(0 to 31); signal CacheLine_Addr : std_logic_vector(0 to 31); signal FSL_Addr : std_logic_vector(0 to 31); signal FSL_Data : 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 Write_Strobe_i : std_logic; signal Write_Strobe_ii : std_logic; signal Write_Done : std_logic := '0'; signal Non_Blocked_Write : std_logic := '0'; signal Address_Written : std_logic := '0'; signal Write_Cacheline_conflict : std_logic := '0'; signal write_cachehit : std_logic; signal write_cachehit_be : std_logic; signal data_write_i : std_logic_vector(0 to 31); signal FSL_Write_Hold : std_logic; signal FSL_Write_Reg_i : std_logic; signal fsl_write_reg_slow : std_logic; attribute keep : string; attribute keep of fsl_write_reg_slow : signal is "true"; signal write_we : std_logic_vector(0 to 3); signal data_cache_write : std_logic_vector(0 to 3); signal null4 : std_logic_vector(0 to 3); signal bram_enable : std_logic; constant null_tag_data : TAG_WORD_TYPE := (others => '0'); begin -- XCL Clocks DCACHE_FSL_IN_Clk <= Clk; DCACHE_FSL_OUT_Clk <= Clk; null4 <= (others => '0'); bram_enable <= '1'; DCache_Enabled_i <= '1' when DCache_Enabled else '0'; --------------------------------------------------------------------------- -- Need to delay the cache enable so that we can stop at the right place --------------------------------------------------------------------------- Dcache_Enabled_DFF : process (Clk) is begin -- process Dcache_Enabled_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) Dcache_Enabled_1 <= '0'; Write_Strobe_ii <= '0'; else Dcache_Enabled_1 <= Dcache_Enabled_i; Write_Strobe_ii <= Write_Strobe and not Write_Done; end if; end if; end process Dcache_Enabled_DFF; Write_Strobe_i <= Write_Strobe_ii; --------------------------------------------------------------------------- -- First we need to detect if the address is within the cacheable range --------------------------------------------------------------------------- Valid_Addr_Detect : process (Data_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 (Data_Addr(I) /= C_DCACHE_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 (D_AS = '1') then Valid_Req <= valid_addr and Dcache_Enabled_i; elsif (dready_i = '1') then Valid_Req <= '0'; end if; if (D_AS = '1') then if (C_DCACHE_ALWAYS_USED = 0) then valid_Req_XX <= valid_addr and DCache_Enabled_i; else valid_Req_XX <= valid_addr; end if; elsif (dready_i = '1') then valid_Req_XX <= '0'; end if; if (C_DCACHE_ALWAYS_USED = 0) then Valid_Req_1st_Cycle_XX <= valid_addr and D_AS and DCache_Enabled_i; else Valid_Req_1st_Cycle_XX <= valid_addr and D_AS; end if; valid_req_1st_cycle <= valid_addr and D_AS and DCache_Enabled_i; end if; end if; end process Valid_Req_Handle; Use_XX_Accesses : if (C_DCACHE_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 = '1') then xx_access <= valid_Req_XX and not valid_Req; 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; 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_DCACHE_ALWAYS_USED = 0) generate xx_valid_data <= '0'; cache_updated_allowed <= '1'; end generate No_XX_Accesses; Valid_Dcache_Access <= valid_Req_XX; --------------------------------------------------------------------------- -- Need a signal to validate if a cache hit is true -- Needed when cache enable is going from true to false to handle a ongoing -- burst transfer --------------------------------------------------------------------------- No_XX_Accesses4 : if (C_DCACHE_ALWAYS_USED = 0) generate valid_cache_hit_dff : process (Clk) is begin -- process valid_cache_hit_dff if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) valid_cache_hit <= '0'; elsif (D_AS = '1') then valid_cache_hit <= Dcache_Enabled_i; end if; end if; end process valid_cache_hit_dff; end generate No_XX_Accesses4; XX_Accesses4 : if (C_DCACHE_ALWAYS_USED /= 0) generate valid_cache_hit <= '1'; end generate XX_Accesses4; --------------------------------------------------------------------------- -- 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) --------------------------------------------------------------------------- -- We need to lock up in the tag memory to see if the cacheline exists in -- the cache Get_Tag_Addr : process (Data_Addr) is begin -- process Get_Tag_Addr tag_addr_lookup <= (others => '0'); tag_addr_lookup <= Data_Addr(30 - CACHELINE_BITS - Tag_Addr_Size to 29-CACHELINE_BITS); end process Get_Tag_Addr; -- Delay Data_Addr one clock cycle to compare with the output from the tag -- memory Data_Addr_DFF : process (Clk) is begin -- process Data_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) Data_Addr_1 <= (others => '0'); else Data_Addr_1 <= Data_Addr; end if; end if; end process Data_Addr_DFF; -- This is what we need to check against the tag memory Check_Tag <= '1' & Data_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 -- Currently only support 4 words/cacheline checking ---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -