/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * * Simulation of simple cache (as in JOP) * */ package com.jopdesign.tools; public class VarBlockCache extends Cache { int[] ctag; // int[] clen; // for different replace policy int next = 0; int currentBlock = 0; int numBlocks; int blockSize; int mask; boolean stackNext; VarBlockCache(int[] main, JopSim js, int size, int num, boolean stkNxt) { mem = main; sim = js; numBlocks = num; blockSize = MAX_BC*size/numBlocks; mask = 0; for (int i=(MAX_BC*size)>>1; i>0; i >>>= 1) { mask <<= 1; mask |= 1; } bc = new byte[blockSize * numBlocks]; ctag = new int[numBlocks]; resetCache(); stackNext = stkNxt; } private void resetCache() { for (int i=0; i<numBlocks; ++i) { ctag[i] = 0; } } int corrPc(int pc) { // save block relative pc on invoke // System.out.println("corr pc:" +((pc - currentBlock*blockSize) & mask)); return (pc - currentBlock*blockSize) & mask; } int invoke(int start, int len) { int off = testCache(start, len); // System.out.println("invoke: "+off); return off; } int ret(int start, int len, int pc) { /* stack-next policy */ if (stackNext) { next = currentBlock; } int off = testCache(start, len); // System.out.println("return pc: "+((off+pc) & mask)); return (off+pc) & mask; } int testCache(int start, int len) { this.lastHit = true; if(flush) { flush = false; resetCache(); } for (int i=0; i<numBlocks; ++i) { if (ctag[i]==start) { // HIT currentBlock = i; // System.out.println("hit in "+i+" off: "+(currentBlock*blockSize)); return currentBlock*blockSize; } } // not found this.lastHit = false; //System.out.println("Missed method: "+start); currentBlock = next; for (int i=0; i<=len*4/blockSize; ++i) { ctag[next] = 0; // block in use ++next; next %= numBlocks; // System.out.print(i+" "+next+" - "); } ctag[currentBlock] = start; // start block // for (int i=0; i<4; ++i) System.out.print(ctag[i]+" "); // System.out.println("next="+next+" len="+len); int off = currentBlock*blockSize; loadBc(off, start, len); return off; } // a different version of loadBc !!! void loadBc(int off, int start, int len) { // high byte of word is first bc!!! for (int i=0; i<len; ++i) { int val = sim.readInstrMem(start+i); for (int j=0; j<4; ++j) { bc[(off+i*4+(3-j)) & mask] = (byte) val; val >>>= 8; } } memRead += len*4; memTrans++; } byte bc(int addr) { ++cacheRead; return bc[addr & mask]; } public String toString() { /* return super.toString()+" ("+(bc.length/1024)+" KB "+ (numBlocks<10 ? " " : "")+numBlocks+" blks)"; return "Variable block cache "+numBlocks+ " blocks & "+ (bc.length/1024)+" KB"; */ return "Variable block cache "+(bc.length/1024)+" KB & "+numBlocks; } }