This change fixes the problem for all the cases we actively use. If you want to try
more creative I/O device attachments (E.g. sharing an L2), this won't work. You
would need another level of caching between the I/O device and the cache
(which you actually need anyway with our current code to make sure writes
propagate). This is required so that you can mark the cache in between as
top level and it won't try to send ownership of a block to the I/O device.
Asserts have been added that should catch any issues.
latency = '1ns'
mshrs = 10
tgts_per_mshr = 5
+ is_top_level = True
class L2Cache(BaseCache):
assoc = 8
mshrs = 10
size = '1kB'
tgts_per_mshr = 12
+ is_top_level = True
class IOCache(BaseCache):
assoc = 8
size = '1kB'
tgts_per_mshr = 12
forward_snoops = False
+ is_top_level = True
{
DPRINTF(Fetch, "Received timing\n");
if (pkt->isResponse()) {
+ // We shouldn't ever get a block in ownership state
+ assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
+
fetch->processCacheCompletion(pkt);
}
//else Snooped a coherence request, just return
assert(pendingCount >= 0);
assert(state);
+ // We shouldn't ever get a block in ownership state
+ assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
+
state->numBytes += pkt->req->getSize();
assert(state->totBytes >= state->numBytes);
if (state->totBytes == state->numBytes) {
size = Param.MemorySize("capacity in bytes")
forward_snoops = Param.Bool(True,
"forward snoops from mem side to cpu side")
+ is_top_level = Param.Bool(False, "Is this cache at the top level (e.g. L1)")
subblock_size = Param.Int(0,
"Size of subblock in IIC used for compression")
tgts_per_mshr = Param.Int("max number of accesses per MSHR")
hitLatency(p->latency),
numTarget(p->tgts_per_mshr),
forwardSnoops(p->forward_snoops),
+ isTopLevel(p->is_top_level),
blocked(0),
noTargetMSHR(NULL),
missCount(p->max_miss_count),
/** Do we forward snoops from mem side port through to cpu side port? */
bool forwardSnoops;
+ /** Is this cache a toplevel cache (e.g. L1, I/O cache). If so we should
+ * never try to forward ownership and similar optimizations to the cpu
+ * side */
+ bool isTopLevel;
+
/**
* Bit vector of the blocking reasons for the access path.
* @sa #BlockedCause
if (blk->isDirty()) {
// special considerations if we're owner:
- if (!deferred_response) {
+ if (!deferred_response && !isTopLevel) {
// if we are responding immediately and can
// signal that we're transferring ownership
// along with exclusivity, do so
mshrs = 10
tgts_per_mshr = 5
+class MyL1Cache(MyCache):
+ is_top_level = True
+
cpu = InOrderCPU(cpu_id=0)
-cpu.addTwoLevelCacheHierarchy(MyCache(size = '128kB'), MyCache(size = '256kB'),
+cpu.addTwoLevelCacheHierarchy(MyL1Cache(size = '128kB'),
+ MyL1Cache(size = '256kB'),
MyCache(size = '2MB', latency='10ns'))
cpu.clock = '2GHz'
block_size = 64
mshrs = 12
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
mshrs = 10
tgts_per_mshr = 5
+class MyL1Cache(MyCache):
+ is_top_level = True
+
cpu = DerivO3CPU(cpu_id=0)
-cpu.addTwoLevelCacheHierarchy(MyCache(size = '128kB'), MyCache(size = '256kB'),
+cpu.addTwoLevelCacheHierarchy(MyL1Cache(size = '128kB'),
+ MyL1Cache(size = '256kB'),
MyCache(size = '2MB'))
cpu.clock = '2GHz'
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
mshrs = 10
size = '1kB'
tgts_per_mshr = 12
+ is_top_level = True
# ---------------------
# I/O Cache
tgts_per_mshr = 12
addr_range = AddrRange(0, size=mem_size)
forward_snoops = False
+ is_top_level = True
#cpu
cpu = AtomicSimpleCPU(cpu_id=0)
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
mshrs = 10
tgts_per_mshr = 5
+class MyL1Cache(MyCache):
+ is_top_level = True
+
cpu = TimingSimpleCPU(cpu_id=0)
-cpu.addTwoLevelCacheHierarchy(MyCache(size = '128kB'), MyCache(size = '256kB'),
+cpu.addTwoLevelCacheHierarchy(MyL1Cache(size = '128kB'),
+ MyL1Cache(size = '256kB'),
MyCache(size = '2MB', latency='10ns'))
system = System(cpu = cpu,
physmem = PhysicalMemory(),
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
tgts_per_mshr = 12
addr_range=AddrRange(0, size='8GB')
forward_snoops = False
+ is_top_level = True
#cpu
cpus = [ DerivO3CPU(cpu_id=i) for i in xrange(2) ]
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
tgts_per_mshr = 12
addr_range=AddrRange(0, size='8GB')
forward_snoops = False
+ is_top_level = True
#cpu
cpu = DerivO3CPU(cpu_id=0)
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
tgts_per_mshr = 12
addr_range=AddrRange(0, size='8GB')
forward_snoops = False
+ is_top_level = True
#cpu
cpus = [ AtomicSimpleCPU(cpu_id=i) for i in xrange(2) ]
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
tgts_per_mshr = 12
addr_range=AddrRange(0, size='8GB')
forward_snoops = False
+ is_top_level = True
#cpu
cpu = AtomicSimpleCPU(cpu_id=0)
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
tgts_per_mshr = 12
addr_range=AddrRange(0, size='8GB')
forward_snoops = False
+ is_top_level = True
#cpu
cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(2) ]
block_size = 64
mshrs = 4
tgts_per_mshr = 8
+ is_top_level = True
# ----------------------
# Base L2 Cache
tgts_per_mshr = 12
addr_range=AddrRange(0, size='8GB')
forward_snoops = False
+ is_top_level = True
#cpu
cpu = TimingSimpleCPU(cpu_id=0)