📄 icache.vhd
字号:
(r.mds or not r.write) and
(r.mds or r.write or not (cacheon and hit and dvalid));
if ((r.overrun and not v.overrun) = '1') then
taddr := ici.fpc(TAG_HIGH downto LINE_LOW);
end if;
if (dco.hold and not (ici.nullify and not v.overrun)) = '1' then
if not ((cacheon and hit and dvalid) = '1') then
v.istate := 1; v.req := '1';
v.burst := '0';
if r.overrun = '1' then
if v.overrun = '0' then
if lastline /= '1' then v.burst := mcio.burst; end if;
else
if (ici.branch = '0') and (xlastline /= '1') then
v.burst := mcio.burst;
end if;
end if;
else
if lastline /= '1' then v.burst := mcio.burst; end if;
end if;
-- v.burst := mcio.burst and
-- not ((r.overrun and ici.branch and r.mds) or lastline);
end if;
end if;
if dco.icdiag.enable = '1' then
diagen := '1';
end if;
if (dco.hold and cacheon and
((not ici.nullify) or ((not r.mds) and (not r.write)))) = '1' then
v.tparerr := tparerr and cacheon and cachable;
v.dparerr := dparerr and cacheon and cachable and hit and valid;
end if;
v.holdn := not v.overrun; v.branch := '0';
if (r.overrun and v.overrun) = '0' then
v.waddress := ici.fpc(31 downto LINE_LOW);
else
v.waddress := r.xaddress(31 downto LINE_LOW);
end if;
ddatain := dci.maddress;
when 1 => -- streaming: update cache and send data to IU
rdatasel := memory;
v.overrun := ((r.overrun or
(r.write and ici.branch and (not ici.nullify) and dco.hold) or
((not r.write) and (not ici.nullify) and dco.hold)) and r.mds)
or (r.underrun and (not ici.nullify) and dco.hold);
v.underrun := r.underrun or
(r.write and dco.hold and ici.nullify and r.mds and not v.overrun);
if ((not r.overrun) and dco.hold and not ici.nullify) = '1' then
v.branch := ici.branch;
end if;
if mcio.ready = '1' then
v.mds := not v.overrun or (ici.branch and not r.overrun) or
(r.branch and r.overrun) or r.underrun;
v.req := r.burst;
v.burst := (r.burst and not (nlastline or (r.write and nnlastline)));
if ((v.overrun and v.branch) or (v.underrun and not cacheon)) = '1' then
v.burst := '0';
end if;
end if;
if ((not r.req) or
((v.underrun or v.overrun) and (not cacheon) and not v.req)) = '1'
then
v.underrun := '0';
if (cacheon = '1') or ((r.flush and not r.flush2) = '1') then
v.istate := 2;
else
v.istate := 0; v.flush := r.flush2;
end if;
end if;
taddr(TAG_HIGH downto LINE_LOW) := r.waddress(TAG_HIGH downto LINE_LOW);
v.holdn := not v.overrun;
when 2 => -- return to main witout overrun
rdatasel := memory;
v.overrun := (r.overrun or
(r.write and ici.branch and (not ici.nullify) and dco.hold) or
((not r.write) and (not ici.nullify) and dco.hold)) and r.mds;
if r.overrun = '1' then
taddr := r.xaddress(TAG_HIGH downto LINE_LOW);
elsif ici.nullify = '0' then
taddr := ici.fpc(TAG_HIGH downto LINE_LOW);
else
taddr := ici.rpc(TAG_HIGH downto LINE_LOW);
end if;
v.istate := 0; v.flush := r.flush2; v.mds := not v.overrun;
v.holdn := not v.overrun;
when others => null;
end case;
-- Generate new valid bits write strobe
vmaskraw := decode(r.waddress(LINE_HIGH downto LINE_LOW));
if (r.waddress(31) = '0') and (r.waddress(30 downto 29) /= "01") then
wcachable := '1';
else wcachable := '0'; end if;
if (icramo.itramout.tag = r.waddress(TAG_HIGH downto TAG_LOW)) then
whit := '1';
else whit := '0'; end if;
twrite := r.write;
if (mcio.ics = "00") or (r.flush = '1') then
twrite := '0'; vmask := (others => '0');
elsif (mcio.ics = "01") then
twrite := twrite and (wcachable and whit);
vmask := icramo.itramout.valid or vmaskraw;
else
twrite := twrite and wcachable;
if whit = '1' then vmask := icramo.itramout.valid or vmaskraw;
else vmask := vmaskraw; end if;
end if;
if mcio.mexc = '1' then vmask := vmask and not vmaskraw; dwrite := '0';
else dwrite := twrite; end if;
-- diagnostic cache access
diagdata := icramo.idramout.data;
if diagen = '1' then -- diagnostic access
taddr(OFFSET_HIGH downto LINE_LOW) :=
dco.icdiag.addr(OFFSET_HIGH downto LINE_LOW);
wtag := dco.icdiag.addr(TAG_HIGH downto TAG_LOW);
if dco.icdiag.tag = '1' then
twrite := not dco.icdiag.read; dwrite := '0';
diagdata := (others => '0');
diagdata(31) := icramo.itramout.parity;
diagdata(8) := icramo.idramout.parity;
diagdata(TAG_HIGH downto TAG_LOW) := icramo.itramout.tag;
diagdata(ILINE_SIZE -1 downto 0) := icramo.itramout.valid;
else
dwrite := not dco.icdiag.read; twrite := '0';
end if;
vmask := dci.maddress(ILINE_SIZE -1 downto 0);
-- ddatain := dci.maddress;
diagrdy := '1';
end if;
-- select data to return on read access
case rdatasel is
when memory => rdata := mcio.data;
when others => rdata := icramo.idramout.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'; vmask := (others => '0'); v.faddr := r.faddr +1;
taddr(OFFSET_HIGH downto OFFSET_LOW) := r.faddr;
if (r.faddr(IOFFSET_BITS -1) and not v.faddr(IOFFSET_BITS -1)) = '1' then
v.flush2 := '0';
end if;
end if;
-- parity generation
tparin := '0';
v.tapar := '0';
if ITAGPAR then
v.tapar := xorv(taddr(OFFSET_HIGH downto OFFSET_LOW)) and ITAGAPAR;
tparin := xorv(wtag & vmask & v.tapar & (diagen and dco.icdiag.addr(31)));
end if;
dparin := '0';
v.dapar := '0';
if DDATPAR then
v.dapar := xorv(taddr(OFFSET_HIGH downto LINE_LOW)) and IDATAPAR;
dparin := xorv(ddatain & v.dapar & (diagen and dco.icdiag.addr(31)));
else
dparin := '0';
end if;
-- reset
if rst = '0' then
v.istate := 0; v.req := '0'; v.burst := '0'; v.holdn := '1';
v.flush := '0'; v.flush2 := '0';
v.overrun := '0'; v.branch := '0'; v.underrun := '0';
end if;
-- Drive signals
c <= v; -- register inputs
-- tag ram inputs
icrami.itramin.valid <= vmask;
icrami.itramin.tag <= wtag;
icrami.itramin.enable <= enable;
icrami.itramin.write <= twrite;
icrami.itramin.parity <= tparin;
-- data ram inputs
icrami.idramin.enable <= enable;
icrami.idramin.address <= taddr(OFFSET_HIGH downto LINE_LOW);
icrami.idramin.data <= ddatain;
icrami.idramin.write <= dwrite;
icrami.idramin.parity <= dparin;
-- memory controller inputs
mcii.address(31 downto LINE_LOW) <= r.waddress;
mcii.address(1 downto 0) <= "00";
mcii.su <= r.su;
mcii.burst <= r.burst;
mcii.req <= r.req;
mcii.tparerr <= r.tparerr;
mcii.dparerr <= r.dparerr;
mcii.flush <= r.flush;
-- IU data cache inputs
ico.data <= rdata;
ico.exception <= mcio.mexc or error;
ico.hold <= r.holdn;
ico.mds <= r.mds;
ico.flush <= r.flush;
ico.diagdata <= diagdata;
ico.diagrdy <= diagrdy;
end process;
-- Local registers
dlat : process(clk)
begin
if clk'event and (clk='1') then
r <= c;
end if;
end process;
end ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -