mmu_utlb.vhd
来自「Xilinx软核microblaze源码(VHDL)版本7.10」· VHDL 代码 · 共 805 行 · 第 1/2 页
VHD
805 行
port map ( A_Vec => PID, B_Vec => DataOutA(TID_Type'range), Mask => pidA_mask, Carry_In => equalA_tag3, Carry_Out => equalA_pid); ----------------------------------------------------------------------------- -- And with DataOutA(C_VALID) -- Hit_DirectA <= EqualA_TAG1 and EqualA_TAG3 and -- EqualA_PID and DataOutA(C_VALID) = '1'; ----------------------------------------------------------------------------- Hit_DirectA_carry : carry_and generic map ( C_TARGET => C_TARGET) port map ( Carry_IN => equalA_pid, A => DataOutA(C_VALID), Carry_OUT => Hit_DirectA_S); Hit_DirectA <= (Hit_DirectA_S = '1'); ----------------------------------------------------------------------------- -- EqualA_TAG2 and Hit_SearchA -- EqualA_TAG2 <= TagCmpA(DirectA_Bits'range)=InputCmpA(DirectA_Bits'range); -- -- Hit_SearchA <= EqualA_TAG1 and EqualA_TAG2 and EqualA_TAG3 and -- EqualA_PID and DataOutA(C_VALID) = '1'; ----------------------------------------------------------------------------- eqa2_carry_compare_mask_I1: carry_compare_mask generic map ( C_TARGET => C_TARGET, Size => DirectA_Bits'length) port map ( A_Vec => InputCmp(DirectA_Bits'range), B_Vec => DataOutA(DirectA_Bits'range), Mask => SizeMaskA(DirectA_Bits'range), Carry_In => Hit_DirectA_S, Carry_Out => Hit_SearchA_S); Hit_SearchA <= (Hit_SearchA_S = '1'); IndexA <= DataOutA(DirectA_Bits'left to DirectA_Bits'left + 5); TagA <= RegData(DirectA_Bits'range); SizeMaskB <= C_SIZE_MASK(to_integer(unsigned(DataOutB(SIZE_Type'range)))); ----------------------------------------------------------------------------- -- EqualB_TAG1 -- InputCmpB <= InputCmp(TAG_MSB_Type'range) & -- (InputCmp(TAG_LSB_Type'range) and SizeMaskB); -- TagCmpB <= DataOutB(TAG_MSB_Type'range) & -- (DataOutB(TAG_LSB_Type'range) and SizeMaskB); -- EqualB_TAG1 <= TagCmpB(TagCmpB'left to DirectB_Bits'left - 1) = -- InputCmpB(InputCmpB'left to DirectB_Bits'left - 1); ----------------------------------------------------------------------------- eqb1_carry_compare : carry_compare generic map ( C_TARGET => C_TARGET, Size => DirectB_Bits'left - TAG_Type'left) port map ( A_Vec => InputCmp(TAG_Type'left to DirectB_Bits'left-1), B_Vec => DataOutB(TAG_Type'left to DirectB_Bits'left-1), Carry_In => '1', Carry_Out => equalB_tag1); ----------------------------------------------------------------------------- -- EqualB_TAG3 -- EqualB_TAG3 <= TagCmpB(DirectB_Bits'right + 1 to InputCmpB'right) = -- InputCmpB(DirectB_Bits'right + 1 to InputCmpB'right); ----------------------------------------------------------------------------- eqb3_carry_compare_mask_I1: carry_compare_mask generic map ( C_TARGET => C_TARGET, Size => TAG_Type'right - DirectB_Bits'right) port map ( A_Vec => InputCmp(DirectB_Bits'right+1 to TAG_Type'right), B_Vec => DataOutB(DirectB_Bits'right+1 to TAG_Type'right), Mask => SizeMaskB(DirectB_Bits'right+1 to TAG_Type'right), Carry_In => equalB_tag1, Carry_Out => equalB_tag3); ----------------------------------------------------------------------------- -- EqualB_PID -- EqualB_PID <= DataOutB(TID_Type'range) = PID or -- DataOutB(TID_Type'range) = (TID_Type'range => '0'); ----------------------------------------------------------------------------- pidB_mask <= (others => DataOutB(C_TID_0)); eqbpid_carry_compare_mask_I1 : carry_compare_mask generic map ( C_TARGET => C_TARGET, Size => 8) port map ( A_Vec => PID, B_Vec => DataOutB(TID_Type'range), Mask => pidB_mask, Carry_In => equalB_tag3, Carry_Out => equalB_pid); ----------------------------------------------------------------------------- -- And with DataOutB(C_VALID) -- Hit_DirectB <= EqualB_TAG1 and EqualB_TAG3 and -- EqualB_PID and DataOutB(C_VALID) = '1'; ----------------------------------------------------------------------------- Hit_DirectB_carry : carry_and generic map ( C_TARGET => C_TARGET) port map ( Carry_IN => equalB_pid, A => DataOutB(C_VALID), Carry_OUT => Hit_DirectB_S); Hit_DirectB <= (Hit_DirectB_S = '1'); ----------------------------------------------------------------------------- -- EqualB_TAG2 and Hit_SearchB -- EqualB_TAG2 <= TagCmpB(DirectB_Bits'range)=InputCmpB(DirectB_Bits'range); -- -- Hit_SearchB <= EqualB_TAG1 and EqualB_TAG2 and EqualB_TAG3 and -- EqualB_PID and DataOutB(C_VALID) = '1'; ----------------------------------------------------------------------------- eqb2_carry_compare : carry_compare generic map ( C_TARGET => C_TARGET, Size => TAG_MSB_Type'right - DirectB_Bits'left + 1) port map ( A_Vec => InputCmp(DirectB_Bits'left to TAG_MSB_Type'right), B_Vec => DataOutB(DirectB_Bits'left to TAG_MSB_Type'right), Carry_In => Hit_DirectB_S, Carry_Out => equalB_tag2_part1); eqb2_carry_compare_mask: carry_compare_mask generic map ( C_TARGET => C_TARGET, Size => DirectB_Bits'right - TAG_MSB_Type'right) port map ( A_Vec => InputCmp(TAG_MSB_Type'right+1 to DirectB_Bits'right), B_Vec => DataOutB(TAG_MSB_Type'right+1 to DirectB_Bits'right), Mask => SizeMaskB(TAG_MSB_Type'right+1 to DirectB_Bits'right), Carry_In => equalB_tag2_part1, Carry_Out => Hit_SearchB_S); Hit_SearchB <= (Hit_SearchB_S = '1'); IndexB <= DataOutB(DirectB_Bits'left to DirectB_Bits'left + 5); TagB <= RegData(DirectB_Bits'range); -- Keep IValid enable signal IValid_DFF: process (Clk) begin -- IValid_DFF if Clk'event and Clk = '1' then if Reset = '1' then IValid_Keep <= '0'; elsif IVMode = '1' and IValid = '1' then IValid_Keep <= '1'; elsif AccessKind = AccessInstr then IValid_Keep <= '0'; end if; end if; end process IValid_DFF; IValid_Active <= (IVMode and IValid) or IValid_Keep; -- Search Counter Counter_DFF: process (Clk) begin -- Counter_DFF if Clk'event and Clk = '1' then if Reset = '1' or Load then Counter <= (others => '0'); elsif Count and not Hit_SearchA and not Hit_SearchB then Counter <= std_logic_vector(unsigned(Counter) + 1); end if; end if; end process Counter_DFF; CountCarry <= Counter(0) = '1'; FoundNx <= Hit_SearchA or Hit_SearchB; NotFoundNx <= CountCarry and not (Hit_SearchA or Hit_SearchB); -- Control Finite State Machine ControlFSM: process (Clk) is begin -- process ControlFSM if Clk'event and Clk = '1' then if Reset = '1' then State <= DirectCompare; Index <= (others => '0'); DDataRdy <= '0'; IDataRdy <= '0'; RDataRdy <= '0'; AccessKind <= AccessNone; else case State is -- Compare data in direct mapped caches using port A and port B -- If both instruction and data are valid, data has priority when DirectCompare => if (IValid_Active = '1') or (DVMode = '1' and DValid = '1') then -- Not (yet) found in direct mapped caches State <= SearchStart; if DValid = '1' then AccessKind <= AccessData; else -- IValid = '1' AccessKind <= AccessInstr; end if; elsif RegWrLo = '1' then State <= WriteLO; elsif RegWrHi = '1' then State <= WriteHICheck; elsif RegWrSx = '1' then State <= SearchStart; AccessKind <= AccessReg; elsif RegRdHi then State <= ReadHI; elsif RegRdLo then State <= ReadLO; end if; -- Search through TLBHI in parallel using port A and port B when SearchStart => if (Hit_DirectA or Hit_DirectB) and AccessKind /= AccessReg then -- Found in direct mapped cache port A or port B State <= Found; if Hit_DirectA then Index <= IndexA; else Index <= IndexB; end if; else -- Searching - continue with next two entries State <= Search; Index <= Counter(1 to 5) & '0'; -- Save index for next cycle end if; when Search => if Hit_SearchA or Hit_SearchB then -- Found by search State <= Found; if Hit_SearchB then Index(Index'right) <= '1'; end if; elsif CountCarry then State <= NotFound; else -- Searching - continue with next two entries Index <= Counter(1 to 5) & '0'; -- Save index for next cycle end if; -- Assign ready signals (if not found) if NotFoundNx then case AccessKind is when AccessData => DDataRdy <= '1'; when AccessInstr => IDataRdy <= '1'; when AccessReg => RDataRdy <= '1'; when others => null; end case; end if; when Found => State <= FoundDone; -- Assign ready signals case AccessKind is when AccessData => DDataRdy <= '1'; when AccessInstr => IDataRdy <= '1'; when AccessReg => RDataRdy <= '1'; when others => null; end case; when FoundDone | NotFound => State <= DirectCompare; DDataRdy <= '0'; IDataRdy <= '0'; RDataRdy <= '0'; AccessKind <= AccessNone; -- Write TLBHI, invalidate direct mapped caches if previous TLBHI -- was valid, and write new TLBHI to direct mapped caches when WriteHICheck => State <= WriteHI; when WriteHI => if DataOutA(C_VALID) = '1' then State <= WriteHIInvalA; else State <= WriteHIDirectA; end if; when WriteHIInvalA => State <= WriteHIInvalB; when WriteHIInvalB => State <= WriteHIDirectA; when WriteHIDirectA => State <= WriteHIDirectB; when WriteHIDirectB => State <= DirectCompare; -- Write TLBLO when WriteLO => State <= DirectCompare; -- Read TLBHI or TLBLO when ReadHI | ReadLO => if not (RegRdHi or RegRdLo) then State <= DirectCompare; end if; when others => State <= DirectCompare; end case; end if; end if; end process ControlFSM; ControlComb: process (State) is begin -- process ControlComb case State is when DirectCompare => AddrSel <= "000"; when SearchStart => AddrSel <= "001"; when Search => AddrSel <= "001"; when Found => AddrSel <= "011"; when WriteHiCheck => AddrSel <= "111"; when WriteHI => AddrSel <= "111"; when WriteHIDirectA => AddrSel <= "100"; when WriteHIInvalA => AddrSel <= "110"; when WriteHIInvalB => AddrSel <= "010"; when WriteHIDirectB => AddrSel <= "101"; when WriteLO => AddrSel <= "110"; when ReadHI => AddrSel <= "111"; when ReadLO => AddrSel <= "111"; when others => AddrSel <= "000"; end case; case State is when WriteHI => WEA <= '1'; WEB <= '0'; when WriteHIDirectA => WEA <= '1'; WEB <= '0'; when WriteHIInvalA => WEA <= '1'; WEB <= '0'; when WriteHIInvalB => WEA <= '1'; WEB <= '0'; when WriteHIDirectB => WEA <= '1'; WEB <= '0'; when WriteLO => WEA <= '0'; WEB <= '1'; when others => WEA <= '0'; WEB <= '0'; end case; Load <= State = DirectCompare; Count <= State = Search; end process ControlComb; MMU_Stall_FF: process (Clk) is variable DValid_Q : std_logic; begin -- process MMU_Stall_FF if Clk'event and Clk = '1' then if Reset = '1' then EX_MMU_Stall <= false; DValid_Q := '0'; else if (State = WriteHIDirectA) or (State = WriteHIDirectB) or (AccessKind = AccessReg and (State = Found or State = FoundDone or NotFoundNx)) or (AccessKind = AccessData and (State = FoundDone or State = NotFound)) then -- End Stall: Register write done -- End Stall: Register look-up done (found or not found) -- End Stall: Data look-up done (found or not found) EX_MMU_Stall <= false; elsif (DValid_Q = '0' and DValid = '1' and DVMode = '1') or (RegWrHi = '1') or (RegWrSx = '1') then -- Stall due to starting data look-up in virtual mode -- Stall due to TLBHI register write -- Stall due to register look-up EX_MMU_Stall <= true; end if; if State = FoundDone then DValid_Q := '0'; -- Detect new contiguous starting data look-up else DValid_Q := DValid; end if; end if; end if; end process MMU_Stall_FF; TagInval_DFF: process (Clk) begin -- process TagInval_DFF if Clk'event and Clk = '1' then if Reset = '1' then TagInvalA <= (others => '0'); TagInvalB <= (others => '0'); elsif State = WriteHI then TagInvalA <= DataOutA(DirectA_Bits'range); TagInvalB <= DataOutA(DirectB_Bits'range); end if; end if; end process TagInval_DFF; SizeMask <= SizeMaskA; MaskedData <= TagCmpA & DataOutA(22 to 35); DataHigh <= DataOutA; DataLow <= DataOutB(0 to 31); RegDataLowOut <= DataOutB(32 to 35); IDataBusy <= '1' when AccessKind = AccessInstr else '0'; DDataBusy <= '1' when AccessKind = AccessData else '0'; RDataBusy <= '1' when AccessKind = AccessReg else '0'; Hit <= '1' when State = FoundDone else '0'; HitIndex <= Index;end architecture IMP;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?