Example #1
0
        //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);
        }
Example #2
0
        /*
        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);

            }
        }
Example #4
0
        //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);
        }
Example #5
0
        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;
        }
Example #6
0
        //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;
        }
Example #7
0
        /// <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");
        }
Example #8
0
        //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;
                }
            }
        }
Example #10
0
        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);
            }
        }
Example #11
0
        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);
                }

            }
        }
Example #12
0
        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);
            }
        }