⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmu.vhd

📁 sparc org, vhdl rtl code
💻 VHD
📖 第 1 页 / 共 2 页
字号:
          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 + -