📄 icache.vhd
字号:
v.holdn := '0'; v.overrun := '1'; else if (ISETS > 1) and (irepl = lru) then vl.write := '1'; end if; end if; v.waddress := ici.fpc(31 downto 2); end if; if dco.icdiag.enable = '1' then diagen := '1'; end if; ddatain := dci.maddress; if (ISETS > 1) then if (irepl = 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 r.flush)) = '1') then case irepl is when rnd => if isetlock = 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 (isetlock = 1) then if (hit and lock(set)) = '1' then v.lock := '1'; else v.lock := '0'; end if; end if; end if; when "01" => -- streaming: update cache and send data to IU rdatasel := memory; taddr(TAG_HIGH downto LINE_LOW) := r.waddress(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 (v.overrun and not r.underrun); mds := not (r.overrun and not r.underrun);-- v.req := r.burst; 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 := "10"; v.holdn := '0'; else v.istate := "00"; 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 "10" => -- return to main taddr := ici.fpc(TAG_HIGH downto LINE_LOW); v.istate := "00"; v.flush := r.flush2; when others => v.istate := "00"; end case; if mcio.retry = '1' then v.req := '1'; end if; if lram = 1 then if LRAMCS_EN then if taddr(31 downto 24) = LRAM_START then lramcs := '1'; else lramcs := '0'; end if; else lramcs := '1'; end if; 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) = '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 (irepl = lru) then vl.write := '1'; end if; end if; if (ISETS > 1) and (irepl = 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 if (dco.icdiag.ilramen = '1') and (lram = 1) then v.diagset := conv_std_logic_vector(1, SETBITS); else v.diagset := dco.icdiag.addr(SETBITS -1 + TAG_LOW downto TAG_LOW); end if; end if; end if; case ISETS is when 1 => vdiagset := 0; rdiagset := 0; when 3 => if conv_integer(v.diagset) < 3 then vdiagset := conv_integer(v.diagset); end if; if conv_integer(r.diagset) < 3 then rdiagset := conv_integer(r.diagset); end if; when others => vdiagset := conv_integer(v.diagset); rdiagset := conv_integer(r.diagset); end case; diagdata := icramo.data(rdiagset); if diagen = '1' then -- diagnostic or local ram access taddr(TAG_HIGH downto LINE_LOW) := dco.icdiag.addr(TAG_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.ilramen = '1') and (lram = 1) then ilramwr := not dco.icdiag.read; elsif 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') and (icen /= 0) then v.flush := '1'; v.flush2 := '1'; v.faddr := (others => '0'); end if; if (r.flush2 = '1') and (icen /= 0) 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'; wtag := (others => '0'); v.lrr := '0'; if (r.faddr(IOFFSET_BITS -1) and not v.faddr(IOFFSET_BITS -1)) = '1' then v.flush2 := '0'; end if; end if;-- reset if rst = '0' then v.istate := "00"; 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.flush3 := '1'; v.waddress := ici.fpc(31 downto 2); v.lrr := '0'; 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 enable := enable and not dco.icdiag.scanen; 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.dpar <= (others => '0'); icrami.tpar <= (others => (others => '0')); icrami.ctx <= (others => '0'); -- data ram inputs icrami.denable <= enable; icrami.address <= taddr(19+LINE_LOW downto LINE_LOW); icrami.data <= ddatain; icrami.dwrite <= cdwrite; -- local ram inputs icrami.ldramin.enable <= (dco.icdiag.ilramen or lramcs or lramacc) and not dco.icdiag.scanen; icrami.ldramin.read <= dco.icdiag.ilramen or lramacc; icrami.ldramin.write <= ilramwr; -- 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; -- 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; regs2 : if (ISETS > 1) and (irepl = 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 (irepl = 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 + -