📄 icache.vhd
字号:
if not (cacheon and hit and valid) = '1' then
v.istate := "01"; v.req := '1';
v.holdn := '0'; v.overrun := '1';
else
if (ISETS > 1) and (ICREPLACE = lru) then vl.write := '1'; end if;
end if;
v.waddress := 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 := std_logic_vector(conv_unsigned(set, SETBITS));
vl.waddr := ici.fpc(OFFSET_HIGH downto OFFSET_LOW);
end if;
v.setrepl := std_logic_vector(conv_unsigned(set, SETBITS));
if (((not hit) 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 := std_logic_vector(conv_unsigned(ISETS-1, SETBITS));
for i in ISETS-1 downto 0 loop
if (lock(i) = '0') and (i>conv_integer(r.rndcnt)) then
v.setrepl := std_logic_vector(conv_unsigned(i, SETBITS));
end if;
end loop;
end if;
else
v.setrepl := r.rndcnt;
end if;
when lru =>
-- pragma translate_off
if not is_x(ici.fpc) then
-- pragma translate_on
v.setrepl := lru_set(rl.lru(conv_integer(ici.fpc(OFFSET_HIGH downto OFFSET_LOW))), lock(0 to ISETS-1));
-- pragma translate_off
end if;
-- pragma translate_on
when lrr =>
v.setrepl := (others => '0');
if ICLOCK_BIT = 1 then
if lock(0) = '1' then v.setrepl(0) := '1';
else
v.setrepl(0) := icramo.itramout(0).lrr xor icramo.itramout(1).lrr;
end if;
else
v.setrepl(0) := icramo.itramout(0).lrr xor icramo.itramout(1).lrr;
end if;
if v.setrepl(0) = '0' then v.lrr := not icramo.itramout(0).lrr;
else v.lrr := icramo.itramout(0).lrr; 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 "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.nullify or not eholdn) and (mcio.ready and not (r.overrun and not r.underrun))));
v.overrun := (r.overrun or (eholdn and not ici.nullify)) 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;
end if;
if mcio.grant = '1' then
v.req := mcio.burst and r.burst and
(not (nnlastline and mcio.ready)) and (mcio.burst or (not branch)) and
not (v.underrun and not cacheon);
v.burst := v.req and not nnlastline;
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 (mcio.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;
-- 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 (mcio.ics = "01") then
twrite := twrite and r.hit;
vmask := icramo.itramout(set).valid 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 (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;
-- pragma translate_off
if not is_x(setrepl) then
-- pragma translate_on
if twrite = '1' then ctwrite(conv_integer(setrepl)) := '1'; end if;
if dwrite = '1' then cdwrite(conv_integer(setrepl)) := '1'; end if;
-- pragma translate_off
end if;
-- pragma translate_on
-- 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
-- pragma translate_off
if not is_x(r.diagset) then
-- pragma translate_on
rdiagset := conv_integer(r.diagset);
-- pragma translate_off
end if;
-- pragma translate_on
-- pragma translate_off
if not is_x(v.diagset) then
-- pragma translate_on
vdiagset := conv_integer(v.diagset);
-- pragma translate_off
end if;
-- pragma translate_on
end if;
diagdata := icramo.idramout(rdiagset).data;
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(ICTAG_LRRPOS);
wlock := dci.maddress(ICTAG_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 := (others => '0');
diagdata(TAG_HIGH downto TAG_LOW) := icramo.itramout(rdiagset).tag(ITAG_BITS - ILINE_SIZE - 1 downto 0);
diagdata(ILINE_SIZE -1 downto 0) := icramo.itramout(rdiagset).valid;
diagdata(ICTAG_LRRPOS) := icramo.itramout(rdiagset).lrr;
diagdata(ICTAG_LOCKPOS) := icramo.itramout(rdiagset).lock;
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(ILINE_SIZE -1 downto 0);
v.diagrdy := '1';
end if;
-- select data to return on read access
case rdatasel is
when memory => rdata := mcio.data;
when others => rdata := icramo.idramout(set).data;
end case;
-- cache flush
if (ici.flush or dco.icdiag.flush) = '1' then
v.flush := '1'; v.flush2 := '1'; v.faddr := (others => '0');
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'; wtag := (others => '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';
end if;
if (not rst or r.flush) = '1' then
vl.lru := (others => (others => '0'));
end if;
-- Drive signals
c <= v; -- register inputs
cl <= vl; -- lru register inputs
-- tag ram inputs
icrami.itramin.valid <= vmask;
icrami.itramin.tag <= wtag;
icrami.itramin.lrr <= wlrr;
icrami.itramin.lock <= wlock;
icrami.itramin.enable <= enable;
icrami.itramin.write <= ctwrite;
icrami.itramin.flush <= r.flush2;
-- data ram inputs
icrami.idramin.enable <= enable;
icrami.idramin.address <= taddr(OFFSET_HIGH downto LINE_LOW);
icrami.idramin.data <= ddatain;
icrami.idramin.write <= 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;
-- IU data cache inputs
ico.data <= rdata;
ico.exception <= mcio.mexc or error;
ico.hold <= r.holdn;
ico.mds <= mds;
ico.flush <= r.flush;
ico.diagdata <= diagdata;
ico.diagrdy <= r.diagrdy;
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;
-- 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 + -