📄 mmu.vhd
字号:
v.splt_is1.tlbactive := '1'; v.splt_is1.op.flush_op := '1'; elsif mmuici.trans_op = '1' then mmuico_grant := '1'; v.splt_is1.tlbactive := '1'; v.splt_is1.op.trans_op := '1'; end if; end if; if spltitlbout.transdata.finish = '1' and (r.splt_is2.op.flush_op = '0') then fault := spltitlbout.fault; end if; if spltdtlbout.transdata.finish = '1' and (r.splt_is2.op.flush_op = '0') then if (spltdtlbout.fault.fault_mexc or spltdtlbout.fault.fault_trans or spltdtlbout.fault.fault_inv or spltdtlbout.fault.fault_pro or spltdtlbout.fault.fault_pri or spltdtlbout.fault.fault_access) = '1' then fault := spltdtlbout.fault; -- overwrite icache fault end if; 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_a0; 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; twoi.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; if cmbtlbout.transdata.finish = '1' and (r.cmb_s2.op.flush_op = '0') then fault := cmbtlbout.fault; 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 = 0 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'; v.twowner := id_icache; end if; -- drive signals if M_TLB_TYPE = 0 then tlbi_a0.trans_op <= r.splt_is1.op.trans_op; tlbi_a0.flush_op <= r.splt_is1.op.flush_op; tlbi_a0.transdata <= spltitlbin; tlbi_a0.s2valid <= r.splt_is2.tlbactive; tlbi_a0.mmctrl1 <= mmudci.mmctrl1; tlbi_a0.wb_op <= '0'; tlbi_a1.trans_op <= r.splt_ds1.op.trans_op; tlbi_a1.flush_op <= r.splt_ds1.op.flush_op; tlbi_a1.transdata <= spltdtlbin; tlbi_a1.s2valid <= r.splt_ds2.tlbactive; tlbi_a1.mmctrl1 <= mmudci.mmctrl1; tlbi_a1.wb_op <= mmudci.wb_op; else tlbi_a0.trans_op <= r.cmb_s1.op.trans_op; tlbi_a0.flush_op <= r.cmb_s1.op.flush_op; tlbi_a0.transdata <= cmbtlbin; tlbi_a0.s2valid <= r.cmb_s2.tlbactive; tlbi_a0.mmctrl1 <= mmudci.mmctrl1; tlbi_a0.wb_op <= '0'; end if; tlbi_a0.tlbcami <= (others => mmutlbcam_in_type_none); tlbi_a1.tlbcami <= (others => mmutlbcam_in_type_none); mmudco.transdata <= mmudco_transdata; mmuico.transdata <= mmuico_transdata; mmudco.grant <= mmudco_grant; mmuico.grant <= mmuico_grant; mmudco.mmctrl2 <= r.mmctrl2; mmudco.wbtransdata <= wbtransdata; twi <= twiv; two_a(0) <= twoi; two_a(1) <= twod; mmctrl1 <= mmudci.mmctrl1; c <= v; end process p0; tlbcomb0: if M_TLB_TYPE = 1 generate -- i/d tlb ctlb0 : mmutlb generic map ( tech, M_ENT_C, 0, tlb_rep ) port map (rst, clk, tlbi_a0, tlbo_a0, two_a(0), twi_a(0)); end generate tlbcomb0; tlbsplit0: if M_TLB_TYPE = 0 generate -- i tlb itlb0 : mmutlb generic map ( tech, M_ENT_I, 0, tlb_rep ) port map (rst, clk, tlbi_a0, tlbo_a0, two_a(0), twi_a(0)); -- d tlb dtlb0 : mmutlb generic map ( tech, M_ENT_D, tlb_type, tlb_rep ) port map (rst, clk, tlbi_a1, tlbo_a1, two_a(1), twi_a(1)); end generate tlbsplit0; -- table walk component tw0 : mmutw port map (rst, clk, mmctrl1, twi, two, mcmmo, mcmmi);-- pragma translate_off chk : process begin assert not ((M_TLB_TYPE = 1) and (M_TLB_FASTWRITE /= 0)) report "Fast writebuffer only supported for combined cache" severity failure; wait; end process;-- pragma translate_on end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -