/// <summary> /// Construct a DataCache given data cache preferences. /// </summary> /// <param name="memoryBlock">reference to main memory block</param> /// <param name="dataCachePreferences">the data cache preferences</param> public DataCache(MemoryBlock memoryBlock, DataCachePreferences dataCachePreferences) : base(memoryBlock, dataCachePreferences) { _writePolicy = dataCachePreferences.WritePolicy; _allocatePolicy = dataCachePreferences.AllocatePolicy; _writeThru = (_writePolicy == WritePolicyEnum.WriteThrough); }
}//allocateLine /// <summary> /// Read from the CacheSet. /// Check each block in the set and compare the line tag with the address. If the address tag matches the /// line tag, then we have a cache block hit. Otherwise we need to get the requested block into the /// cache and this will depend on the allocate policy. /// </summary> /// <param name="address">address to read</param> /// <param name="ms">size to read</param> /// <param name="allocatePolicy">allocation policy to use</param> /// <returns>value read</returns> public uint GetMemory(uint address, ARMPluginInterfaces.MemorySize ms, AllocatePolicyEnum allocatePolicy) { //check each line in the cache set foreach (CacheBlock cb in Blocks) { //only check valid lines and look for a tag match if (cb.Valid && ((address & cb.Mask) == cb.Tag)) { //cache read hit ReadHits++; return(cb.GetMemory(address, ms)); } } //cache read miss ReadMisses++; if (allocatePolicy != AllocatePolicyEnum.Write) { //read or both policy return(allocateLine(address).GetMemory(address, ms)); } else { //write policy, do not allocate a new cache line return(memBlock.GetMemory(address, ms)); } }//GetMemory
/// <summary> /// Write to the CacheSet. /// Check each block in the set and compare the block tag with the address. If the address tag matches the /// block tag, then we have a cache write block hit. Otherwise we need to get the requested block into the /// cache and this will depend on the allocate policy. /// </summary> /// <param name="address">address to write to</param> /// <param name="ms">size to write</param> /// <param name="data">data to write</param> /// <param name="writeThru">true then write through to main memory</param> /// <param name="allocatePolicy">allocate policy to use</param> public void SetMemory(uint address, ARMPluginInterfaces.MemorySize ms, uint data, bool writeThru, AllocatePolicyEnum allocatePolicy) { //iterate over the cache blocks looking for the block that holds this address foreach (CacheBlock cb in Blocks) { //check if this block is valid and has this address if (cb.Valid && ((address & cb.Mask) == cb.Tag)) { //cache write hit, set data into cache memory WriteHits++; cb.SetMemory(address, ms, data, writeThru); //if the changed handler is set, call it if (_cacheChangedHandler != null) { _cacheChangedHandler(cb.BlockNumber, address & cb.Mask); } //done return; } //if } //foreach //cache write miss WriteMisses++; //allocate a cache line based on the allocation policy if (allocatePolicy != AllocatePolicyEnum.Read) { //write or both policy allocateLine(address).SetMemory(address, ms, data, writeThru); } else { //read policy, do not allocate a new cache line memBlock.SetMemory(address, ms, data); } } //SetMemory