summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/BaseCPU.py106
-rw-r--r--src/cpu/FuncUnit.py46
-rw-r--r--src/cpu/IntrControl.py34
-rw-r--r--src/cpu/SConscript5
-rw-r--r--src/cpu/base.cc7
-rw-r--r--src/cpu/exetrace.cc17
-rw-r--r--src/cpu/memtest/MemTest.py52
-rw-r--r--src/cpu/memtest/SConscript2
-rw-r--r--src/cpu/memtest/memtest.cc12
-rw-r--r--src/cpu/memtest/memtest.hh4
-rw-r--r--src/cpu/o3/FUPool.py40
-rw-r--r--src/cpu/o3/FuncUnitConfig.py69
-rw-r--r--src/cpu/o3/O3CPU.py153
-rw-r--r--src/cpu/o3/O3Checker.py43
-rwxr-xr-xsrc/cpu/o3/SConscript5
-rw-r--r--src/cpu/o3/fetch.hh4
-rw-r--r--src/cpu/o3/fetch_impl.hh13
-rw-r--r--src/cpu/o3/lsq.hh4
-rw-r--r--src/cpu/op_class.cc2
-rw-r--r--src/cpu/ozone/OzoneCPU.py127
-rw-r--r--src/cpu/ozone/OzoneChecker.py43
-rw-r--r--src/cpu/ozone/SConscript4
-rw-r--r--src/cpu/ozone/SimpleOzoneCPU.py115
-rw-r--r--src/cpu/ozone/cpu_impl.hh1
-rw-r--r--src/cpu/ozone/front_end.hh4
-rw-r--r--src/cpu/ozone/lw_lsq.hh4
-rw-r--r--src/cpu/simple/AtomicSimpleCPU.py43
-rw-r--r--src/cpu/simple/SConscript2
-rw-r--r--src/cpu/simple/TimingSimpleCPU.py41
-rw-r--r--src/cpu/simple/atomic.cc6
-rw-r--r--src/cpu/simple/atomic.hh4
-rw-r--r--src/cpu/simple/base.cc54
-rw-r--r--src/cpu/simple/base.hh9
-rw-r--r--src/cpu/simple/timing.cc14
-rw-r--r--src/cpu/simple/timing.hh11
-rw-r--r--src/cpu/simple_thread.hh1
-rw-r--r--src/cpu/static_inst.cc6
-rw-r--r--src/cpu/static_inst.hh160
38 files changed, 1178 insertions, 89 deletions
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
new file mode 100644
index 000000000..6c2aace51
--- /dev/null
+++ b/src/cpu/BaseCPU.py
@@ -0,0 +1,106 @@
+# Copyright (c) 2005-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.proxy import *
+from m5 import build_env
+from Bus import Bus
+import sys
+
+if build_env['FULL_SYSTEM']:
+ if build_env['TARGET_ISA'] == 'alpha':
+ from AlphaTLB import AlphaDTB, AlphaITB
+
+ if build_env['TARGET_ISA'] == 'sparc':
+ from SparcTLB import SparcDTB, SparcITB
+
+class BaseCPU(SimObject):
+ type = 'BaseCPU'
+ abstract = True
+
+ system = Param.System(Parent.any, "system object")
+ cpu_id = Param.Int("CPU identifier")
+
+ if build_env['FULL_SYSTEM']:
+ do_quiesce = Param.Bool(True, "enable quiesce instructions")
+ do_checkpoint_insts = Param.Bool(True,
+ "enable checkpoint pseudo instructions")
+ do_statistics_insts = Param.Bool(True,
+ "enable statistics pseudo instructions")
+
+ if build_env['TARGET_ISA'] == 'sparc':
+ dtb = Param.SparcDTB(SparcDTB(), "Data TLB")
+ itb = Param.SparcITB(SparcITB(), "Instruction TLB")
+ elif build_env['TARGET_ISA'] == 'alpha':
+ dtb = Param.AlphaDTB(AlphaDTB(), "Data TLB")
+ itb = Param.AlphaITB(AlphaITB(), "Instruction TLB")
+ else:
+ print "Unknown architecture, can't pick TLBs"
+ sys.exit(1)
+ else:
+ workload = VectorParam.Process("processes to run")
+
+ max_insts_all_threads = Param.Counter(0,
+ "terminate when all threads have reached this inst count")
+ max_insts_any_thread = Param.Counter(0,
+ "terminate when any thread reaches this inst count")
+ max_loads_all_threads = Param.Counter(0,
+ "terminate when all threads have reached this load count")
+ max_loads_any_thread = Param.Counter(0,
+ "terminate when any thread reaches this load count")
+ progress_interval = Param.Tick(0,
+ "interval to print out the progress message")
+
+ defer_registration = Param.Bool(False,
+ "defer registration with system (for sampling)")
+
+ clock = Param.Clock('1t', "clock speed")
+ phase = Param.Latency('0ns', "clock phase")
+
+ _mem_ports = []
+
+ def connectMemPorts(self, bus):
+ for p in self._mem_ports:
+ exec('self.%s = bus.port' % p)
+
+ def addPrivateSplitL1Caches(self, ic, dc):
+ assert(len(self._mem_ports) == 2)
+ self.icache = ic
+ self.dcache = dc
+ self.icache_port = ic.cpu_side
+ self.dcache_port = dc.cpu_side
+ self._mem_ports = ['icache.mem_side', 'dcache.mem_side']
+
+ def addTwoLevelCacheHierarchy(self, ic, dc, l2c):
+ self.addPrivateSplitL1Caches(ic, dc)
+ self.toL2Bus = Bus()
+ self.connectMemPorts(self.toL2Bus)
+ self.l2cache = l2c
+ self.l2cache.cpu_side = self.toL2Bus.port
+ self._mem_ports = ['l2cache.mem_side']
diff --git a/src/cpu/FuncUnit.py b/src/cpu/FuncUnit.py
new file mode 100644
index 000000000..ad2d1b87b
--- /dev/null
+++ b/src/cpu/FuncUnit.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Kevin Lim
+
+from m5.SimObject import SimObject
+from m5.params import *
+
+class OpClass(Enum):
+ vals = ['No_OpClass', 'IntAlu', 'IntMult', 'IntDiv', 'FloatAdd',
+ 'FloatCmp', 'FloatCvt', 'FloatMult', 'FloatDiv', 'FloatSqrt',
+ 'MemRead', 'MemWrite', 'IprAccess', 'InstPrefetch']
+
+class OpDesc(SimObject):
+ type = 'OpDesc'
+ issueLat = Param.Int(1, "cycles until another can be issued")
+ opClass = Param.OpClass("type of operation")
+ opLat = Param.Int(1, "cycles until result is available")
+
+class FUDesc(SimObject):
+ type = 'FUDesc'
+ count = Param.Int("number of these FU's available")
+ opList = VectorParam.OpDesc("operation classes for this FU type")
diff --git a/src/cpu/IntrControl.py b/src/cpu/IntrControl.py
new file mode 100644
index 000000000..eb4b1696b
--- /dev/null
+++ b/src/cpu/IntrControl.py
@@ -0,0 +1,34 @@
+# Copyright (c) 2005-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.proxy import *
+class IntrControl(SimObject):
+ type = 'IntrControl'
+ sys = Param.System(Parent.any, "the system we are part of")
diff --git a/src/cpu/SConscript b/src/cpu/SConscript
index 1c2278f6f..cce13a072 100644
--- a/src/cpu/SConscript
+++ b/src/cpu/SConscript
@@ -103,6 +103,9 @@ env.Depends('static_inst_exec_sigs.hh', Value(env['CPU_MODELS']))
# and one of these are not being used.
CheckerSupportedCPUList = ['O3CPU', 'OzoneCPU']
+SimObject('BaseCPU.py')
+SimObject('FuncUnit.py')
+
Source('activity.cc')
Source('base.cc')
Source('cpuevent.cc')
@@ -116,6 +119,8 @@ Source('simple_thread.cc')
Source('thread_state.cc')
if env['FULL_SYSTEM']:
+ SimObject('IntrControl.py')
+
Source('intr_control.cc')
Source('profile.cc')
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 4dccee0d3..078ae1283 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -179,10 +179,9 @@ BaseCPU::BaseCPU(Params *p)
if (p->functionTraceStart == 0) {
functionTracingEnabled = true;
} else {
- Event *e =
- new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
- true);
- e->schedule(p->functionTraceStart);
+ new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
+ p->functionTraceStart,
+ true);
}
}
#if FULL_SYSTEM
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index 3e2b0f03e..9b87f2e8a 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -162,7 +162,7 @@ Trace::InstRecord::dump()
static int fd = 0;
//Don't print what happens for each micro-op, just print out
//once at the last op, and for regular instructions.
- if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
+ if(!staticInst->isMicroop() || staticInst->isLastMicroop())
{
if(!cosim_listener)
{
@@ -245,7 +245,7 @@ Trace::InstRecord::dump()
#if 0 //THE_ISA == SPARC_ISA
//Don't print what happens for each micro-op, just print out
//once at the last op, and for regular instructions.
- if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
+ if(!staticInst->isMicroop() || staticInst->isLastMicroop())
{
static uint64_t regs[32] = {
0, 0, 0, 0, 0, 0, 0, 0,
@@ -432,7 +432,7 @@ Trace::InstRecord::dump()
setupSharedData();
// We took a trap on a micro-op...
- if (wasMicro && !staticInst->isMicroOp())
+ if (wasMicro && !staticInst->isMicroop())
{
// let's skip comparing this tick
while (!compared)
@@ -444,13 +444,13 @@ Trace::InstRecord::dump()
wasMicro = false;
}
- if (staticInst->isLastMicroOp())
+ if (staticInst->isLastMicroop())
wasMicro = false;
- else if (staticInst->isMicroOp())
+ else if (staticInst->isMicroop())
wasMicro = true;
- if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
+ if(!staticInst->isMicroop() || staticInst->isLastMicroop()) {
while (!compared) {
if (shared_data->flags == OWN_M5) {
m5Pc = PC & TheISA::PAddrImplMask;
@@ -650,12 +650,13 @@ Trace::InstRecord::dump()
<< endl;
predecoder.setTC(thread);
- predecoder.moreBytes(m5Pc, 0, shared_data->instruction);
+ predecoder.moreBytes(m5Pc, m5Pc, 0,
+ shared_data->instruction);
assert(predecoder.extMachInstReady());
StaticInstPtr legionInst =
- StaticInst::decode(predecoder.getExtMachInst());
+ StaticInst::decode(predecoder.getExtMachInst(), lgnPc);
outs << setfill(' ') << setw(15)
<< " Legion Inst: "
<< "0x" << setw(8) << setfill('0') << hex
diff --git a/src/cpu/memtest/MemTest.py b/src/cpu/memtest/MemTest.py
new file mode 100644
index 000000000..381519972
--- /dev/null
+++ b/src/cpu/memtest/MemTest.py
@@ -0,0 +1,52 @@
+# Copyright (c) 2005-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.proxy import *
+from m5 import build_env
+
+class MemTest(SimObject):
+ type = 'MemTest'
+ max_loads = Param.Counter("number of loads to execute")
+ atomic = Param.Bool(False, "Execute tester in atomic mode? (or timing)\n")
+ memory_size = Param.Int(65536, "memory size")
+ percent_dest_unaligned = Param.Percent(50,
+ "percent of copy dest address that are unaligned")
+ percent_reads = Param.Percent(65, "target read percentage")
+ percent_source_unaligned = Param.Percent(50,
+ "percent of copy source address that are unaligned")
+ percent_functional = Param.Percent(50, "percent of access that are functional")
+ percent_uncacheable = Param.Percent(10,
+ "target uncacheable percentage")
+ progress_interval = Param.Counter(1000000,
+ "progress report interval (in accesses)")
+ trace_addr = Param.Addr(0, "address to trace")
+
+ test = Port("Port to the memory system to test")
+ functional = Port("Port to the functional memory used for verification")
diff --git a/src/cpu/memtest/SConscript b/src/cpu/memtest/SConscript
index 7b4d6d2c5..1f6621a4c 100644
--- a/src/cpu/memtest/SConscript
+++ b/src/cpu/memtest/SConscript
@@ -31,4 +31,6 @@
Import('*')
if 'O3CPU' in env['CPU_MODELS']:
+ SimObject('MemTest.py')
+
Source('memtest.cc')
diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index 607cf1066..15774904a 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -190,14 +190,8 @@ MemTest::init()
blockAddrMask = blockSize - 1;
traceBlockAddr = blockAddr(traceBlockAddr);
- // set up intial memory contents here
-
- cachePort.memsetBlob(baseAddr1, 1, size);
- funcPort.memsetBlob(baseAddr1, 1, size);
- cachePort.memsetBlob(baseAddr2, 2, size);
- funcPort.memsetBlob(baseAddr2, 2, size);
- cachePort.memsetBlob(uncacheAddr, 3, size);
- funcPort.memsetBlob(uncacheAddr, 3, size);
+ // initial memory contents for both physical memory and functional
+ // memory should be 0; no need to initialize them.
}
static void
@@ -267,7 +261,7 @@ MemTest::completeRequest(PacketPtr pkt)
break;
*/
default:
- panic("invalid command");
+ panic("invalid command %s (%d)", pkt->cmdString(), pkt->cmd.toInt());
}
if (blockAddr(req->getPaddr()) == traceBlockAddr) {
diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh
index 264309fd7..123ee2a6c 100644
--- a/src/cpu/memtest/memtest.hh
+++ b/src/cpu/memtest/memtest.hh
@@ -115,8 +115,8 @@ class MemTest : public MemObject
virtual void recvRetry();
virtual void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); }
+ bool &snoop)
+ { resp.clear(); snoop = true; }
};
CpuPort cachePort;
diff --git a/src/cpu/o3/FUPool.py b/src/cpu/o3/FUPool.py
new file mode 100644
index 000000000..4f07f9867
--- /dev/null
+++ b/src/cpu/o3/FUPool.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Kevin Lim
+
+from m5.SimObject import SimObject
+from m5.params import *
+from FuncUnit import *
+from FuncUnitConfig import *
+
+class FUPool(SimObject):
+ type = 'FUPool'
+ FUList = VectorParam.FUDesc("list of FU's for this pool")
+
+class DefaultFUPool(FUPool):
+ FUList = [ IntALU(), IntMultDiv(), FP_ALU(), FP_MultDiv(), ReadPort(),
+ WritePort(), RdWrPort(), IprPort() ]
diff --git a/src/cpu/o3/FuncUnitConfig.py b/src/cpu/o3/FuncUnitConfig.py
new file mode 100644
index 000000000..954381f86
--- /dev/null
+++ b/src/cpu/o3/FuncUnitConfig.py
@@ -0,0 +1,69 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Kevin Lim
+
+from m5.SimObject import SimObject
+from m5.params import *
+from FuncUnit import *
+
+class IntALU(FUDesc):
+ opList = [ OpDesc(opClass='IntAlu') ]
+ count = 6
+
+class IntMultDiv(FUDesc):
+ opList = [ OpDesc(opClass='IntMult', opLat=3),
+ OpDesc(opClass='IntDiv', opLat=20, issueLat=19) ]
+ count=2
+
+class FP_ALU(FUDesc):
+ opList = [ OpDesc(opClass='FloatAdd', opLat=2),
+ OpDesc(opClass='FloatCmp', opLat=2),
+ OpDesc(opClass='FloatCvt', opLat=2) ]
+ count = 4
+
+class FP_MultDiv(FUDesc):
+ opList = [ OpDesc(opClass='FloatMult', opLat=4),
+ OpDesc(opClass='FloatDiv', opLat=12, issueLat=12),
+ OpDesc(opClass='FloatSqrt', opLat=24, issueLat=24) ]
+ count = 2
+
+class ReadPort(FUDesc):
+ opList = [ OpDesc(opClass='MemRead') ]
+ count = 0
+
+class WritePort(FUDesc):
+ opList = [ OpDesc(opClass='MemWrite') ]
+ count = 0
+
+class RdWrPort(FUDesc):
+ opList = [ OpDesc(opClass='MemRead'), OpDesc(opClass='MemWrite') ]
+ count = 4
+
+class IprPort(FUDesc):
+ opList = [ OpDesc(opClass='IprAccess', opLat = 3, issueLat = 3) ]
+ count = 1
+
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
new file mode 100644
index 000000000..e031faefa
--- /dev/null
+++ b/src/cpu/o3/O3CPU.py
@@ -0,0 +1,153 @@
+# Copyright (c) 2005-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Kevin Lim
+
+from m5.params import *
+from m5.proxy import *
+from m5 import build_env
+from BaseCPU import BaseCPU
+from FUPool import *
+
+if build_env['USE_CHECKER']:
+ from O3Checker import O3Checker
+
+class DerivO3CPU(BaseCPU):
+ type = 'DerivO3CPU'
+ activity = Param.Unsigned(0, "Initial count")
+ numThreads = Param.Unsigned(1, "number of HW thread contexts")
+
+ if build_env['FULL_SYSTEM']:
+ profile = Param.Latency('0ns', "trace the kernel stack")
+ if build_env['USE_CHECKER']:
+ if not build_env['FULL_SYSTEM']:
+ checker = Param.BaseCPU(O3Checker(workload=Parent.workload,
+ exitOnError=False,
+ updateOnError=True,
+ warnOnlyOnLoadError=False),
+ "checker")
+ else:
+ checker = Param.BaseCPU(O3Checker(exitOnError=False, updateOnError=True,
+ warnOnlyOnLoadError=False), "checker")
+ checker.itb = Parent.itb
+ checker.dtb = Parent.dtb
+
+ cachePorts = Param.Unsigned("Cache Ports")
+ icache_port = Port("Instruction Port")
+ dcache_port = Port("Data Port")
+ _mem_ports = ['icache_port', 'dcache_port']
+
+ decodeToFetchDelay = Param.Unsigned(1, "Decode to fetch delay")
+ renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay")
+ iewToFetchDelay = Param.Unsigned(1, "Issue/Execute/Writeback to fetch "
+ "delay")
+ commitToFetchDelay = Param.Unsigned(1, "Commit to fetch delay")
+ fetchWidth = Param.Unsigned(8, "Fetch width")
+
+ renameToDecodeDelay = Param.Unsigned(1, "Rename to decode delay")
+ iewToDecodeDelay = Param.Unsigned(1, "Issue/Execute/Writeback to decode "
+ "delay")
+ commitToDecodeDelay = Param.Unsigned(1, "Commit to decode delay")
+ fetchToDecodeDelay = Param.Unsigned(1, "Fetch to decode delay")
+ decodeWidth = Param.Unsigned(8, "Decode width")
+
+ iewToRenameDelay = Param.Unsigned(1, "Issue/Execute/Writeback to rename "
+ "delay")
+ commitToRenameDelay = Param.Unsigned(1, "Commit to rename delay")
+ decodeToRenameDelay = Param.Unsigned(1, "Decode to rename delay")
+ renameWidth = Param.Unsigned(8, "Rename width")
+
+ commitToIEWDelay = Param.Unsigned(1, "Commit to "
+ "Issue/Execute/Writeback delay")
+ renameToIEWDelay = Param.Unsigned(2, "Rename to "
+ "Issue/Execute/Writeback delay")
+ issueToExecuteDelay = Param.Unsigned(1, "Issue to execute delay (internal "
+ "to the IEW stage)")
+ dispatchWidth = Param.Unsigned(8, "Dispatch width")
+ issueWidth = Param.Unsigned(8, "Issue width")
+ wbWidth = Param.Unsigned(8, "Writeback width")
+ wbDepth = Param.Unsigned(1, "Writeback depth")
+ fuPool = Param.FUPool(DefaultFUPool(), "Functional Unit pool")
+
+ iewToCommitDelay = Param.Unsigned(1, "Issue/Execute/Writeback to commit "
+ "delay")
+ renameToROBDelay = Param.Unsigned(1, "Rename to reorder buffer delay")
+ commitWidth = Param.Unsigned(8, "Commit width")
+ squashWidth = Param.Unsigned(8, "Squash width")
+ trapLatency = Param.Tick(13, "Trap latency")
+ fetchTrapLatency = Param.Tick(1, "Fetch trap latency")
+
+ backComSize = Param.Unsigned(5, "Time buffer size for backwards communication")
+ forwardComSize = Param.Unsigned(5, "Time buffer size for forward communication")
+
+ predType = Param.String("tournament", "Branch predictor type ('local', 'tournament')")
+ localPredictorSize = Param.Unsigned(2048, "Size of local predictor")
+ localCtrBits = Param.Unsigned(2, "Bits per counter")
+ localHistoryTableSize = Param.Unsigned(2048, "Size of local history table")
+ localHistoryBits = Param.Unsigned(11, "Bits for the local history")
+ globalPredictorSize = Param.Unsigned(8192, "Size of global predictor")
+ globalCtrBits = Param.Unsigned(2, "Bits per counter")
+ globalHistoryBits = Param.Unsigned(13, "Bits of history")
+ choicePredictorSize = Param.Unsigned(8192, "Size of choice predictor")
+ choiceCtrBits = Param.Unsigned(2, "Bits of choice counters")
+
+ BTBEntries = Param.Unsigned(4096, "Number of BTB entries")
+ BTBTagSize = Param.Unsigned(16, "Size of the BTB tags, in bits")
+
+ RASSize = Param.Unsigned(16, "RAS size")
+
+ LQEntries = Param.Unsigned(32, "Number of load queue entries")
+ SQEntries = Param.Unsigned(32, "Number of store queue entries")
+ LFSTSize = Param.Unsigned(1024, "Last fetched store table size")
+ SSITSize = Param.Unsigned(1024, "Store set ID table size")
+
+ numRobs = Param.Unsigned(1, "Number of Reorder Buffers");
+
+ numPhysIntRegs = Param.Unsigned(256, "Number of physical integer registers")
+ numPhysFloatRegs = Param.Unsigned(256, "Number of physical floating point "
+ "registers")
+ numIQEntries = Param.Unsigned(64, "Number of instruction queue entries")
+ numROBEntries = Param.Unsigned(192, "Number of reorder buffer entries")
+
+ instShiftAmt = Param.Unsigned(2, "Number of bits to shift instructions by")
+
+ function_trace = Param.Bool(False, "Enable function trace")
+ function_trace_start = Param.Tick(0, "Cycle to start function trace")
+
+ smtNumFetchingThreads = Param.Unsigned("SMT Number of Fetching Threads")
+ smtFetchPolicy = Param.String("SMT Fetch policy")
+ smtLSQPolicy = Param.String("SMT LSQ Sharing Policy")
+ smtLSQThreshold = Param.String("SMT LSQ Threshold Sharing Parameter")
+ smtIQPolicy = Param.String("SMT IQ Sharing Policy")
+ smtIQThreshold = Param.String("SMT IQ Threshold Sharing Parameter")
+ smtROBPolicy = Param.String("SMT ROB Sharing Policy")
+ smtROBThreshold = Param.String("SMT ROB Threshold Sharing Parameter")
+ smtCommitPolicy = Param.String("SMT Commit Policy")
+
+ def addPrivateSplitL1Caches(self, ic, dc):
+ BaseCPU.addPrivateSplitL1Caches(self, ic, dc)
+ self.icache.tgts_per_mshr = 20
+ self.dcache.tgts_per_mshr = 20
diff --git a/src/cpu/o3/O3Checker.py b/src/cpu/o3/O3Checker.py
new file mode 100644
index 000000000..43a71d67b
--- /dev/null
+++ b/src/cpu/o3/O3Checker.py
@@ -0,0 +1,43 @@
+# Copyright (c) 2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from m5.params import *
+from m5 import build_env
+from BaseCPU import BaseCPU
+
+class O3Checker(BaseCPU):
+ type = 'O3Checker'
+ exitOnError = Param.Bool(False, "Exit on an error")
+ updateOnError = Param.Bool(False,
+ "Update the checker with the main CPU's state on an error")
+ warnOnlyOnLoadError = Param.Bool(False,
+ "If a load result is incorrect, only print a warning and do not exit")
+ function_trace = Param.Bool(False, "Enable function trace")
+ function_trace_start = Param.Tick(0, "Cycle to start function trace")
+ if build_env['FULL_SYSTEM']:
+ profile = Param.Latency('0ns', "trace the kernel stack")
diff --git a/src/cpu/o3/SConscript b/src/cpu/o3/SConscript
index bb1dfb613..ad61ad228 100755
--- a/src/cpu/o3/SConscript
+++ b/src/cpu/o3/SConscript
@@ -33,6 +33,10 @@ import sys
Import('*')
if 'O3CPU' in env['CPU_MODELS']:
+ SimObject('FUPool.py')
+ SimObject('FuncUnitConfig.py')
+ SimObject('O3CPU.py')
+
Source('base_dyn_inst.cc')
Source('bpred_unit.cc')
Source('commit.cc')
@@ -71,6 +75,7 @@ if 'O3CPU' in env['CPU_MODELS']:
sys.exit('O3 CPU does not support the \'%s\' ISA' % env['TARGET_ISA'])
if env['USE_CHECKER']:
+ SimObject('O3Checker.py')
Source('checker_builder.cc')
if 'O3CPU' in env['CPU_MODELS'] or 'OzoneCPU' in env['CPU_MODELS']:
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 7645a226c..d954bd1e7 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -100,8 +100,8 @@ class DefaultFetch
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); }
+ bool &snoop)
+ { resp.clear(); snoop = true; }
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 3ae7bc402..0fd1e7bac 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -29,6 +29,9 @@
* Korey Sewell
*/
+#include <algorithm>
+#include <cstring>
+
#include "config/use_checker.hh"
#include "arch/isa_traits.hh"
@@ -48,8 +51,6 @@
#include "sim/system.hh"
#endif // FULL_SYSTEM
-#include <algorithm>
-
template<class Impl>
void
DefaultFetch<Impl>::IcachePort::setPeer(Port *port)
@@ -374,7 +375,7 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
return;
}
- memcpy(cacheData[tid], pkt->getPtr<uint8_t *>(), cacheBlkSize);
+ memcpy(cacheData[tid], pkt->getPtr<uint8_t>(), cacheBlkSize);
cacheDataValid[tid] = true;
if (!drainPending) {
@@ -1116,7 +1117,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
(&cacheData[tid][offset]));
predecoder.setTC(cpu->thread[tid]->getTC());
- predecoder.moreBytes(fetch_PC, 0, inst);
+ predecoder.moreBytes(fetch_PC, fetch_PC, 0, inst);
ext_inst = predecoder.getExtMachInst();
staticInst = StaticInstPtr(ext_inst);
@@ -1153,10 +1154,14 @@ DefaultFetch<Impl>::fetch(bool &status_change)
DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n",
tid, instruction->staticInst->disassemble(fetch_PC));
+#if TRACING_ON
instruction->traceData =
Trace::getInstRecord(curTick, cpu->tcBase(tid),
instruction->staticInst,
instruction->readPC());
+#else
+ instruction->traceData = NULL;
+#endif
///FIXME This needs to be more robust in dealing with delay slots
predicted_branch |=
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index fd8f878a7..06de608e0 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -316,8 +316,8 @@ class LSQ {
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); }
+ bool &snoop)
+ { resp.clear(); snoop = true; }
/** Timing version of receive. Handles writing back and
* completing the load or store that has returned from
diff --git a/src/cpu/op_class.cc b/src/cpu/op_class.cc
index f7ef49c0f..02cb4a08a 100644
--- a/src/cpu/op_class.cc
+++ b/src/cpu/op_class.cc
@@ -34,7 +34,7 @@
const char *
opClassStrings[Num_OpClasses] =
{
- "(null)",
+ "No_OpClass",
"IntAlu",
"IntMult",
"IntDiv",
diff --git a/src/cpu/ozone/OzoneCPU.py b/src/cpu/ozone/OzoneCPU.py
new file mode 100644
index 000000000..b9cfb448f
--- /dev/null
+++ b/src/cpu/ozone/OzoneCPU.py
@@ -0,0 +1,127 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Kevin Lim
+
+from m5.params import *
+from m5 import build_env
+from BaseCPU import BaseCPU
+
+if build_env['USE_CHECKER']:
+ from OzoneChecker import OzoneChecker
+
+class DerivOzoneCPU(BaseCPU):
+ type = 'DerivOzoneCPU'
+
+ numThreads = Param.Unsigned("number of HW thread contexts")
+
+ if build_env['USE_CHECKER']:
+ checker = Param.BaseCPU("Checker CPU")
+ if build_env['FULL_SYSTEM']:
+ profile = Param.Latency('0ns', "trace the kernel stack")
+
+ icache_port = Port("Instruction Port")
+ dcache_port = Port("Data Port")
+
+ width = Param.Unsigned("Width")
+ frontEndWidth = Param.Unsigned("Front end width")
+ frontEndLatency = Param.Unsigned("Front end latency")
+ backEndWidth = Param.Unsigned("Back end width")
+ backEndSquashLatency = Param.Unsigned("Back end squash latency")
+ backEndLatency = Param.Unsigned("Back end latency")
+ maxInstBufferSize = Param.Unsigned("Maximum instruction buffer size")
+ maxOutstandingMemOps = Param.Unsigned("Maximum number of outstanding memory operations")
+ decodeToFetchDelay = Param.Unsigned("Decode to fetch delay")
+ renameToFetchDelay = Param.Unsigned("Rename to fetch delay")
+ iewToFetchDelay = Param.Unsigned("Issue/Execute/Writeback to fetch "
+ "delay")
+ commitToFetchDelay = Param.Unsigned("Commit to fetch delay")
+ fetchWidth = Param.Unsigned("Fetch width")
+
+ renameToDecodeDelay = Param.Unsigned("Rename to decode delay")
+ iewToDecodeDelay = Param.Unsigned("Issue/Execute/Writeback to decode "
+ "delay")
+ commitToDecodeDelay = Param.Unsigned("Commit to decode delay")
+ fetchToDecodeDelay = Param.Unsigned("Fetch to decode delay")
+ decodeWidth = Param.Unsigned("Decode width")
+
+ iewToRenameDelay = Param.Unsigned("Issue/Execute/Writeback to rename "
+ "delay")
+ commitToRenameDelay = Param.Unsigned("Commit to rename delay")
+ decodeToRenameDelay = Param.Unsigned("Decode to rename delay")
+ renameWidth = Param.Unsigned("Rename width")
+
+ commitToIEWDelay = Param.Unsigned("Commit to "
+ "Issue/Execute/Writeback delay")
+ renameToIEWDelay = Param.Unsigned("Rename to "
+ "Issue/Execute/Writeback delay")
+ issueToExecuteDelay = Param.Unsigned("Issue to execute delay (internal "
+ "to the IEW stage)")
+ issueWidth = Param.Unsigned("Issue width")
+ executeWidth = Param.Unsigned("Execute width")
+ executeIntWidth = Param.Unsigned("Integer execute width")
+ executeFloatWidth = Param.Unsigned("Floating point execute width")
+ executeBranchWidth = Param.Unsigned("Branch execute width")
+ executeMemoryWidth = Param.Unsigned("Memory execute width")
+
+ iewToCommitDelay = Param.Unsigned("Issue/Execute/Writeback to commit "
+ "delay")
+ renameToROBDelay = Param.Unsigned("Rename to reorder buffer delay")
+ commitWidth = Param.Unsigned("Commit width")
+ squashWidth = Param.Unsigned("Squash width")
+
+ predType = Param.String("Type of branch predictor ('local', 'tournament')")
+ localPredictorSize = Param.Unsigned("Size of local predictor")
+ localCtrBits = Param.Unsigned("Bits per counter")
+ localHistoryTableSize = Param.Unsigned("Size of local history table")
+ localHistoryBits = Param.Unsigned("Bits for the local history")
+ globalPredictorSize = Param.Unsigned("Size of global predictor")
+ globalCtrBits = Param.Unsigned("Bits per counter")
+ globalHistoryBits = Param.Unsigned("Bits of history")
+ choicePredictorSize = Param.Unsigned("Size of choice predictor")
+ choiceCtrBits = Param.Unsigned("Bits of choice counters")
+
+ BTBEntries = Param.Unsigned("Number of BTB entries")
+ BTBTagSize = Param.Unsigned("Size of the BTB tags, in bits")
+
+ RASSize = Param.Unsigned("RAS size")
+
+ LQEntries = Param.Unsigned("Number of load queue entries")
+ SQEntries = Param.Unsigned("Number of store queue entries")
+ lsqLimits = Param.Bool(True, "LSQ size limits dispatch")
+ LFSTSize = Param.Unsigned("Last fetched store table size")
+ SSITSize = Param.Unsigned("Store set ID table size")
+
+ numPhysIntRegs = Param.Unsigned("Number of physical integer registers")
+ numPhysFloatRegs = Param.Unsigned("Number of physical floating point "
+ "registers")
+ numIQEntries = Param.Unsigned("Number of instruction queue entries")
+ numROBEntries = Param.Unsigned("Number of reorder buffer entries")
+
+ instShiftAmt = Param.Unsigned("Number of bits to shift instructions by")
+
+ function_trace = Param.Bool(False, "Enable function trace")
+ function_trace_start = Param.Tick(0, "Cycle to start function trace")
diff --git a/src/cpu/ozone/OzoneChecker.py b/src/cpu/ozone/OzoneChecker.py
new file mode 100644
index 000000000..f20b8770e
--- /dev/null
+++ b/src/cpu/ozone/OzoneChecker.py
@@ -0,0 +1,43 @@
+# Copyright (c) 2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from m5.params import *
+from m5 import build_env
+from BaseCPU import BaseCPU
+
+class OzoneChecker(BaseCPU):
+ type = 'OzoneChecker'
+ exitOnError = Param.Bool(False, "Exit on an error")
+ updateOnError = Param.Bool(False,
+ "Update the checker with the main CPU's state on an error")
+ warnOnlyOnLoadError = Param.Bool(False,
+ "If a load result is incorrect, only print a warning and do not exit")
+ function_trace = Param.Bool(False, "Enable function trace")
+ function_trace_start = Param.Tick(0, "Cycle to start function trace")
+ if build_env['FULL_SYSTEM']:
+ profile = Param.Latency('0ns', "trace the kernel stack")
diff --git a/src/cpu/ozone/SConscript b/src/cpu/ozone/SConscript
index 4a040684a..cb2006456 100644
--- a/src/cpu/ozone/SConscript
+++ b/src/cpu/ozone/SConscript
@@ -31,6 +31,9 @@
Import('*')
if 'OzoneCPU' in env['CPU_MODELS']:
+ SimObject('OzoneCPU.py')
+ SimObject('SimpleOzoneCPU.py')
+
need_bp_unit = True
Source('base_dyn_inst.cc')
Source('bpred_unit.cc')
@@ -42,4 +45,5 @@ if 'OzoneCPU' in env['CPU_MODELS']:
Source('lw_lsq.cc')
Source('rename_table.cc')
if env['USE_CHECKER']:
+ SimObject('OzoneChecker.py')
Source('checker_builder.cc')
diff --git a/src/cpu/ozone/SimpleOzoneCPU.py b/src/cpu/ozone/SimpleOzoneCPU.py
new file mode 100644
index 000000000..93603092b
--- /dev/null
+++ b/src/cpu/ozone/SimpleOzoneCPU.py
@@ -0,0 +1,115 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Kevin Lim
+
+from m5.params import *
+from m5 import build_env
+from BaseCPU import BaseCPU
+
+class SimpleOzoneCPU(BaseCPU):
+ type = 'SimpleOzoneCPU'
+
+ numThreads = Param.Unsigned("number of HW thread contexts")
+
+ if not build_env['FULL_SYSTEM']:
+ mem = Param.FunctionalMemory(NULL, "memory")
+
+ width = Param.Unsigned("Width")
+ frontEndWidth = Param.Unsigned("Front end width")
+ backEndWidth = Param.Unsigned("Back end width")
+ backEndSquashLatency = Param.Unsigned("Back end squash latency")
+ backEndLatency = Param.Unsigned("Back end latency")
+ maxInstBufferSize = Param.Unsigned("Maximum instruction buffer size")
+ decodeToFetchDelay = Param.Unsigned("Decode to fetch delay")
+ renameToFetchDelay = Param.Unsigned("Rename to fetch delay")
+ iewToFetchDelay = Param.Unsigned("Issue/Execute/Writeback to fetch "
+ "delay")
+ commitToFetchDelay = Param.Unsigned("Commit to fetch delay")
+ fetchWidth = Param.Unsigned("Fetch width")
+
+ renameToDecodeDelay = Param.Unsigned("Rename to decode delay")
+ iewToDecodeDelay = Param.Unsigned("Issue/Execute/Writeback to decode "
+ "delay")
+ commitToDecodeDelay = Param.Unsigned("Commit to decode delay")
+ fetchToDecodeDelay = Param.Unsigned("Fetch to decode delay")
+ decodeWidth = Param.Unsigned("Decode width")
+
+ iewToRenameDelay = Param.Unsigned("Issue/Execute/Writeback to rename "
+ "delay")
+ commitToRenameDelay = Param.Unsigned("Commit to rename delay")
+ decodeToRenameDelay = Param.Unsigned("Decode to rename delay")
+ renameWidth = Param.Unsigned("Rename width")
+
+ commitToIEWDelay = Param.Unsigned("Commit to "
+ "Issue/Execute/Writeback delay")
+ renameToIEWDelay = Param.Unsigned("Rename to "
+ "Issue/Execute/Writeback delay")
+ issueToExecuteDelay = Param.Unsigned("Issue to execute delay (internal "
+ "to the IEW stage)")
+ issueWidth = Param.Unsigned("Issue width")
+ executeWidth = Param.Unsigned("Execute width")
+ executeIntWidth = Param.Unsigned("Integer execute width")
+ executeFloatWidth = Param.Unsigned("Floating point execute width")
+ executeBranchWidth = Param.Unsigned("Branch execute width")
+ executeMemoryWidth = Param.Unsigned("Memory execute width")
+
+ iewToCommitDelay = Param.Unsigned("Issue/Execute/Writeback to commit "
+ "delay")
+ renameToROBDelay = Param.Unsigned("Rename to reorder buffer delay")
+ commitWidth = Param.Unsigned("Commit width")
+ squashWidth = Param.Unsigned("Squash width")
+
+ localPredictorSize = Param.Unsigned("Size of local predictor")
+ localCtrBits = Param.Unsigned("Bits per counter")
+ localHistoryTableSize = Param.Unsigned("Size of local history table")
+ localHistoryBits = Param.Unsigned("Bits for the local history")
+ globalPredictorSize = Param.Unsigned("Size of global predictor")
+ globalCtrBits = Param.Unsigned("Bits per counter")
+ globalHistoryBits = Param.Unsigned("Bits of history")
+ choicePredictorSize = Param.Unsigned("Size of choice predictor")
+ choiceCtrBits = Param.Unsigned("Bits of choice counters")
+
+ BTBEntries = Param.Unsigned("Number of BTB entries")
+ BTBTagSize = Param.Unsigned("Size of the BTB tags, in bits")
+
+ RASSize = Param.Unsigned("RAS size")
+
+ LQEntries = Param.Unsigned("Number of load queue entries")
+ SQEntries = Param.Unsigned("Number of store queue entries")
+ LFSTSize = Param.Unsigned("Last fetched store table size")
+ SSITSize = Param.Unsigned("Store set ID table size")
+
+ numPhysIntRegs = Param.Unsigned("Number of physical integer registers")
+ numPhysFloatRegs = Param.Unsigned("Number of physical floating point "
+ "registers")
+ numIQEntries = Param.Unsigned("Number of instruction queue entries")
+ numROBEntries = Param.Unsigned("Number of reorder buffer entries")
+
+ instShiftAmt = Param.Unsigned("Number of bits to shift instructions by")
+
+ function_trace = Param.Bool(False, "Enable function trace")
+ function_trace_start = Param.Tick(0, "Cycle to start function trace")
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index d78162243..d1214223b 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -53,7 +53,6 @@
#include "arch/vtophys.hh"
#include "base/callback.hh"
#include "cpu/profile.hh"
-#include "mem/physical.hh"
#include "sim/faults.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh
index 0acf99ead..667392c06 100644
--- a/src/cpu/ozone/front_end.hh
+++ b/src/cpu/ozone/front_end.hh
@@ -91,8 +91,8 @@ class FrontEnd
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); }
+ bool &snoop)
+ { resp.clear(); snoop = true; }
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh
index c981b8e63..2048ad6bb 100644
--- a/src/cpu/ozone/lw_lsq.hh
+++ b/src/cpu/ozone/lw_lsq.hh
@@ -257,8 +257,8 @@ class OzoneLWLSQ {
virtual void recvStatusChange(Status status);
virtual void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); }
+ bool &snoop)
+ { resp.clear(); snoop = true; }
virtual bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py
new file mode 100644
index 000000000..e97f059c1
--- /dev/null
+++ b/src/cpu/simple/AtomicSimpleCPU.py
@@ -0,0 +1,43 @@
+# Copyright (c) 2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from m5.params import *
+from m5 import build_env
+from BaseCPU import BaseCPU
+
+class AtomicSimpleCPU(BaseCPU):
+ type = 'AtomicSimpleCPU'
+ width = Param.Int(1, "CPU width")
+ simulate_stalls = Param.Bool(False, "Simulate cache stall cycles")
+ function_trace = Param.Bool(False, "Enable function trace")
+ function_trace_start = Param.Tick(0, "Cycle to start function trace")
+ if build_env['FULL_SYSTEM']:
+ profile = Param.Latency('0ns', "trace the kernel stack")
+ icache_port = Port("Instruction Port")
+ dcache_port = Port("Data Port")
+ _mem_ports = ['icache_port', 'dcache_port']
diff --git a/src/cpu/simple/SConscript b/src/cpu/simple/SConscript
index 9a6a80473..ccccab2b5 100644
--- a/src/cpu/simple/SConscript
+++ b/src/cpu/simple/SConscript
@@ -33,10 +33,12 @@ Import('*')
need_simple_base = False
if 'AtomicSimpleCPU' in env['CPU_MODELS']:
need_simple_base = True
+ SimObject('AtomicSimpleCPU.py')
Source('atomic.cc')
if 'TimingSimpleCPU' in env['CPU_MODELS']:
need_simple_base = True
+ SimObject('TimingSimpleCPU.py')
Source('timing.cc')
if need_simple_base:
diff --git a/src/cpu/simple/TimingSimpleCPU.py b/src/cpu/simple/TimingSimpleCPU.py
new file mode 100644
index 000000000..2fcde175c
--- /dev/null
+++ b/src/cpu/simple/TimingSimpleCPU.py
@@ -0,0 +1,41 @@
+# Copyright (c) 2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from m5.params import *
+from m5 import build_env
+from BaseCPU import BaseCPU
+
+class TimingSimpleCPU(BaseCPU):
+ type = 'TimingSimpleCPU'
+ function_trace = Param.Bool(False, "Enable function trace")
+ function_trace_start = Param.Tick(0, "Cycle to start function trace")
+ if build_env['FULL_SYSTEM']:
+ profile = Param.Latency('0ns', "trace the kernel stack")
+ icache_port = Port("Instruction Port")
+ dcache_port = Port("Data Port")
+ _mem_ports = ['icache_port', 'dcache_port']
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index b0a01c3a3..ea1c7d87f 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -540,8 +540,8 @@ AtomicSimpleCPU::tick()
}
// @todo remove me after debugging with legion done
- if (curStaticInst && (!curStaticInst->isMicroOp() ||
- curStaticInst->isFirstMicroOp()))
+ if (curStaticInst && (!curStaticInst->isMicroop() ||
+ curStaticInst->isFirstMicroop()))
instCnt++;
if (simulate_stalls) {
@@ -557,7 +557,7 @@ AtomicSimpleCPU::tick()
}
}
- if(predecoder.needMoreBytes() || fault != NoFault)
+ if(fault != NoFault || !stayAtPC)
advancePC(fault);
}
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index ad4aa4708..b127e3791 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -104,8 +104,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
virtual void recvRetry();
virtual void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); }
+ bool &snoop)
+ { resp.clear(); snoop = true; }
};
CpuPort icachePort;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 4fed2059b..b7f60522f 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -70,7 +70,7 @@ using namespace std;
using namespace TheISA;
BaseSimpleCPU::BaseSimpleCPU(Params *p)
- : BaseCPU(p), thread(NULL), predecoder(NULL)
+ : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
{
#if FULL_SYSTEM
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
@@ -91,6 +91,9 @@ BaseSimpleCPU::BaseSimpleCPU(Params *p)
lastDcacheStall = 0;
threadContexts.push_back(tc);
+
+ fetchOffset = 0;
+ stayAtPC = false;
}
BaseSimpleCPU::~BaseSimpleCPU()
@@ -326,18 +329,19 @@ BaseSimpleCPU::checkForInterrupts()
Fault
BaseSimpleCPU::setupFetchRequest(Request *req)
{
+ Addr threadPC = thread->readPC();
+
// set up memory request for instruction fetch
#if ISA_HAS_DELAY_SLOT
- DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(),
+ DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC,
thread->readNextPC(),thread->readNextNPC());
#else
- DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",thread->readPC(),
+ DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p\n",threadPC,
thread->readNextPC());
#endif
- req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst),
- (FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0,
- thread->readPC());
+ Addr fetchPC = (threadPC & PCMask) + fetchOffset;
+ req->setVirt(0, fetchPC, sizeof(MachInst), 0, threadPC);
Fault fault = thread->translateInstReq(req);
@@ -365,8 +369,10 @@ BaseSimpleCPU::preExecute()
// decode the instruction
inst = gtoh(inst);
+
//If we're not in the middle of a macro instruction
if (!curMacroStaticInst) {
+
StaticInstPtr instPtr = NULL;
//Predecode, ie bundle up an ExtMachInst
@@ -374,36 +380,50 @@ BaseSimpleCPU::preExecute()
predecoder.setTC(thread->getTC());
//If more fetch data is needed, pass it in.
if(predecoder.needMoreBytes())
- predecoder.moreBytes(thread->readPC(), 0, inst);
+ predecoder.moreBytes(thread->readPC(),
+ (thread->readPC() & PCMask) + fetchOffset, 0, inst);
else
predecoder.process();
- //If an instruction is ready, decode it
- if (predecoder.extMachInstReady())
- instPtr = StaticInst::decode(predecoder.getExtMachInst());
+
+ //If an instruction is ready, decode it. Otherwise, we'll have to
+ //fetch beyond the MachInst at the current pc.
+ if (predecoder.extMachInstReady()) {
+#if THE_ISA == X86_ISA
+ thread->setNextPC(thread->readPC() + predecoder.getInstSize());
+#endif // X86_ISA
+ stayAtPC = false;
+ instPtr = StaticInst::decode(predecoder.getExtMachInst(),
+ thread->readPC());
+ } else {
+ stayAtPC = true;
+ fetchOffset += sizeof(MachInst);
+ }
//If we decoded an instruction and it's microcoded, start pulling
//out micro ops
- if (instPtr && instPtr->isMacroOp()) {
+ if (instPtr && instPtr->isMacroop()) {
curMacroStaticInst = instPtr;
curStaticInst = curMacroStaticInst->
- fetchMicroOp(thread->readMicroPC());
+ fetchMicroop(thread->readMicroPC());
} else {
curStaticInst = instPtr;
}
} else {
//Read the next micro op from the macro op
curStaticInst = curMacroStaticInst->
- fetchMicroOp(thread->readMicroPC());
+ fetchMicroop(thread->readMicroPC());
}
//If we decoded an instruction this "tick", record information about it.
if(curStaticInst)
{
+#if TRACING_ON
traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
thread->readPC());
DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
curStaticInst->getName(), curStaticInst->machInst);
+#endif // TRACING_ON
#if FULL_SYSTEM
thread->setInst(inst);
@@ -418,7 +438,7 @@ BaseSimpleCPU::postExecute()
if (thread->profile) {
bool usermode = TheISA::inUserMode(tc);
thread->profilePC = usermode ? 1 : thread->readPC();
- StaticInstPtr si(inst);
+ StaticInstPtr si(inst, thread->readPC());
ProfileNode *node = thread->profile->consume(tc, si);
if (node)
thread->profileNode = node;
@@ -447,14 +467,16 @@ BaseSimpleCPU::postExecute()
void
BaseSimpleCPU::advancePC(Fault fault)
{
+ //Since we're moving to a new pc, zero out the offset
+ fetchOffset = 0;
if (fault != NoFault) {
curMacroStaticInst = StaticInst::nullStaticInstPtr;
fault->invoke(tc);
thread->setMicroPC(0);
thread->setNextMicroPC(1);
- } else if (predecoder.needMoreBytes()) {
+ } else {
//If we're at the last micro op for this instruction
- if (curStaticInst && curStaticInst->isLastMicroOp()) {
+ if (curStaticInst && curStaticInst->isLastMicroop()) {
//We should be working with a macro op
assert(curMacroStaticInst);
//Close out this macro op, and clean up the
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index 787259c96..d221baca8 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -137,6 +137,12 @@ class BaseSimpleCPU : public BaseCPU
StaticInstPtr curStaticInst;
StaticInstPtr curMacroStaticInst;
+ //This is the offset from the current pc that fetch should be performed at
+ Addr fetchOffset;
+ //This flag says to stay at the current pc. This is useful for
+ //instructions which go beyond MachInst boundaries.
+ bool stayAtPC;
+
void checkForInterrupts();
Fault setupFetchRequest(Request *req);
void preExecute();
@@ -160,6 +166,9 @@ class BaseSimpleCPU : public BaseCPU
return numInst - startNumInst;
}
+ // Mask to align PCs to MachInst sized boundaries
+ static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1);
+
// number of simulated memory references
Stats::Scalar<> numMemRefs;
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index fa7bb4f86..7698a588d 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -168,9 +168,7 @@ TimingSimpleCPU::resume()
delete fetchEvent;
}
- fetchEvent =
- new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false);
- fetchEvent->schedule(nextCycle());
+ fetchEvent = new FetchEvent(this, nextCycle());
}
changeState(SimObject::Running);
@@ -224,9 +222,7 @@ TimingSimpleCPU::activateContext(int thread_num, int delay)
_status = Running;
// kick things off by initiating the fetch of the next instruction
- fetchEvent =
- new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false);
- fetchEvent->schedule(nextCycle(curTick + cycles(delay)));
+ fetchEvent = new FetchEvent(this, nextCycle(curTick + cycles(delay)));
}
@@ -564,8 +560,7 @@ TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
{
if (pkt->isResponse()) {
// delay processing of returned data until next CPU clock edge
- Tick mem_time = pkt->req->getTime();
- Tick next_tick = cpu->nextCycle(mem_time);
+ Tick next_tick = cpu->nextCycle(curTick);
if (next_tick == curTick)
cpu->completeIfetch(pkt);
@@ -659,8 +654,7 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{
if (pkt->isResponse()) {
// delay processing of returned data until next CPU clock edge
- Tick mem_time = pkt->req->getTime();
- Tick next_tick = cpu->nextCycle(mem_time);
+ Tick next_tick = cpu->nextCycle(curTick);
if (next_tick == curTick)
cpu->completeDataAccess(pkt);
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index ef062d24a..39958bfb6 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -66,8 +66,6 @@ class TimingSimpleCPU : public BaseSimpleCPU
Event *drainEvent;
- Event *fetchEvent;
-
private:
class CpuPort : public Port
@@ -93,8 +91,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
virtual void recvStatusChange(Status status);
virtual void getDeviceAddressRanges(AddrRangeList &resp,
- AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); }
+ bool &snoop)
+ { resp.clear(); snoop = false; }
struct TickEvent : public Event
{
@@ -199,7 +197,12 @@ class TimingSimpleCPU : public BaseSimpleCPU
void completeIfetch(PacketPtr );
void completeDataAccess(PacketPtr );
void advanceInst(Fault fault);
+
private:
+
+ typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> FetchEvent;
+ FetchEvent *fetchEvent;
+
void completeDrain();
};
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 824914ad0..95848ee2c 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -38,7 +38,6 @@
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
-#include "mem/physical.hh"
#include "mem/request.hh"
#include "sim/byteswap.hh"
#include "sim/eventq.hh"
diff --git a/src/cpu/static_inst.cc b/src/cpu/static_inst.cc
index 64fcc0580..52a7ede03 100644
--- a/src/cpu/static_inst.cc
+++ b/src/cpu/static_inst.cc
@@ -37,6 +37,8 @@ StaticInstPtr StaticInst::nullStaticInstPtr;
// Define the decode cache hash map.
StaticInst::DecodeCache StaticInst::decodeCache;
+StaticInst::AddrDecodeCache StaticInst::addrDecodeCache;
+StaticInst::cacheElement StaticInst::recentDecodes[2];
void
StaticInst::dumpDecodeCacheStats()
@@ -76,9 +78,9 @@ StaticInst::hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const
}
StaticInstPtr
-StaticInst::fetchMicroOp(MicroPC micropc)
+StaticInst::fetchMicroop(MicroPC micropc)
{
- panic("StaticInst::fetchMicroOp() called on instruction "
+ panic("StaticInst::fetchMicroop() called on instruction "
"that is not microcoded.");
}
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index a58ac85d6..b0a19c151 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -63,6 +63,7 @@ class AtomicSimpleCPU;
class TimingSimpleCPU;
class InorderCPU;
class SymbolTable;
+class AddrDecodePage;
namespace Trace {
class InstRecord;
@@ -143,11 +144,11 @@ class StaticInstBase : public RefCounted
IsUnverifiable, ///< Can't be verified by a checker
//Flags for microcode
- IsMacroOp, ///< Is a macroop containing microops
- IsMicroOp, ///< Is a microop
+ IsMacroop, ///< Is a macroop containing microops
+ IsMicroop, ///< Is a microop
IsDelayedCommit, ///< This microop doesn't commit right away
- IsLastMicroOp, ///< This microop ends a microop sequence
- IsFirstMicroOp, ///< This microop begins a microop sequence
+ IsLastMicroop, ///< This microop ends a microop sequence
+ IsFirstMicroop, ///< This microop begins a microop sequence
//This flag doesn't do anything yet
IsMicroBranch, ///< This microop branches within the microcode for a macroop
@@ -242,11 +243,11 @@ class StaticInstBase : public RefCounted
bool isQuiesce() const { return flags[IsQuiesce]; }
bool isIprAccess() const { return flags[IsIprAccess]; }
bool isUnverifiable() const { return flags[IsUnverifiable]; }
- bool isMacroOp() const { return flags[IsMacroOp]; }
- bool isMicroOp() const { return flags[IsMicroOp]; }
+ bool isMacroop() const { return flags[IsMacroop]; }
+ bool isMicroop() const { return flags[IsMicroop]; }
bool isDelayedCommit() const { return flags[IsDelayedCommit]; }
- bool isLastMicroOp() const { return flags[IsLastMicroOp]; }
- bool isFirstMicroOp() const { return flags[IsFirstMicroOp]; }
+ bool isLastMicroop() const { return flags[IsLastMicroop]; }
+ bool isFirstMicroop() const { return flags[IsFirstMicroop]; }
//This flag doesn't do anything yet
bool isMicroBranch() const { return flags[IsMicroBranch]; }
//@}
@@ -349,6 +350,7 @@ class StaticInst : public StaticInstBase
: StaticInstBase(__opClass),
machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
{
+ memset(&recentDecodes, 0, 2 * sizeof(cacheElement));
}
public:
@@ -369,7 +371,7 @@ class StaticInst : public StaticInstBase
* Return the microop that goes with a particular micropc. This should
* only be defined/used in macroops which will contain microops
*/
- virtual StaticInstPtr fetchMicroOp(MicroPC micropc);
+ virtual StaticInstPtr fetchMicroop(MicroPC micropc);
/**
* Return the target address for a PC-relative branch.
@@ -437,11 +439,52 @@ class StaticInst : public StaticInstBase
/// Decode a machine instruction.
/// @param mach_inst The binary instruction to decode.
/// @retval A pointer to the corresponding StaticInst object.
- //This is defined as inline below.
- static StaticInstPtr decode(ExtMachInst mach_inst);
+ //This is defined as inlined below.
+ static StaticInstPtr decode(ExtMachInst mach_inst, Addr addr);
/// Return name of machine instruction
std::string getName() { return mnemonic; }
+
+ /// Decoded instruction cache type, for address decoding.
+ /// A generic hash_map is used.
+ typedef m5::hash_map<Addr, AddrDecodePage *> AddrDecodeCache;
+
+ /// A cache of decoded instruction objects from addresses.
+ static AddrDecodeCache addrDecodeCache;
+
+ struct cacheElement {
+ Addr page_addr;
+ AddrDecodePage *decodePage;
+ } ;
+
+ /// An array of recently decoded instructions.
+ // might not use an array if there is only two elements
+ static struct cacheElement recentDecodes[2];
+
+ /// Updates the recently decoded instructions entries
+ /// @param page_addr The page address recently used.
+ /// @param decodePage Pointer to decoding page containing the decoded
+ /// instruction.
+ static inline void
+ updateCache(Addr page_addr, AddrDecodePage *decodePage)
+ {
+ recentDecodes[1].page_addr = recentDecodes[0].page_addr;
+ recentDecodes[1].decodePage = recentDecodes[0].decodePage;
+ recentDecodes[0].page_addr = page_addr;
+ recentDecodes[0].decodePage = decodePage;
+ }
+
+ /// Searches the decoded instruction cache for instruction decoding.
+ /// If it is not found, then we decode the instruction.
+ /// Otherwise, we get the instruction from the cache and move it into
+ /// the address-to-instruction decoding page.
+ /// @param mach_inst The binary instruction to decode.
+ /// @param addr The address that contained the binary instruction.
+ /// @param decodePage Pointer to decoding page containing the instruction.
+ /// @retval A pointer to the corresponding StaticInst object.
+ //This is defined as inlined below.
+ static StaticInstPtr searchCache(ExtMachInst mach_inst, Addr addr,
+ AddrDecodePage * decodePage);
};
typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
@@ -472,8 +515,8 @@ class StaticInstPtr : public RefCountingPtr<StaticInst>
/// Construct directly from machine instruction.
/// Calls StaticInst::decode().
- explicit StaticInstPtr(TheISA::ExtMachInst mach_inst)
- : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
+ explicit StaticInstPtr(TheISA::ExtMachInst mach_inst, Addr addr)
+ : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst, addr))
{
}
@@ -484,8 +527,55 @@ class StaticInstPtr : public RefCountingPtr<StaticInst>
}
};
+/// A page of a list of decoded instructions from an address.
+class AddrDecodePage
+{
+ typedef TheISA::ExtMachInst ExtMachInst;
+ protected:
+ StaticInstPtr instructions[TheISA::PageBytes];
+ bool valid[TheISA::PageBytes];
+ Addr lowerMask;
+
+ public:
+ /// Constructor
+ AddrDecodePage() {
+ lowerMask = TheISA::PageBytes - 1;
+ memset(valid, 0, TheISA::PageBytes);
+ }
+
+ /// Checks if the instruction is already decoded and the machine
+ /// instruction in the cache matches the current machine instruction
+ /// related to the address
+ /// @param mach_inst The binary instruction to check
+ /// @param addr The address containing the instruction
+ inline bool decoded(ExtMachInst mach_inst, Addr addr)
+ {
+ return (valid[addr & lowerMask] &&
+ (instructions[addr & lowerMask]->machInst == mach_inst));
+ }
+
+ /// Returns the instruction object. decoded should be called first
+ /// to check if the instruction is valid.
+ /// @param addr The address of the instruction.
+ /// @retval A pointer to the corresponding StaticInst object.
+ inline StaticInstPtr getInst(Addr addr)
+ { return instructions[addr & lowerMask]; }
+
+ /// Inserts a pointer to a StaticInst object into the list of decoded
+ /// instructions on the page.
+ /// @param addr The address of the instruction.
+ /// @param si A pointer to the corresponding StaticInst object.
+ inline void insert(Addr addr, StaticInstPtr &si)
+ {
+ instructions[addr & lowerMask] = si;
+ valid[addr & lowerMask] = true;
+ }
+
+};
+
+
inline StaticInstPtr
-StaticInst::decode(StaticInst::ExtMachInst mach_inst)
+StaticInst::decode(StaticInst::ExtMachInst mach_inst, Addr addr)
{
#ifdef DECODE_CACHE_HASH_STATS
// Simple stats on decode hash_map. Turns out the default
@@ -499,12 +589,54 @@ StaticInst::decode(StaticInst::ExtMachInst mach_inst)
}
#endif
+ Addr page_addr = addr & ~(TheISA::PageBytes - 1);
+
+ // checks recently decoded addresses
+ if (recentDecodes[0].decodePage &&
+ page_addr == recentDecodes[0].page_addr) {
+ if (recentDecodes[0].decodePage->decoded(mach_inst, addr))
+ return recentDecodes[0].decodePage->getInst(addr);
+
+ return searchCache(mach_inst, addr, recentDecodes[0].decodePage);
+ }
+
+ if (recentDecodes[1].decodePage &&
+ page_addr == recentDecodes[1].page_addr) {
+ if (recentDecodes[1].decodePage->decoded(mach_inst, addr))
+ return recentDecodes[1].decodePage->getInst(addr);
+
+ return searchCache(mach_inst, addr, recentDecodes[1].decodePage);
+ }
+
+ // searches the page containing the address to decode
+ AddrDecodeCache::iterator iter = addrDecodeCache.find(page_addr);
+ if (iter != addrDecodeCache.end()) {
+ updateCache(page_addr, iter->second);
+ if (iter->second->decoded(mach_inst, addr))
+ return iter->second->getInst(addr);
+
+ return searchCache(mach_inst, addr, iter->second);
+ }
+
+ // creates a new object for a page of decoded instructions
+ AddrDecodePage * decodePage = new AddrDecodePage;
+ addrDecodeCache[page_addr] = decodePage;
+ updateCache(page_addr, decodePage);
+ return searchCache(mach_inst, addr, decodePage);
+}
+
+inline StaticInstPtr
+StaticInst::searchCache(ExtMachInst mach_inst, Addr addr,
+ AddrDecodePage * decodePage)
+{
DecodeCache::iterator iter = decodeCache.find(mach_inst);
if (iter != decodeCache.end()) {
+ decodePage->insert(addr, iter->second);
return iter->second;
}
StaticInstPtr si = TheISA::decodeInst(mach_inst);
+ decodePage->insert(addr, si);
decodeCache[mach_inst] = si;
return si;
}