icache.vhd

来自「Xilinx软核microblaze源码(VHDL)版本7.10」· VHDL 代码 · 共 916 行 · 第 1/3 页

VHD
916
字号
  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 Last_Valid_Instr_Addr : std_logic_vector(0 to 31);  signal True_Instr_Addr       : 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 null4            : std_logic_vector(0 to 3);  signal null32           : std_logic_vector(0 to 31);  signal bram_enable      : std_logic;  constant null_tag_data  : TAG_WORD_TYPE             := (others => '0');  constant null_data_data : std_logic_vector(0 to 31) := (others => '0');  signal data_cache_write : std_logic_vector(0 to 3);begin  -- XCL Clocks  ICACHE_FSL_IN_Clk  <= Clk;  ICACHE_FSL_OUT_Clk <= Clk;  null4  <= (others => '0');  null32 <= (others => '0');  bram_enable <= '1';  True_Instr_Addr <= Last_Valid_Instr_Addr when I_AS = '0' else Instr_Addr;  TT : process (Clk) is  begin  -- process TT    if Clk'event and Clk = '1' then     -- rising clock edge      if (I_AS = '1') then        Last_Valid_Instr_Addr <= Instr_Addr;      end if;    end if;  end process TT;  ---------------------------------------------------------------------------  -- Need to delay the cache enable so that we can stop at the right place  ---------------------------------------------------------------------------  ICache_Enabled_DFF : process (Clk) is  begin  -- process ICache_Enabled_DFF    if Clk'event and Clk = '1' then     -- rising clock edge      if Reset then                     -- synchronous reset (active true)        ICache_Enabled_1 <= '0';      else        ICache_Enabled_1 <= ICache_Enabled_i;      end if;    end if;  end process ICache_Enabled_DFF;  ICache_Enabled_i <= '1' when ICache_Enabled else                      '0';  ---------------------------------------------------------------------------  -- First we need to detect if the address is within the cacheable range  ---------------------------------------------------------------------------  Valid_Addr_Detect : process (Instr_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 (Instr_Addr(I) /= C_ICACHE_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 (I_AS = '1') then          Valid_Req <= valid_addr and ICache_Enabled_i;        elsif (IReady_I = '1') then          Valid_Req <= '0';        end if;        if (I_AS = '1') then          if (C_ICACHE_ALWAYS_USED = 0) then            valid_Req_XX <= valid_addr and ICache_Enabled_i;          else            valid_Req_XX <= valid_addr;          end if;        elsif (IReady_I = '1') then          valid_Req_XX <= '0';        end if;        if (C_ICACHE_ALWAYS_USED = 0) then          Valid_Req_1st_Cycle_XX <= valid_addr and I_AS and ICache_Enabled_i;        else          Valid_Req_1st_Cycle_XX <= valid_addr and I_AS;        end if;        Valid_Req_1st_Cycle <= valid_addr and I_AS and ICache_Enabled_i;      end if;    end if;  end process Valid_Req_Handle;  Use_XX_Accesses : if (C_ICACHE_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 and not Tag_Ok) = '1') then            xx_access <= valid_Req_XX and not valid_Req;          end if;                   if ((xx_access = '1') and (xx_access_done = '1') and (ICACHE_FSL_IN_Exists = '1')) then            xx_data        <= ICACHE_FSL_IN_Data;            xx_valid_data  <= '1';            xx_access_done <= '0';            xx_access      <= '0';          end if;          if (ICACHE_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_ICACHE_ALWAYS_USED = 0) generate    xx_valid_data         <= '0';    cache_updated_allowed <= '1';  end generate No_XX_Accesses;  Valid_ICache_Access <= valid_Req_XX;  ---------------------------------------------------------------------------  -- 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)  ---------------------------------------------------------------------------  -- Instruction address is only valid for 1 clock cycle due to the  -- pipelining of the instruction fetches  -- We need to compare the tag read from the tag with the current instr addr  -- The instr address needs to be clocked  Instr_Addr_DFF : process (Clk) is  begin  -- process Instr_Addr_DFF    if Clk'event and Clk = '1' then     -- rising clock edge      if Reset then                     -- synchronous reset (active true)        Instr_Addr_1 <= (others => '0');      else        Instr_Addr_1 <= True_Instr_Addr;      end if;    end if;  end process Instr_Addr_DFF;  -- This is what we need to check against the tag memory  Check_Tag <= '1' & Instr_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  ---------------------------------------------------------------------------  Using_FPGA_FSL_2 : if C_TARGET /= RTL generate    signal combined_iready_n : std_logic;  begin    Using_8word_lines : if (C_CACHELINE_SIZE = 8) generate      signal temp_Instr_Addr   : std_logic_vector(0 to CACHELINE_BITS-1);    begin      temp_Instr_Addr <= Instr_Addr_1(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_Instr_Addr) is        begin  -- process Gen_Addr_Decoder          addr_dec                                       <= (others => '0');          addr_dec(to_integer(unsigned(temp_Instr_Addr))) <= '1';        end process Gen_Addr_Decoder;          valid_check_carry(4) <= tag_ok;                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 (tag_bits(2*I+1) = '1') else                              '1' when (addr_dec(2*I) = '1') and (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;          Word_Is_Valid <= 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) <= tag_ok;                valid_check_sel(0) <= tag_bits(0) when ( temp_Instr_Addr = "000" ) else                              tag_bits(1) when ( temp_Instr_Addr = "001" ) else                              tag_bits(2) when ( temp_Instr_Addr = "010" ) else                              '1';                                             -- Bypass                valid_check_sel(1) <= tag_bits(3) when ( temp_Instr_Addr = "011" ) else                              tag_bits(4) when ( temp_Instr_Addr = "100" ) else                              tag_bits(5) when ( temp_Instr_Addr = "101" ) else                              '1';                                             -- Bypass                valid_check_sel(2) <= tag_bits(6) when ( temp_Instr_Addr = "110" ) else                              tag_bits(7) when ( temp_Instr_Addr = "111" ) else                              '1';                                             -- Bypass                valid_check_cacheline : for I in 2 downto 0 generate        begin            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;          Word_Is_Valid <= valid_check_carry(0);      end generate Using_8Line_6LUT;    end generate Using_8word_lines;    Using_4word_lines : if (C_CACHELINE_SIZE = 4) generate    begin      Using_4LUT : if ( not C_LUT6_OPTIMIZED ) generate        signal sel1  : std_logic;        signal sel2  : std_logic;        signal carry : std_logic;      begin        -- Instr_Addr_1(28 to 29) = "11" <=> tag_bits(3)        -- Instr_Addr_1(28 to 29) = "10" <=> tag_bits(2)        Sel1 <= not(Instr_Addr_1(28)) or                ((Instr_Addr_1(29) and tag_bits(3)) or

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?