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

📄 mmu_dcache.vhd

📁 leon3 source code 虽然gaisler网站上有下载
💻 VHD
📖 第 1 页 / 共 4 页
字号:
              end if;            else              -- ## mmu case >  false and              --if  ((r.stpend  = '0') or ((mcdo.ready and not r.req)= '1')) and ( mmudco.wbtransdata.accexc = '0' ) and (dci.size /= "11") and (M_TLB_FASTWRITE /= 0)               if  ((r.stpend  = '0') or ((mcdo.ready and not r.req)= '1')) and ( mmudco.wbtransdata.accexc = '0' ) and (M_TLB_FASTWRITE /= 0)               then                v.req := '1'; v.stpend := '1';                 v.burst := dci.size(1) and dci.size(0);                if (dci.size = "11") then v.dstate := dblwrite; end if; -- double store	                    else              if (r.stpend  = '0') or ((mcdo.ready and not r.req)= '1')              then                v.wbinit := '1';     -- wb init in idle                v.burst := dci.size(1) and dci.size(0);                            else                v.wbinit := '0';              end if;                mmudci_trans_op := '1';  -- start translation              v.trans_op := not mmudco.grant;               v.vaddr := dci.maddress; v.holdn := '0';              v.dstate := wtrans;              v.dblwdata := dci.size(0) or dci.size(1);  -- "11"              -- ## < mmu case               end if;              end if;            -- note: cache hit disabled if BYPASS            if (r.cctrl.dcs(0) = '1') and ((hit and (dci.size(1) or validraw)) = '1')             then  -- write hit              twrite := '1'; dwrite := '1';              if (DSETS > 1) and (DCREPLACE = lru) then vl.write := '1'; end if;              setrepl := conv_std_logic_vector(set, SETBITS);              if DSNOOP2 /= 0 then                if ((dci.enaddr and not dci.read) = '1') or (eholdn = '0')                then v.xaddress := dci.maddress; else v.xaddress := dci.eaddress; end if;                vs.readbpx(set) := '1';              end if;                          end if;	    if (dci.size = "11") then v.xaddress(2) := '1'; end if;	  end if;          if (DSETS > 1) then    	    vl.set := conv_std_logic_vector(set, SETBITS);            v.setrepl := conv_std_logic_vector(set, SETBITS);            if ((not hit) and (not dparerr(set)) and (not r.flush)) = '1' then              case DCREPLACE is              when rnd =>                if DCLOCK_BIT = 1 then                   if lock(conv_integer(r.rndcnt)) = '0' then v.setrepl := r.rndcnt;                  else                    v.setrepl := conv_std_logic_vector(DSETS-1, SETBITS);                    for i in DSETS-1 downto 0 loop                      if (lock(i) = '0') and (i>conv_integer(r.rndcnt)) then                        v.setrepl := conv_std_logic_vector(i, SETBITS);                      end if;                    end loop;                  end if;                else                  v.setrepl := r.rndcnt;                end if;              when lru =>                v.setrepl := lru_set(rl.lru(conv_integer(dci.maddress(OFFSET_HIGH downto OFFSET_LOW))), lock(0 to DSETS-1));              when lrr =>                v.setrepl := (others => '0');                if DCLOCK_BIT = 1 then                   if lock(0) = '1' then v.setrepl(0) := '1';                  else                    v.setrepl(0) := dcramov.tag(0)(CTAG_LRRPOS) xor dcramov.tag(1)(CTAG_LRRPOS);                  end if;                else                  v.setrepl(0) := dcramov.tag(0)(CTAG_LRRPOS) xor dcramov.tag(1)(CTAG_LRRPOS);                end if;                if v.setrepl(0) = '0' then                  v.lrr := not dcramov.tag(0)(CTAG_LRRPOS);                else                  v.lrr := dcramov.tag(0)(CTAG_LRRPOS);                end if;              end case;            end if;            if (DCLOCK_BIT = 1) then              if (hit and (not dparerr(set)) and lock(set)) = '1' then v.lock := '1';              else v.lock := '0'; end if;            end if;                        end if;        end case;      end if;    when rtrans =>      if M_EN then        if r.stpend = '1' then          if ((mcdo.ready and not r.req) = '1') then	            v.ready := '1';       -- buffer store finish          end if;        end if;                v.holdn := '0';        if mmudco.transdata.finish = '1' then          -- translation error, i.e. page fault          if (mmudco.transdata.accexc) = '1' then            v.holdn := '1'; v.dstate := idle;            mds := '0'; mexc := not r.mmctrl1.nf;          else            v.dstate := wread;            v.cache := r.cache and mmudco.transdata.cache;            --v.xaddress := mmudco.data;            v.paddress := mmudco.transdata.data;            if v.wbinit = '1' then              v.wb.addr := mmudco.transdata.data;              v.req := '1';            end if;          end if;        end if;      end if;    when wread => 		-- read miss, wait for memory data      taddr := r.xaddress(OFFSET_HIGH downto LINE_LOW);      newtag := r.xaddress(TAG_HIGH downto TAG_LOW);      newptag := paddress(TAG_HIGH downto TAG_LOW);      v.nomds := r.nomds and not eholdn;      v.holdn := v.nomds; rdatasel := memory;      for i in 0 to DSETS-1 loop wlock(i) := r.lock; end loop;      for i in 0 to 1 loop wlrr(i) := r.lrr; end loop;      if (r.stpend = '0') and (r.ready = '0') then        if mcdo.ready = '1' then          mds := r.holdn or r.nomds; v.xaddress(2) := '1'; v.holdn := '1';          if (r.cctrl.dcs = "01") then 	    v.hit := mcdo.cache and r.hit and r.cache; twrite := v.hit;          elsif (r.cctrl.dcs(1) = '1') then 	    v.hit := mcdo.cache and (r.hit or (r.asi(3) and not r.asi(2))) and r.cache; twrite := v.hit;	  end if;           dwrite := twrite; rdatasel := memory;          mexc := mcdo.mexc;          tpwrite := twrite;          	  if r.req = '0' then	    if (((dci.enaddr and not mds) = '1') or               ((dci.eenaddr and mds and eholdn) = '1')) and (r.cctrl.dcs(0) = '1') then	      v.dstate := loadpend; v.holdn := '0';	    else v.dstate := idle; end if;	  else v.nomds := '1'; end if;        end if;	v.mexc := mcdo.mexc; v.wb.data2 := mcdo.data;      else	if (r.ready or (mcdo.ready and not r.req)) = '1' then	-- wait for store queue	  v.burst := r.size(1) and r.size(0) and not r.xaddress(2);          v.wb.addr := paddress;          v.wb.size := r.size; 	  v.wb.read := r.read; v.wb.data1 := dci.maddress; v.req := '1'; 	  v.wb.lock := dci.lock; v.wb.asi := r.asi(3 downto 0); v.ready := '0';        end if;      end if;      if DSNOOP2 /= 0 then vs.readbpx(conv_integer(setrepl)) := '1'; end if;    when loadpend =>		-- return from read miss with load pending      taddr := dci.maddress(OFFSET_HIGH downto LINE_LOW);      v.dstate := idle;     when dblwrite => 		-- second part of double store cycle      v.dstate := idle; v.wb.data2 := dci.edata;       edata := dci.edata;  -- needed for STD store hit      taddr := r.xaddress(OFFSET_HIGH downto LINE_LOW);         if (r.cctrl.dcs(0) = '1') and (r.hit = '1') then dwrite := '1'; end if;    when asi_idtag =>		-- icache diag access      rdatasel := icache; v.icenable := '1'; v.holdn := dci.dsuen;      if  ico.diagrdy = '1' then	v.dstate := loadpend; v.icenable := '0'; mds := not r.read;      end if;          when wtrans =>      edata := dci.edata;  -- needed for STD store hit      taddr := r.xaddress(OFFSET_HIGH downto LINE_LOW);       newtag := r.xaddress(TAG_HIGH downto TAG_LOW);                if M_EN then        if r.stpend = '1' then          if ((mcdo.ready and not r.req) = '1') then	            v.ready := '1';       -- buffer store finish          end if;        end if;        -- fetch dblwrite data 2, does the same as state dblwrite,        -- except that init of data2 is omitted to end of translation or in wwrite        if ((r.dblwdata) = '1') and ((r.size) = "11") then            v.dblwdata := '0';        end if;                v.holdn := '0';        if mmudco.transdata.finish = '1' then                  if (mmudco.transdata.accexc) = '1' then            v.holdn := '1'; v.dstate := idle;            mds := '0'; mexc := not r.mmctrl1.nf;                          tagclear := r.cctrl.dcs(0) and r.hit;                        twrite := tagclear;            	    if (twrite = '1') and (((dci.enaddr and not mds) = '1') or 	        ((dci.eenaddr and mds and eholdn) = '1')) and (r.cctrl.dcs(0) = '1') then	      v.dstate := loadpend; v.holdn := '0';	    end if;                      else            v.dstate := wwrite;            v.cache := mmudco.transdata.cache;            v.paddress := mmudco.transdata.data;                        if (r.wbinit) = '1' then              v.wb.data2 := dci.edata;               v.wb.addr := mmudco.transdata.data;              v.dstate := idle;  v.holdn := '1';               v.req := '1'; v.stpend := '1';              v.burst := r.size(1) and r.size(0) and not v.wb.addr(2);              --if (mcdo.dcs(0) = '1') and (r.hit = '1') and (r.size = "11")  then  -- write hit              if (r.cctrl.dcs(0) = '1') and (r.hit = '1') and (r.size = "11")  then  -- write hit                dwrite := '1';              end if;            end if;          end if;        else          -- mmudci_trans_op := '1';  -- start translation        end if;      end if;            when wwrite => 		-- wait for store buffer to empty (store access)      edata := dci.edata;  -- needed for STD store hit      if (v.ready or (mcdo.ready and not r.req)) = '1' then	-- store queue emptied          if (r.cctrl.dcs(0) = '1') and (r.hit = '1') and (r.size = "11")  then  -- write hit            taddr := r.xaddress(OFFSET_HIGH downto LINE_LOW); dwrite := '1';          end if;        v.dstate := idle; 	v.req := '1'; v.burst := r.size(1) and r.size(0); v.stpend := '1';        v.wb.addr := paddress;        v.wb.size := r.size;	v.wb.read := r.read; v.wb.data1 := dci.maddress;	v.wb.lock := dci.lock; v.wb.data2 := dci.edata;	v.wb.asi := r.asi(3 downto 0); 	if r.size = "11" then v.wb.addr(2) := '0'; end if;      else  -- hold cpu until buffer empty        v.holdn := '0';      end if;          when wflush =>       v.holdn := '0';      if mmudco.transdata.finish = '1' then                v.dstate := idle; v.holdn := '1';      end if;          when others => v.dstate := idle;    end case;-- select data to return on read access-- align if byte/half word read from cache or memory.    --mmudiagaddr := dci.maddress(CNR_U downto CNR_D); mmuwdata := dci.edata;    if (dsu = 1) and (dci.dsuen = '1') then      v.dsuset := conv_std_logic_vector(ddset, SETBITS);       case dci.asi(4 downto 0) is      when ASI_ITAG | ASI_IDATA =>        v.icenable := not ico.diagrdy;        rdatasel := icache;      when ASI_DTAG =>        tdiagwrite := not dci.eenaddr and dci.enaddr and dci.write;        twrite := not dci.eenaddr and dci.enaddr and dci.write;        rdatasel := dtag;       when ASI_MMUSNOOP_DTAG =>        if M_EN then        tdiagwrite := not dci.eenaddr and dci.enaddr and dci.write;        tpwrite := not dci.eenaddr and dci.enaddr and dci.write;        rdatasel := mmusnoop_dtag;        end if;      when ASI_DDATA =>        ddiagwrite := not dci.eenaddr and dci.enaddr and dci.write;        dwrite := not dci.eenaddr and dci.enaddr and dci.write;        rdatasel := dddata;       when ASI_MMUREGS =>        mmuregw := not dci.eenaddr and dci.enaddr and dci.write;        rdatasel := misc;        when others =>      end case;    end if;    -- note: mmudiagaddr is (10 downto 8) (000,001, ...)    -- read    case mmudiagaddr is      when CNR_CTRL =>         miscdata(MMCTRL_E) := r.mmctrl1.e;         miscdata(MMCTRL_NF) := r.mmctrl1.nf;         miscdata(MMCTRL_PSO) := r.mmctrl1.pso;        miscdata(MMCTRL_VER_U downto MMCTRL_VER_D) := "0000";        miscdata(MMCTRL_IMPL_U downto MMCTRL_IMPL_D) := "0000";        miscdata(23 downto 21) := conv_std_logic_vector(M_ENT_ILOG,3);        miscdata(20 downto 18) := conv_std_logic_vector(M_ENT_DLOG,3);        if M_TLB_TYPE = 0 then miscdata(17) := '1'; else          miscdata(23 downto 21) := conv_std_logic_vector(M_ENT_CLOG,3);          miscdata(20 downto 18) := (others => '0');        end if;        miscdata(MMCTRL_TLBDIS) := r.mmctrl1.tlbdis;        --custom       when CNR_CTXP =>        miscdata(MMCTXP_U downto MMCTXP_D) := r.mmctrl1.ctxp;       when CNR_CTX =>         miscdata(MMCTXNR_U downto MMCTXNR_D) := r.mmctrl1.ctx;       when CNR_F =>        miscdata(FS_OW) := mmudco.mmctrl2.fs.ow;        miscdata(FS_FAV) := mmudco.mmctrl2.fs.fav;        miscdata(FS_FT_U downto FS_FT_D) := mmudco.mmctrl2.fs.ft;        miscdata(FS_AT_LS) := mmudco.mmctrl2.fs.at_ls;        miscdata(FS_AT_ID) := mmudco.mmctrl2.fs.at_id;        miscdata(FS_AT_SU) := mmudco.mmctrl2.fs.at_su;        miscdata(FS_L_U downto FS_L_D) := mmudco.mmctrl2.fs.l;        miscdata(FS_EBE_U downto FS_EBE_D) := mmudco.mmctrl2.fs.ebe;      when CNR_FADDR =>         miscdata(VA_I_U downto VA_I_D) := mmudco.mmctrl2.fa;       when others => null;     end case;            rdata := (others => '0'); rdatav := (others => (others => '0'));    align_data := (others => '0'); align_datav := (others => (others => '0'));    maddrlow := maddress(1 downto 0); -- stupid Synopsys VSS bug ...    case rdatasel is    when misc =>      set := 0;      rdatav(0) := miscdata;    when dddata =>       rdatav := dcramov.data;      if dci.dsuen = '1' then set := conv_integer(r.dsuset);      else set := ddset; end if;     when dtag =>       rdatav := dcramov.tag;       if dci.dsuen = '1' then set := conv_integer(r.dsuset);      else set := ddset; end if;     when mmusnoop_dtag =>       rdatav := dcramov.stag;       if dci.dsuen = '1' then set := conv_integer(r.dsuset);      else set := ddset; end if;     when dctx =>      --rdata(M_CTX_SZ-1 downto 0) := dcramov.dtramout(ddset).ctx;    when icache =>       rdatav(0) := ico.diagdata; set := 0;    when ddata | memory =>        if rdatasel = memory then	  rdatav(0) := mcdo.data; set := 0; --FIXME        else	  for i in 0 to DSETS-1 loop rdatav(i) := dcramov.data(i); end loop;        end if;    when sysr =>       set := 0;      case dci.maddress(3 downto 2) is      when "00" | "01" =>        rdatav(0)(23) := r.cctrl.dsnoop;        rdatav(0)(16 downto 14) := r.cctrl.burst & ico.flush & r.flush;        rdatav(0)(5 downto 0) :=             r.cctrl.dfrz & r.cctrl.ifrz & r.cctrl.dcs & r.cctrl.ics;      when "10" =>	rdatav(0) := ico.cfg;      when others =>	rdatav(0) := cache_cfg(drepl, dsets, dlinesize, dsetsize, dsetlock, 		dsnoop, lram, lramsize, lramstart, 1);      end case;    end case;-- select which data to update the data cache with       for i in 0 to DSETS-1 loop        case size is		-- merge data during partial write        when "00" =>          case maddrlow is          when "00" =>	    ddatainv(i) := edata(7 downto 0) & dcramov.data(i)(23 downto 0);          when "01" =>	    ddatainv(i) := dcramov.data(i)(31 downto 24) & edata(7 downto 0) & 		     dcramov.data(i)(15 downto 0);          when "10" =>	    ddatainv(i) := dcramov.data(i)(31 downto 16) & edata(7 downto 0) & 		     dcramov.data(i)(7 downto 0);          when others =>	    ddatainv(i) := dcramov.data(i)(31 downto 8) & edata(7 downto 0);           end case;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -