📄 mmu.vhd
字号:
signal ib_tlb_addr_strobe_i : std_logic; signal icache_drop_request_q : std_logic; signal iDataBusy_q : std_logic; signal USizeMask : Size_Addr_Type;begin -- architecture IMP Using_TLBS : if (C_USE_MMU >= C_MMU_PROTECT) generate ex_databus_write_FF : process (Clk) is begin -- process ex_databus_write_FF if Clk'event and Clk = '1' then if reset = '1' then ex_databus_write_q <= '0'; else ex_databus_write_q <= EX_DataBus_Write; end if; end if; end process ex_databus_write_FF; -- Unified TLB UTLB_I : MMU_UTLB generic map ( C_TARGET => C_TARGET, C_MMU_TLB_WRITE => C_MMU_TLB_WRITE ) port map ( Clk => Clk, Reset => Reset, IVAddr => IB_Addr(0 to 21), IValid => utlb_IValid, IVMode => IB_VMode, DVAddr => EX_DataBus_Addr(0 to 21), DValid => utlb_DValid, DVMode => EX_VMode, PID => mem_pid_i, RegAddr => TLBX_Low, RegData => ex_Op1, RegDataLowIn => RegDataLowIn, RegRdLo => EX_Sel_SPR_TLBLO, RegRdHi => EX_Sel_SPR_TLBHI, RegWrLo => RegWrLo, RegWrHi => RegWrHi, RegWrSx => RegWrSx, SizeMask => USizeMask, MaskedData => MaskedData, DataHigh => DataHigh, DataLow => DataLow, RegDataLowOut => RegDataLowOut, IDataBusy => iDataBusy, DDataBusy => dDataBusy, RDataBusy => rDataBusy, IDataRdy => iDataRdy, DDataRdy => dDataRdy, RDataRdy => rDataRdy, Hit => utlb_Hit, HitIndex => utlb_HitIndex, EX_MMU_Stall => ex_MMU_Stall_UTLB ); utlb_IValid <= IB_Addr_Strobe and not IDATA_HIT; utlb_DValid <= EX_DataBus_Access and not DDATA_HIT; RegDataLowIn <= ICACHE_Valid_Addr & "000"; RegWrLo <= EX_MTS_TLBLO; RegWrHi <= EX_MTS_TLBHI; RegWrSx <= EX_MTS_TLBSX when C_MMU_TLB_WRITE else '0'; IB_Cache_Addr_MMU <= ex_Op1(0 to 21) & (22 to 31 => '0'); -- Instruction shadow TLB ITLB_I : MMU_TLB generic map ( C_TARGET => C_TARGET, C_TLBHI_WIDTH => 34, C_ADDR_WIDTH => ITLB_WIDTH, C_STORE_TID => C_STORE_TID, C_STORE_EX => C_STORE_PROT, C_STORE_WR => C_STORE_VALID, -- Used as valid TLB cache address C_MMU_ZONES => C_MMU_ZONES, C_STORE_G => C_USE_GUARDED) port map( Clk => Clk, EN => IB_VMode, TLB_Inval => itlb_Inval, TLB_ADDR => itlb_Addr, TLBLO_WE => itlb_WE, TLBLO_IN => ITLBLo_In, TLBHI_WE => ITLB_WE, TLBHI_IN => ITLBHi_In, HIT_EN => IDATA_HIT_EN, DATA_ADDR => IData_Addr, SIZE_OUT => ISIZE_OUT, DATALO_OUT => IDATALO_OUT, DATA_HIT => IDATA_HIT ); ITLBHi_In <= MaskedData(ITLBHi_In'range); IData_Addr <= IB_Addr(0 to 21) & mem_pid_i; IDATA_HIT_EN <= not iDataBusy; itlb_Inval <= tlb_inval or if_Instr_Storage_Excep_i = '1'; ITLBLo_Assign : process (DataLow, RegDataLowOut) is begin -- process ITLBLo_Assign ITLBLo_In <= DataLow; ITLBLo_In(C_WR) <= RegDataLowOut(0); -- Used as valid TLB cache address end process ITLBLo_Assign; -- Data shadow TLB DTLB_I : MMU_TLB generic map ( C_TARGET => C_TARGET, C_TLBHI_WIDTH => 34, C_ADDR_WIDTH => DTLB_WIDTH, C_STORE_TID => C_STORE_TID, C_STORE_EX => false, C_STORE_WR => C_STORE_PROT, C_MMU_ZONES => C_MMU_ZONES, C_STORE_G => false) port map( Clk => Clk, EN => EX_VMode, TLB_Inval => dtlb_Inval, TLB_ADDR => dtlb_Addr, TLBLO_WE => dtlb_WE, TLBLO_IN => DataLow, TLBHI_WE => DTLB_WE, TLBHI_IN => DTLBHi_In, DATA_ADDR => DData_Addr, HIT_EN => DDATA_HIT_EN, SIZE_OUT => DSIZE_OUT, DATALO_OUT => DDATALO_OUT, DATA_HIT => DDATA_HIT ); DTLBHi_In <= MaskedData(DTLBHi_In'range); DData_Addr <= EX_DataBus_Addr(0 to 21) & mem_pid_i; DDATA_HIT_EN <= EX_DataBus_Access and not dDataBusy; dtlb_Inval <= tlb_inval or ex_Data_Storage_Excep_i = '1'; tlb_Inval <= (EX_MTS_TLBLO = '1') or (EX_MTS_TLBHI = '1') or (EX_MTS_PID = '1' and not C_STORE_TID) or (EX_MTS_ZPR = '1' and not C_STORE_PROT); -- Increment the ITLB and DTLB addresses cyclically when writing Using_Many_ITLB: if (C_MMU_ITLB_SIZE > 1) generate signal itlb_Addr_i : std_logic_vector(0 to ITLB_WIDTH - 1); begin ITLB_AddrCounter_Process: process (Clk) begin -- process ITLB_AddrCounter if Clk'event and Clk = '1' then if Reset = '1' then itlb_Addr_i <= (others => '0'); elsif ITLB_WE = '1' then itlb_Addr_i <= std_logic_vector(unsigned(itlb_Addr_i) + 1); end if; end if; end process ITLB_AddrCounter_Process; itlb_Addr <= to_integer(unsigned(itlb_addr_i)); end generate Using_Many_ITLB; Not_Using_Many_ITLB: if (C_MMU_ITLB_SIZE = 1) generate itlb_Addr <= 0; end generate Not_Using_Many_ITLB; Using_Many_DTLB: if (C_MMU_DTLB_SIZE > 1) generate signal dtlb_Addr_i : std_logic_vector(0 to DTLB_WIDTH - 1); begin DTLB_AddrCounter_Process: process (Clk) begin -- process DTLB_AddrCounter if Clk'event and Clk = '1' then if Reset = '1' then dtlb_Addr_i <= (others => '0'); elsif DTLB_WE = '1' then dtlb_Addr_i <= std_logic_vector(unsigned(dtlb_Addr_i) + 1); end if; end if; end process DTLB_AddrCounter_Process; dtlb_Addr <= to_integer(unsigned(dtlb_addr_i)); end generate Using_Many_DTLB; Not_Using_Many_DTLB: if (C_MMU_DTLB_SIZE = 1) generate dtlb_Addr <= 0; end generate Not_Using_Many_DTLB; ITLB_WE <= iDataRdy and utlb_Hit; DTLB_WE <= dDataRdy and utlb_Hit; -- Special registers implementation Using_TLB_Register_Write: if (C_MMU_TLB_WRITE) generate mem_pid_FF : process (Clk) is begin -- process mem_pid_FF if Clk'event and Clk = '1' then if Reset = '1' then mem_pid_i <= (others => '0'); elsif EX_MTS_PID = '1' and EX_PipeRun then mem_pid_i <= EX_Op1(mem_pid_i'range); elsif MEM_Sel_SPR_TLBHI and Mem_PipeRun then mem_pid_i <= DataHigh(28 to 35); end if; end if; end process mem_pid_FF; wb_pid_FF : process (Clk) is begin -- process wb_pid_FF if Clk'event and Clk = '1' then if Reset = '1' then wb_pid_i <= (others => '0'); elsif Mem_PipeRun then wb_pid_i <= mem_pid_i; end if; end if; end process wb_pid_FF; Using_ZPR : if (C_MMU_ZONES > 0) generate constant mem_zpr_unused : Zone_Vector_Type(C_MMU_ZONES to 15) := (others => "11"); signal mem_zpr_value : Zone_Vector_Type(0 to C_MMU_ZONES - 1); begin mem_zpr_FF : process (Clk) is begin -- process mem_zpr_FF if Clk'event and Clk = '1' then if Reset = '1' then mem_zpr_value <= (others => "00"); elsif EX_MTS_ZPR = '1' and EX_PipeRun then for I in mem_zpr_value'range loop mem_zpr_value(I) <= EX_Op1(I * 2 to I * 2 + 1); end loop; end if; end if; end process mem_zpr_FF; mem_zpr <= mem_zpr_value & mem_zpr_unused; end generate Using_ZPR; Not_Using_ZPR : if (C_MMU_ZONES = 0) generate mem_zpr <= (others => "11"); -- No zone protection end generate Not_Using_ZPR; end generate Using_TLB_Register_Write; Not_Using_TLB_Register_Write: if (not C_MMU_TLB_WRITE) generate mem_pid_i <= (others => '0'); mem_zpr <= (others => "01"); -- No zone override wb_pid_i <= (others => '0'); end generate Not_Using_TLB_Register_Write; mem_tlbx_FF : process (Clk) is begin -- process mem_tlbx_FF if Clk'event and Clk = '1' then if Reset = '1' then mem_tlbx <= (others => '0'); elsif EX_MTS_TLBX = '1' and EX_PipeRun then mem_tlbx <= '0' & EX_Op1(33 - mem_tlbx'length to 31); elsif rDataRdy = '1' and C_MMU_TLB_WRITE then mem_tlbx <= (not utlb_Hit) & utlb_HitIndex; end if; end if; end process mem_tlbx_FF; TLBX_Low <= mem_tlbx(26 to 31); -- Generate memory protection exceptions Protection_FF : process (Clk) is begin -- process Protection_FF if Clk'event and Clk = '1' then utlb_Hit_Q <= utlb_Hit; DataLow_ZSEL_Q <= DataLow(ZSEL_Type'range); DataLow_EX_Q <= DataLow(C_EX); DataLow_I_Q <= DataLow(C_I); DataLow_G_Q <= DataLow(C_G); iDataRdy_Q <= iDataRdy; UZPR_Q <= mem_zpr(UZIndex); DataLow_WR_Q <= DataLow(C_WR); dDataRdy_Q <= dDataRdy; IDATALO_ZSEL_Q <= IDATALO_OUT(ZSEL_Type'range); IDATALO_EX_Q <= IDATALO_OUT(C_EX); IDATALO_G_Q <= IDATALO_OUT(C_G); IDATA_HIT_Q <= IDATA_HIT and not if_Instr_Storage_Excep_i; I_UM <= IB_UMode; DZPR_Q <= mem_zpr(DZIndex); DDATALO_WR_Q <= DDATALO_OUT(C_WR); DDATALO_I_Q <= DDATALO_OUT(C_I); DDATA_HIT_Q <= DDATA_HIT; D_UM <= EX_UMode; end if; end process Protection_FF; UZIndex <= to_integer(unsigned(DataLow(ZSEL_Type'range))); UZIndex_Q <= to_integer(unsigned(DataLow_ZSEL_Q)); IZIndex_Q <= to_integer(unsigned(IDATALO_ZSEL_Q)); IZone <= mem_zpr(IZIndex_Q) when C_STORE_PROT and IDATA_HIT_Q = '1' else mem_zpr(UZIndex_Q) when iDataRdy_Q = '1' else "11"; IEx <= IDATALO_EX_Q when C_STORE_PROT and IDATA_HIT_Q = '1' else DataLow_EX_Q when iDataRdy_Q = '1' else '1'; IG <= IDATALO_G_Q when C_STORE_PROT and IDATA_HIT_Q = '1' else -- G bit DataLow_G_Q when iDataRdy_Q = '1' else -- G bit '0'; IValid <= IDATA_HIT_Q or (utlb_Hit_Q and iDataRdy_Q); if_Instr_Storage_Excep_i <= '1' when (IZone = "00" and I_UM='1' and IValid ='1') or (IZone /= "11" and IEx = '0' and I_UM='1' and IValid ='1') or (IZone(0) = '0' and IEx = '0' and I_UM='0' and IValid ='1') or (C_USE_GUARDED and IG = '1' and IValid ='1') else '0'; IF_Instr_Storage_Excep <= if_Instr_Storage_Excep_i; DZIndex <= to_integer(unsigned(DDATALO_OUT(ZSEL_Type'range))); DZone <= DZPR_Q when C_STORE_PROT and DDATA_HIT_Q = '1' else UZPR_Q when dDataRdy_Q = '1' else "11"; DWr <= DDATALO_WR_Q when C_STORE_PROT and DDATA_HIT_Q = '1' else DataLow_WR_Q when dDataRdy_Q = '1' else '1'; NoWr <= DWr = '0' and ex_databus_write_q = '1'; DValid <= DDATA_HIT_Q or (utlb_Hit_Q and dDataRdy_Q); ex_Data_Storage_Excep_i <= '1' when (DZone = "00" and D_UM = '1' and DValid = '1') or (DZone /= "11" and NoWr and D_UM = '1' and DValid = '1') or (DZone(0) = '0' and NoWr and D_UM = '0' and DValid = '1') else '0'; EX_Data_Storage_Excep <= ex_Data_Storage_Excep_i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -