📄 mmu.vhd
字号:
wb_Zone_Protect_FF : process (Clk) is begin -- process wb_Zone_Protect_FF if Clk'event and Clk = '1' then if Reset = '1' then wb_Zone_Protect_i <= '0'; elsif if_Instr_Storage_Excep_i = '1' then if IZone = "00" and I_UM ='1' and IValid = '1' then wb_Zone_Protect_i <= '1'; else wb_Zone_Protect_i <= '0'; end if; elsif ex_Data_Storage_Excep_i = '1' then if DZone = "00" and D_UM = '1' and DValid = '1' then wb_Zone_Protect_i <= '1'; else wb_Zone_Protect_i <= '0'; end if; end if; end if; end process wb_Zone_Protect_FF; -- Generate cache inhibit signals IF_ICache_Inhibit <= IDATALO_OUT(C_I) when IDATA_HIT = '1' else -- I bit DataLow(C_I) when iDataRdy = '1' else -- I bit '0'; EX_DCache_Inhibit <= DDATALO_I_Q when DDATA_HIT_Q = '1' else -- I bit DataLow_I_Q when dDataRdy_Q = '1' else -- I bit '0'; -- Generate TLB miss exceptions IF_Instr_TLB_Miss_FF : process (Clk) is begin -- process IF_Instr_TLB_Miss_FF if Clk'event and Clk = '1' then if Reset = '1' then IF_Instr_TLB_Miss_Excep <= '0'; elsif utlb_Hit = '0' and iDataRdy = '1' then IF_Instr_TLB_Miss_Excep <= '1'; else IF_Instr_TLB_Miss_Excep <= '0'; end if; end if; end process IF_Instr_TLB_Miss_FF; EX_Data_TLB_Miss_FF : process (Clk) is begin -- process EX_Data_TLB_Miss_FF if Clk'event and Clk = '1' then if Reset = '1' then EX_Data_TLB_Miss_Excep <= '0'; elsif utlb_Hit = '0' and dDataRdy = '1' then EX_Data_TLB_Miss_Excep <= '1'; else EX_Data_TLB_Miss_Excep <= '0'; end if; end if; end process EX_Data_TLB_Miss_FF; -- Special registers read Using_TLB_Register_Read : if (C_MMU_TLB_READ and C_MMU_TLB_WRITE) generate mem_SPR_FF : process (Clk) is begin -- process mem_SPR_PID_FF if Clk'event and Clk = '1' then if Reset = '1' or not (MEM_Sel_SPR_PID or MEM_Sel_SPR_ZPR or MEM_Sel_SPR_TLBX or MEM_Sel_SPR_TLBLO or MEM_Sel_SPR_TLBHI) then wb_Sel_MMU_Res_i <= false; WB_MMU_Result <= (others => '0'); elsif MEM_PipeRun then wb_Sel_MMU_Res_i <= true; WB_MMU_Result <= (others => '0'); if MEM_Sel_SPR_PID then WB_MMU_Result(mem_pid_i'range) <= mem_pid_i; end if; if C_MMU_ZONES > 0 and MEM_Sel_SPR_ZPR then for I in 0 to C_MMU_ZONES - 1 loop WB_MMU_Result(I*2 to I*2 + 1) <= mem_zpr(I); end loop; end if; if MEM_Sel_SPR_TLBX then WB_MMU_Result(0) <= mem_tlbx(25); WB_MMU_Result(26 to 31) <= mem_tlbx(26 to 31); end if; if MEM_Sel_SPR_TLBLO then WB_MMU_Result <= DataLow; end if; if MEM_Sel_SPR_TLBHI then -- Bit 26 and 27 fixed to 0 WB_MMU_Result(0 to 25) <= DataHigh(0 to 25); end if; end if; end if; end process mem_SPR_FF; end generate Using_TLB_Register_Read; Not_Using_TLB_Register_Read : if (not C_MMU_TLB_READ and C_MMU_TLB_WRITE) generate mem_SPR_PID_FF : process (Clk) is begin -- process mem_SPR_PID_FF if Clk'event and Clk = '1' then if Reset = '1' or not MEM_Sel_SPR_TLBX then wb_Sel_MMU_Res_i <= false; WB_MMU_Result(0) <= '0'; WB_MMU_Result(26 to 31) <= (others => '0'); elsif MEM_PipeRun then wb_Sel_MMU_Res_i <= true; WB_MMU_Result(0) <= mem_tlbx(25); WB_MMU_Result(26 to 31) <= mem_tlbx(26 to 31); end if; end if; end process mem_SPR_PID_FF; WB_MMU_Result(1 to 25) <= (others => '0'); end generate Not_Using_TLB_Register_Read; Not_Using_TLB_Register_Access : if (not C_MMU_TLB_READ and not C_MMU_TLB_WRITE) generate WB_MMU_Result <= (others => '0'); end generate Not_Using_TLB_Register_Access; -- Instruction strobe handling ib_tlb_addr_strobe_i <= (IDATA_HIT and IB_Addr_Strobe) or (utlb_Hit and iDataRdy); IB_TLB_Addr_Strobe <= ib_tlb_addr_strobe_i; -- Instruction strobe handling IB_Strobes_FF : process (Clk) is begin -- process IB_Strobes_FF if Clk'event and Clk = '1' then if Reset = '1' or IB_VMode = '0' then IB_Addr_Strobe_1 <= '0'; IB_Fetch_1 <= '0'; else IB_Addr_Strobe_1 <= (IDATA_HIT and IB_Addr_Strobe) or (utlb_Hit and iDataRdy); IB_Fetch_1 <= IB_Fetch; end if; end if; end process IB_Strobes_FF; Drop_Request_FF : process (Clk) is begin -- process Drop_Request_FF if Clk'event and Clk = '1' then if Reset = '1' then icache_drop_request_q <= '0'; elsif ICACHE_Req_Prev = '1' then icache_drop_request_q <= '0'; else icache_drop_request_q <= ICACHE_Drop_Request; end if; end if; end process Drop_Request_FF; IDataBusy_FF : process (Clk) is begin -- process IDataBusy_FF if Clk'event and Clk = '1' then iDataBusy_q <= iDataBusy; end if; end process IDataBusy_FF; IB_Block_Ready_MMU <= utlb_Hit and iDataRdy; IB_Addr_Strobe_MMU <= IB_Addr_Strobe when IB_VMode = '0' or (icache_drop_request_q = '1' and ICACHE_Req_Prev = '0' and IDATA_HIT = '1' and iDataBusy = '0' and iDataBusy_q = '0') else '0' when (icache_drop_request_q = '1' and ICACHE_Req_Prev = '0' and IDATA_HIT = '0' and iDataBusy = '0' and iDataBusy_q = '0') else IB_Addr_Strobe_1 and not if_Instr_Storage_Excep_i; IB_Addr_Strobe_LMB_MMU <= IB_Addr_Strobe when IB_VMode = '0' else IB_Addr_Strobe_1 and not if_Instr_Storage_Excep_i; IB_Fetch_MMU <= IB_Fetch when IB_VMode = '0' else IB_Fetch_1; -- Stall handling ex_MMU_Stall_i <= ex_MMU_Stall_UTLB or ex_access_stall; EX_Stall_Cycle_Process : process (EX_DataBus_Access, RegWrHi, RegWrLo, RegWrSx, EX_Sel_SPR_TLBHI, EX_Sel_SPR_TLBLO) is begin if EX_DataBus_Access = '1' or -- Data look-up stall RegWrHi = '1' or -- TLBHI register write stall RegWrLo = '1' or -- TLBLO register write stall RegWrSx = '1' or -- Register look-up stall EX_Sel_SPR_TLBHI or -- TLBHI register read stall EX_Sel_SPR_TLBLO then -- TLBLO register read stall ex_stall_cycle <= '1'; else ex_stall_cycle <= '0'; end if; end process EX_Stall_Cycle_Process; EX_Stall_Cycle_FF : process (Clk) is begin -- process EX_Stall_Cycle_FF if Clk'event and Clk = '1' then if Reset = '1' then ex_stall_cycle_q <= '0'; elsif OF_PipeRun then ex_stall_cycle_q <= '0'; -- New contiguous stall start else ex_stall_cycle_q <= ex_stall_cycle; end if; end if; end process EX_Stall_Cycle_FF; -- Stall first cycle ex_access_stall <= ex_stall_cycle = '1' and ex_stall_cycle_q = '0'; -- Stop databus access until EX stall is over EX_DataBus_Access_MMU <= '0' when EX_VMode = '1' and ex_MMU_Stall_i else EX_DataBus_Access; end generate Using_TLBs; Not_Using_TLBS : if (C_USE_MMU < C_MMU_PROTECT) generate IF_Instr_Storage_Excep <= '0'; IF_Instr_TLB_Miss_Excep <= '0'; EX_Data_Storage_Excep <= '0'; EX_Data_TLB_Miss_Excep <= '0'; ex_MMU_Stall_i <= false; wb_Zone_Protect_i <= '0'; IF_ICache_Inhibit <= '0'; EX_DCache_Inhibit <= '0'; wb_Sel_MMU_Res_i <= false; WB_MMU_Result <= (others => '0'); mem_pid_i <= (others => '0'); wb_pid_i <= (others => '0'); IB_TLB_Addr_Strobe <= '0'; IB_Cache_Addr_MMU <= (others => '0'); IB_Addr_Strobe_MMU <= IB_Addr_Strobe; IB_Addr_Strobe_LMB_MMU <= IB_Addr_Strobe; IB_Block_Ready_MMU <= '0'; IB_Fetch_MMU <= IB_Fetch; EX_DataBus_Access_MMU <= EX_DataBus_Access; end generate Not_Using_TLBs; EX_MMU_Stall <= ex_MMU_Stall_i; MEM_PID <= mem_pid_i; WB_Zone_Protect <= wb_Zone_Protect_i; WB_Sel_MMU_Res <= wb_Sel_MMU_Res_i; WB_PID <= wb_pid_i; Using_Virtual_Memory : if (C_USE_MMU = C_MMU_VIRTUAL) generate signal DDATALO_OUT_Q : std_logic_vector(0 to 21); signal DSIZE_OUT_Q : SIZE_Type; signal DSizeMask_Q : Size_Addr_Type; signal DataLow_Q : std_logic_vector(0 to 21); signal ISizeMask : Size_Addr_Type; signal USizeMask_Q : Size_Addr_Type; signal ex_databus_addr_1 : std_logic_vector(0 to 31); signal ex_databus_addr_q : std_logic_vector(8 to 31); begin -- Generate physical addresses ISizeMask <= C_SIZE_MASK(to_integer(unsigned(ISIZE_OUT))); IB_TLB_Addr_Process : process (DataLow, IB_Addr, IDATA_HIT, IDATALO_OUT, ISizeMask, USizeMask) is begin -- process IB_TLB_Addr_Process if IDATA_HIT = '1' then ib_tlb_addr_mmu_i(0 to 7) <= IDATALO_OUT(0 to 7); ib_tlb_addr_mmu_i(8 to 21) <= IDATALO_OUT(8 to 21) or (IB_Addr(8 to 21) and not ISizeMask); else ib_tlb_addr_mmu_i(0 to 7) <= DataLow(0 to 7); ib_tlb_addr_mmu_i(8 to 21) <= DataLow(8 to 21) or (IB_Addr(8 to 21) and not USizeMask); end if; ib_tlb_addr_mmu_i(22 to 31) <= IB_Addr(22 to 31); end process IB_TLB_Addr_Process; IB_TLB_Addr_MMU <= ib_tlb_addr_mmu_i; IB_Valid_TLB_Addr_Process : process (IDATA_HIT, IDATALO_OUT, utlb_Hit, iDataRdy, RegDataLowOut) is begin -- process IB_Valid_TLB_Addr_Process if IDATA_HIT = '1' then IB_Valid_TLB_Addr <= IDATALO_OUT(C_WR); -- Used as valid TLB cache addr elsif utlb_Hit = '1' and iDataRdy = '1' then IB_Valid_TLB_Addr <= RegDataLowOut(0); else IB_Valid_TLB_Addr <= '0'; end if; end process IB_Valid_TLB_Addr_Process; IB_Addr_FF : process (Clk) is begin -- process IB_Addr_FF if Clk'event and Clk = '1' then if IDATA_HIT = '1' then IB_Addr_1(0 to 7) <= IDATALO_OUT(0 to 7); IB_Addr_1(8 to 21) <= IDATALO_OUT(8 to 21) or (IB_Addr(8 to 21) and not ISizeMask); else IB_Addr_1(0 to 7) <= DataLow(0 to 7); IB_Addr_1(8 to 21) <= DataLow(8 to 21) or (IB_Addr(8 to 21) and not USizeMask); end if; IB_Addr_1(22 to 31) <= IB_Addr(22 to 31); end if; end process IB_Addr_FF; IB_Addr_MMU <= IB_Addr when IB_VMode = '0' else IB_Addr_1; DSizeMask_Q <= C_SIZE_MASK(to_integer(unsigned(DSIZE_OUT_Q))); EX_DataBus_Addr_MMU <= EX_DataBus_Addr when EX_VMode = '0' else ex_databus_addr_1; EX_DataBus_Addr_Mux : process(DDATA_HIT_Q, DDATALO_OUT_Q, DSizeMask_Q, utlb_Hit_Q, DataLow_Q, USizeMask_Q, ex_databus_addr_q) is begin -- process EX_DataBus_Addr_Mux if DDATA_HIT_Q = '1' then ex_databus_addr_1(0 to 7) <= DDATALO_OUT_Q(0 to 7); ex_databus_addr_1(8 to 21) <= DDATALO_OUT_Q(8 to 21) or (ex_databus_addr_q(8 to 21) and not DSizeMask_Q); else -- utlb_Hit_Q = '1' ex_databus_addr_1(0 to 7) <= DataLow_Q(0 to 7); ex_databus_addr_1(8 to 21) <= DataLow_Q(8 to 21) or (ex_databus_addr_q(8 to 21) and not USizeMask_Q); end if; ex_databus_addr_1(22 to 31) <= ex_databus_addr_q(22 to 31); end process EX_DataBus_Addr_Mux; EX_DataBus_Addr_Reg : process (Clk) is begin -- process EX_DataBus_Addr_Reg if Clk'event and Clk = '1' then DDATALO_OUT_Q <= DDATALO_OUT(0 to 21); DataLow_Q <= DataLow(0 to 21); DSIZE_OUT_Q <= DSIZE_OUT; USizeMask_Q <= USizeMask; ex_databus_addr_q <= EX_DataBus_Addr(8 to 31); end if; end process EX_DataBus_Addr_Reg; end generate Using_Virtual_Memory; Not_Using_Virtual_Memory : if (C_USE_MMU /= C_MMU_VIRTUAL) generate IB_TLB_Addr_MMU <= IB_Addr; IB_Addr_MMU <= IB_Addr; EX_DataBus_Addr_MMU <= EX_DataBus_Addr; IB_Valid_TLB_Addr <= '0'; end generate Not_Using_Virtual_Memory;end architecture IMP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -