📄 mmu.vhd
字号:
v.splt_is1.tlbactive := '1';
v.splt_is1.op.trans_op := '1';
end if;
end if;
if spltitlbout.transdata.finish = '1' then
fault := spltitlbout.fault;
end if;
if spltdtlbout.transdata.finish = '1' then
fault := spltdtlbout.fault; -- overwrite icache fault
end if;
if spltitlbout.s1finished = '1' then
v.splt_is2 := r.splt_is1;
end if;
if spltdtlbout.s1finished = '1' then
v.splt_ds2 := r.splt_ds1;
end if;
if ( r.splt_is2.op.flush_op ) = '1' then
mmuico_transdata.finish := '0';
end if;
-- share tw
if two.finish = '1' then
v.twactive := '0';
end if;
if r.twowner = id_icache then
twiv := twi_a(0);
twoi.finish := two.finish;
else
twiv := twi_a(1);
twod.finish := two.finish;
end if;
if (v.twactive) = '0' then
if (twi_a(1).areq_ur or twi_a(1).walk_op_ur) = '1' then
v.twactive := '1';
v.twowner := id_dcache;
elsif (twi_a(0).areq_ur or twi_a(0).walk_op_ur) = '1' then
v.twactive := '1';
v.twowner := id_icache;
end if;
end if;
else
--# combined i/d cache: 1 tlb, 1 tw
-- share one tlb among i and d cache
cmbtlbout := tlbo_a(0);
fault := cmbtlbout.fault;
mmuico_grant := '0'; mmudco_grant := '0';
mmuico_transdata.finish := '0'; mmudco_transdata.finish := '0';
twiv := twi_a(0);
twod := two; twoi := two;
twod.finish := '0'; twoi.finish := '0';
twod.finish := two.finish;
if ((not v.cmb_s1.tlbactive) or cmbtlbout.s1finished) = '1' then
v.cmb_s1.tlbactive := '0';
v.cmb_s1.op.trans_op := '0';
v.cmb_s1.op.flush_op := '0';
if (mmudci.trans_op or mmudci.flush_op or mmuici.trans_op) = '1' then
v.cmb_s1.tlbactive := '1';
end if;
if mmudci.trans_op = '1' then
mmudco_grant := '1';
v.cmb_s1.tlbowner := id_dcache;
v.cmb_s1.op.trans_op := '1';
elsif mmudci.flush_op = '1' then
mmudco_grant := '1';
v.cmb_s1.tlbowner := id_dcache;
v.cmb_s1.op.flush_op := '1';
elsif mmuici.trans_op = '1' then
mmuico_grant := '1';
v.cmb_s1.tlbowner := id_icache;
v.cmb_s1.op.trans_op := '1';
end if;
end if;
if (r.cmb_s1.tlbactive and not r.cmb_s2.tlbactive) = '1' then
end if;
if cmbtlbout.s1finished = '1' then
v.cmb_s2 := r.cmb_s1;
end if;
if r.cmb_s1.tlbowner = id_dcache then
cmbtlbin := mmudci.transdata;
else
cmbtlbin := mmuici.transdata;
end if;
if r.cmb_s2.tlbowner = id_dcache then
mmudco_transdata := cmbtlbout.transdata;
else
mmuico_transdata := cmbtlbout.transdata;
end if;
end if;
-- # fault status register
if (mmudci.fsread) = '1' then
v.mmctrl2.valid := '0'; v.mmctrl2.fs.fav := '0';
end if;
if (fault.fault_mexc) = '1' then
fs.ft := FS_FT_TRANS;
elsif (fault.fault_trans) = '1' then
fs.ft := FS_FT_INV;
elsif (fault.fault_inv) = '1' then
fs.ft := FS_FT_INV;
elsif (fault.fault_pri) = '1' then
fs.ft := FS_FT_PRI;
elsif (fault.fault_pro) = '1' then
fs.ft := FS_FT_PRO;
elsif (fault.fault_access) = '1' then
fs.ft := FS_FT_BUS;
else
fs.ft := FS_FT_NONE;
end if;
fs.ow := '0';
fs.l := fault.fault_lvl;
if fault.fault_isid = id_dcache then
fs.at_id := '0';
else
fs.at_id := '1';
end if;
fs.at_su := fault.fault_su;
fs.at_ls := not fault.fault_read;
fs.fav := '1';
fs.ebe := (others => '0');
fa := fault.fault_addr(VA_I_U downto VA_I_D);
if (fault.fault_mexc or
fault.fault_trans or
fault.fault_inv or
fault.fault_pro or
fault.fault_pri or
fault.fault_access) = '1' then
--# priority
if v.mmctrl2.valid = '1'then
if (fault.fault_mexc) = '1' then
v.mmctrl2.fs := fs;
v.mmctrl2.fa := fa;
else
if (r.mmctrl2.fs.ft /= FS_FT_INV) then
if fault.fault_isid = id_dcache then
-- dcache
v.mmctrl2.fs := fs;
v.mmctrl2.fa := fa;
else
-- icache
if (not r.mmctrl2.fs.at_id) = '0' then
fs.ow := '1';
v.mmctrl2.fs := fs;
v.mmctrl2.fa := fa;
end if;
end if;
end if;
end if;
else
v.mmctrl2.fs := fs;
v.mmctrl2.fa := fa;
v.mmctrl2.valid := '1';
end if;
if (fault.fault_isid) = id_dcache then
mmudco_transdata.accexc := '1';
else
mmuico_transdata.accexc := '1';
end if;
end if;
-- # reset
if ( rst = '0' ) then
if M_TLB_TYPE = splittlb then
v.splt_is1.tlbactive := '0';
v.splt_is2.tlbactive := '0';
v.splt_ds1.tlbactive := '0';
v.splt_ds2.tlbactive := '0';
v.splt_is1.op.trans_op := '0';
v.splt_is2.op.trans_op := '0';
v.splt_ds1.op.trans_op := '0';
v.splt_ds2.op.trans_op := '0';
v.splt_is1.op.flush_op := '0';
v.splt_is2.op.flush_op := '0';
v.splt_ds1.op.flush_op := '0';
v.splt_ds2.op.flush_op := '0';
else
v.cmb_s1.tlbactive := '0';
v.cmb_s2.tlbactive := '0';
v.cmb_s1.op.trans_op := '0';
v.cmb_s2.op.trans_op := '0';
v.cmb_s1.op.flush_op := '0';
v.cmb_s2.op.flush_op := '0';
end if;
v.flush := '0';
v.mmctrl2.valid := '0';
v.twactive := '0';
end if;
-- drive signals
if M_TLB_TYPE = splittlb then
tlbi_a(0).trans_op <= r.splt_is1.op.trans_op;
tlbi_a(0).flush_op <= r.splt_is1.op.flush_op;
tlbi_a(0).transdata <= spltitlbin;
tlbi_a(0).s2valid <= r.splt_is2.tlbactive;
tlbi_a(0).mmctrl1 <= mmudci.mmctrl1;
tlbi_a(1).trans_op <= r.splt_ds1.op.trans_op;
tlbi_a(1).flush_op <= r.splt_ds1.op.flush_op;
tlbi_a(1).transdata <= spltdtlbin;
tlbi_a(1).s2valid <= r.splt_ds2.tlbactive;
tlbi_a(1).mmctrl1 <= mmudci.mmctrl1;
else
tlbi_a(0).trans_op <= r.cmb_s1.op.trans_op;
tlbi_a(0).flush_op <= r.cmb_s1.op.flush_op;
tlbi_a(0).transdata <= cmbtlbin;
tlbi_a(0).s2valid <= r.cmb_s2.tlbactive;
tlbi_a(0).mmctrl1 <= mmudci.mmctrl1;
end if;
mmudco.transdata <= mmudco_transdata;
mmuico.transdata <= mmuico_transdata;
mmudco.grant <= mmudco_grant;
mmuico.grant <= mmuico_grant;
mmudco.mmctrl2 <= r.mmctrl2;
twi <= twiv;
two_a(0) <= twoi;
two_a(1) <= twod;
mmctrl1 <= mmudci.mmctrl1;
c <= v;
end process p0;
tlbcomb0: if M_TLB_TYPE = combinedtlb generate
-- i/d tlb
ctlb0 : mmutlb
generic map ( entries => M_ENT_C )
port map (rst, clk, tlbi_a(0), tlbo_a(0), two_a(0), twi_a(0));
end generate tlbcomb0;
tlbsplit0: if M_TLB_TYPE = splittlb generate
-- i tlb
itlb0 : mmutlb
generic map ( entries => M_ENT_I )
port map (rst, clk, tlbi_a(0), tlbo_a(0), two_a(0), twi_a(0));
-- d tlb
dtlb0 : mmutlb
generic map ( entries => M_ENT_D )
port map (rst, clk, tlbi_a(1), tlbo_a(1), two_a(1), twi_a(1));
end generate tlbsplit0;
-- table walk component
tw0 : mmutw
port map (rst, clk, mmctrl1, twi, two, mcmmo, mcmmi);
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -