📄 mmu_tlb.vhd
字号:
signal valid_ci : std_logic; signal TLBHI_Entry : TLBHI_Entry_Type; -- TLBHI entry begin TLBHI_Entry <= TLBHI(I); -- Generate the mask that is needed for the hit detection Generate_Mask: process (TLBHI_Entry) is variable Size : SIZE_Type; -- Entry size begin -- process Generate_Mask if C_STORE_TID then TAG_TID <= TLBHI_Entry(TAG_Type'range) & TLBHI_Entry(TID_Type'range); else TAG_TID <= TLBHI_Entry(TAG_Type'range); end if; Size := TLBHI_Entry(SIZE_Type'range); -- pragma translate_off if Size = (Size'range => 'U') then Size := (others => '0'); end if; -- pragma translate_on -- Set comparison mask for each entry - assume TAG masked when written AddrMask <= (others => '1'); AddrMask(Size_Addr_Type'range) <= C_SIZE_MASK(to_integer(unsigned(Size))); valid <= TLBHI_Entry(C_VALID); end process Generate_Mask; -- Instantiate extra carry input if necessary No_Extra_Carry: if not C_EXTRA_INPUT_FOR_LUT6 generate begin valid_ci <= valid; end generate No_Extra_Carry; Using_Extra_Carry: if C_EXTRA_INPUT_FOR_LUT6 generate begin MUXCY_EXTRA_I : MUXCY_L port map ( DI => '0', CI => valid, S => '1', LO => valid_ci); end generate Using_Extra_Carry; -- Instantiate special comparator -- The 8 highest bits in TAG_TID has a constant mask of '1' so they will -- not be masked USING_C_STORE_TID : if (C_STORE_TID) generate signal mask_cmp_carry1 : std_logic; signal mask_cmp_carry2 : std_logic; signal A_Vec : std_logic_vector(0 to 8); signal B_Vec : std_logic_vector(0 to 8); begin AddrMask(TID_Mask_Type'range) <= (others => not TLBHI_Entry(C_TID_0)); Mask_bits_compare_TID : carry_compare_mask generic map ( C_TARGET => C_TARGET, Size => TID_Mask_Type'length) port map ( A_Vec => TAG_TID(TID_Mask_Type'range), B_Vec => DATA_ADDR(TID_Mask_Type'range), Mask => AddrMask(TID_Mask_Type'range), Carry_In => valid_ci, Carry_Out => mask_cmp_carry1); Mask_bits_compare : carry_compare_mask generic map ( C_TARGET => C_TARGET, Size => Size_Addr_Type'length) port map ( A_Vec => TAG_TID(Size_Addr_Type'range), B_Vec => DATA_ADDR(Size_Addr_Type'range), Mask => AddrMask(Size_Addr_Type'range), Carry_In => mask_cmp_carry1, Carry_Out => mask_cmp_carry2); -- Do the last 8 bit comparison which has no masking A_Vec <= HIT_EN & TAG_TID(TAG_MSB_Type'range); B_Vec <= '1' & DATA_ADDR(TAG_MSB_Type'range); direct_compare: carry_compare generic map ( C_TARGET => C_TARGET, Size => TAG_MSB_Type'length + 1) port map ( A_Vec => A_Vec, B_Vec => B_Vec, Carry_In => mask_cmp_carry2, Carry_Out => shadow_hit(I)); end generate USING_C_STORE_TID; No_C_STORE_TID: if (not C_STORE_TID) generate signal mask_cmp_carry : std_logic; signal A_Vec : std_logic_vector(0 to 8); signal B_Vec : std_logic_vector(0 to 8); begin Mask_bits_compare : carry_compare_mask generic map ( C_TARGET => C_TARGET, Size => Size_Addr_Type'length) port map ( A_Vec => TAG_TID(Size_Addr_Type'range), B_Vec => DATA_ADDR(Size_Addr_Type'range), Mask => AddrMask(Size_Addr_Type'range), Carry_In => valid_ci, Carry_Out => mask_cmp_carry); -- Do the last 8 bit comparison which has no masking A_Vec <= HIT_EN & TAG_TID(TAG_MSB_Type'range); B_Vec <= '1' & DATA_ADDR(TAG_MSB_Type'range); direct_compare: carry_compare generic map ( C_TARGET => C_TARGET, Size => TAG_MSB_Type'length + 1) port map ( A_Vec => A_Vec, B_Vec => B_Vec, Carry_In => mask_cmp_carry, Carry_Out => shadow_hit(I)); end generate No_C_STORE_TID; end generate Lookup_Shadow_Reg; Generate_Hit_and_Addr : process (shadow_hit) is begin -- process Generate_Hit_and_Addr hit <= false; HitAddr <= 0; for I in Addr_type loop if (shadow_hit(I) = '1') then hit <= true; HitAddr <= I; end if; end loop; end process Generate_Hit_and_Addr; Using_Many_TLB: if (C_ADDR_WIDTH > 1) generate signal TLBLO : TLBLO_Type; attribute ram_style : string; attribute ram_style of TLBLO : signal is "distributed"; begin TLBLO_RAM : process(CLK) begin if CLK'event and CLK = '1' then if EN = '1' and TLBLO_WE = '1' then TLBLO(TLB_ADDR) <= TLBLO_Data; end if; end if; end process TLBLO_RAM; TLBLO_Out <= TLBLO(HitAddr); end generate Using_Many_TLB; Using_Two_TLB: if (C_ADDR_WIDTH = 1) generate signal TLBLO0 : TLBLO_Entry_Type; signal TLBLO1 : TLBLO_Entry_Type; begin TLBLO_DFF : process(CLK) begin if CLK'event and CLK = '1' then if EN = '1' and TLBLO_WE = '1' then if TLB_ADDR = 0 then TLBLO0 <= TLBLO_Data; else TLBLO1 <= TLBLO_Data; end if; end if; end if; end process TLBLO_DFF; TLBLO_Out <= TLBLO0 when HitAddr = 0 else TLBLO1; end generate Using_Two_TLB; Not_Using_Many_TLB: if (C_ADDR_WIDTH = 0) generate begin TLBLO_DFF : process(CLK) begin if CLK'event and CLK = '1' then if EN = '1' and TLBLO_WE = '1' then TLBLO_Out <= TLBLO_Data; end if; end if; end process TLBLO_DFF; end generate Not_Using_Many_TLB; Assign_TLBLO_Data: process (TLBLO_IN) is begin TLBLO_Data(RPN_Type'range) <= TLBLO_IN(RPN_Type'range); if C_STORE_EX then TLBLO_Data(C_EX) <= TLBLO_IN(C_EX); end if; if C_STORE_WR then TLBLO_Data(C_WR_OFFSET) <= TLBLO_IN(C_WR); end if; if C_MMU_ZONES > 1 then TLBLO_Data(C_ZSEL_OFFSET to C_ZSEL_OFFSET + C_ZSEL_WIDTH - 1) <= TLBLO_IN(ZSEL_Type'right - C_ZSEL_WIDTH + 1 to ZSEL_Type'right); end if; TLBLO_Data(C_I_OFFSET) <= TLBLO_IN(C_I); if C_STORE_G then TLBLO_Data(C_G_OFFSET) <= TLBLO_IN(C_G); end if; end process Assign_TLBLO_Data; Assign_DATALO_OUT: process (TLBLO_Out) is begin DATALO_OUT <= (others => '0'); DATALO_OUT(RPN_Type'range) <= TLBLO_Out(RPN_Type'range); if C_STORE_EX then DATALO_OUT(C_EX) <= TLBLO_Out(C_EX); end if; if C_STORE_WR then DATALO_OUT(C_WR) <= TLBLO_Out(C_WR_OFFSET); end if; if C_MMU_ZONES > 1 then DATALO_OUT(ZSEL_Type'right - C_ZSEL_WIDTH + 1 to ZSEL_Type'right) <= TLBLO_Out(C_ZSEL_OFFSET to C_ZSEL_OFFSET + C_ZSEL_WIDTH - 1); end if; DATALO_OUT(C_I) <= TLBLO_Out(C_I_OFFSET); if C_STORE_G then DATALO_OUT(C_G) <= TLBLO_Out(C_G_OFFSET); end if; end process Assign_DATALO_OUT; SIZE_OUT <= TLBHI(HitAddr)(SIZE_Type'range); DATA_HIT <= '1' when Hit else '0';end architecture IMP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -