📄 dcache_gti.vhd
字号:
DCACHE_FSL_OUT_Write <= dcache_FSL_OUT_Write_i; -- We immediately use(consume) incoming data on the FSL DCACHE_FSL_IN_Read <= DCACHE_FSL_IN_Exists; DCACHE_FSL_OUT_Data <= mem_mch_addr when mem_Address_Written = '0' else mem_mch_data; MEM_MCH_DFF : process (Clk) is begin -- process MEM_MCH_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset_b then -- synchronous reset (active high) mem_mch_addr(30 to 31) <= (others => '0'); mem_mch_byte_access <= '0'; elsif (Ex_piperun) then mem_mch_byte_access <= '0'; if (EX_Byte_Access) then mem_mch_addr(30 to 31) <= EX_DataBus_Addr(30 to 31); mem_mch_byte_access <= '1'; elsif (EX_Doublet_Access) then mem_mch_addr(30) <= EX_DataBus_Addr(30); mem_mch_addr(31) <= '1'; else mem_mch_addr(30 to 31) <= "00"; end if; end if; end if; end process MEM_MCH_DFF; mem_mch_addr(0 to 29) <= MEM_DataBus_Addr(0 to 29); mem_mch_data <= MEM_DataBus_Write_Data; mem_mch_be <= MEM_DataBus_Byte_Enable; Handle_Control_Bit : process (mem_write_req, mem_Address_Written, mem_mch_byte_access) is begin -- process Handle_Control_Bit if (mem_write_req = '1') then if (mem_Address_Written = '0') then DCACHE_FSL_OUT_Control <= '1'; -- Write request else if (mem_mch_byte_access = '1') then DCACHE_FSL_OUT_Control <= '1'; -- Byte Access else DCACHE_FSL_OUT_Control <= '0'; -- Word or Halfword end if; end if; else DCACHE_FSL_OUT_Control <= '0'; -- Read request end if; end process Handle_Control_Bit; mem_data_write <= mem_Address_Written and not DCACHE_FSL_OUT_Full and not mem_Data_Written; ----------------------------------------------------------------------------- -- Need to make sure that there is only clock cycle between the write to the -- data memory before the pipe can move since the next instruction can access -- this data and it takes one clock cycle before the RAM is updated ----------------------------------------------------------------------------- Mem_Data_Updated_DFF: process (Clk) is begin -- process Mem_Data_Updated_DFF if Clk'event and Clk = '1' then -- rising clock edge if reset_b then -- synchronous reset (active high) mem_data_updated <= '0'; else if (Ex_piperun) then mem_data_updated <= '0'; elsif (mem_write_cache_hit = '1') then mem_data_updated <= '1'; end if; end if; end if; end process Mem_Data_Updated_DFF; ----------------------------------------------------------------------------- -- ----------------------------------------------------------------------------- update_cache_posted_write_done <= mem_write_cache_hit_delayed and (mem_data_write or mem_Data_Written) and mem_data_updated; ----------------------------------------------------------------------------- -- mem_Address_Written is high when the address is written into MCH on a write -- mem_Data_Written is high when the data has been written into MCH on a write ----------------------------------------------------------------------------- mem_Writing_Address : process (Clk) is begin -- process Mem_Writing_Address if Clk'event and Clk = '1' then -- rising clock edge if Reset_b then -- synchronous reset (active high) mem_Address_Written <= '0'; mem_Data_written <= '0'; else if (mem_write_req and mem_Valid_Req_XX and not DCACHE_FSL_OUT_Full) = '1' then mem_Address_Written <= '1'; end if; if (mem_data_write = '1') then mem_Data_written <= '1'; end if; if (Ex_piperun) then mem_Address_Written <= '0'; mem_Data_written <= '0'; end if; end if; end if; end process mem_Writing_Address; --------------------------------------------------------------------------- -- Store the address for the current cachemiss so we have the address that -- will be used when the data is return for the cacheline -- We can have a new data access while we writing in a previous cache miss so -- we need to registrate the correct one --------------------------------------------------------------------------- Req_Addr_DFF : process (Clk) is begin -- process Req_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset_b then -- synchronous reset (active true) Req_Addr <= (others => '0'); elsif (mem_Valid_Req_XX and mem_tag_miss) = '1' then Req_Addr <= mem_mch_addr; end if; end if; end process Req_Addr_DFF; ----------------------------------------------------------------------------- -- Store the address for the cacheline BEING written into the dcache -- This address can be different from Req_Addr in the end of a cacheline update ----------------------------------------------------------------------------- New_Cacheline_Addr_DFF : process (Clk) is begin -- process New_Cacheline_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset_b then -- synchronous reset (active true) new_cacheline_addr <= (others => '0'); elsif (Update_Idle = '1') then new_cacheline_addr <= Req_Addr; end if; end if; end process New_Cacheline_Addr_DFF; ----------------------------------------------------------------------------- -- just count the number of words that we write into a cacheline in the cache -- will be a wrap-around counter ----------------------------------------------------------------------------- CacheLine_Counter : process (Clk) is begin -- process CacheLine_Counter if Clk'event and Clk = '1' then -- rising clock edge if Reset_b 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; ----------------------------------------------------------------------------- -- Keep a counter for where in a cacheline we are when writing into the cache -- Reset it to the lowest address bit on a start of a cacheline ----------------------------------------------------------------------------- CacheLine_Counter2 : process (Clk) is begin -- process CacheLine_Counter2 if Clk'event and Clk = '1' then -- rising clock edge if Reset_b 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; ----------------------------------------------------------------------------- -- Detect when we not writing into the cache -- A MCH cacheline is fully written into the cache ----------------------------------------------------------------------------- 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'; mem_new_tag_addr_i <= new_cacheline_addr(30 - CACHELINE_BITS - Tag_Addr_Size to 29-CACHELINE_BITS) when DCACHE_FSL_IN_Exists = '1' else mem_mch_addr(30 - CACHELINE_BITS - Tag_Addr_Size to 29-CACHELINE_BITS); mem_new_tag_addr <= WB_Fwd(30 - CACHELINE_BITS - Tag_Addr_Size to 29-CACHELINE_BITS) when WB_Write_DCache else mem_new_tag_addr_i; 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(Req_Addr(30-CACHELINE_BITS to 29)))) <= '1'; elsif (DCACHE_FSL_IN_Exists = '1') then tmp(1 to tmp'right) := Valid_Bits(0 to tmp'right-1); tmp(0) := Valid_Bits(Valid_Bits'right); Valid_Bits <= tmp or Valid_Bits; end if; end if; end process Valid_Bits_Handle; Mem_New_Tag_Bits_Gen : process(DCACHE_FSL_IN_Exists, Valid_Bits, new_cacheline_addr, mem_mch_addr, WB_Write_DCache) is begin -- process Mem_New_Tag_Bits_Gen if (WB_Write_DCache) then mem_new_tag_bits(C_CACHELINE_SIZE) <= '0'; mem_new_tag_bits(0 to C_CACHELINE_SIZE-1) <= (others => '0'); mem_new_tag_bits(1 + C_CACHELINE_SIZE to C_CACHELINE_SIZE + NO_ADDR_TAG_BITS) <= (others => '0'); elsif DCACHE_FSL_IN_Exists = '1' then mem_new_tag_bits(C_CACHELINE_SIZE) <= '1'; -- Always write in a valid tag mem_new_tag_bits(0 to C_CACHELINE_SIZE-1) <= Valid_Bits; mem_new_tag_bits(1 + C_CACHELINE_SIZE to C_CACHELINE_SIZE + NO_ADDR_TAG_BITS) <= new_cacheline_addr(30 - CACHELINE_BITS - Tag_Addr_Size - NO_ADDR_TAG_BITS to 29 - CACHELINE_BITS - Tag_Addr_Size); else mem_new_tag_bits(C_CACHELINE_SIZE) <= '1'; -- Always write in a valid tag mem_new_tag_bits(0 to C_CACHELINE_SIZE-1) <= (others => '1'); mem_new_tag_bits(1 + C_CACHELINE_SIZE to C_CACHELINE_SIZE + NO_ADDR_TAG_BITS) <= mem_mch_addr(30 - CACHELINE_BITS - Tag_Addr_Size - NO_ADDR_TAG_BITS to 29 - CACHELINE_BITS - Tag_Addr_Size); end if; end process Mem_New_Tag_Bits_Gen; ----------------------------------------------------------------------------- -- The cacheline copy section ----------------------------------------------------------------------------- Using_Cacheline_Copy : process (Clk) is begin -- process Using_Cacheline_Copy if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) use_cacheline_copy_i <= '0'; delay_update_idle <= '1'; cacheline_copy_hit_hold <= '0'; else if (cacheline_copy_hit = '1') then cacheline_copy_hit_hold <= '1'; end if; -- Hit on the tag but the actual word hasn't been fetch to cache yet if (mem_cache_hit_pending = '1') then use_cacheline_copy_i <= '1'; -- No writing into the cache is active elsif (delay_update_idle = '1') then -- Keep the current value of use_cacheline_copy_i use_cacheline_copy_i <= use_cacheline_copy_i or mem_read_cache_miss; end if; -- When pipe is moving flush the signals if (ex_piperun_i = '1') then use_cacheline_copy_i <= '0'; cacheline_copy_hit_hold <= '0'; end if; -- Need to delay update_idle usage since the valid bits for the -- cacheline_copy is valid one extra clock cycle after update_idle is -- active again. delay_update_idle <= Update_Idle; end if; end if; end process Using_Cacheline_Copy; DCache_Idle <= delay_update_idle = '1';-- use_cacheline_copy <= (mem_cache_hit_pending and mem_Valid_Req) or use_cacheline_copy_i; use_cacheline_copy <= use_cacheline_copy_i; ----------------------------------------------------------------------------- -- handling the valid bits for the cacheline copy data ----------------------------------------------------------------------------- Cacheline_Copy_Valid_DFF : process (Clk) is begin -- process Cacheline_Copy_Valid_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset_b then -- synchronous reset (active true) cacheline_copy_valid <= (others => '0'); elsif (mem_cache_hit_pending = '0') and (Update_Idle = '1') and (DCACHE_FSL_IN_Exists = '0') then cacheline_copy_valid <= (others => '0'); elsif (DCACHE_FSL_IN_Exists = '1') then cacheline_copy_valid <= Valid_Bits; end if; end if; end process Cacheline_Copy_Valid_DFF; Cacheline_Copy_RAM : process (Clk) is begin -- process Cacheline_Copy_RAM if Clk'event and Clk = '1' then -- rising clock edge if DCACHE_FSL_IN_Exists = '1' then Cacheline_copy(to_integer(unsigned(CacheLine_Cnt2))) <= DCACHE_FSL_IN_Data; end if; end if; end process Cacheline_Copy_RAM; cacheline_copy_data <= cacheline_copy(to_integer(unsigned(mem_mch_addr(30-CACHELINE_BITS to 29)))); cacheline_copy_hit <= use_cacheline_copy and cacheline_copy_valid(to_integer(unsigned(mem_mch_addr(30-CACHELINE_BITS to 29)))); --------------------------------------------------------------------------- -- The Data memory section -- Generating the address and write signals --------------------------------------------------------------------------- ex_data_addr_lookup <= EX_DataBus_Addr(30-Data_Addr_Size to 29); -- Only write to data cache mmeory on write hit mem_write_data_be <= mem_mch_be when mem_write_cache_hit = '1' else (others => '0'); New_Data_Addr <= new_cacheline_addr(30-Data_Addr_Size to 29-CACHELINE_BITS) & Cacheline_Cnt2 when DCACHE_FSL_IN_Exists = '1' else mem_mch_addr(30-Data_Addr_Size to 29); New_Data_Data <= DCACHE_FSL_IN_Data when DCACHE_FSL_IN_Exists = '1' else mem_mch_data; New_Data_Write <= cacheline_update_write when (DCACHE_FSL_IN_Exists = '1') and (cache_updated_allowed = '1') else mem_write_data_be; DATA_RAM_Module : RAM_Module generic map ( C_TARGET => C_TARGET, C_DATA_WIDTH => 32, -- [natural range 1 to 32] C_ADDR_WIDTH => Data_Addr_Size, -- [natural range 1 to 14] C_FORCE_BRAM => false) -- [boolean] port map ( -- PORT A for cache hits CLKA => CLK, -- [in std_logic] WEA => null4, -- [in std_logic_vector(0 to 3)] Assume byte write handling ENA => ram_enable, -- [in std_logic] ADDRA => ex_data_addr_lookup, -- [in std_logic_vector(0 to C_ADDR_WIDTH-1)] DATA_INA => null32, -- [in std_logic_vector(0 to C_DATA_WIDTH-1)] DATA_OUTA => mem_cachehit_data, -- [out std_logic_vector(0 to C_DATA_WIDTH-1)] -- PORT B CLKB => CLK, -- [in std_logic] WEB => New_Data_Write, -- [in std_logic_vector(0 to 3)] Assume byte write handling ENB => '1', -- [in std_logic] ADDRB => New_Data_Addr, -- [in std_logic_vector(0 to C_ADDR_WIDTH-1)] DATA_INB => New_Data_Data, -- [in std_logic_vector(0 to C_DATA_WIDTH-1)] DATA_OUTB => open); -- [out std_logic_vector(0 to C_DATA_WIDTH-1)]end architecture IMP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -