📄 dcache.vhd
字号:
-- Store the address for the current cachemiss --------------------------------------------------------------------------- Req_Addr_DFF : process (Clk) is begin -- process Req_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) Req_Addr <= (others => '0'); elsif (Valid_req_1st_cycle and (not Tag_ok) and DCache_Enabled_1 and not Write_Strobe) = '1' then Req_Addr <= Data_Addr_1; end if; end if; end process Req_Addr_DFF; --------------------------------------------------------------------------- -- Store the address that will be used for this cacheline fill -- Only use the Req_Addr if there isn't a cacheline in progress --------------------------------------------------------------------------- CacheLine_Addr_DFF : process (Clk) is begin -- process CacheLine_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) CacheLine_Addr <= (others => '0'); elsif (Update_Idle = '1') then CacheLine_Addr <= Data_Addr_1; end if; end if; end process CacheLine_Addr_DFF; Writing_Address : process (Clk) is begin -- process Writing_Address if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) Address_Written <= '0'; Non_Blocked_Write <= '0'; else Non_Blocked_Write <= Write_Strobe_i and valid_Req_XX and not Address_Written; if (Write_Done = '1') then Address_Written <= '0'; elsif (DCACHE_FSL_OUT_Full = '0') then Address_Written <= Write_Strobe_i and valid_Req_XX; end if; end if; end if; end process Writing_Address; --------------------------------------------------------------------------- -- Write is not done, if we write into a cacheline which is currently -- updated since this can cause problems. If the Write_Address is the same -- as the Cacheline_Addr and Update_Idle = '0', we need to wait for the -- Update_Idle = '1' --------------------------------------------------------------------------- Write_To_Current_Cacheline_fill : process (Clk) is begin -- process Write_To_Current_Cacheline_fill if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) Write_Cacheline_conflict <= '0'; else Write_Cacheline_conflict <= '0'; if (Data_Addr_1(0 to 29-CACHELINE_BITS) = CacheLine_Addr(0 to 29-CACHELINE_BITS)) then Write_Cacheline_conflict <= Write_Strobe_i and not(Update_Idle); end if; end if; end if; end process Write_To_Current_Cacheline_fill; -- Write_Done <= Address_Written and not DCACHE_FSL_OUT_Full; Write_Done <= not(Write_Cacheline_conflict) and Address_Written and not DCACHE_FSL_OUT_Full; --------------------------------------------------------------------------- -- --------------------------------------------------------------------------- DCACHE_FSL_IN_Read <= DCACHE_FSL_IN_Exists; CacheLine_Counter : process (Clk) is begin -- process CacheLine_Counter if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) CacheLine_Cnt <= (others => '0'); elsif (DCACHE_FSL_IN_Exists = '1') then CacheLine_Cnt <= std_logic_vector(unsigned(CacheLine_Cnt) + 1); end if; end if; end process CacheLine_Counter; CacheLine_Counter2 : process (Clk) is begin -- process CacheLine_Counter2 if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) CacheLine_Cnt2 <= (others => '0'); else if (Update_Idle = '1') then CacheLine_Cnt2 <= Req_Addr(30 - CACHELINE_BITS to 29); elsif (DCACHE_FSL_IN_Exists = '1') then CacheLine_Cnt2 <= std_logic_vector(unsigned(CacheLine_Cnt2) + 1); end if; end if; end if; end process CacheLine_Counter2; Update_Idle <= '1' when (CacheLine_Cnt = CacheLine_Cnt_Low and DCACHE_FSL_IN_Exists /= '1') or (CacheLine_Cnt = CacheLine_Cnt_High and DCACHE_FSL_IN_Exists = '1') else '0'; DCache_Read_Idle_DFF : process (Clk) is variable Update_Idle_1 : std_logic; variable DCACHE_FSL_OUT_Write_1 : std_logic; begin -- process DCache_Read_Idle_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) DCache_Read_Idle <= true; Update_Idle_1 := '1'; DCACHE_FSL_OUT_Write_1 := DCACHE_FSL_OUT_Write_i; else if (Read_Strobe_1 = '1') and (DCACHE_FSL_OUT_Write_1 = '1') then DCache_Read_Idle <= false; -- FSL read access started elsif (Update_Idle_1 = '0') and (Update_Idle = '1') then DCache_Read_Idle <= true; -- FSL read access ended end if; DCACHE_FSL_OUT_Write_1 := DCACHE_FSL_OUT_Write_i; Update_Idle_1 := Update_Idle; end if; end if; end process DCache_Read_Idle_DFF; New_Tag_Addr_DFF : process (Clk) is begin -- process New_Tag_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if Update_Idle = '1' then New_Tag_Addr <= CacheLine_Addr(30 - CACHELINE_BITS - Tag_Addr_Size to 29-CACHELINE_BITS); end if; end if; end process New_Tag_Addr_DFF; -- Calculate the valid bits that will be written during a cacheline update Valid_Bits_Handle : process (Clk) is variable tmp : std_logic_vector(valid_Bits'range); begin -- process Valid_Bits_Handle if Clk'event and Clk = '1' then -- rising clock edge if Update_Idle = '1' then -- synchronous reset (active high) valid_Bits <= (others => '0'); valid_Bits(to_integer(unsigned(CacheLine_Addr(30-CACHELINE_BITS to 29)))) <= '1'; elsif (DCACHE_FSL_IN_Exists = '1') then tmp(1 to tmp'right) := valid_Bits(0 to valid_Bits'right-1); tmp(0) := valid_Bits(valid_Bits'right); valid_Bits <= tmp or valid_Bits; end if; end if; end process Valid_Bits_Handle; New_Tag_Bits_Gen : process(Real_Valid_Bits, CacheLine_Addr, DCACHE_FSL_IN_Exists) is begin -- process New_Tag_Bits_Gen new_tag_bits <= (others => '0'); if DCACHE_FSL_IN_Exists = '1' then new_tag_bits(C_CACHELINE_SIZE) <= '1'; -- Always write in a valid tag else new_tag_bits(C_CACHELINE_SIZE) <= '0'; end if; new_tag_bits(0 to C_CACHELINE_SIZE-1) <= Real_Valid_Bits; new_tag_bits(1 + C_CACHELINE_SIZE to C_CACHELINE_SIZE + NO_ADDR_TAG_BITS) <= CacheLine_Addr(30 - CACHELINE_BITS - Tag_Addr_Size - NO_ADDR_TAG_BITS to 29 - CACHELINE_BITS - Tag_Addr_Size); end process New_Tag_Bits_Gen; write_to_cache <= '1' when Write_Dcache else DCACHE_FSL_IN_Exists and cache_updated_allowed; write_to_cache_be <= (others => write_to_cache); Real_Valid_Bits <= valid_Bits when DCACHE_FSL_IN_Exists = '1' else All_False_Bits; Real_New_Tag_Addr <= New_Tag_Addr when DCACHE_FSL_IN_Exists = '1' else Op1(30 - CACHELINE_BITS - Tag_Addr_Size to 29-CACHELINE_BITS); --------------------------------------------------------------------------- -- The tag memory --------------------------------------------------------------------------- Tag_Memory : RAM_Module generic map ( C_TARGET => C_TARGET, -- [TARGET_FAMILY_TYPE] C_DATA_WIDTH => Tag_Word_Size, -- [natural range 1 to 36] C_ADDR_WIDTH => Tag_Addr_Size, -- [natural range 1 to 14] C_FORCE_BRAM => Tag_Force_BRAM) -- [boolean] port map ( -- PORT A CLKA => CLK, -- [in std_logic] WEA => null4, -- [in std_logic_vector(0 to 3)] Assume byte write handling ENA => bram_enable, -- [in std_logic] ADDRA => tag_addr_lookup, -- [in std_logic_vector(0 to C_ADDR_WIDTH-1)] DATA_INA => null_tag_data, -- [in std_logic_vector(0 to C_DATA_WIDTH-1)] DATA_OUTA => tag_bits, -- [out std_logic_vector(0 to C_DATA_WIDTH-1)] -- PORT B CLKB => CLK, -- [in std_logic] WEB => write_to_cache_be, -- [in std_logic_vector(0 to 3)] Assume byte write handling ENB => '1', -- [in std_logic] ADDRB => Real_New_Tag_Addr, -- [in std_logic_vector(0 to C_ADDR_WIDTH-1)] DATA_INB => new_tag_bits, -- [in std_logic_vector(0 to C_DATA_WIDTH-1)] DATA_OUTB => open); -- [out std_logic_vector(0 to C_DATA_WIDTH-1)] --------------------------------------------------------------------------- -- Then the Data memory --------------------------------------------------------------------------- -- We need to lock up in the data memory to see if the cacheline exists in -- the cache Get_Data_Addr : process (Data_Addr) is begin -- process Get_Data_Addr data_addr_lookup <= (others => '0'); data_addr_lookup <= Data_Addr(30-Data_Addr_Size to 29); end process Get_Data_Addr; New_Data_Addr1 <= CacheLine_Addr(30-Data_Addr_Size to 29-CACHELINE_BITS); New_Data_Addr <= New_Data_Addr1 & Cacheline_Cnt2; Need_to_Mux_In_Bytes : if (nr_of_data_brams < 4) generate Byte_Writes : process (write_cachehit, Byte_Enable, Data_Read_i, Data_Write) is begin -- process Byte_Writes for I in 0 to 3 loop if (Byte_Enable(I) = '1') then Data_Write_i(I*8 to (I+1)*8-1) <= Data_Write(I*8 to (I+1)*8-1); else Data_Write_i(I*8 to (I+1)*8-1) <= Data_Read_i(I*8 to (I+1)*8-1); end if; end loop; -- I write_we <= (others => write_cachehit); end process Byte_Writes; end generate Need_to_Mux_In_Bytes; Write_With_Byte_Enables : if (nr_of_data_brams > 3) generate Data_Write_i <= Data_Write; write_we <= Byte_Enable when write_cachehit = '1' else "0000"; end generate Write_With_Byte_Enables; data_cache_write <= (others => DCACHE_FSL_IN_Exists and cache_updated_allowed); Data_Memory : RAM_Module generic map ( C_TARGET => C_TARGET, -- [TARGET_FAMILY_TYPE] C_DATA_WIDTH => 32, -- [natural range 1 to 36] C_ADDR_WIDTH => Data_Addr_Size, -- [natural range 1 to 14] C_FORCE_BRAM => true) -- [boolean] - Force use of BRAM since both ports used port map ( -- PORT A CLKA => Clk, -- [in std_logic] WEA => write_we, -- [in std_logic_vector(0 to 3)] Assume byte write handling ENA => bram_enable, -- [in std_logic] ADDRA => data_addr_lookup, -- [in std_logic_vector(0 to C_ADDR_WIDTH-1)] DATA_INA => data_write_i, -- [in std_logic_vector(0 to C_DATA_WIDTH-1)] DATA_OUTA => Data_Read_i, -- [out std_logic_vector(0 to C_DATA_WIDTH-1)] -- PORT B CLKB => Clk, -- [in std_logic] WEB => data_cache_write, -- [in std_logic_vector(0 to 3)] Assume byte write handling ENB => bram_enable, -- [in std_logic] ADDRB => new_data_addr, -- [in std_logic_vector(0 to C_ADDR_WIDTH-1)] DATA_INB => DCACHE_FSL_IN_Data, -- [in std_logic_vector(0 to C_DATA_WIDTH-1)] DATA_OUTB => open); -- [out std_logic_vector(0 to C_DATA_WIDTH-1)] ----------------------------------------------------------------------------- -- If or not DEXT exists -- Data is muxed between External Data bus and Dcache -- This is not the same route as the ready signal take -- Dready is first muxed between DLMB and ext. Data bus before connecting to -- Dcache ----------------------------------------------------------------------------- Also_Using_DExt_2 : if (C_D_Ext) generate signal data_read_ii : DATA_TYPE; begin data_read_ii <= Data_Read_I when xx_valid_data = '0' else xx_data; Data_Read <= DExt_Data_Read when DExt_DReady = '1' else data_read_ii; end generate Also_Using_DExt_2; Not_Using_DExt_2 : if not(C_D_Ext) generate Data_Read <= Data_Read_I when xx_valid_data = '0' else xx_data; end generate Not_Using_DExt_2; Trace_DFF: process (Clk) is begin -- process Trace_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) Trace_Cache_Hit <= '0'; Trace_Cache_Req <= '0'; else Trace_Cache_Hit <= word_is_valid; Trace_Cache_Req <= Valid_req_1st_cycle; end if; end if; end process Trace_DFF;end architecture IMP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -