/** * @param TAG Address of the Data to be inserted This method brings 4 words from the Memory to the * Cache together with the data asked */ public void Fetch(int TAG) { String DATA = "", sMsg = ""; int block; String sTag = ""; // Choose the new block to be inserted block = TAG % 16; SetDataBitsIntheBlock("0000000", block, 0, 6); // valid-dirty-index-offset bits sTag = Long.toBinaryString(TAG); // TAG (physical address) of the first word in the cache sTag = String.format("%0" + (13 - sTag.length()) + "d", 0) + sTag; SetDataBitsIntheBlock(sTag, block, 7, 19); // Tag bits int indexStart = 20, indexEnd = 39; // first word in the CACHE for (int i = 1; i <= 4; i++) { DATA = ControlPanel.MEMORY.getDirect(Long.toBinaryString(TAG + i - 1)); SetDataBitsIntheBlock(DATA, block, i * indexStart, indexEnd + ((i - 1) * indexStart)); sMsg = sMsg + String.format("%s", TAG + i - 1) + "-"; } // ControlPanel.jMessages.append("CACHE(" + block + ") --> " + sMsg.substring(0, // sMsg.length()-1) + "\n"); }
/** * @param block The block on the cache to be written to Memory This method writes 4 words from * Cache to Memory This happens during the read miss if block is dirty Data should be read * from Write-Buffer For the simplicity, we are reading it from the cache before exchanging */ public void WriteBack(int block) { int TAG; String ADDR = ""; String DATA = ""; TAG = Integer.parseInt(TakeDataBitsFromtheBlock(block, 7, 19), 2); int indexStart = 20, indexEnd = 39; // first word in the CACHE for (int i = 1; i <= 4; i++) { DATA = TakeDataBitsFromtheBlock(block, i * indexStart, indexEnd + ((i - 1) * indexStart)); ADDR = Long.toBinaryString(TAG + i - 1); ADDR = String.format("%0" + (20 - ADDR.length()) + "d", 0) + ADDR; ControlPanel.MEMORY.setDirect(DATA, ADDR); } }
/** * @param WORD the data to be updated * @param Addr the address of the data on either Memory or Cache This is the WRITE operation of * the CACHE If Address updated is on the Cache, find on the cache, and simply update it * (Write Hit) Set the DIRTY BIT, UPDATE the Memory during the WRITE-BACK operation which * occurs on read miss If not on the Cache (Write Miss), bring it from the Memory by using * WRITE-ALLOCATE (fetch) */ public void Write(String WORD, int Addr) { int TAG = 0; String sAddr = ""; Integer OffSet; boolean OntheCache = false; OffSet = Addr % 4; TAG = Addr - OffSet; // block's physical address String sOffSet = ""; // 00,01,10,11 sOffSet = (OffSet <= 1) ? "0" + String.format("%s", OffSet) : Long.toBinaryString(OffSet); int block = 0; // check if it is in the CACHE block by block for (int i = 0; i <= 15; i++) { if (GetBlockTag(i) == TAG) { /** * WRITE HIT !.. we are using Write Back method if data on the cache, we will not update the * Memory right away instead we set dirty bit and update it while we are swapping cache * blocks from the memory */ CACHE_DATA[i][1] = 1; // set Dirty bit, block updated // Set offSet bits to select the word asked CACHE_DATA[i][5] = Integer.parseInt(sOffSet.substring(0, 1)); // first bit of offset 01 -> 1 CACHE_DATA[i][6] = Integer.parseInt(sOffSet.substring(1, 2)); // second bit of offset 01 -> 0 UpdateWordInBlock(i, WORD); // ControlPanel.jMessages.append("Write Hit!\n"); OntheCache = true; break; } } if (!OntheCache) { /** * WRITE MISS !.. Data is not on the cache so write to memory Since we are using write * allocate method, Fetch words from Memory */ // System.out.println("Write Miss!"); // ControlPanel.jMessages.append("Write Miss!\n"); sAddr = Long.toBinaryString(Addr); sAddr = String.format("%0" + (20 - sAddr.length()) + "d", 0) + sAddr; ControlPanel.MEMORY.setDirect(WORD, sAddr); Fetch(TAG); } }