//Generates a 24 bit physical address and 12 bit page offset from a block value public static Tuple<uint, ushort> generatePhysicalAddr36Pair(Block block, int tagWidth, int SetIdxWidth) { uint block_offs_tmp = block.block_offset; uint set_tmp = ((uint)block.set << 6); uint block_mask = (uint)((1 << (tagWidth)) - 1); ulong block_tag_tmp = (ulong)((ulong)(block.tag & block_mask) << (6 + SetIdxWidth)); ulong retVal36 = block_tag_tmp | set_tmp | block_offs_tmp; uint retVal24 = (uint)(retVal36 >> 12) & 0x0FFFFFF; ushort retVal12 = (ushort)(retVal36 & 0x0FFF); return new Tuple<uint,ushort>(retVal24, retVal12); }
/* public ulong getEntry(int entry) { return entries[entry]; } public void setEntry(int entry, ulong value) { entries[entry] = value; }*/ public Block search(uint PhysicalAddr24, ushort PageOffset) { Random random = new Random(); int rVL3CacheMiss = random.Next(2); int rMainMemoryMiss; ulong PhysicalAddr36 = CacheFieldParser.generatePhysAddr36(PhysicalAddr24, PageOffset); uint tag = CacheFieldParser.getTagFromPhysAddr(PhysicalAddr36, TAG_WIDTH); ushort set = CacheFieldParser.getSetIdxFromPhysAddr(PhysicalAddr36, SET_IDX_WIDTH); byte Block_Offset = CacheFieldParser.getBlockOffsetFromPhysAddr(PhysicalAddr36); Block retblock = new Block(0, set, Block_Offset, tag); StatisticsGatherer.RecordL3CacheAccesses(); if (entries.Contains(retblock)) { //hit StatisticsGatherer.RecordL3CacheHits(); return retblock; } if (rVL3CacheMiss == 1) { StatisticsGatherer.RecordL3CacheMissess(); //Record V3 Cache Miss rMainMemoryMiss = random.Next(2); if(rMainMemoryMiss == 1) { //Disk Access StatisticsGatherer.RecordDiskAccess(); } else { //Main Memory Hit StatisticsGatherer.RecordMemoryAccess(); } } else { //Record V3 Hit entries.Add(retblock); StatisticsGatherer.RecordL3CacheHits(); } return retblock; }
public void translateCacheBlockTest() { //Cache L1 = new Cache(Constants.CACHE_TYPE.dL1Cache); //Cache L2 = new Cache(Constants.CACHE_TYPE.L2Cache); Cache L1 = new Cache(Constants.CACHE_TYPE.L2Cache); VL3Cache L2 = new VL3Cache(); Random rand = new Random(1); const int NUM_BLOCKS = 512; //iterator vars ulong phys36; Block L1_Block; Block L2_Block; Block Result_Block; uint L1_Tag; uint L2_Tag; ushort L1_Set; ushort L2_Set; byte L1_Offs; byte L2_Offs; for (int i = 0; i < NUM_BLOCKS; i++) { phys36 = (ulong)rand.Next(int.MaxValue); L1_Tag = CacheFieldParser.getTagFromPhysAddr(phys36, L1.TAG_WIDTH); L1_Set = CacheFieldParser.getSetIdxFromPhysAddr(phys36, L1.SET_IDX_WIDTH); L1_Offs = CacheFieldParser.getBlockOffsetFromPhysAddr(phys36); L2_Tag = CacheFieldParser.getTagFromPhysAddr(phys36, L2.TAG_WIDTH); L2_Set = CacheFieldParser.getSetIdxFromPhysAddr(phys36, L2.SET_IDX_WIDTH); L2_Offs = CacheFieldParser.getBlockOffsetFromPhysAddr(phys36); L1_Block = new Block(0, L1_Set, L1_Offs, L1_Tag); L2_Block = new Block(0, L2_Set, L2_Offs, L2_Tag); Result_Block = CacheFieldParser.translateCacheBlock(L2_Block, L2, L1); Assert.AreEqual(L1_Block.block_offset, Result_Block.block_offset); Assert.AreEqual(L1_Block.set, Result_Block.set); Assert.AreEqual(L1_Block.tag, Result_Block.tag); } }
//Sets number of bytes in array (A Write, not a block replacement) public void WriteBlock(Block BankSetBlockTag) { int bank = BankSetBlockTag.bank; ushort set = BankSetBlockTag.set; uint Tag = BankSetBlockTag.tag; LRU.toFront(bank, set); //Set Dirty Bit meta[bank][set] = CacheFieldParser.generateMetaEntry(true, true, Tag, TAG_WIDTH); }
public static Block translateCacheBlock(Block inBlock, VL3Cache Source, Cache Target) { int SourceTagWidth = Source.TAG_WIDTH; int SourceSetIdxWidth = Source.SET_IDX_WIDTH; int TargetTagWidth = Target.TAG_WIDTH; int TargetSetIdxWidth = Target.SET_IDX_WIDTH; Tuple<uint, ushort> Phys36_Pair = generatePhysicalAddr36Pair(inBlock, SourceTagWidth, SourceSetIdxWidth); ulong Phys36 = generatePhysAddr36(Phys36_Pair.Item1, Phys36_Pair.Item2); ushort SetIdx = getSetIdxFromPhysAddr(Phys36, TargetSetIdxWidth); byte BlockOffset = getBlockOffsetFromPhysAddr(Phys36); uint Tag = getTagFromPhysAddr(Phys36, TargetTagWidth); Block retBlock = new Block(0, SetIdx, BlockOffset, Tag); return retBlock; }
//Replaces the LRU block in the set with the block given. //Returns evicted block if dirty public Block ReplaceBlock(Block BankSetBlockTag) { int bank = BankSetBlockTag.bank; //Bank in cache above ushort set = BankSetBlockTag.set; uint tag = BankSetBlockTag.tag; Block Evicted = null; int Evicted_Bank = LRU.Get_LRU(set); uint Evicted_Tag; if (CacheFieldParser.getDirtyBitFromEntry(meta[Evicted_Bank][set],TAG_WIDTH) && CacheFieldParser.getValidBitFromEntry(meta[Evicted_Bank][set], TAG_WIDTH)) { Evicted_Tag = CacheFieldParser.getTagFromEntry(meta[Evicted_Bank][set],TAG_WIDTH); //LRU Evicted = new Block(Evicted_Bank, set, 0, Evicted_Tag); } //Replace old meta data with old bit to zero for this block meta[Evicted_Bank][set] = CacheFieldParser.generateMetaEntry(true, false, tag, TAG_WIDTH); LRU.toFront(Evicted_Bank, set); //Put block at back of Queue return Evicted; }
/// <summary> /// Updates block content from lower level block (doesn't actually, because we do not track data, but it would! Instead moves to MRU. /// Must find block with tag anb set first, since data comes from another cache /// </summary> public void UpdateBlock(Block BankSetBlockTag) { ushort set = BankSetBlockTag.set; uint tag = BankSetBlockTag.tag; uint Meta_Curr; bool Meta_Valid; uint Meta_Tag; //Find it in this cache for (int b = 0; b < BANKS; b++) //Bank Iterator { Meta_Curr = meta[b][set]; //Search Metadata at set index Meta_Tag = CacheFieldParser.getTagFromEntry(Meta_Curr, TAG_WIDTH); if (Meta_Tag == tag) { Meta_Valid = CacheFieldParser.getValidBitFromEntry(Meta_Curr, TAG_WIDTH); if (Meta_Valid) { LRU.toFront(b,set); return; } } } //If it gets to this point the cache block being updated is not in this cache, which should not happen. This function can only be used on the superset cache of a dirty cache block throw new Exception("UpdateBlock Function: block not found - This function can only be used on the superset cache of a dirty cache block"); }
//Read numBytes bytes public void ReadBlock(Block BankSetBlockTag) { int bank = BankSetBlockTag.bank; ushort set = BankSetBlockTag.set; LRU.toFront(bank, set); }
//Takes an L2 Block thats going into L2 from L3. Ensures no block leaving L2 is in either L1 Cache private void Enforce_L2_Superset(Block inBlock) { Block LRU_Block; Tuple<uint, ushort> Phys36Pair; Block iL1Block; Block dL1Block; bool done = false; while (!done) { LRU_Block = L2Cache.getLRU(inBlock.set); Phys36Pair = CacheFieldParser.generatePhysicalAddr36Pair(LRU_Block, L2Cache.TAG_WIDTH, L2Cache.SET_IDX_WIDTH); iL1Block = iL1Cache.search(Phys36Pair.Item1, Phys36Pair.Item2); dL1Block = dL1Cache.search(Phys36Pair.Item1, Phys36Pair.Item2); if (dL1Block != null | iL1Block != null) { L2Cache.ReadBlock(LRU_Block); } else { done = true; } } }
public void ReplaceBlockTest() { Cache L1 = new Cache(Constants.CACHE_TYPE.iL1Cache); int ENTRIES = L1.SETS * L1.BANKS * 2; Block retBlock = null; Block[] blocks = new Block[ENTRIES]; Block inBlock; ushort cmpr_set; uint cmpr_tag; ushort ret_set; uint ret_tag; Tuple<uint, ushort>[] Phys36 = new Tuple<uint, ushort>[ENTRIES]; Tuple<uint, ushort> inPhys; for (int i = 0; i < ENTRIES; i++) { blocks[i] = new Block(i%L1.BANKS, (ushort)(i%L1.SETS), 0, (uint)(i)); Phys36[i] = CacheFieldParser.generatePhysicalAddr36Pair(blocks[i], L1.TAG_WIDTH, L1.SET_IDX_WIDTH); } for (int i = 0; i < ENTRIES; i++) { inBlock = blocks[i]; inPhys = Phys36[i]; retBlock = L1.ReplaceBlock(inBlock); Assert.AreEqual(null, retBlock); retBlock = L1.search(inPhys.Item1, inPhys.Item2); ret_tag = retBlock.tag; ret_set = retBlock.set; cmpr_tag = inBlock.tag; cmpr_set = inBlock.set; Assert.AreEqual(cmpr_tag, ret_tag); Assert.AreEqual(cmpr_set, ret_set); } }
public void WriteBlockTest() { { Cache L1 = new Cache(Constants.CACHE_TYPE.iL1Cache); int ENTRIES = L1.SETS * L1.BANKS * 2; Block retBlock = null; Block[] blocks = new Block[ENTRIES]; Block inBlock; Block repBlock; ushort cmpr_set; uint cmpr_tag; ushort ret_set; uint ret_tag; Tuple<uint, ushort>[] Phys36 = new Tuple<uint, ushort>[ENTRIES]; Tuple<uint, ushort> inPhys; //Generate blocks and associated physical addresses for (int i = 0; i < ENTRIES; i++) { blocks[i] = new Block(i % L1.BANKS, (ushort)(i % L1.SETS), 0, (uint)(i)); Phys36[i] = CacheFieldParser.generatePhysicalAddr36Pair(blocks[i], L1.TAG_WIDTH, L1.SET_IDX_WIDTH); } //Fill cache for (int i = 0; i < ENTRIES / 2; i++) { inBlock = blocks[i]; retBlock = L1.ReplaceBlock(inBlock); Assert.AreEqual(null, retBlock); } //Write whole cache (to set dirty flag) for (int i = 0; i < ENTRIES / 2; i++) { inPhys = Phys36[i]; retBlock = L1.search(inPhys.Item1, inPhys.Item2); L1.WriteBlock(retBlock); } //Replace full cache and check if first iteration is found for (int i = 0; i < ENTRIES/2; i++) { repBlock = blocks[i+ENTRIES/2]; //2nd Gen blocks inBlock = blocks[i]; //1st gen blocks retBlock = L1.ReplaceBlock(repBlock); ret_tag = retBlock.tag; ret_set = retBlock.set; cmpr_tag = inBlock.tag; cmpr_set = inBlock.set; Assert.AreEqual(cmpr_tag, ret_tag); Assert.AreEqual(cmpr_set, ret_set); } } }
public void ReadBlockTest() { Cache L1 = new Cache(Constants.CACHE_TYPE.iL1Cache); uint test = StatisticsGatherer.iL1CacheAccesses; int ENTRIES = L1.SETS * L1.BANKS * 2; Block retBlock = null; Block[] blocks = new Block[ENTRIES]; Block inBlock; ushort cmpr_set; uint cmpr_tag; ushort ret_set; uint ret_tag; Tuple<uint, ushort>[] Phys36 = new Tuple<uint, ushort>[ENTRIES]; Tuple<uint, ushort> inPhys; //Generate blocks and associated physical addresses for (int i = 0; i < ENTRIES; i++) { blocks[i] = new Block(i % L1.BANKS, (ushort)(i % L1.SETS), 0, (uint)(i)); Phys36[i] = CacheFieldParser.generatePhysicalAddr36Pair(blocks[i], L1.TAG_WIDTH, L1.SET_IDX_WIDTH); } //Fill cache for (int i = 0; i < ENTRIES / 2; i++) { inBlock = blocks[i]; retBlock = L1.ReplaceBlock(inBlock); Assert.AreEqual(null, retBlock); } //Read First half for (int i = 0; i < ENTRIES / 4; i++) { inPhys = Phys36[i]; retBlock = L1.search(inPhys.Item1, inPhys.Item2); L1.ReadBlock(retBlock); } for (int i = ENTRIES / 2; i < (ENTRIES * 3 / 4); i++) { inBlock = blocks[i]; retBlock = L1.ReplaceBlock(inBlock); Assert.AreEqual(null, retBlock); } for(int i = 0; i < ENTRIES / 4; i++) { inBlock = blocks[i]; inPhys = Phys36[i]; retBlock = L1.search(inPhys.Item1, inPhys.Item2); ret_tag = retBlock.tag; ret_set = retBlock.set; cmpr_tag = inBlock.tag; cmpr_set = inBlock.set; Assert.AreEqual(cmpr_tag, ret_tag); Assert.AreEqual(cmpr_set, ret_set); } }