📄 cache.cpp
字号:
case 3: // Read reqest to fill the cache line before a write if(!waitingForAck) {#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Memory read request for filling a cache line before a write" << endl;#endif line = GetLineStorage(bankToReplace, index); length = 0; lineOffset = 0; outMemReq = true; outMemWrite = false; outMemAddr = AlignToLineBoundary(inAddr); waitingForAck = true; state = 4; #ifdef DEBUG if(Debug(DebugCache)) { cout << name() << ": Reading " << linesize << " bytes at "; WriteHex(cout, AlignToLineBoundary(inAddr)); cout << endl; }#endif } break; case 4: if(!waitingForAck) { outMemReq = false; } break; case 5: outAck = true; break; case 6: // write request to eject the cache line before a read { DataArray<CACHE2MEM> data; #ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Memory write request for ejecting a cache line before a read" << endl;#endif line = GetLineStorage(bankToReplace, index); lineOffset = 0; length = 0; memcpy(data.buffer, &line[lineOffset], CACHE2MEM); lineOffset = (lineOffset + CACHE2MEM) % linesize; length += CACHE2MEM; if(length == linesize) { state = 8; } else { state = 7; } outMemReq = true; outMemAddr = GetLineAddr(bankToReplace, index); outMemWrite = true; outMemData = data; waitingForAck = true; } break; case 7: // Cache line eject before a read if(!waitingForAck) {#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Ejecting a cache line before a read" << endl;#endif DataArray<CACHE2MEM> data; memcpy(data.buffer, &line[lineOffset], CACHE2MEM); lineOffset = (lineOffset + CACHE2MEM) % linesize; length += CACHE2MEM; if(length == linesize) { state = 8; } outMemReq = false; outMemData = data; } break;#endif case 8: // read request to fill the cache line#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Memory read request for filling a cache line before a read" << endl;#endif line = GetLineStorage(bankToReplace, index); length = 0; lineOffset = AlignToMemoryWord(offset); dataLength = 0 - (offset % CACHE2MEM); outMemReq = true;#ifndef ICACHE outMemWrite = false;#endif outMemAddr = AlignToMemoryWord(addr); dataSent = false; waitingForAck = true; state = 9; break; case 9: outAck = false; break; }}void CLASSNAME::Forward(){ /* Forward data to LSU while filling cache line */ if(state == 9 && !dataSent) { if(size <= CACHE2MEM) { DataArray<CPU2CACHE> data; const DataArray<CACHE2MEM>& memdata = inMemData; memcpy(data.buffer, &memdata.buffer[offset % CACHE2MEM], size);#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Forwarding " << size << " bytes to cpu (" << data << ")" << endl;#endif outData = data;#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Sending an ack" << endl;#endif outAck = true; dataSent = true; } else { if(dataLength + CACHE2MEM >= size) { DataArray<CPU2CACHE> data; memcpy(data.buffer, &line[offset], dataLength); const DataArray<CACHE2MEM>& memdata = inMemData; memcpy(&data.buffer[dataLength], memdata.buffer, size - dataLength);#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Forwarding " << size << " bytes to cpu (" << data << ")" << endl;#endif outData = data;#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Sending an ack" << endl;#endif outAck = true; dataSent = true; } dataLength += CACHE2MEM; } }}void CLASSNAME::OnFallingEdge(){#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": state " << state << endl;#endif if(waitingForAck) {#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Waiting for an ack" << endl;#endif if(inMemAck) {#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Getting an ack" << endl;#endif waitingForAck = false; outMemReq = false; } } switch(state) {#ifndef ICACHE case 4: // filling the cache line before a write if(!waitingForAck) {#ifdef DEBUG if(Debug(DebugCache)) { cout << name() << ": cache line filling before a write" << endl; cout << name() << ": Writing " << CACHE2MEM << " bytes into cache line (lineOffset = " << lineOffset << ")" << endl; }#endif const DataArray<CACHE2MEM>& data = inMemData; memcpy(&line[lineOffset], data.buffer, CACHE2MEM); lineOffset = (lineOffset + CACHE2MEM) % linesize; length += CACHE2MEM; if(length == linesize) { state = 5; } } break; case 5: // write into the cache line { /* directory update */ ReplaceLine(bankToReplace, index, tag); if(zeroBlock) {#ifdef DEBUG if(Debug(DebugCache)) { cout << name() << ": writing into cache line" << endl; cout << name() << ": Writing " << linesize << " zeros into cache line" << endl; }#endif Zero(bankToReplace, index); } else {#ifdef DEBUG if(Debug(DebugCache)) { cout << name() << ": writing into cache line" << endl; cout << name() << ": Writing " << size << " bytes into cache line" << endl; }#endif const DataArray<CPU2CACHE>& data = inData; Write(bankToReplace, index, offset, data.buffer, size); } state = 0; busy = false; } break;#endif case 9: // filling the cache line before a read if(!waitingForAck) { const DataArray<CACHE2MEM>& data = inMemData;#ifdef DEBUG if(Debug(DebugCache)) { cout << name() << ": filling a cache line before for a read" << endl; cout << name() << ": Writing " << CACHE2MEM << " bytes (" << data << ") into cache line (lineOffset = " << lineOffset << ")" << endl; }#endif memcpy(&line[lineOffset], data.buffer, CACHE2MEM); lineOffset = (lineOffset + CACHE2MEM) % linesize; length += CACHE2MEM; if(length == linesize) { /* directory update */ ReplaceLine(bankToReplace, index, tag); state = 0; busy = false; } } break; } #ifndef ICACHE#ifdef DEBUG if(Debug(DebugCache)) { cout << name() << ": ##### inReq = " <<(bool) inReq << endl; cout << name() << ": ##### hit = " << hit << endl; cout << name() << ": ##### inWrite = " << (bool) inWrite << endl; }#endif if(inReq && hit) { if(inWrite) { // Write const DataArray<CPU2CACHE>& data = inData; if(writeZeroBlock) {#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Writing " << linesize << " zeros" << endl;#endif Zero(writeBank, writeIndex); } else {#ifdef DEBUG if(Debug(DebugCache)) cout << name() << ": Writing " << inSize << " bytes (" << data << ")" << endl;#endif Write(writeBank, writeIndex, writeOffset, data.buffer, inSize); } } }#endif outAck = false;#ifdef DCACHE outBusy = state != 0;#endif}void CLASSNAME::MemoryRead(UInt8 *buffer, UInt32 addr, UInt32 size){ while(size > 0) { UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); UInt32 count = (offset + size > linesize) ? linesize - offset : size; if(bank >= 0) memcpy(buffer, &storage[bank][index][offset], count); buffer += count; size -= count; addr += count; }}void CLASSNAME::MemoryWrite(UInt32 addr, UInt8 *buffer, UInt32 size){ while(size > 0) { UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); UInt32 count = (offset + size > linesize) ? linesize - offset : size; if(bank >= 0) memcpy(&storage[bank][index][offset], buffer, count); buffer += count; size -= count; addr += count; }}void CLASSNAME::MemorySet(UInt32 addr, UInt8 value, UInt32 size){ while(size > 0) { UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); UInt32 count = (offset + size > linesize) ? linesize - offset : size; if(bank >= 0) memset(&storage[bank][index][offset], value, count); size -= count; addr += count; }}bool CLASSNAME::ReadDWord(UInt32 addr, UInt64& value){ UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); if(bank >= 0) { value = ((UInt64) storage[bank][index][offset] << 56) | ((UInt64) storage[bank][index][offset + 1] << 48) | ((UInt64) storage[bank][index][offset + 2] << 40) | ((UInt64) storage[bank][index][offset + 3] << 32) | ((UInt64) storage[bank][index][offset + 4] << 24) | ((UInt64) storage[bank][index][offset + 5] << 16) | ((UInt64) storage[bank][index][offset + 6] << 8) | ((UInt64) storage[bank][index][offset + 7]); return true; } return false;}void CLASSNAME::WriteDWord(UInt32 addr, UInt64 value){ UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); if(bank >= 0) { storage[bank][index][offset] = value >> 56; storage[bank][index][offset + 1] = value >> 48; storage[bank][index][offset + 2] = value >> 40; storage[bank][index][offset + 3] = value >> 32; storage[bank][index][offset + 4] = value >> 24; storage[bank][index][offset + 5] = value >> 16; storage[bank][index][offset + 6] = value >> 8; storage[bank][index][offset + 7] = value; }}bool CLASSNAME::ReadWord(UInt32 addr, UInt32& value){ UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); if(bank >= 0) { value = (storage[bank][index][offset] << 24) | (storage[bank][index][offset + 1] << 16) | (storage[bank][index][offset + 2] << 8) | storage[bank][index][offset + 3]; return true; } return false;}void CLASSNAME::WriteWord(UInt32 addr, UInt32 value){ UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); if(bank >= 0) { storage[bank][index][offset] = value >> 24; storage[bank][index][offset + 1] = value >> 16; storage[bank][index][offset + 2] = value >> 8; storage[bank][index][offset + 3] = value; }}bool CLASSNAME::ReadHalfWord(UInt32 addr, UInt16& value){ UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); if(bank >= 0) { value = (storage[bank][index][offset] << 8) | (storage[bank][index][offset + 1]); return true; } return false;}void CLASSNAME::WriteHalfWord(UInt32 addr, UInt16 value){ UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); if(bank >= 0) { storage[bank][index][offset] = value >> 8; storage[bank][index][offset + 1] = value; }}bool CLASSNAME::ReadByte(UInt32 addr, UInt8& value){ UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); if(bank >= 0) { value = storage[bank][index][offset]; return true; } return false;}void CLASSNAME::WriteByte(UInt32 addr, UInt8 value){ UInt32 tag; UInt32 index; UInt32 offset; DecodeAddress(addr, tag, index, offset); int bank = Search(index, tag); if(bank >= 0) { storage[bank][index][offset] = value; }}void CLASSNAME::Reset(){ state = 0; busy = false; hit = false; waitingForAck = false; hits = misses = 0;}void CLASSNAME::ResetStats(){ hits = misses = 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -