/*******************************************************************************
* openDLX - A DLX/MIPS processor simulator.
* Copyright (C) 2013 The openDLX project, University of Augsburg, Germany
* Project URL: <https://sourceforge.net/projects/opendlx>
* Development branch: <https://github.com/smetzlaff/openDLX>
*
*
* 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
* 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, see <LICENSE>. If not, see
* <http://www.gnu.org/licenses/>.
******************************************************************************/
package openDLX.memory;
import java.util.Properties;
import openDLX.datatypes.CacheReplacementPolicy;
import openDLX.datatypes.CacheType;
import openDLX.datatypes.DCacheWritePolicy;
import openDLX.datatypes.RequestType;
import openDLX.datatypes.uint32;
import openDLX.exception.CacheException;
import openDLX.exception.MemoryException;
import openDLX.exception.PipelineDataTypeException;
import openDLX.util.Statistics;
/**
* Encapsulates instruction memory hierarchy.
*/
public class InstructionMemory
{
private MemoryInterface mem;
private Statistics stat = Statistics.getInstance();
public InstructionMemory(MainMemory mem, Properties config) throws MemoryException, PipelineDataTypeException
{
boolean useIcache;
if(Integer.decode(config.getProperty("icache_use"))==0)
{
useIcache = false;
}
else
{
useIcache = true;
}
if(useIcache == false)
{
this.mem = mem;
}
else
{
int lineSize = 8;
if(config.getProperty("icache_line_size")!=null)
{
lineSize = Integer.decode(config.getProperty("icache_line_size"));
}
int lineNo = 32;
if(config.getProperty("icache_line_number")!=null)
{
lineNo = Integer.decode(config.getProperty("icache_line_number"));
}
int associativity = 1;
if(config.getProperty("icache_associativity")!=null)
{
associativity = Integer.decode(config.getProperty("icache_associativity"));
}
CacheReplacementPolicy rpol = CacheReplacementPolicy.UNKNOWN;
if(config.getProperty("icache_replacement_policy")!=null)
{
rpol = Cache.getCacheReplacementPolicyFromString(config.getProperty("icache_replacement_policy"));
}
if(associativity == 1)
{
this.mem = new CacheDirectMapped(CacheType.ICACHE, lineSize, lineNo, associativity, mem);
if((rpol != CacheReplacementPolicy.DIRECT_MAPPED) && (rpol != CacheReplacementPolicy.UNKNOWN))
{
throw new CacheException("Wrong replacement policy for cache with associativity of 1. Replacement policy: " + rpol);
}
rpol = CacheReplacementPolicy.DIRECT_MAPPED;
}
else
{
switch(rpol)
{
case FIFO:
this.mem = new CacheFIFO(CacheType.ICACHE, lineSize, lineNo, associativity, mem);
break;
case LRU:
this.mem = new CacheLRU(CacheType.ICACHE, lineSize, lineNo, associativity, mem);
break;
default:
throw new CacheException("Unknown cache replacement policy: " + rpol);
}
}
stat.setCacheParameters(CacheType.ICACHE, rpol, lineSize, lineNo, associativity, DCacheWritePolicy.UNKNOWN);
}
}
public int getRequestDelay(uint32 addr) throws MemoryException
{
return mem.getRequestDelay(RequestType.INSTR_RD, addr);
}
public uint32 read_u32(uint32 addr) throws MemoryException
{
return mem.read_u32(addr);
}
}