URL
https://opencores.org/ocsvn/mytwoqcache/mytwoqcache/trunk
Subversion Repositories mytwoqcache
Compare Revisions
- This comparison shows the changes necessary to convert path
/mytwoqcache/trunk
- from Rev 19 to Rev 20
- ↔ Reverse comparison
Rev 19 → Rev 20
/2QCache.vhd
137,7 → 137,7
signal statetag: tType; |
signal stateram: rType; |
signal statequeue: fType; |
signal enableram, enablequeue, queuedone, readsh, writesh, doneh, preempted, |
signal enableram, enablequeue, queuedone, readsh, writesh, doneh, preempted, isfull, flag, |
interrupt, readb, writeb, writec, writet, accdone, accqueue, accinterrupt, serviced, oldint: std_ulogic; |
signal gal: std_ulogic_vector( 7 downto 0); |
|
261,11 → 261,11
found <= a; |
free <= b; |
|
if ways = 1 then |
elim <= 0; |
else |
elim <= to_integer( gal( ldways - 1 downto 0)); |
end if; |
if ways = 1 then |
elim <= 0; |
else |
elim <= to_integer( gal( ldways - 1 downto 0)); |
end if; |
|
if stateram = ramstart then |
enableram <= '1'; |
276,25 → 276,25
|
if interrupt = '1' and oldint = '0' then |
enableram <= '0'; |
AddressInt <= toFlush; |
statetag <= stateget; |
elsif queuedone = '1' then |
AddressInt <= toFlush; |
statetag <= stateget; |
elsif queuedone = '1' then |
enableram <= '0'; |
statetag <= finish; |
end if; |
statetag <= finish; |
end if; |
when stateget => |
statetag <= stateget1; |
when stateget1 => |
enableram <= '1'; |
enableram <= '1'; |
tagDummy <= tagRAMOut; |
|
for i in tagRAMIn'range loop |
if del = i then |
tagRAMIn( i).tagvalid <= '0'; |
tagRAMIn( i).tagvalid <= '0'; |
tagRAMIn( i).cacheValid <= '0'; |
tagRAMIn( i).tag <= ( others => '0'); |
tagRAMIn( i).cacheAddr <= ( others => '0'); |
writet <= '1'; |
writet <= '1'; |
else |
tagRAMIn( i) <= tagRAMOut( i); |
end if; |
304,10 → 304,10
when finish => |
if doneh = '1' then |
tagRAMIn <= tagBuff; |
writet <= '1'; |
AddressInt <= AddressInh( AddressInt'range); |
done <= '1'; |
statetag <= finished; |
writet <= '1'; |
AddressInt <= AddressInh( AddressInt'range); |
done <= '1'; |
statetag <= finished; |
end if; |
when finished => -- NEW |
writet <= '0'; |
356,6 → 356,8
doneh <= '0'; |
accinterrupt <= '0'; |
accqueue <= '0'; |
isfull <= '0'; |
flag <= '0'; |
initcount1 <= ( others => '0'); |
FreeIn <= ( others => '0'); |
firstf <= ( others => '0'); |
375,8 → 377,8
case stateram is |
when raminit => |
FreeIn <= std_ulogic_vector( initcount1); |
initcount1 <= initcount1 + 1; |
|
initcount1 <= initcount1 + 1; |
|
if unsigned( not FreeIn) = 0 then |
stateram <= ramstart; |
putf <= '0'; |
384,16 → 386,38
putf <= '1'; |
end if; |
when ramstart => |
if enableram = '1' then -- UPDATE |
tagBuff <= tagRAMOut; |
if found /= 15 then |
if enableram = '1' then -- UPDATE |
if isfull = '0' then |
tagBuff <= tagRAMOut; |
end if; |
if found /= 15 then |
cindex <= tagRAMOut( found).cacheAddr; |
isfull <= '0'; |
stateram <= ramupdate; |
elsif free /= 15 then |
elsif free /= 15 then |
en := '1'; |
stateram <= ramwait; |
if emptyf = '1' and isfull = '0' then |
isfull <= '1'; |
stateram <= ramwait; |
else |
cindex <= FreeOut; |
tagBuff( free).cacheAddr <= FreeOut; |
tagBuff( free).cacheValid <= '1'; |
tagBuff( free).tag <= AddressInh( tagBuff( free).tag'range); |
tagBuff( free).tagValid <= '1'; |
isfull <= '0'; |
getf <= '1'; |
if IOCodeh = "111" and ldCachedWords = 0 then |
stateram <= ramupdate2; |
else |
readb <= '1'; |
AddressOut <= AddressInh( AddressOut'range); |
stateram <= ramread; |
end if; |
end if; |
else |
cindex <= tagRAMOut( elim).cacheAddr; |
isfull <= '0'; |
stateram <= ramupdate; |
end if; |
end if; |
400,61 → 424,40
when ramupdate => |
stateram <= ramupdate1; |
when ramupdate1 => |
cacheIn <= cacheOut; |
cacheIn <= cacheOut; |
blockOut <= cacheOut.Words; |
RecBuff <= cacheOut; |
en := '1'; |
stateram <= ramwait; |
if found /= 15 then |
stateram <= ramupdate2; |
else |
AddressOut <= tagBuff( elim).tag & AddressInh( AddressInt'range) & ( ldCachedWords + 1 downto 0 => '0'); |
writeb <= '1'; |
flag <= '1'; |
stateram <= ramflush; |
end if; |
when ramwait => |
doneh <= '0'; |
|
if hi = '1' then |
stateram <= ramwait1; |
elsif acc = '1' then |
if found /= 15 then |
cindex <= tagBuff( found).cacheAddr; |
cacheIn <= RecBuff; |
blockOut <= RecBuff.Words; |
stateram <= ramupdate2; |
elsif free /= 15 then |
cindex <= FreeOut; |
tagBuff( free).cacheAddr <= FreeOut; |
tagBuff( free).cacheValid <= '1'; |
tagBuff( free).tag <= AddressInh( tagBuff( free).tag'range); |
tagBuff( free).tagValid <= '1'; |
getf <= '1'; |
if IOCodeh = "111" and ldCachedWords = 0 then |
stateram <= ramupdate2; |
else |
readb <= '1'; |
AddressOut <= AddressInh( AddressOut'range); |
stateram <= ramread; |
end if; |
else |
cindex <= tagBuff( elim).cacheAddr; |
cacheIn <= RecBuff; |
blockOut <= RecBuff.Words; |
AddressOut <= tagBuff( elim).tag & AddressInh( AddressInt'range) & ( ldCachedWords + 1 downto 0 => '0'); |
writeb <= '1'; |
stateram <= ramflush; |
end if; |
end if; |
stateram <= ramwait1; |
end if; |
when ramwait1 => |
writec <= '0'; |
|
if del /= 15 and enableram = '1' then |
if toflush = AddressInh( toflush'range) then -- inserted, tagline could match flushing tagline !!!! |
tagBuff( del).tagvalid <= '0'; |
tagBuff( del).tagvalid <= '0'; |
tagBuff( del).cacheValid <= '0'; |
tagBuff( del).tag <= ( others => '0'); |
tagBuff( del).cacheAddr <= ( others => '0'); |
end if; |
end if; |
cindex <= tagdummy( del).cacheAddr; |
FreeIn <= tagdummy( del).cacheAddr; |
putf <= tagdummy( del).cacheValid; |
FreeIn <= tagdummy( del).cacheAddr; |
putf <= tagdummy( del).cacheValid; |
stateram <= ramclean; |
end if; |
when ramread => |
readb <= '0'; |
getf <= '0'; |
getf <= '0'; |
stateram <= ramread1; |
when ramread1 => |
if readsh = '0' then |
468,30 → 471,30
if IOCodeh(1) = '1' then |
If IOCodeh(0) = '1' then |
cacheIn.Words( index).Word <= DataInh; |
cacheIn.Words( index).Modified <= "1111"; |
cacheIn.Words( index).Modified <= "1111"; |
elsif AddressInh(1) = '1' then |
cacheIn.Words( index).Word( 31 downto 16) <= DataInh( 15 downto 0); |
cacheIn.Words( index).Modified( 3 downto 2) <= "11"; |
cacheIn.Words( index).Modified( 3 downto 2) <= "11"; |
else |
cacheIn.Words( index).Word( 15 downto 0) <= DataInh( 15 downto 0); |
cacheIn.Words( index).Modified( 1 downto 0) <= "11"; |
cacheIn.Words( index).Modified( 1 downto 0) <= "11"; |
end if; |
else |
if AddressInh(1) = '0' then |
if AddressInh(0) = '0' then |
cacheIn.Words( index).Word( 7 downto 0) <= DataInh( 7 downto 0); |
cacheIn.Words( index).Modified(0) <= '1'; |
cacheIn.Words( index).Modified(0) <= '1'; |
else |
cacheIn.Words( index).Word( 15 downto 8) <= DataInh( 7 downto 0); |
cacheIn.Words( index).Modified(1) <= '1'; |
cacheIn.Words( index).Modified(1) <= '1'; |
end if; |
else |
if AddressInh(0) = '0' then |
cacheIn.Words( index).Word( 23 downto 16) <= DataInh( 7 downto 0); |
cacheIn.Words( index).Modified(2) <= '1'; |
cacheIn.Words( index).Modified(2) <= '1'; |
else |
cacheIn.Words( index).Word( 31 downto 24) <= DataInh( 7 downto 0); |
cacheIn.Words( index).Modified(3) <= '1'; |
cacheIn.Words( index).Modified(3) <= '1'; |
end if; |
end if; |
end if; |
504,16 → 507,20
|
getf <= '0'; |
writec <= '1'; |
doneh <= '1'; |
|
stateram <= ramupdate3; |
|
if hi = '1' then |
stateram <= ramwait1; |
elsif acc = '1' then |
doneh <= '1'; |
stateram <= ramupdate3; |
end if; |
when ramupdate3 => |
hi := '0'; |
acc := '0'; |
en := '0'; |
writec <= '0'; |
acc := '0'; |
en := '0'; |
writec <= '0'; |
doneh <= '0'; |
stateram <= ramstart; |
stateram <= ramstart; |
when ramclean => |
putf <= '0'; |
stateram <= ramclean1; |
520,8 → 527,8
when ramclean1 => |
if del /= 15 then |
blockOut <= cacheOut.words; |
writeb <= tagdummy( del).tagValid; |
AddressOut <= tagdummy( del).tag & toFlush & ( ldCachedWords + 1 downto 0 => '0'); |
writeb <= tagdummy( del).tagValid; |
AddressOut <= tagdummy( del).tag & toFlush & ( ldCachedWords + 1 downto 0 => '0'); |
stateram <= ramflush; |
end if; |
when ramflush => |
528,26 → 535,30
writeb <= '0'; |
for i in blockIn'range loop |
cacheIn.Words( i).Word <= ( others => '0'); |
cacheIn.Words( i).Modified <= ( others => '0'); |
cacheIn.Words( i).Modified <= ( others => '0'); |
end loop; |
|
stateram <= ramflush1; |
when ramflush1 => |
if writesh = '0' then |
if del /= 15 and hi = '1' then |
hi := '0'; |
stateram <= ramwait; |
else |
tagBuff( elim).tag <= AddressInh( tagBuff( elim).tag'range); |
tagBuff( elim).tagValid <= '1'; |
if IOCodeh = "111" and ldCachedWords = 0 then |
stateram <= ramupdate2; |
else |
readb <= '1'; |
AddressOut <= AddressInh( AddressOut'range); |
stateram <= ramread; |
end if; |
end if; |
if flag = '1' then |
tagBuff( elim).tag <= AddressInh( tagBuff( elim).tag'range); |
tagBuff( elim).tagValid <= '1'; |
flag <= '0'; |
if IOCodeh = "111" and ldCachedWords = 0 then |
stateram <= ramupdate2; |
else |
readb <= '1'; |
AddressOut <= AddressInh( AddressOut'range); |
stateram <= ramread; |
end if; |
elsif isfull = '1' then |
hi := '0'; |
stateram <= ramstart; |
elsif acc = '1' then |
doneh <= '1'; |
stateram <= ramupdate3; |
end if; |
end if; |
end case; |
|
638,12 → 649,12
removeAm <= '0'; -- NEW |
putA1 <= '0'; -- NEW |
putAm <= '0'; -- NEW |
serviced <= '0'; |
serviced <= '0'; |
else |
hi := interrupt; |
acc := accdone or doneh; |
acc := accdone or doneh; |
|
diff := firstA1 - unsigned( RecBuff.FiFoAddr); |
diff := firstA1 - unsigned( RecBuff.FiFoAddr); |
|
case statequeue is |
when queuestart => |
653,30 → 664,30
if found /= 15 then |
if RecBuff.Am = '1' or -- in Am |
( RecBuff.Am = '0' and diff( diff'high) = '0') then -- in lower half of A1 |
queuedone <= '1'; |
queuedone <= '1'; |
newFiFoAddr <= RecBuff.FiFoAddr; |
newAm <= RecBuff.Am; |
statequeue <= queuewait; |
statequeue <= queuewait; |
elsif fullAm = '1' then |
-- Am full |
if AmOut.valid = '1' then |
del <= to_integer( AmOut.way); |
toFlush <= AmOut.word; |
getAm <= '1'; |
toFlush <= AmOut.word; |
getAm <= '1'; |
hi := '1'; |
statequeue <= queuewait; |
end if; |
else |
AmIn.word <= AddressInh( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords); |
AmIn.way <= std_ulogic_vector(to_unsigned( found, ldways + 1)); |
AmIn.valid <= '1'; |
putAm <= '1'; |
A1Inaddr <= RecBuff.FiFoAddr; |
removeA1 <= '1'; |
statequeue <= queuewaitAm1; |
AmIn.way <= std_ulogic_vector(to_unsigned( found, ldways + 1)); |
AmIn.valid <= '1'; |
putAm <= '1'; |
A1Inaddr <= RecBuff.FiFoAddr; |
removeA1 <= '1'; |
statequeue <= queuewaitAm1; |
end if; |
elsif free /= 15 then |
if fullA1 = '1' or (emptyf = '1' and emptyA1 = '0' and serviced = '0') then |
if fullA1 = '1' or (isfull = '1' and emptyA1 = '0' and serviced = '0') then |
-- remove last entry from A1 |
if A1Out.valid = '1' then |
del <= to_integer( A1Out.way); |
683,10 → 694,10
toFlush <= A1Out.word; |
getA1 <= '1'; |
hi := '1'; |
serviced <= '1'; |
serviced <= '1'; |
statequeue <= queuewait; |
end if; |
elsif fullAm = '1' and emptyf = '1' and serviced = '0' then |
elsif emptyAm = '0' and isfull = '1' and serviced = '0' then |
-- remove last entry from Am |
if AmOut.valid = '1' then |
del <= to_integer( AmOut.way); |
693,7 → 704,7
toFlush <= AmOut.word; |
getAm <= '1'; |
hi := '1'; |
serviced <= '1'; |
serviced <= '1'; |
statequeue <= queuewait; |
end if; |
else |
701,7 → 712,7
A1In.way <= std_ulogic_vector(to_unsigned( free, ldways + 1)); |
A1In.valid <= '1'; |
putA1 <= '1'; |
serviced <= '0'; |
serviced <= '0'; |
statequeue <= queuewaitA11; |
end if; |
elsif elim /= 15 then |
717,72 → 728,72
getA1 <= '1'; |
end if; |
else |
if getA1 = '1' then |
preempted <= '1'; |
end if; |
getA1 <= '0'; -- NEW, inserted the only bug!!!!!!!!!!!!!! |
if getA1 = '1' then |
preempted <= '1'; |
end if; |
getA1 <= '0'; -- NEW, inserted the only bug!!!!!!!!!!!!!! |
A1In.word <= AddressInh( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords); |
A1In.way <= std_ulogic_vector(to_unsigned( elim, ldways + 1)); |
A1In.valid <= '1'; |
putA1 <= '1'; |
statequeue <= queueelim; |
A1In.way <= std_ulogic_vector(to_unsigned( elim, ldways + 1)); |
A1In.valid <= '1'; |
putA1 <= '1'; |
statequeue <= queueelim; |
end if; |
end if; |
end if; |
when queuewait => |
removeA1 <= '0'; |
removeAm <= '0'; |
removeA1 <= '0'; |
removeAm <= '0'; |
getAm <= '0'; |
getA1 <= '0'; |
queuedone <= '0'; |
queuedone <= '0'; |
|
if hi = '1' then |
hi := '0'; |
statequeue <= queuestart; |
elsif acc = '1' then |
acc := '0'; |
del <= 15; |
statequeue <= queuestart; |
end if; |
if hi = '1' then |
hi := '0'; |
statequeue <= queuestart; |
elsif acc = '1' then |
acc := '0'; |
del <= 15; |
statequeue <= queuestart; |
end if; |
when queuewaitAm1 => |
putAm <= '0'; |
removeA1 <= '0'; |
statequeue <= queuewaitAm2; |
removeA1 <= '0'; |
statequeue <= queuewaitAm2; |
when queuewaitAm2 => |
newFiFoAddr <= AmOutAddr; |
newAm <= '1'; |
queuedone <= '1'; |
statequeue <= queuewait; |
newFiFoAddr <= AmOutAddr; |
newAm <= '1'; |
queuedone <= '1'; |
statequeue <= queuewait; |
when queuewaitA11 => |
putA1 <= '0'; |
statequeue <= queuewaitA12; |
statequeue <= queuewaitA12; |
when queuewaitA12 => |
newFiFoAddr <= A1OutAddr; |
newAm <= '0'; |
removeA1 <= '0'; |
removeAm <= '0'; |
queuedone <= '1'; |
newFiFoAddr <= A1OutAddr; |
newAm <= '0'; |
removeA1 <= '0'; |
removeAm <= '0'; |
queuedone <= '1'; |
preempted <= '0'; |
statequeue <= queuewait; |
statequeue <= queuewait; |
when queueelim => |
putA1 <= '0'; |
getA1 <= '0'; |
getA1 <= '0'; |
|
if RecBuff.Am = '1' and preempted = '0' then |
AmInAddr <= RecBuff.FiFoAddr; |
removeAm <= '1'; |
elsif preempted = '0' then |
A1InAddr <= RecBuff.FiFoAddr; |
removeA1 <= '1'; |
end if; |
if RecBuff.Am = '1' and preempted = '0' then |
AmInAddr <= RecBuff.FiFoAddr; |
removeAm <= '1'; |
elsif preempted = '0' then |
A1InAddr <= RecBuff.FiFoAddr; |
removeA1 <= '1'; |
end if; |
|
if getA1 = '1' then |
hi := '1'; |
preempted <= '1'; |
statequeue <= queuewait; |
else |
statequeue <= queuewaitA12; |
end if; |
if getA1 = '1' then |
hi := '1'; |
preempted <= '1'; |
statequeue <= queuewait; |
else |
statequeue <= queuewaitA12; |
end if; |
end case; |
|
interrupt <= hi; |
/readme.txt
1,72 → 5,72
It is Your job to optimize the cache! Process 'dataram' is optimizable. |
Clocks required |
hit : 3 + 4 + overhead |
load : 3 + 4 + read + overhead |
replace : 3 + 8 + write + read + overhead |
overhead from queues (optional) : 5 + write |