📄 mmuconfig.vhd
字号:
constant FS_FT_U : integer := 4;
constant FS_FT_D : integer := 2;
constant FS_FT_NONE : std_logic_vector(2 downto 0) := "000";
constant FS_FT_INV : std_logic_vector(2 downto 0) := "001";
constant FS_FT_PRO : std_logic_vector(2 downto 0) := "010";
constant FS_FT_PRI : std_logic_vector(2 downto 0) := "011";
constant FS_FT_TRANS : std_logic_vector(2 downto 0):= "110";
constant FS_FT_BUS : std_logic_vector(2 downto 0) := "101";
constant FS_FT_INT : std_logic_vector(2 downto 0) := "110";
constant FS_FT_RVD : std_logic_vector(2 downto 0) := "111";
constant FS_FAV : natural := 1;
constant FS_OW : natural := 0;
--# mmu ctrl reg
type mmctrl_type1 is record
e : std_logic; -- enable
nf : std_logic; -- no fault
pso : std_logic; -- partial store order
-- pre : std_logic; -- pretranslation source
-- pri : std_logic; -- i/d priority
ctx : std_logic_vector(M_CTX_SZ-1 downto 0);-- context nr
ctxp : std_logic_vector(MMCTRL_CTXP_SZ-1 downto 0); -- context table pointer
tlbdis : std_logic; -- tlb disabled
bar : std_logic_vector(1 downto 0); -- preplace barrier
end record;
--# fault status reg
type mmctrl_fs_type is record
ow : std_logic;
fav : std_logic;
ft : std_logic_vector(2 downto 0); -- fault type
at_ls : std_logic; -- access type, load/store
at_id : std_logic; -- access type, i/dcache
at_su : std_logic; -- access type, su/user
l : std_logic_vector(1 downto 0); -- level
ebe : std_logic_vector(7 downto 0);
end record;
type mmctrl_type2 is record
fs : mmctrl_fs_type;
valid : std_logic;
fa : std_logic_vector(VA_I_SZ-1 downto 0); -- fault address register
end record;
-- ##############################################################
-- 6. Virtual Flush/Probe address [sparc V8: p.249,Appx.H,Figure H-9]
-- +---------------------------------------+--------+-------+
-- | VIRTUAL FLUSH&Probe Address (VFPA) | type | rvd |
-- +---------------------------------------+--------+-------+
-- 31 12 11 8 7 0
--
--
subtype FPA is natural range 31 downto 12;
constant FPA_I1_U : integer := 31;
constant FPA_I1_D : integer := 24;
constant FPA_I2_U : integer := 23;
constant FPA_I2_D : integer := 18;
constant FPA_I3_U : integer := 17;
constant FPA_I3_D : integer := 12;
constant FPTY_U : integer := 10; -- only 3 bits
constant FPTY_D : integer := 8;
-- ##############################################################
-- 7. control register virtual address [sparc V8: p.253,Appx.H,Table H-5]
-- +---------------------------------+-----+--------+
-- | | CNR | rsvd |
-- +---------------------------------+-----+--------+
-- 31 10 8 7 0
constant CNR_U : integer := 10;
constant CNR_D : integer := 8;
constant CNR_CTRL : std_logic_vector(2 downto 0) := "000";
constant CNR_CTXP : std_logic_vector(2 downto 0) := "001";
constant CNR_CTX : std_logic_vector(2 downto 0) := "010";
constant CNR_F : std_logic_vector(2 downto 0) := "011";
constant CNR_FADDR : std_logic_vector(2 downto 0) := "100";
-- ##############################################################
-- 8. Precise flush (ASI 0x10-14) [sparc V8: p.266,Appx.I]
-- supported: ASI_FLUSH_PAGE
-- ASI_FLUSH_CTX
constant PFLUSH_PAGE : std_logic := '0';
constant PFLUSH_CTX : std_logic := '1';
-- ##############################################################
-- 9. Diagnostic access
--
constant DIAGF_LVL_U : integer := 1;
constant DIAGF_LVL_D : integer := 0;
constant DIAGF_WR : integer := 3;
constant DIAGF_HIT : integer := 4;
constant DIAGF_CTX_U : integer := 12;
constant DIAGF_CTX_D : integer := 5;
constant DIAGF_VALID : integer := 13;
end mmuconfig;
-- Konrad Eisele<eiselekd@web.de> ,2002
library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.mmuconfig.all;
package mmulib is
function TLB_CreateCamWrite( two_data : std_logic_vector(31 downto 0);
read : std_logic;
lvl : std_logic_vector(1 downto 0);
ctx : std_logic_vector(M_CTX_SZ-1 downto 0);
vaddr : std_logic_vector(31 downto 0)
) return tlbcam_reg;
procedure TLB_CheckFault( ACC : in std_logic_vector(2 downto 0);
isid : in mmu_idcache;
su : in std_logic;
read : in std_logic;
fault_pro : out std_logic;
fault_pri : out std_logic );
procedure TLB_MergeData( LVL : in std_logic_vector(1 downto 0);
PTE : in std_logic_vector(31 downto 0);
data : in std_logic_vector(31 downto 0);
transdata : out std_logic_vector(31 downto 0));
function TLB_CreateCamTrans( vaddr : std_logic_vector(31 downto 0);
read : std_logic;
ctx : std_logic_vector(M_CTX_SZ-1 downto 0)
) return tlbcam_tfp;
function TLB_CreateCamFlush( data : std_logic_vector(31 downto 0);
ctx : std_logic_vector(M_CTX_SZ-1 downto 0)
) return tlbcam_tfp;
end;
package body mmulib is
procedure TLB_CheckFault( ACC : in std_logic_vector(2 downto 0);
isid : in mmu_idcache;
su : in std_logic;
read : in std_logic;
fault_pro : out std_logic;
fault_pri : out std_logic ) is
variable c_isd : std_logic;
begin
fault_pro := '0';
fault_pri := '0';
-- use '0' == icache '1' == dcache
if isid = id_icache then
c_isd := '0';
else
c_isd := '1';
end if;
--# fault, todo: should we flush on a fault?
case ACC is
when "000" => fault_pro := (not c_isd) or (not read);
when "001" => fault_pro := (not c_isd);
when "010" => fault_pro := (not read);
when "011" => null;
when "100" => fault_pro := (c_isd);
when "101" => fault_pro := (not c_isd) or ((not read) and (not su));
when "110" => fault_pri := (not su);
fault_pro := (not read);
when "111" => fault_pri := (not su);
when others => null;
end case;
end;
procedure TLB_MergeData( LVL : in std_logic_vector(1 downto 0);
PTE : in std_logic_vector(31 downto 0);
data : in std_logic_vector(31 downto 0);
transdata : out std_logic_vector(31 downto 0) ) is
begin
--# merge data
transdata := (others => '0');
case LVL is
when LVL_PAGE => transdata := PTE(PTE_PPN32PAG_U downto PTE_PPN32PAG_D) & data(VA_OFFPAG_U downto VA_OFFPAG_D);
when LVL_SEGMENT => transdata := PTE(PTE_PPN32SEG_U downto PTE_PPN32SEG_D) & data(VA_OFFSEG_U downto VA_OFFSEG_D);
when LVL_REGION => transdata := PTE(PTE_PPN32REG_U downto PTE_PPN32REG_D) & data(VA_OFFREG_U downto VA_OFFREG_D);
when LVL_CTX => transdata := data(VA_OFFCTX_U downto VA_OFFCTX_D);
when others => transdata := (others => 'X');
end case;
end;
function TLB_CreateCamWrite( two_data : std_logic_vector(31 downto 0);
read : std_logic;
lvl : std_logic_vector(1 downto 0);
ctx : std_logic_vector(M_CTX_SZ-1 downto 0);
vaddr : std_logic_vector(31 downto 0)
) return tlbcam_reg is
variable tlbcam_tagwrite : tlbcam_reg;
begin
tlbcam_tagwrite.ET := two_data(PT_ET_U downto PT_ET_D);
tlbcam_tagwrite.ACC := two_data(PTE_ACC_U downto PTE_ACC_D);
tlbcam_tagwrite.M := two_data(PTE_M) or (not read); -- tw : p-update modified
tlbcam_tagwrite.R := '1';
case tlbcam_tagwrite.ACC is -- tw : p-su ACC >= 6
when "110" | "111" => tlbcam_tagwrite.SU := '1';
when others => tlbcam_tagwrite.SU := '0';
end case;
tlbcam_tagwrite.VALID := '1';
tlbcam_tagwrite.LVL := lvl;
tlbcam_tagwrite.I1 := vaddr(VA_I1_U downto VA_I1_D);
tlbcam_tagwrite.I2 := vaddr(VA_I2_U downto VA_I2_D);
tlbcam_tagwrite.I3 := vaddr(VA_I3_U downto VA_I3_D);
tlbcam_tagwrite.CTX := ctx;
tlbcam_tagwrite.PPN := two_data(PTE_PPN_U downto PTE_PPN_D);
tlbcam_tagwrite.C := two_data(PTE_C);
return tlbcam_tagwrite;
end;
function TLB_CreateCamTrans( vaddr : std_logic_vector(31 downto 0);
read : std_logic;
ctx : std_logic_vector(M_CTX_SZ-1 downto 0)
) return tlbcam_tfp is
variable mtag : tlbcam_tfp;
begin
mtag.TYP := (others => '0');
mtag.I1 := vaddr(VA_I1_U downto VA_I1_D);
mtag.I2 := vaddr(VA_I2_U downto VA_I2_D);
mtag.I3 := vaddr(VA_I3_U downto VA_I3_D);
mtag.CTX := ctx;
mtag.M := not (read);
return mtag;
end;
function TLB_CreateCamFlush( data : std_logic_vector(31 downto 0);
ctx : std_logic_vector(M_CTX_SZ-1 downto 0)
) return tlbcam_tfp is
variable ftag : tlbcam_tfp;
begin
ftag.TYP := data(FPTY_U downto FPTY_D);
ftag.I1 := data(FPA_I1_U downto FPA_I1_D);
ftag.I2 := data(FPA_I2_U downto FPA_I2_D);
ftag.I3 := data(FPA_I3_U downto FPA_I3_D);
ftag.CTX := ctx;
ftag.M := '0';
return ftag;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -