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

📄 mmu_icache.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
            v.istate := trans;             mmuici_trans_op := '1';            v.trans_op := not mmuico.grant;            v.cache := '0';            --v.req := '0';          else                                      v.req := '1';             v.cache := '1';          end if;          	else          if (ISETS > 1) and (ICREPLACE = lru) then vl.write := '1'; end if;        end if;        v.waddress := ici.fpc(31 downto PCLOW);        v.vaddress := ici.fpc(31 downto PCLOW);                  end if;      if dco.icdiag.enable = '1' then	diagen := '1';      end if;      ddatain := dci.maddress;      if (ISETS > 1) then        if (ICREPLACE = lru) then	  vl.set := conv_std_logic_vector(set, SETBITS); 	  vl.waddr := ici.fpc(OFFSET_HIGH downto OFFSET_LOW);	end if;        v.setrepl := conv_std_logic_vector(set, SETBITS); 	if (((not hit) and (not dparerr(set)) and (not r.flush)) = '1') then          case ICREPLACE is	  when rnd =>            if ICLOCK_BIT = 1 then               if lock(conv_integer(r.rndcnt)) = '0' then v.setrepl := r.rndcnt;              else                v.setrepl := conv_std_logic_vector(ISETS-1, SETBITS);                for i in ISETS-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(ici.fpc(OFFSET_HIGH downto OFFSET_LOW))), lock(0 to ISETS-1));          when lrr =>            v.setrepl := (others => '0');            if isetlock = 1 then              if lock(0) = '1' then v.setrepl(0) := '1';              else                v.setrepl(0) := icramo.tag(0)(CTAG_LRRPOS) xor icramo.tag(1)(CTAG_LRRPOS);              end if;            else              v.setrepl(0) := icramo.tag(0)(CTAG_LRRPOS) xor icramo.tag(1)(CTAG_LRRPOS);            end if;            if v.setrepl(0) = '0' then v.lrr := not icramo.tag(0)(CTAG_LRRPOS);            else v.lrr := icramo.tag(0)(CTAG_LRRPOS); end if;          end case;          end if;          if (ICLOCK_BIT = 1) then          if (hit and lock(set)) = '1' then v.lock := '1';          else v.lock := '0'; end if;        end if;      end if;    when trans =>        v.holdn := '0';                if (mmuico.transdata.finish = '1') then          if (mmuico.transdata.accexc) = '1' and ((mmudci.mmctrl1.nf) /= '1' or (r.su) = '1') then             -- if su then always do mexc            error := '1'; mds := '0';            v.holdn := '1'; v.istate := idle; v.burst := '0';          else            v.cache := mmuico.transdata.cache;            v.waddress := mmuico.transdata.data(31 downto PCLOW);            v.istate := streaming; v.req := '1';           end if;      end if;          when streaming =>		-- streaming: update cache and send data to IU      rdatasel := memory;      taddr(TAG_HIGH downto LINE_LOW) := r.vaddress(TAG_HIGH downto LINE_LOW);      branch := (ici.fbranch and r.overrun) or		      (ici.rbranch and (not r.overrun));      v.underrun := r.underrun or         (write and ((ici.inull or not eholdn) and (mcio.ready and not (r.overrun and not r.underrun))));      v.overrun := (r.overrun or (eholdn and not ici.inull)) and 		    not (write or r.underrun);      if mcio.ready = '1' then        mds := not (r.overrun and not r.underrun);        v.burst := v.req and not (nnlastline and mcio.ready);      end if;      if mcio.grant = '1' then         v.req := dco.icdiag.cctrl.burst and r.burst and 	         (not (nnlastline and mcio.ready)) and (dco.icdiag.cctrl.burst or (not branch)) and		 not (v.underrun and not cacheon);        v.burst := v.req and not (nnlastline and mcio.ready);      end if;      v.underrun := (v.underrun or branch) and not v.overrun;      v.holdn := not (v.overrun or v.underrun);      if (mcio.ready = '1') and (r.req = '0') then --(v.burst = '0') then        v.underrun := '0'; v.overrun := '0';        if (dco.icdiag.cctrl.ics(0) and not r.flush2) = '1' then	  v.istate := stop; v.holdn := '0';	else          v.istate := idle; v.flush := r.flush2; v.holdn := '1';	  if r.overrun = '1' then taddr := ici.fpc(TAG_HIGH downto LINE_LOW);	  else taddr := ici.rpc(TAG_HIGH downto LINE_LOW); end if;	end if;      end if;    when stop => 		-- return to main      taddr := ici.fpc(TAG_HIGH downto LINE_LOW);      v.istate := idle; v.flush := r.flush2;    when others => v.istate := idle;    end case;    if mcio.retry = '1' then v.req := '1'; end if;-- Generate new valid bits write strobe    vmaskraw := decode(r.waddress(LINE_HIGH downto LINE_LOW));    twrite := write;    if cacheon = '0' then      twrite := '0'; vmask := (others => '0');    elsif (dco.icdiag.cctrl.ics = "01") then      twrite := twrite and r.hit;      vmask := icramo.tag(set)(ilinesize-1 downto 0) or vmaskraw;    else      if r.hit = '1' then vmask := r.valid or vmaskraw;      else vmask := vmaskraw; end if;    end if;     if (mcio.mexc or (not mcio.cache) or (not r.cache)) = '1' then       twrite := '0'; dwrite := '0';    else dwrite := twrite; end if;    if twrite = '1' then      v.valid := vmask; v.hit := '1';      if (ISETS > 1) and (ICREPLACE = lru) then vl.write := '1'; end if;    end if;    if (ISETS > 1) and (ICREPLACE = lru) and (rl.write = '1') then      vl.lru(conv_integer(rl.waddr)) :=	  lru_calc(rl.lru(conv_integer(rl.waddr)), conv_integer(rl.set));    end if;-- cache write signals        if ISETS > 1 then setrepl := r.setrepl; else setrepl := (others => '0'); end if;    if twrite = '1' then ctwrite(conv_integer(setrepl)) := '1'; end if;    if dwrite = '1' then cdwrite(conv_integer(setrepl)) := '1'; end if;    -- diagnostic cache access    if diagen = '1' then     if (ISETS /= 1) then        v.diagset := dco.icdiag.addr(SETBITS -1 + TAG_LOW downto TAG_LOW);     end if;   end if;         if (ISETS /= 1) then       rdiagset := conv_integer(r.diagset);      vdiagset := conv_integer(v.diagset);    end if;    diagdata := icramo.data(rdiagset);    if diagen = '1' then -- diagnostic access      taddr(OFFSET_HIGH downto LINE_LOW) := dco.icdiag.addr(OFFSET_HIGH downto LINE_LOW);      wtag(TAG_HIGH downto TAG_LOW) := dci.maddress(TAG_HIGH downto TAG_LOW);      wlrr := dci.maddress(CTAG_LRRPOS);      wlock := dci.maddress(CTAG_LOCKPOS);      if dco.icdiag.tag = '1' then	twrite := not dco.icdiag.read; dwrite := '0';        ctwrite := (others => '0'); cdwrite := (others => '0');	ctwrite(vdiagset) := not dco.icdiag.read;        diagdata := icramo.tag(rdiagset);      else	dwrite := not dco.icdiag.read; twrite := '0';        cdwrite := (others => '0'); cdwrite(vdiagset) := not dco.icdiag.read;        ctwrite := (others => '0');      end if;      vmask := dci.maddress(ilinesize -1 downto 0);      v.diagrdy := '1';    end if;-- select data to return on read access    rdata := icramo.data;    case rdatasel is    when memory => rdata(0) := mcio.data; set := 0;    when others =>     end case;-- cache flush    if (ici.flush or dco.icdiag.flush) = '1' then      v.flush := '1'; v.flush2 := '1'; v.faddr := (others => '0');      v.pflush := dco.icdiag.pflush; wtag := (others => '0');      v.pflushr := '1';      v.pflushaddr := dco.icdiag.pflushaddr;      v.pflushtyp := dco.icdiag.pflushtyp;    end if;    if r.flush2 = '1' then      twrite := '1'; ctwrite := (others => '1'); vmask := (others => '0'); v.faddr := r.faddr +1;       taddr(OFFSET_HIGH downto OFFSET_LOW) := r.faddr; wlrr := '0'; wlock := '0';      if (r.faddr(IOFFSET_BITS -1) and not v.faddr(IOFFSET_BITS -1)) = '1' then	v.flush2 := '0';      end if;      v.lrr := '0';           -- precise flush, ASI_FLUSH_PAGE & ASI_FLUSH_CTX      --if M_EN then        if r.pflush = '1' then          twrite := '0'; ctwrite := (others => '0');          v.pflushr := not r.pflushr;          if r.pflushr = '0' then            for i in ISETS-1 downto 0 loop              pftag(OFFSET_HIGH downto OFFSET_LOW) := r.faddr;              pftag(TAG_HIGH downto TAG_LOW) := icramo.tag(i)(TAG_HIGH downto TAG_LOW); --icramo.itramout(i).tag;              --if (icramo.itramout(i).ctx = mmudci.mmctrl1.ctx) and              --   ((pftag(VA_I_U downto VA_I_D) = r.pflushaddr(VA_I_U downto VA_I_D)) or              --    (r.pflushtyp = '1')) then                ctwrite(i) := '1';              --end if;            end loop;          end if;        end if;      --end if;    end if;-- reset    if rst = '0' then       v.istate := idle; v.req := '0'; v.burst := '0'; v.holdn := '1';      v.flush := '0'; v.flush2 := '0'; v.overrun := '0'; v.underrun := '0';      v.rndcnt := (others => '0'); v.lrr := '0'; v.setrepl := (others => '0');      v.diagset := (others => '0'); v.lock := '0'; v.trans_op := '0';      v.flush3 := '1';    end if;    if r.flush3 = '1' then        vl.lru := (others => (others => '0'));    end if;    -- Drive signals    c  <= v;	   -- register inputs    cl <= vl;  -- lru register inputs    -- tag ram inputs    for i in 0 to ISETS-1 loop      tag(i) := (others => '0');      tag(i)(ilinesize-1 downto 0) := vmask;      tag(i)(TAG_HIGH downto TAG_LOW) := wtag;      tag(i)(CTAG_LRRPOS) := wlrr;      tag(i)(CTAG_LOCKPOS) := wlock;    end loop;    icrami.tag <= tag;    icrami.tenable   <= enable;    icrami.twrite    <= ctwrite;    icrami.flush    <= r.flush2;    icrami.ctx      <= mmudci.mmctrl1.ctx;    -- data ram inputs    icrami.denable   <= enable;    icrami.address(19 downto (OFFSET_HIGH - LINE_LOW +1)) <=         zero32(19 downto (OFFSET_HIGH - LINE_LOW +1));    icrami.address(OFFSET_HIGH - LINE_LOW downto 0) <= taddr(OFFSET_HIGH downto LINE_LOW);    icrami.data     <= ddatain;    icrami.dwrite    <= cdwrite;         -- memory controller inputs    mcii.address(31 downto 2)  <= r.waddress(31 downto 2);    mcii.address(1 downto 0)  <= "00";    mcii.su       <= r.su;    mcii.burst    <= r.burst;    mcii.req      <= r.req;    mcii.flush    <= r.flush;    -- mmu <-> icache    mmuici.trans_op <= mmuici_trans_op;    mmuici.transdata.data <= r.waddress(31 downto 2) & "00";    mmuici.transdata.su   <= r.su;    mmuici.transdata.isid <= id_icache;    mmuici.transdata.read <= '1';          -- IU data cache inputs    ico.data      <= rdata;    ico.mexc      <= mcio.mexc or error;    ico.hold      <= r.holdn;    ico.mds       <= mds;    ico.flush     <= r.flush;    ico.diagdata  <= diagdata;    ico.diagrdy   <= r.diagrdy;    ico.set       <= conv_std_logic_vector(set, 2);    ico.cfg  	  <= icfg;    ico.idle      <= sidle;  end process;-- Local registers  regs1 : process(clk)  begin if rising_edge(clk) then r <= c; end if; end process;  regs2gen : if (ISETS > 1) and (ICREPLACE = lru) generate    regs2 : process(clk)    begin if rising_edge(clk) then rl <= cl; end if; end process;  end generate;  nolru : if (ISETS = 1) or (irepl /= lru) generate    rl.write <= '0'; rl.waddr <= (others => '0');    rl.set <= (others => '0'); rl.lru <= (others => (others => '0'));  end generate;-- pragma translate_off  chk : process  begin    assert not ((ISETS > 2) and (ICREPLACE = lrr)) report	"Wrong instruction cache configuration detected: LRR replacement requires 2 sets"    severity failure;    wait;  end process;-- pragma translate_on      end ;

⌨️ 快捷键说明

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