URL
https://opencores.org/ocsvn/mytwoqcache/mytwoqcache/trunk
Subversion Repositories mytwoqcache
Compare Revisions
- This comparison shows the changes necessary to convert path
/mytwoqcache
- from Rev 10 to Rev 11
- ↔ Reverse comparison
Rev 10 → Rev 11
/trunk/2QCache.vhd
1,41 → 1,41
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 07:41:47 12/14/2010 |
-- Design Name: |
-- Module Name: Cache - Rtl |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE, work; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_arith.all; |
use work.global.all; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity Cache is |
generic( constant blocksizeld: integer := 11; |
constant ldways: integer := 1; |
constant ldCachedWords: integer := 2); |
port( nReset: in std_ulogic; -- System reset active low |
Clock: in std_ulogic; -- System Clock |
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 07:41:47 12/14/2010 |
-- Design Name: |
-- Module Name: Cache - Rtl |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE, work; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_arith.all; |
use work.global.all; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity Cache is |
generic( constant blocksizeld: integer := 11; |
constant ldways: integer := 1; |
constant ldCachedWords: integer := 2); |
port( nReset: in std_ulogic; -- System reset active low |
Clock: in std_ulogic; -- System Clock |
AddressIn: in std_ulogic_vector(RAMrange'high + 1 downto 0); -- Address of memory fetch |
DataIn: in std_ulogic_vector( 31 downto 0); -- Data to write |
IOCode: in std_ulogic_vector(2 downto 0); -- operation |
DataIn: in std_ulogic_vector( 31 downto 0); -- Data to write |
IOCode: in std_ulogic_vector(2 downto 0); -- operation |
-- Bit |
-- 2 0 read |
-- 1 write |
42,47 → 42,47
-- 1 0 11 word |
-- 10 halfword |
-- 01 single byte |
-- 00 no operation |
DataOut: out std_ulogic_vector( 31 downto 0); -- Data read |
-- 00 no operation |
DataOut: out std_ulogic_vector( 31 downto 0); -- Data read |
done: out std_ulogic; |
-- memory interface |
AddressOut: out std_ulogic_vector(RAMrange'high downto 0); -- memory address |
DataBlockIn: in std_ulogic_vector( 2 ** ldCachedWords * 32 - 1 downto 0); -- data from memory |
reads: out std_ulogic; -- read memory |
DataBlockOut: out std_ulogic_vector( 2 ** ldCachedWords * 32 - 1 downto 0); -- data to memory |
Mask: out std_ulogic_vector( 2 ** ldCachedWords * 4 - 1 downto 0); -- enables for each byte active low |
-- memory interface |
AddressOut: out std_ulogic_vector(RAMrange'high downto 0); -- memory address |
DataBlockIn: in std_ulogic_vector( 2 ** ldCachedWords * 32 - 1 downto 0); -- data from memory |
reads: out std_ulogic; -- read memory |
DataBlockOut: out std_ulogic_vector( 2 ** ldCachedWords * 32 - 1 downto 0); -- data to memory |
Mask: out std_ulogic_vector( 2 ** ldCachedWords * 4 - 1 downto 0); -- enables for each byte active low |
writes: out std_ulogic; -- write memory |
ack: in std_ulogic -- acknowledge from memory |
); |
end Cache; |
|
ack: in std_ulogic -- acknowledge from memory |
); |
end Cache; |
|
architecture Rtl of Cache is |
constant ways: integer := 2 ** ldways; |
constant ldram: integer := blocksizeld + ldways - 1; |
constant ldqueuelength: integer := ldram; |
|
type IOType is ( Start, busy); |
type tType is ( inittag, startt, startt1, tagtest, tagwait, stateget, stateget1, finish, finished); |
type IOType is ( Start, busy); |
type tType is ( inittag, startt, startt1, tagtest, tagwait, stateget, stateget1, finish, finished); |
type rType is ( raminit, ramstart, ramstart1, ramcheck, ramcheck1, ramcheck2, ramread, ramread1, ramupdate, |
ramupdate1, ramupdate2, ramupdate3, ramflush, ramflush1, ramwait, ramwait1, ramclean, ramclean1); |
type fType is ( queuestart, queuewait, queuewaitAm1, queuewaitAm2, queuewaitA11, queuewaitA12, queueelim); |
subtype myint is natural range 15 downto 0; |
type TagRAMType is record |
cacheAddr: std_ulogic_vector( ldram - 1 downto 0); |
cacheValid: std_ulogic; |
Tag: std_ulogic_vector( RAMrange'high downto 2 + ldCachedWords + blocksizeld); |
TagValid: std_ulogic; |
ramupdate1, ramupdate2, ramupdate3, ramflush, ramflush1, ramwait, ramwait1, ramclean, ramclean1); |
type fType is ( queuestart, queuewait, queuewaitAm1, queuewaitAm2, queuewaitA11, queuewaitA12, queueelim); |
subtype myint is natural range 15 downto 0; |
type TagRAMType is record |
cacheAddr: std_ulogic_vector( ldram - 1 downto 0); |
cacheValid: std_ulogic; |
Tag: std_ulogic_vector( RAMrange'high downto 2 + ldCachedWords + blocksizeld); |
TagValid: std_ulogic; |
end record; |
type WordType is record |
Word: std_ulogic_vector(31 downto 0); |
Word: std_ulogic_vector(31 downto 0); |
Modified: std_ulogic_vector( 3 downto 0); |
end record; |
type WordArray is array ( 2 ** ldCachedWords - 1 downto 0) of WordType; |
type CacheType is record |
type WordArray is array ( 2 ** ldCachedWords - 1 downto 0) of WordType; |
type CacheType is record |
Words: WordArray; |
FiFoaddr: std_ulogic_vector( ldqueuelength - 1 downto 0); |
Am: std_ulogic; -- redifined and renamed |
end record; |
Am: std_ulogic; -- redifined and renamed |
end record; |
type FiFoType is record |
Word: std_ulogic_vector( blocksizeld - 1 downto 0); |
way: std_ulogic_vector( ldways downto 0); |
97,7 → 97,7
type RAMFile is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( 35 downto 0); |
type RAMFiles is array ( 2 ** ldCachedWords - 1 downto 0) of RAMFile; |
type RAMBuffer is array ( 2 ** ldCachedWords - 1 downto 0) of std_ulogic_vector( 35 downto 0); |
type AFile is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( ldqueuelength downto 0); -- redimensioned |
type AFile is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( ldqueuelength downto 0); -- redimensioned |
|
type myarrayf is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( ldram - 1 downto 0); |
type myarrayA is array ( 2 ** ldram - 1 downto 0) of std_ulogic_vector( blocksizeld + ldways + 1 downto 0); |
104,7 → 104,7
|
signal RAMs: RAMFiles; |
signal Ax: AFile; |
signal tagRAM: TagFiles; |
signal tagRAM: TagFiles; |
signal tagdummy, tagBuff, TagRAMIn, TagRAMOut: TagRAMarray; |
signal RecBuff, CacheIn, CacheOut: CacheType; |
signal blockIn, blockOut: WordArray; |
114,36 → 114,36
signal putAm, removeAm, getAm, emptyAm, fullAm: std_ulogic; |
signal A1Inaddr, A1Outaddr, AmInaddr, AmOutaddr: std_ulogic_vector( ldqueuelength - 1 downto 0); |
signal emptyf, getf, putf: std_ulogic; |
signal cindex, FreeOut, FreeIn: std_ulogic_vector( ldram - 1 downto 0); |
signal ramf: myarrayf; |
signal counterf: unsigned( ldram downto 0); |
signal cindex, FreeOut, FreeIn: std_ulogic_vector( ldram - 1 downto 0); |
signal ramf: myarrayf; |
signal counterf: unsigned( ldram downto 0); |
signal firstf, lastf: unsigned( ldram - 1 downto 0); |
signal newFiFoAddr: std_ulogic_vector( ldqueuelength - 1 downto 0); |
signal newAm: std_ulogic; -- redifined and renamed |
signal newAm: std_ulogic; -- redifined and renamed |
signal initcount: unsigned( blocksizeld - 1 downto 0); |
signal initcount1: unsigned( ldram - 1 downto 0); |
signal ramA1: myarrayA; |
signal counterA1: unsigned( ldqueuelength downto 0); |
signal firstA1, lastA1: unsigned( ldqueuelength - 1 downto 0); |
signal ramAm: myarrayA; |
signal counterAm: unsigned( ldqueuelength downto 0); |
signal firstAm, lastAm: unsigned( ldqueuelength - 1 downto 0); |
signal ramA1: myarrayA; |
signal counterA1: unsigned( ldqueuelength downto 0); |
signal firstA1, lastA1: unsigned( ldqueuelength - 1 downto 0); |
signal ramAm: myarrayA; |
signal counterAm: unsigned( ldqueuelength downto 0); |
signal firstAm, lastAm: unsigned( ldqueuelength - 1 downto 0); |
|
signal AddressInh: std_ulogic_vector( AddressIn'high -1 downto 0); |
signal IOCodeh: std_ulogic_vector( IOCode'range); |
signal toFlush, AddressInt: std_ulogic_vector( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords); |
signal found, free, elim, del: myint; |
signal IOCodeh: std_ulogic_vector( IOCode'range); |
signal toFlush, AddressInt: std_ulogic_vector( 2 + ldCachedWords + blocksizeld - 1 downto 2 + ldCachedWords); |
signal found, free, elim, del: myint; |
signal stateIO: IOType; |
signal statetag: tType; |
signal stateram: rType; |
signal statequeue: fType; |
signal enableram, enablequeue, queuedone, readsh, writesh, doneh, preempted, |
interrupt, readb, writeb, writec, writet, accdone, accqueue, accinterrupt: std_ulogic; |
|
begin |
|
|
interrupt, readb, writeb, writec, writet, accdone, accqueue, accinterrupt: std_ulogic; |
|
begin |
|
|
|
blockIO: process( nReset, Clock, readb, writeb) is |
variable s: std_ulogic; |
begin |
197,7 → 197,7
|
tagrams: process ( nReset, Clock) is |
variable a, b, d: myint; |
variable DataInTag, DataOutTag: TagBuffer; |
variable DataInTag, DataOutTag: TagBuffer; |
begin |
if rising_edge(Clock) then |
if nReset /= '1' then |
233,7 → 233,7
if IOCode( 1 downto 0) /= "00" and AddressIn( AddressIn'high) = '0' then |
-- request encountered |
AddressInh <= AddressIn(AddressInh'range); |
IOCodeh <= IOCode; |
IOCodeh <= IOCode; |
AddressInt <= AddressIn( AddressInt'range); |
DataInh <= DataIn; |
statetag <= startt1; |
241,22 → 241,22
when startt1 => |
statetag <= tagtest; |
when tagtest => |
a := 15; |
a := 15; |
b := 15; |
|
for i in 0 to TagRAMarray'high loop |
if tagRAMOut( i).tagValid = '1' then |
if AddressInh(tagRAMout( i).tag'range) = tagRAMout( i).tag then |
|
for i in 0 to TagRAMarray'high loop |
if tagRAMOut( i).tagValid = '1' then |
if AddressInh(tagRAMout( i).tag'range) = tagRAMout( i).tag then |
a := i; -- present |
end if; |
else |
b := i; -- free entry |
end if; |
end loop; |
|
found <= a; |
free <= b; |
end if; |
else |
b := i; -- free entry |
end if; |
end loop; |
|
found <= a; |
free <= b; |
|
if stateram = ramstart then |
enableram <= '1'; |
statetag <= tagwait; |
329,10 → 329,10
variable a, b: RAMBuffer; |
variable index, index1: integer; |
|
variable address: std_ulogic_vector( ldram - 1 downto 0); |
variable uaddress: unsigned( ldram - 1 downto 0); |
variable address: std_ulogic_vector( ldram - 1 downto 0); |
variable uaddress: unsigned( ldram - 1 downto 0); |
variable datum: std_ulogic_vector( FreeIn'range); |
variable w: std_ulogic; |
variable w: std_ulogic; |
begin |
if rising_edge(Clock) then |
if nReset /= '1' then |
349,9 → 349,9
accqueue <= '0'; |
initcount1 <= ( others => '0'); |
FreeIn <= ( others => '0'); |
firstf <= ( others => '0'); |
lastf <= ( others => '0'); |
counterf <= ( others => '0'); |
firstf <= ( others => '0'); |
lastf <= ( others => '0'); |
counterf <= ( others => '0'); |
else |
hi := accinterrupt or interrupt; |
acc := accqueue or queuedone; |
379,7 → 379,7
tagBuff <= tagRAMOut; |
elim <= 15; |
stateram <= ramstart1; |
end if; |
end if; |
when ramstart1 => |
if enableram = '1' then |
if found /= 15 then |
451,7 → 451,7
end if; |
when ramwait1 => |
if del /= 15 and enableram = '1' then |
if toflush = AddressInh( toflush'range) then -- inserted, tagline could match flushing tagline !!!! |
if toflush = AddressInh( toflush'range) then -- inserted, tagline could match flushing tagline !!!! |
tagBuff( del).tagvalid <= '0'; |
tagBuff( del).cacheValid <= '0'; |
tagBuff( del).tag <= ( others => '0'); |
587,28 → 587,28
end if; |
end loop; |
|
if putf = '1' then |
address := std_ulogic_vector( firstf); |
datum := FreeIn; |
firstf <= firstf + 1; |
counterf <= counterf + 1; |
if putf = '1' then |
address := std_ulogic_vector( firstf); |
datum := FreeIn; |
firstf <= firstf + 1; |
counterf <= counterf + 1; |
w := '1'; |
else |
uaddress := lastf; |
if getf = '1' and counterf /= 0 then |
uaddress := lastf; |
if getf = '1' and counterf /= 0 then |
counterf <= counterf - 1; |
uaddress := uaddress + 1; |
uaddress := uaddress + 1; |
end if; |
lastf <= uaddress; |
lastf <= uaddress; |
address := std_ulogic_vector( uaddress); |
w := '0'; |
end if; |
w := '0'; |
end if; |
|
if w = '1' then |
ramf( to_integer( address)) <= datum; |
ramf( to_integer( address)) <= datum; |
else |
FreeOut <= ramf( to_integer( address)); |
end if; |
FreeOut <= ramf( to_integer( address)); |
end if; |
|
end if; |
end if; |
619,14 → 619,14
queues: process( nReset, Clock, enablequeue) is |
variable acc, hi: std_ulogic; |
variable A1OutBuff, AmOutBuff: std_ulogic_vector( blocksizeld + ldways + 1 downto 0); |
variable addressA1: std_ulogic_vector( ldqueuelength - 1 downto 0); |
variable diff, uaddressA1: unsigned( ldqueuelength - 1 downto 0); |
variable addressA1: std_ulogic_vector( ldqueuelength - 1 downto 0); |
variable diff, uaddressA1: unsigned( ldqueuelength - 1 downto 0); |
variable datumA1: std_ulogic_vector( A1OutBuff'range); |
variable wA1: std_ulogic; |
variable addressAm: std_ulogic_vector( ldqueuelength - 1 downto 0); |
variable uaddressAm: unsigned( ldqueuelength - 1 downto 0); |
variable wA1: std_ulogic; |
variable addressAm: std_ulogic_vector( ldqueuelength - 1 downto 0); |
variable uaddressAm: unsigned( ldqueuelength - 1 downto 0); |
variable datumAm: std_ulogic_vector( AmOutBuff'range); |
variable wAm: std_ulogic; |
variable wAm: std_ulogic; |
begin |
if rising_edge(Clock) then |
if nReset /= '1' then |
636,13 → 636,13
interrupt <= '0'; |
accdone <= '0'; |
preempted <= '0'; |
firstA1 <= ( others => '0'); |
A1Outaddr <= ( others => '0'); |
lastA1 <= ( others => '0'); |
firstA1 <= ( others => '0'); |
A1Outaddr <= ( others => '0'); |
lastA1 <= ( others => '0'); |
counterA1 <= ( others => '0'); |
firstAm <= ( others => '0'); |
AmOutaddr <= ( others => '0'); |
lastAm <= ( others => '0'); |
firstAm <= ( others => '0'); |
AmOutaddr <= ( others => '0'); |
lastAm <= ( others => '0'); |
counterAm <= ( others => '0'); |
getA1 <= '0'; -- NEW |
getAm <= '0'; -- NEW |
649,7 → 649,7
removeA1 <= '0'; -- NEW |
removeAm <= '0'; -- NEW |
putA1 <= '0'; -- NEW |
putAm <= '0'; -- NEW |
putAm <= '0'; -- NEW |
else |
hi := '0'; |
acc := accdone or doneh; |
725,6 → 725,7
getA1 <= '1'; |
end if; |
else |
preempted <= getA1; |
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)); |
790,80 → 791,80
interrupt <= hi; |
accdone <= acc; |
|
if putA1 = '1' or removeA1 = '1' then |
if removeA1 = '0' then |
addressA1 := std_ulogic_vector( firstA1); |
if putA1 = '1' or removeA1 = '1' then |
if removeA1 = '0' then |
addressA1 := std_ulogic_vector( firstA1); |
datumA1 := A1In.valid & A1In.way & A1In.Word; |
firstA1 <= firstA1 + 1; |
counterA1 <= counterA1 + 1; |
A1Outaddr <= std_ulogic_vector( firstA1); |
else |
addressA1 := A1Inaddr( addressA1'range); |
datumA1 := ( others => '0'); |
firstA1 <= firstA1 + 1; |
counterA1 <= counterA1 + 1; |
A1Outaddr <= std_ulogic_vector( firstA1); |
else |
addressA1 := A1Inaddr( addressA1'range); |
datumA1 := ( others => '0'); |
end if; |
wA1 := '1'; |
else |
uaddressA1 := lastA1; |
if (getA1 = '1' or A1Out.valid = '0') and counterA1 /= 0 then |
counterA1 <= counterA1 - 1; |
uaddressA1 := uaddressA1 + 1; |
wA1 := '1'; |
else |
uaddressA1 := lastA1; |
if (getA1 = '1' or A1Out.valid = '0') and counterA1 /= 0 then |
counterA1 <= counterA1 - 1; |
uaddressA1 := uaddressA1 + 1; |
end if; |
lastA1 <= uaddressA1; |
addressA1 := std_ulogic_vector( uaddressA1); |
wA1 := '0'; |
wA1 := '0'; |
end if; |
|
if wA1 = '1' then |
ramA1( to_integer( addressA1)) <= datumA1; |
ramA1( to_integer( addressA1)) <= datumA1; |
else |
A1OutBuff := ramA1( to_integer( addressA1)); |
A1OutBuff := ramA1( to_integer( addressA1)); |
|
A1Out.Word <= A1OutBuff( blocksizeld - 1 downto 0); |
A1Out.way <= A1OutBuff( blocksizeld + ldways downto blocksizeld); |
A1Out.valid <= A1OutBuff( blocksizeld + ldways + 1); |
end if; |
end if; |
|
if putAm = '1' or removeAm = '1' then |
if removeAm = '0' then |
addressAm := std_ulogic_vector( firstAm); |
if putAm = '1' or removeAm = '1' then |
if removeAm = '0' then |
addressAm := std_ulogic_vector( firstAm); |
datumAm := AmIn.valid & AmIn.way & AmIn.Word; |
firstAm <= firstAm + 1; |
counterAm <= counterAm + 1; |
AmOutaddr <= std_ulogic_vector( firstAm); |
else |
addressAm := AmInaddr( addressAm'range); |
datumAm := ( others => '0'); |
firstAm <= firstAm + 1; |
counterAm <= counterAm + 1; |
AmOutaddr <= std_ulogic_vector( firstAm); |
else |
addressAm := AmInaddr( addressAm'range); |
datumAm := ( others => '0'); |
end if; |
wAm := '1'; |
else |
uaddressAm := lastAm; |
if (getAm = '1' or AmOut.valid = '0') and counterAm /= 0 then |
counterAm <= counterAm - 1; |
uaddressAm := uaddressAm + 1; |
wAm := '1'; |
else |
uaddressAm := lastAm; |
if (getAm = '1' or AmOut.valid = '0') and counterAm /= 0 then |
counterAm <= counterAm - 1; |
uaddressAm := uaddressAm + 1; |
end if; |
lastAm <= uaddressAm; |
addressAm := std_ulogic_vector( uaddressAm); |
wAm := '0'; |
wAm := '0'; |
end if; |
|
|
if wAm = '1' then |
ramAm( to_integer( addressAm)) <= datumAm; |
ramAm( to_integer( addressAm)) <= datumAm; |
else |
AmOutBuff := ramAm( to_integer( addressAm)); |
|
|
AmOut.Word <= AmOutBuff( blocksizeld - 1 downto 0); |
AmOut.way <= AmOutBuff( blocksizeld + ldways downto blocksizeld); |
AmOut.valid <= AmOutBuff( blocksizeld + ldways + 1); |
end if; |
end if; |
end if; |
end if; |
end process queues; |
|
fullA1 <= counterA1( counterA1'high); |
emptyA1 <= '1' when counterA1 = 0 else '0'; |
emptyA1 <= '1' when counterA1 = 0 else '0'; |
|
fullAm <= counterAm( counterAm'high); |
emptyAm <= '1' when counterAm = 0 else '0'; |
emptyAm <= '1' when counterAm = 0 else '0'; |
|
end Rtl; |
|
end Rtl; |
|