Changes to get OzoneCPU to compile once more.

The changes largely are fixing up the memory accesses to use ports/Requests/Packets, supporting the splitting off of instantiation of template classes, and handling some of the reorganization that happened.

OzoneCPU is untested for now but at least compiles.  Fixes will be coming shortly.

SConstruct:
    Remove OzoneSimpleCPU from list of CPUs.
src/cpu/SConscript:
    Leave out OzoneSimpleCPU.
src/cpu/ozone/bpred_unit.cc:
    Fixes to get OzoneCPU to compile.
src/cpu/ozone/checker_builder.cc:
src/cpu/ozone/cpu.cc:
src/cpu/ozone/cpu.hh:
src/cpu/ozone/cpu_builder.cc:
src/cpu/ozone/cpu_impl.hh:
src/cpu/ozone/dyn_inst.hh:
src/cpu/ozone/dyn_inst_impl.hh:
src/cpu/ozone/front_end.cc:
src/cpu/ozone/front_end.hh:
src/cpu/ozone/front_end_impl.hh:
src/cpu/ozone/lw_back_end.hh:
src/cpu/ozone/lw_back_end_impl.hh:
src/cpu/ozone/lw_lsq.hh:
src/cpu/ozone/lw_lsq_impl.hh:
src/cpu/ozone/ozone_impl.hh:
src/cpu/ozone/rename_table.cc:
src/cpu/ozone/simple_params.hh:
src/cpu/ozone/thread_state.hh:
    Fixes to get OzoneCPU back to compiling.

--HG--
extra : convert_revision : 90ffb397263bcf9fea3987317272c64f2b20f7e6
This commit is contained in:
Kevin Lim 2006-06-22 23:33:26 -04:00
parent e6c04b1584
commit 17f870f6d8
23 changed files with 1173 additions and 1059 deletions

View file

@ -264,7 +264,7 @@ env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips']
# Define the universe of supported CPU models
env['ALL_CPU_LIST'] = ['AtomicSimpleCPU', 'TimingSimpleCPU',
'FullCPU', 'AlphaO3CPU',
'OzoneSimpleCPU', 'OzoneCPU']
'OzoneCPU']
# Sticky options get saved in the options file so they persist from
# one invocation to the next (unless overridden, in which case the new

View file

@ -161,24 +161,17 @@ if 'AlphaO3CPU' in env['CPU_MODELS']:
if env['USE_CHECKER']:
sources += Split('o3/checker_builder.cc')
if 'OzoneSimpleCPU' in env['CPU_MODELS']:
sources += Split('''
ozone/cpu.cc
ozone/cpu_builder.cc
ozone/dyn_inst.cc
ozone/front_end.cc
ozone/inorder_back_end.cc
ozone/inst_queue.cc
ozone/rename_table.cc
''')
if 'OzoneCPU' in env['CPU_MODELS']:
sources += Split('''
ozone/base_dyn_inst.cc
ozone/bpred_unit.cc
ozone/lsq_unit.cc
ozone/cpu.cc
ozone/cpu_builder.cc
ozone/dyn_inst.cc
ozone/front_end.cc
ozone/lw_back_end.cc
ozone/lw_lsq.cc
ozone/rename_table.cc
''')
if env['USE_CHECKER']:
sources += Split('ozone/checker_builder.cc')

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2006 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
*/
#include "cpu/base_dyn_inst_impl.hh"
#include "cpu/ozone/ozone_impl.hh"
// Explicit instantiation
template class BaseDynInst<OzoneImpl>;
template <>
int
BaseDynInst<OzoneImpl>::instcount = 0;

View file

@ -30,7 +30,7 @@
#include "cpu/o3/bpred_unit_impl.hh"
#include "cpu/ozone/ozone_impl.hh"
#include "cpu/ozone/simple_impl.hh"
//#include "cpu/ozone/simple_impl.hh"
template class BPredUnit<OzoneImpl>;
template class BPredUnit<SimpleImpl>;
//template class BPredUnit<SimpleImpl>;

View file

@ -34,18 +34,20 @@
#include "cpu/inst_seq.hh"
#include "cpu/ozone/dyn_inst.hh"
#include "cpu/ozone/ozone_impl.hh"
#include "mem/base_mem.hh"
#include "sim/builder.hh"
#include "sim/process.hh"
#include "sim/sim_object.hh"
class MemObject;
template
class Checker<RefCountingPtr<OzoneDynInst<OzoneImpl> > >;
/**
* Specific non-templated derived class used for SimObject configuration.
*/
class OzoneChecker : public Checker<RefCountingPtr<OzoneDynInst<OzoneImpl> > >
class OzoneChecker :
public Checker<RefCountingPtr<OzoneDynInst<OzoneImpl> > >
{
public:
OzoneChecker(Params *p)
@ -67,7 +69,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
SimObjectParam<AlphaDTB *> dtb;
SimObjectParam<FunctionalMemory *> mem;
SimObjectParam<System *> system;
Param<int> cpu_id;
Param<Tick> profile;
@ -75,8 +76,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
SimObjectParam<Process *> workload;
#endif // FULL_SYSTEM
Param<int> clock;
SimObjectParam<BaseMem *> icache;
SimObjectParam<BaseMem *> dcache;
Param<bool> defer_registration;
Param<bool> exitOnError;
@ -100,7 +99,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
INIT_PARAM(dtb, "Data TLB"),
INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM(profile, ""),
@ -109,8 +107,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
#endif // FULL_SYSTEM
INIT_PARAM(clock, "clock speed"),
INIT_PARAM(icache, "L1 instruction cache object"),
INIT_PARAM(dcache, "L1 data cache object"),
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(exitOnError, "exit on error"),
@ -144,13 +140,10 @@ CREATE_SIM_OBJECT(OzoneChecker)
temp = max_insts_all_threads;
temp = max_loads_any_thread;
temp = max_loads_all_threads;
BaseMem *cache = icache;
cache = dcache;
#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
params->mem = mem;
params->system = system;
params->cpu_id = cpu_id;
params->profile = profile;

View file

@ -31,7 +31,7 @@
#include "cpu/ozone/cpu_impl.hh"
#include "cpu/ozone/ozone_impl.hh"
#include "cpu/ozone/simple_impl.hh"
//#include "cpu/ozone/simple_impl.hh"
template class OzoneCPU<SimpleImpl>;
//template class OzoneCPU<SimpleImpl>;
template class OzoneCPU<OzoneImpl>;

View file

@ -43,6 +43,7 @@
#include "cpu/ozone/thread_state.hh"
#include "cpu/pc_event.hh"
#include "cpu/static_inst.hh"
#include "mem/page_table.hh"
#include "sim/eventq.hh"
// forward declarations
@ -70,6 +71,7 @@ class Process;
class Checkpoint;
class EndQuiesceEvent;
class MemObject;
class Request;
namespace Trace {
@ -111,7 +113,7 @@ class OzoneCPU : public BaseCPU
void setCpuId(int id);
int readCpuId() { return thread->cpuId; }
int readCpuId() { return thread->readCpuId(); }
#if FULL_SYSTEM
System *getSystemPtr() { return cpu->system; }
@ -122,22 +124,22 @@ class OzoneCPU : public BaseCPU
AlphaDTB * getDTBPtr() { return cpu->dtb; }
Kernel::Statistics *getKernelStats() { return thread->kernelStats; }
Kernel::Statistics *getKernelStats()
{ return thread->getKernelStats(); }
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
VirtualPort *getVirtPort(ThreadContext *tc = NULL)
{ return thread->getVirtPort(tc); }
void delVirtPort(VirtualPort *vp)
{ thread->delVirtPort(vp); }
void delVirtPort(VirtualPort *vp);
#else
TranslatingPort *getMemPort() { return thread->port; }
TranslatingPort *getMemPort() { return thread->getMemPort(); }
Process *getProcessPtr() { return thread->process; }
Process *getProcessPtr() { return thread->getProcessPtr(); }
#endif
Status status() const { return thread->_status; }
Status status() const { return thread->status(); }
void setStatus(Status new_status);
@ -250,7 +252,7 @@ class OzoneCPU : public BaseCPU
{ thread->renameTable[TheISA::ArgumentReg0 + i]->setIntResult(i); }
void setSyscallReturn(SyscallReturn return_value)
{ cpu->setSyscallReturn(return_value, thread->tid); }
{ cpu->setSyscallReturn(return_value, thread->readTid()); }
Counter readFuncExeInst() { return thread->funcExeInst; }
@ -374,6 +376,8 @@ class OzoneCPU : public BaseCPU
PhysicalMemory *physmem;
#endif
MemObject *mem;
FrontEnd *frontEnd;
BackEnd *backEnd;
@ -415,50 +419,41 @@ class OzoneCPU : public BaseCPU
#if FULL_SYSTEM
bool validInstAddr(Addr addr) { return true; }
bool validDataAddr(Addr addr) { return true; }
Fault translateInstReq(Request *req)
/** Translates instruction requestion. */
Fault translateInstReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
{
return itb->translate(req, tc);
return itb->translate(req, thread->getTC());
}
Fault translateDataReadReq(Request *req)
/** Translates data read request. */
Fault translateDataReadReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
{
return dtb->translate(req, tc, false);
return dtb->translate(req, thread->getTC(), false);
}
Fault translateDataWriteReq(Request *req)
/** Translates data write request. */
Fault translateDataWriteReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
{
return dtb->translate(req, tc, true);
return dtb->translate(req, thread->getTC(), true);
}
#else
bool validInstAddr(Addr addr)
{ return true; }
bool validDataAddr(Addr addr)
{ return true; }
int getInstAsid() { return thread.asid; }
int getDataAsid() { return thread.asid; }
/** Translates instruction requestion in syscall emulation mode. */
Fault translateInstReq(Request *req)
Fault translateInstReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
{
return thread.translateInstReq(req);
return thread->getProcessPtr()->pTable->translate(req);
}
/** Translates data read request in syscall emulation mode. */
Fault translateDataReadReq(Request *req)
Fault translateDataReadReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
{
return thread.translateDataReadReq(req);
return thread->getProcessPtr()->pTable->translate(req);
}
/** Translates data write request in syscall emulation mode. */
Fault translateDataWriteReq(Request *req)
Fault translateDataWriteReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
{
return thread.translateDataWriteReq(req);
return thread->getProcessPtr()->pTable->translate(req);
}
#endif
@ -599,14 +594,14 @@ class OzoneCPU : public BaseCPU
#if FULL_SYSTEM
Fault hwrei();
int readIntrFlag() { return thread.regs.intrflag; }
void setIntrFlag(int val) { thread.regs.intrflag = val; }
int readIntrFlag() { return thread.intrflag; }
void setIntrFlag(int val) { thread.intrflag = val; }
bool inPalMode() { return AlphaISA::PcPAL(thread.PC); }
bool inPalMode(Addr pc) { return AlphaISA::PcPAL(pc); }
bool simPalCheck(int palFunc);
void processInterrupts();
#else
void syscall();
void syscall(uint64_t &callnum);
void setSyscallReturn(SyscallReturn return_value, int tid);
#endif

View file

@ -34,9 +34,7 @@
#include "cpu/inst_seq.hh"
#include "cpu/ozone/cpu.hh"
#include "cpu/ozone/ozone_impl.hh"
#include "cpu/ozone/simple_impl.hh"
#include "cpu/ozone/simple_params.hh"
#include "mem/cache/base_cache.hh"
#include "sim/builder.hh"
#include "sim/process.hh"
#include "sim/sim_object.hh"
@ -49,14 +47,6 @@ class DerivOzoneCPU : public OzoneCPU<OzoneImpl>
{ }
};
class SimpleOzoneCPU : public OzoneCPU<SimpleImpl>
{
public:
SimpleOzoneCPU(SimpleParams *p)
: OzoneCPU<SimpleImpl>(p)
{ }
};
////////////////////////////////////////////////////////////////////////
//
@ -78,7 +68,7 @@ SimObjectVectorParam<Process *> workload;
//SimObjectParam<PageTable *> page_table;
#endif // FULL_SYSTEM
SimObjectParam<FunctionalMemory *> mem;
SimObjectParam<MemObject *> mem;
SimObjectParam<BaseCPU *> checker;
@ -87,8 +77,8 @@ Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache;
//SimObjectParam<BaseCache *> icache;
//SimObjectParam<BaseCache *> dcache;
Param<unsigned> cachePorts;
Param<unsigned> width;
@ -215,8 +205,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
"count",
0),
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
// INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
// INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
INIT_PARAM_DFLT(cachePorts, "Cache Ports", 200),
INIT_PARAM_DFLT(width, "Width", 1),
@ -361,8 +351,8 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
//
// Caches
//
params->icacheInterface = icache ? icache->getInterface() : NULL;
params->dcacheInterface = dcache ? dcache->getInterface() : NULL;
// params->icacheInterface = icache ? icache->getInterface() : NULL;
// params->dcacheInterface = dcache ? dcache->getInterface() : NULL;
params->cachePorts = cachePorts;
params->width = width;
@ -459,405 +449,3 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
}
REGISTER_SIM_OBJECT("DerivOzoneCPU", DerivOzoneCPU)
////////////////////////////////////////////////////////////////////////
//
// OzoneCPU Simulation Object
//
BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
Param<int> clock;
Param<int> numThreads;
#if FULL_SYSTEM
SimObjectParam<System *> system;
Param<int> cpu_id;
SimObjectParam<AlphaITB *> itb;
SimObjectParam<AlphaDTB *> dtb;
#else
SimObjectVectorParam<Process *> workload;
//SimObjectParam<PageTable *> page_table;
#endif // FULL_SYSTEM
SimObjectParam<FunctionalMemory *> mem;
SimObjectParam<BaseCPU *> checker;
Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache;
Param<unsigned> cachePorts;
Param<unsigned> width;
Param<unsigned> frontEndWidth;
Param<unsigned> backEndWidth;
Param<unsigned> backEndSquashLatency;
Param<unsigned> backEndLatency;
Param<unsigned> maxInstBufferSize;
Param<unsigned> numPhysicalRegs;
Param<unsigned> decodeToFetchDelay;
Param<unsigned> renameToFetchDelay;
Param<unsigned> iewToFetchDelay;
Param<unsigned> commitToFetchDelay;
Param<unsigned> fetchWidth;
Param<unsigned> renameToDecodeDelay;
Param<unsigned> iewToDecodeDelay;
Param<unsigned> commitToDecodeDelay;
Param<unsigned> fetchToDecodeDelay;
Param<unsigned> decodeWidth;
Param<unsigned> iewToRenameDelay;
Param<unsigned> commitToRenameDelay;
Param<unsigned> decodeToRenameDelay;
Param<unsigned> renameWidth;
Param<unsigned> commitToIEWDelay;
Param<unsigned> renameToIEWDelay;
Param<unsigned> issueToExecuteDelay;
Param<unsigned> issueWidth;
Param<unsigned> executeWidth;
Param<unsigned> executeIntWidth;
Param<unsigned> executeFloatWidth;
Param<unsigned> executeBranchWidth;
Param<unsigned> executeMemoryWidth;
Param<unsigned> iewToCommitDelay;
Param<unsigned> renameToROBDelay;
Param<unsigned> commitWidth;
Param<unsigned> squashWidth;
Param<std::string> predType;
Param<unsigned> localPredictorSize;
Param<unsigned> localCtrBits;
Param<unsigned> localHistoryTableSize;
Param<unsigned> localHistoryBits;
Param<unsigned> globalPredictorSize;
Param<unsigned> globalCtrBits;
Param<unsigned> globalHistoryBits;
Param<unsigned> choicePredictorSize;
Param<unsigned> choiceCtrBits;
Param<unsigned> BTBEntries;
Param<unsigned> BTBTagSize;
Param<unsigned> RASSize;
Param<unsigned> LQEntries;
Param<unsigned> SQEntries;
Param<unsigned> LFSTSize;
Param<unsigned> SSITSize;
Param<unsigned> numPhysIntRegs;
Param<unsigned> numPhysFloatRegs;
Param<unsigned> numIQEntries;
Param<unsigned> numROBEntries;
Param<bool> decoupledFrontEnd;
Param<int> dispatchWidth;
Param<int> wbWidth;
Param<unsigned> smtNumFetchingThreads;
Param<std::string> smtFetchPolicy;
Param<std::string> smtLSQPolicy;
Param<unsigned> smtLSQThreshold;
Param<std::string> smtIQPolicy;
Param<unsigned> smtIQThreshold;
Param<std::string> smtROBPolicy;
Param<unsigned> smtROBThreshold;
Param<std::string> smtCommitPolicy;
Param<unsigned> instShiftAmt;
Param<bool> defer_registration;
Param<bool> function_trace;
Param<Tick> function_trace_start;
END_DECLARE_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
INIT_PARAM(clock, "clock speed"),
INIT_PARAM(numThreads, "number of HW thread contexts"),
#if FULL_SYSTEM
INIT_PARAM(system, "System object"),
INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM(itb, "Instruction translation buffer"),
INIT_PARAM(dtb, "Data translation buffer"),
#else
INIT_PARAM(workload, "Processes to run"),
// INIT_PARAM(page_table, "Page table"),
#endif // FULL_SYSTEM
INIT_PARAM_DFLT(mem, "Memory", NULL),
INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
INIT_PARAM_DFLT(max_insts_any_thread,
"Terminate when any thread reaches this inst count",
0),
INIT_PARAM_DFLT(max_insts_all_threads,
"Terminate when all threads have reached"
"this inst count",
0),
INIT_PARAM_DFLT(max_loads_any_thread,
"Terminate when any thread reaches this load count",
0),
INIT_PARAM_DFLT(max_loads_all_threads,
"Terminate when all threads have reached this load"
"count",
0),
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
INIT_PARAM_DFLT(cachePorts, "Cache Ports", 200),
INIT_PARAM_DFLT(width, "Width", 1),
INIT_PARAM_DFLT(frontEndWidth, "Front end width", 1),
INIT_PARAM_DFLT(backEndWidth, "Back end width", 1),
INIT_PARAM_DFLT(backEndSquashLatency, "Back end squash latency", 1),
INIT_PARAM_DFLT(backEndLatency, "Back end latency", 1),
INIT_PARAM_DFLT(maxInstBufferSize, "Maximum instruction buffer size", 16),
INIT_PARAM(numPhysicalRegs, "Number of physical registers"),
INIT_PARAM(decodeToFetchDelay, "Decode to fetch delay"),
INIT_PARAM(renameToFetchDelay, "Rename to fetch delay"),
INIT_PARAM(iewToFetchDelay, "Issue/Execute/Writeback to fetch"
"delay"),
INIT_PARAM(commitToFetchDelay, "Commit to fetch delay"),
INIT_PARAM(fetchWidth, "Fetch width"),
INIT_PARAM(renameToDecodeDelay, "Rename to decode delay"),
INIT_PARAM(iewToDecodeDelay, "Issue/Execute/Writeback to decode"
"delay"),
INIT_PARAM(commitToDecodeDelay, "Commit to decode delay"),
INIT_PARAM(fetchToDecodeDelay, "Fetch to decode delay"),
INIT_PARAM(decodeWidth, "Decode width"),
INIT_PARAM(iewToRenameDelay, "Issue/Execute/Writeback to rename"
"delay"),
INIT_PARAM(commitToRenameDelay, "Commit to rename delay"),
INIT_PARAM(decodeToRenameDelay, "Decode to rename delay"),
INIT_PARAM(renameWidth, "Rename width"),
INIT_PARAM(commitToIEWDelay, "Commit to "
"Issue/Execute/Writeback delay"),
INIT_PARAM(renameToIEWDelay, "Rename to "
"Issue/Execute/Writeback delay"),
INIT_PARAM(issueToExecuteDelay, "Issue to execute delay (internal"
"to the IEW stage)"),
INIT_PARAM(issueWidth, "Issue width"),
INIT_PARAM(executeWidth, "Execute width"),
INIT_PARAM(executeIntWidth, "Integer execute width"),
INIT_PARAM(executeFloatWidth, "Floating point execute width"),
INIT_PARAM(executeBranchWidth, "Branch execute width"),
INIT_PARAM(executeMemoryWidth, "Memory execute width"),
INIT_PARAM(iewToCommitDelay, "Issue/Execute/Writeback to commit "
"delay"),
INIT_PARAM(renameToROBDelay, "Rename to reorder buffer delay"),
INIT_PARAM(commitWidth, "Commit width"),
INIT_PARAM(squashWidth, "Squash width"),
INIT_PARAM(predType, "Type of branch predictor ('local', 'tournament')"),
INIT_PARAM(localPredictorSize, "Size of local predictor"),
INIT_PARAM(localCtrBits, "Bits per counter"),
INIT_PARAM(localHistoryTableSize, "Size of local history table"),
INIT_PARAM(localHistoryBits, "Bits for the local history"),
INIT_PARAM(globalPredictorSize, "Size of global predictor"),
INIT_PARAM(globalCtrBits, "Bits per counter"),
INIT_PARAM(globalHistoryBits, "Bits of history"),
INIT_PARAM(choicePredictorSize, "Size of choice predictor"),
INIT_PARAM(choiceCtrBits, "Bits of choice counters"),
INIT_PARAM(BTBEntries, "Number of BTB entries"),
INIT_PARAM(BTBTagSize, "Size of the BTB tags, in bits"),
INIT_PARAM(RASSize, "RAS size"),
INIT_PARAM(LQEntries, "Number of load queue entries"),
INIT_PARAM(SQEntries, "Number of store queue entries"),
INIT_PARAM(LFSTSize, "Last fetched store table size"),
INIT_PARAM(SSITSize, "Store set ID table size"),
INIT_PARAM(numPhysIntRegs, "Number of physical integer registers"),
INIT_PARAM(numPhysFloatRegs, "Number of physical floating point "
"registers"),
INIT_PARAM(numIQEntries, "Number of instruction queue entries"),
INIT_PARAM(numROBEntries, "Number of reorder buffer entries"),
INIT_PARAM_DFLT(decoupledFrontEnd, "Decoupled front end", true),
INIT_PARAM_DFLT(dispatchWidth, "Dispatch width", 0),
INIT_PARAM_DFLT(wbWidth, "Writeback width", 0),
INIT_PARAM_DFLT(smtNumFetchingThreads, "SMT Number of Fetching Threads", 1),
INIT_PARAM_DFLT(smtFetchPolicy, "SMT Fetch Policy", "SingleThread"),
INIT_PARAM_DFLT(smtLSQPolicy, "SMT LSQ Sharing Policy", "Partitioned"),
INIT_PARAM_DFLT(smtLSQThreshold,"SMT LSQ Threshold", 100),
INIT_PARAM_DFLT(smtIQPolicy, "SMT IQ Policy", "Partitioned"),
INIT_PARAM_DFLT(smtIQThreshold, "SMT IQ Threshold", 100),
INIT_PARAM_DFLT(smtROBPolicy, "SMT ROB Sharing Policy", "Partitioned"),
INIT_PARAM_DFLT(smtROBThreshold,"SMT ROB Threshold", 100),
INIT_PARAM_DFLT(smtCommitPolicy,"SMT Commit Fetch Policy", "RoundRobin"),
INIT_PARAM(instShiftAmt, "Number of bits to shift instructions by"),
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(function_trace, "Enable function trace"),
INIT_PARAM(function_trace_start, "Cycle to start function trace")
END_INIT_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
CREATE_SIM_OBJECT(SimpleOzoneCPU)
{
SimpleOzoneCPU *cpu;
#if FULL_SYSTEM
// Full-system only supports a single thread for the moment.
int actual_num_threads = 1;
#else
// In non-full-system mode, we infer the number of threads from
// the workload if it's not explicitly specified.
int actual_num_threads =
numThreads.isValid() ? numThreads : workload.size();
if (workload.size() == 0) {
fatal("Must specify at least one workload!");
}
#endif
SimpleParams *params = new SimpleParams;
params->clock = clock;
params->name = getInstanceName();
params->numberOfThreads = actual_num_threads;
#if FULL_SYSTEM
params->system = system;
params->cpu_id = cpu_id;
params->itb = itb;
params->dtb = dtb;
#else
params->workload = workload;
// params->pTable = page_table;
#endif // FULL_SYSTEM
params->mem = mem;
params->checker = checker;
params->max_insts_any_thread = max_insts_any_thread;
params->max_insts_all_threads = max_insts_all_threads;
params->max_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads;
//
// Caches
//
params->icacheInterface = icache ? icache->getInterface() : NULL;
params->dcacheInterface = dcache ? dcache->getInterface() : NULL;
params->cachePorts = cachePorts;
params->width = width;
params->frontEndWidth = frontEndWidth;
params->backEndWidth = backEndWidth;
params->backEndSquashLatency = backEndSquashLatency;
params->backEndLatency = backEndLatency;
params->maxInstBufferSize = maxInstBufferSize;
params->numPhysicalRegs = numPhysIntRegs + numPhysFloatRegs;
params->decodeToFetchDelay = decodeToFetchDelay;
params->renameToFetchDelay = renameToFetchDelay;
params->iewToFetchDelay = iewToFetchDelay;
params->commitToFetchDelay = commitToFetchDelay;
params->fetchWidth = fetchWidth;
params->renameToDecodeDelay = renameToDecodeDelay;
params->iewToDecodeDelay = iewToDecodeDelay;
params->commitToDecodeDelay = commitToDecodeDelay;
params->fetchToDecodeDelay = fetchToDecodeDelay;
params->decodeWidth = decodeWidth;
params->iewToRenameDelay = iewToRenameDelay;
params->commitToRenameDelay = commitToRenameDelay;
params->decodeToRenameDelay = decodeToRenameDelay;
params->renameWidth = renameWidth;
params->commitToIEWDelay = commitToIEWDelay;
params->renameToIEWDelay = renameToIEWDelay;
params->issueToExecuteDelay = issueToExecuteDelay;
params->issueWidth = issueWidth;
params->executeWidth = executeWidth;
params->executeIntWidth = executeIntWidth;
params->executeFloatWidth = executeFloatWidth;
params->executeBranchWidth = executeBranchWidth;
params->executeMemoryWidth = executeMemoryWidth;
params->iewToCommitDelay = iewToCommitDelay;
params->renameToROBDelay = renameToROBDelay;
params->commitWidth = commitWidth;
params->squashWidth = squashWidth;
params->predType = predType;
params->localPredictorSize = localPredictorSize;
params->localCtrBits = localCtrBits;
params->localHistoryTableSize = localHistoryTableSize;
params->localHistoryBits = localHistoryBits;
params->globalPredictorSize = globalPredictorSize;
params->globalCtrBits = globalCtrBits;
params->globalHistoryBits = globalHistoryBits;
params->choicePredictorSize = choicePredictorSize;
params->choiceCtrBits = choiceCtrBits;
params->BTBEntries = BTBEntries;
params->BTBTagSize = BTBTagSize;
params->RASSize = RASSize;
params->LQEntries = LQEntries;
params->SQEntries = SQEntries;
params->SSITSize = SSITSize;
params->LFSTSize = LFSTSize;
params->numPhysIntRegs = numPhysIntRegs;
params->numPhysFloatRegs = numPhysFloatRegs;
params->numIQEntries = numIQEntries;
params->numROBEntries = numROBEntries;
params->decoupledFrontEnd = decoupledFrontEnd;
params->dispatchWidth = dispatchWidth;
params->wbWidth = wbWidth;
params->smtNumFetchingThreads = smtNumFetchingThreads;
params->smtFetchPolicy = smtFetchPolicy;
params->smtIQPolicy = smtIQPolicy;
params->smtLSQPolicy = smtLSQPolicy;
params->smtLSQThreshold = smtLSQThreshold;
params->smtROBPolicy = smtROBPolicy;
params->smtROBThreshold = smtROBThreshold;
params->smtCommitPolicy = smtCommitPolicy;
params->instShiftAmt = 2;
params->deferRegistration = defer_registration;
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
cpu = new SimpleOzoneCPU(params);
return cpu;
}
REGISTER_SIM_OBJECT("SimpleOzoneCPU", SimpleOzoneCPU)

View file

@ -29,21 +29,17 @@
* Nathan Binkert
*/
//#include <cstdio>
//#include <cstdlib>
#include "config/full_system.hh"
#include "config/use_checker.hh"
#include "arch/isa_traits.hh" // For MachInst
#include "base/trace.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/checker/thread_context.hh"
#include "cpu/thread_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/ozone/cpu.hh"
#include "cpu/quiesce_event.hh"
#include "cpu/static_inst.hh"
//#include "mem/base_mem.hh"
#include "mem/mem_interface.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
@ -56,17 +52,18 @@
//#include "base/remote_gdb.hh"
#include "cpu/profile.hh"
#include "kern/kernel_stats.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
#include "sim/faults.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/system.hh"
#else // !FULL_SYSTEM
#include "mem/functional/functional.hh"
#include "sim/process.hh"
#endif // FULL_SYSTEM
#if USE_CHECKER
#include "cpu/checker/thread_context.hh"
#endif
using namespace TheISA;
template <class Impl>
@ -101,13 +98,12 @@ OzoneCPU<Impl>::TickEvent::description()
template <class Impl>
OzoneCPU<Impl>::OzoneCPU(Params *p)
#if FULL_SYSTEM
: BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width),
mem(p->mem),
: BaseCPU(p), thread(this, 0), tickEvent(this, p->width),
#else
: BaseCPU(p), thread(this, 0, p->workload[0], 0), tickEvent(this, p->width),
mem(p->workload[0]->getMemory()),
: BaseCPU(p), thread(this, 0, p->workload[0], 0, p->mem),
tickEvent(this, p->width),
#endif
comm(5, 5)
mem(p->mem), comm(5, 5)
{
frontEnd = new FrontEnd(p);
backEnd = new BackEnd(p);
@ -115,6 +111,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
_status = Idle;
if (p->checker) {
#if USE_CHECKER
BaseCPU *temp_checker = p->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
checker->setMemory(mem);
@ -123,7 +120,10 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
#endif
checkerTC = new CheckerThreadContext<OzoneTC>(&ozoneTC, checker);
thread.tc = checkerTC;
tc = checkerXC;
tc = checkerTC;
#else
panic("Checker enabled but not compiled in!");
#endif
} else {
checker = NULL;
thread.tc = &ozoneTC;
@ -139,15 +139,13 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
#if FULL_SYSTEM
/***** All thread state stuff *****/
thread.cpu = this;
thread.tid = 0;
thread.mem = p->mem;
thread.setTid(0);
thread.quiesceEvent = new EndQuiesceEvent(tc);
system = p->system;
itb = p->itb;
dtb = p->dtb;
memctrl = p->system->memctrl;
physmem = p->system->physmem;
if (p->profile) {
@ -166,9 +164,6 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
thread.profilePC = 3;
#else
thread.cpu = this;
thread.tid = 0;
thread.process = p->workload[0];
thread.asid = 0;
#endif // !FULL_SYSTEM
numInst = 0;
@ -237,8 +232,11 @@ OzoneCPU<Impl>::signalSwitched()
if (++switchCount == 2) {
backEnd->doSwitchOut();
frontEnd->doSwitchOut();
#if USE_CHECKER
if (checker)
checker->switchOut(sampler);
#endif
_status = SwitchedOut;
if (tickEvent.scheduled())
tickEvent.squash();
@ -291,7 +289,7 @@ OzoneCPU<Impl>::activateContext(int thread_num, int delay)
notIdleFraction++;
scheduleTickEvent(delay);
_status = Running;
thread._status = ThreadContext::Active;
thread.setStatus(ThreadContext::Active);
frontEnd->wakeFromQuiesce();
}
@ -510,7 +508,7 @@ template <class Impl>
Addr
OzoneCPU<Impl>::dbg_vtophys(Addr addr)
{
return vtophys(tcProxy, addr);
return vtophys(tc, addr);
}
#endif // FULL_SYSTEM
@ -526,7 +524,7 @@ OzoneCPU<Impl>::post_interrupt(int int_num, int index)
// thread.activate();
// Hack for now. Otherwise might have to go through the tc, or
// I need to figure out what's the right thing to call.
activateContext(thread.tid, 1);
activateContext(thread.readTid(), 1);
}
}
#endif // FULL_SYSTEM
@ -565,7 +563,7 @@ OzoneCPU<Impl>::squashFromTC()
#if !FULL_SYSTEM
template <class Impl>
void
OzoneCPU<Impl>::syscall()
OzoneCPU<Impl>::syscall(uint64_t &callnum)
{
// Not sure this copy is needed, depending on how the TC proxy is made.
thread.renameTable.copyFrom(backEnd->renameTable);
@ -576,7 +574,7 @@ OzoneCPU<Impl>::syscall()
DPRINTF(OzoneCPU, "FuncExeInst: %i\n", thread.funcExeInst);
thread.process->syscall(yc);
thread.process->syscall(callnum, tc);
thread.funcExeInst--;
@ -690,9 +688,9 @@ OzoneCPU<Impl>::simPalCheck(int palFunc)
switch (palFunc) {
case PAL::halt:
haltContext(thread.tid);
haltContext(thread.readTid());
if (--System::numSystemsRunning == 0)
new SimExitEvent("all cpus halted");
exitSimLoop("all cpus halted");
break;
case PAL::bpt:
@ -718,21 +716,31 @@ void
OzoneCPU<Impl>::OzoneTC::setCpuId(int id)
{
cpu->cpuId = id;
thread->cpuId = id;
thread->setCpuId(id);
}
#if FULL_SYSTEM
template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::delVirtPort(VirtualPort *vp)
{
delete vp->getPeer();
delete vp;
}
#endif
template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::setStatus(Status new_status)
{
thread->_status = new_status;
thread->setStatus(new_status);
}
template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::activate(int delay)
{
cpu->activateContext(thread->tid, delay);
cpu->activateContext(thread->readTid(), delay);
}
/// Set the status to Suspended.
@ -740,7 +748,7 @@ template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::suspend()
{
cpu->suspendContext(thread->tid);
cpu->suspendContext(thread->readTid());
}
/// Set the status to Unallocated.
@ -748,7 +756,7 @@ template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::deallocate()
{
cpu->deallocateContext(thread->tid);
cpu->deallocateContext(thread->readTid());
}
/// Set the status to Halted.
@ -756,7 +764,7 @@ template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::halt()
{
cpu->haltContext(thread->tid);
cpu->haltContext(thread->readTid());
}
#if FULL_SYSTEM
@ -771,7 +779,6 @@ void
OzoneCPU<Impl>::OzoneTC::takeOverFrom(ThreadContext *old_context)
{
// some things should already be set up
assert(getMemPtr() == old_context->getMemPtr());
#if FULL_SYSTEM
assert(getSystemPtr() == old_context->getSystemPtr());
#else
@ -867,7 +874,7 @@ template <class Impl>
int
OzoneCPU<Impl>::OzoneTC::getThreadNum()
{
return thread->tid;
return thread->readTid();
}
// Also somewhat obnoxious. Really only used for the TLB fault.
@ -875,7 +882,7 @@ template <class Impl>
TheISA::MachInst
OzoneCPU<Impl>::OzoneTC::getInst()
{
return thread->inst;
return thread->getInst();
}
template <class Impl>
@ -894,7 +901,7 @@ OzoneCPU<Impl>::OzoneTC::copyArchRegs(ThreadContext *tc)
} else if (i < (TheISA::FP_Base_DepTag + TheISA::NumFloatRegs)) {
int fp_idx = i - TheISA::FP_Base_DepTag;
thread->renameTable[i]->setDoubleResult(
tc->readFloatRegDouble(fp_idx));
tc->readFloatReg(fp_idx, 64));
}
}
@ -904,7 +911,7 @@ OzoneCPU<Impl>::OzoneTC::copyArchRegs(ThreadContext *tc)
// Need to copy the TC values into the current rename table,
// copy the misc regs.
thread->regs.miscRegs.copyMiscRegs(tc);
copyMiscRegs(tc, this);
}
template <class Impl>
@ -922,7 +929,7 @@ OzoneCPU<Impl>::OzoneTC::readIntReg(int reg_idx)
}
template <class Impl>
float
TheISA::FloatReg
OzoneCPU<Impl>::OzoneTC::readFloatReg(int reg_idx, int width)
{
int idx = reg_idx + TheISA::FP_Base_DepTag;
@ -1049,15 +1056,15 @@ template <class Impl>
TheISA::MiscReg
OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
{
return thread->regs.miscRegs.readReg(misc_reg);
return thread->miscRegFile.readReg(misc_reg);
}
template <class Impl>
TheISA::MiscReg
OzoneCPU<Impl>::OzoneTC::readMiscRegWithEffect(int misc_reg, Fault &fault)
{
return thread->regs.miscRegs.readRegWithEffect(misc_reg,
fault, this);
return thread->miscRegFile.readRegWithEffect(misc_reg,
fault, this);
}
template <class Impl>
@ -1065,7 +1072,7 @@ Fault
OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
{
// Needs to setup a squash event unless we're in syscall mode
Fault ret_fault = thread->regs.miscRegs.setReg(misc_reg, val);
Fault ret_fault = thread->miscRegFile.setReg(misc_reg, val);
if (!thread->inSyscall) {
cpu->squashFromTC();
@ -1079,8 +1086,8 @@ Fault
OzoneCPU<Impl>::OzoneTC::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
// Needs to setup a squash event unless we're in syscall mode
Fault ret_fault = thread->regs.miscRegs.setRegWithEffect(misc_reg, val,
this);
Fault ret_fault = thread->miscRegFile.setRegWithEffect(misc_reg, val,
this);
if (!thread->inSyscall) {
cpu->squashFromTC();

View file

@ -34,9 +34,8 @@
#include "arch/isa_traits.hh"
#include "config/full_system.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/ozone/cpu.hh" // MUST include this
#include "cpu/inst_seq.hh"
//#include "cpu/ozone/simple_impl.hh" // Would be nice to not have to include this
#include "cpu/ozone/cpu.hh" // MUST include this
#include "cpu/ozone/ozone_impl.hh"
#include <list>
@ -47,15 +46,17 @@ class OzoneDynInst : public BaseDynInst<Impl>
{
public:
// Typedefs
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::OzoneCPU OzoneCPU;
typedef typename FullCPU::ImplState ImplState;
typedef typename OzoneCPU::ImplState ImplState;
// Typedef for DynInstPtr. This is really just a RefCountingPtr<OoODynInst>.
typedef typename Impl::DynInstPtr DynInstPtr;
typedef TheISA::ExtMachInst ExtMachInst;
typedef TheISA::MachInst MachInst;
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
typedef TheISA::MiscReg MiscReg;
typedef typename std::list<DynInstPtr>::iterator ListIt;
@ -67,10 +68,10 @@ class OzoneDynInst : public BaseDynInst<Impl>
MaxInstDestRegs = TheISA::MaxInstDestRegs
};
OzoneDynInst(FullCPU *cpu);
OzoneDynInst(OzoneCPU *cpu);
OzoneDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC,
InstSeqNum seq_num, FullCPU *cpu);
InstSeqNum seq_num, OzoneCPU *cpu);
OzoneDynInst(StaticInstPtr inst);
@ -131,7 +132,7 @@ class OzoneDynInst : public BaseDynInst<Impl>
Fault initiateAcc();
Fault completeAcc();
Fault completeAcc(Packet *pkt);
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
@ -149,17 +150,30 @@ class OzoneDynInst : public BaseDynInst<Impl>
return srcInsts[idx]->readIntResult();
}
float readFloatRegSingle(const StaticInst *si, int idx)
FloatReg readFloatReg(const StaticInst *si, int idx, int width)
{
switch(width) {
case 32:
return srcInsts[idx]->readFloatResult();
case 64:
return srcInsts[idx]->readDoubleResult();
default:
panic("Width not supported");
return 0;
}
}
FloatReg readFloatReg(const StaticInst *si, int idx)
{
return srcInsts[idx]->readFloatResult();
}
double readFloatRegDouble(const StaticInst *si, int idx)
FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width)
{
return srcInsts[idx]->readDoubleResult();
return srcInsts[idx]->readIntResult();
}
uint64_t readFloatRegInt(const StaticInst *si, int idx)
FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
{
return srcInsts[idx]->readIntResult();
}
@ -172,19 +186,25 @@ class OzoneDynInst : public BaseDynInst<Impl>
BaseDynInst<Impl>::setIntReg(si, idx, val);
}
void setFloatRegSingle(const StaticInst *si, int idx, float val)
void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
{
BaseDynInst<Impl>::setFloatRegSingle(si, idx, val);
BaseDynInst<Impl>::setFloatReg(si, idx, val, width);
}
void setFloatRegDouble(const StaticInst *si, int idx, double val)
void setFloatReg(const StaticInst *si, int idx, FloatReg val)
{
BaseDynInst<Impl>::setFloatRegDouble(si, idx, val);
BaseDynInst<Impl>::setFloatReg(si, idx, val);
}
void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
void setFloatRegBits(const StaticInst *si, int idx,
FloatRegBits val, int width)
{
BaseDynInst<Impl>::setFloatRegInt(si, idx, val);
BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
}
void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val)
{
BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
}
void setIntResult(uint64_t result) { this->instResult.integer = result; }
@ -223,7 +243,7 @@ class OzoneDynInst : public BaseDynInst<Impl>
void trap(Fault fault);
bool simPalCheck(int palFunc);
#else
void syscall();
void syscall(uint64_t &callnum);
#endif
ListIt iqIt;

View file

@ -37,7 +37,7 @@
using namespace TheISA;
template <class Impl>
OzoneDynInst<Impl>::OzoneDynInst(FullCPU *cpu)
OzoneDynInst<Impl>::OzoneDynInst(OzoneCPU *cpu)
: BaseDynInst<Impl>(0, 0, 0, 0, cpu)
{
this->setResultReady();
@ -47,7 +47,7 @@ OzoneDynInst<Impl>::OzoneDynInst(FullCPU *cpu)
template <class Impl>
OzoneDynInst<Impl>::OzoneDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC,
InstSeqNum seq_num, FullCPU *cpu)
InstSeqNum seq_num, OzoneCPU *cpu)
: BaseDynInst<Impl>(inst, PC, Pred_PC, seq_num, cpu)
{
initInstPtrs();
@ -111,19 +111,9 @@ OzoneDynInst<Impl>::initiateAcc()
template <class Impl>
Fault
OzoneDynInst<Impl>::completeAcc()
OzoneDynInst<Impl>::completeAcc(Packet *pkt)
{
if (this->isLoad()) {
this->fault = this->staticInst->completeAcc(this->req->data,
this,
this->traceData);
} else if (this->isStore()) {
this->fault = this->staticInst->completeAcc((uint8_t*)&this->req->result,
this,
this->traceData);
} else {
panic("Unknown type!");
}
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
return this->fault;
}
@ -298,7 +288,7 @@ template <class Impl>
void
OzoneDynInst<Impl>::trap(Fault fault)
{
fault->invoke(this->thread->getXCProxy());
fault->invoke(this->thread->getTC());
}
template <class Impl>
@ -310,8 +300,8 @@ OzoneDynInst<Impl>::simPalCheck(int palFunc)
#else
template <class Impl>
void
OzoneDynInst<Impl>::syscall()
OzoneDynInst<Impl>::syscall(uint64_t &callnum)
{
this->cpu->syscall();
this->cpu->syscall(callnum);
}
#endif

View file

@ -30,7 +30,7 @@
#include "cpu/ozone/front_end_impl.hh"
#include "cpu/ozone/ozone_impl.hh"
#include "cpu/ozone/simple_impl.hh"
//#include "cpu/ozone/simple_impl.hh"
template class FrontEnd<OzoneImpl>;
template class FrontEnd<SimpleImpl>;
//template class FrontEnd<SimpleImpl>;

View file

@ -33,9 +33,11 @@
#include <deque>
#include "arch/utility.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/bpred_unit.hh"
#include "cpu/ozone/rename_table.hh"
#include "mem/port.hh"
#include "mem/request.hh"
#include "sim/eventq.hh"
#include "sim/stats.hh"
@ -55,17 +57,55 @@ class FrontEnd
typedef typename Impl::Params Params;
typedef typename Impl::DynInst DynInst;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::CPUType CPUType;
typedef typename Impl::BackEnd BackEnd;
typedef typename Impl::FullCPU::OzoneTC OzoneTC;
typedef typename Impl::FullCPU::CommStruct CommStruct;
typedef typename Impl::CPUType::OzoneTC OzoneTC;
typedef typename Impl::CPUType::CommStruct CommStruct;
/** IcachePort class. Handles doing the communication with the
* cache/memory.
*/
class IcachePort : public Port
{
protected:
/** Pointer to FE. */
FrontEnd<Impl> *fe;
public:
/** Default constructor. */
IcachePort(FrontEnd<Impl> *_fe)
: Port(_fe->name() + "-iport"), fe(_fe)
{ }
protected:
/** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
/** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt);
/** Receives status change. Other than range changing, panics. */
virtual void recvStatusChange(Status status);
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
{ resp.clear(); snoop.clear(); }
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
virtual bool recvTiming(PacketPtr pkt);
/** Handles doing a retry of a failed fetch. */
virtual void recvRetry();
};
FrontEnd(Params *params);
std::string name() const;
void setCPU(FullCPU *cpu_ptr)
void setCPU(CPUType *cpu_ptr)
{ cpu = cpu_ptr; }
void setBackEnd(BackEnd *back_end_ptr)
@ -104,6 +144,8 @@ class FrontEnd
bool switchedOut;
private:
void recvRetry();
bool updateStatus();
void checkBE();
@ -130,7 +172,7 @@ class FrontEnd
{ return cpu->globalSeqNum++; }
public:
FullCPU *cpu;
CPUType *cpu;
BackEnd *backEnd;
@ -141,8 +183,9 @@ class FrontEnd
enum Status {
Running,
Idle,
IcacheMissStall,
IcacheMissComplete,
IcacheWaitResponse,
IcacheWaitRetry,
IcacheAccessComplete,
SerializeBlocked,
SerializeComplete,
RenameBlocked,
@ -161,38 +204,8 @@ class FrontEnd
BranchPred branchPred;
class IcachePort : public Port
{
protected:
FrontEnd *fe;
public:
IcachePort(const std::string &_name, FrontEnd *_fe)
: Port(_name), fe(_fe)
{ }
protected:
virtual Tick recvAtomic(PacketPtr pkt);
virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
{ resp.clear(); snoop.clear(); }
virtual bool recvTiming(PacketPtr pkt);
virtual void recvRetry();
};
IcachePort icachePort;
#if !FULL_SYSTEM
PageTable *pTable;
#endif
RequestPtr memReq;
/** Mask to get a cache block's address. */
@ -209,6 +222,11 @@ class FrontEnd
bool cacheBlkValid;
bool cacheBlocked;
/** The packet that is waiting to be retried. */
PacketPtr retryPkt;
public:
RenameTable<Impl> renameTable;

View file

@ -34,14 +34,55 @@
#include "cpu/thread_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/ozone/front_end.hh"
#include "mem/mem_interface.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
using namespace TheISA;
template<class Impl>
Tick
FrontEnd<Impl>::IcachePort::recvAtomic(PacketPtr pkt)
{
panic("FrontEnd doesn't expect recvAtomic callback!");
return curTick;
}
template<class Impl>
void
FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
{
panic("FrontEnd doesn't expect recvFunctional callback!");
}
template<class Impl>
void
FrontEnd<Impl>::IcachePort::recvStatusChange(Status status)
{
if (status == RangeChange)
return;
panic("FrontEnd doesn't expect recvStatusChange callback!");
}
template<class Impl>
bool
FrontEnd<Impl>::IcachePort::recvTiming(Packet *pkt)
{
fe->processCacheCompletion(pkt);
return true;
}
template<class Impl>
void
FrontEnd<Impl>::IcachePort::recvRetry()
{
fe->recvRetry();
}
template <class Impl>
FrontEnd<Impl>::FrontEnd(Params *params)
: branchPred(params),
icacheInterface(params->icacheInterface),
icachePort(this),
instBufferSize(0),
maxInstBufferSize(params->maxInstBufferSize),
width(params->frontEndWidth),
@ -56,7 +97,7 @@ FrontEnd<Impl>::FrontEnd(Params *params)
memReq = NULL;
// Size of cache block.
cacheBlkSize = icacheInterface ? icacheInterface->getBlockSize() : 64;
cacheBlkSize = 64;
assert(isPowerOf2(cacheBlkSize));
@ -68,11 +109,10 @@ FrontEnd<Impl>::FrontEnd(Params *params)
fetchCacheLineNextCycle = true;
cacheBlkValid = false;
cacheBlkValid = cacheBlocked = false;
retryPkt = NULL;
#if !FULL_SYSTEM
// pTable = params->pTable;
#endif
fetchFault = NoFault;
}
@ -271,7 +311,7 @@ FrontEnd<Impl>::tick()
IFQFcount += instBufferSize == maxInstBufferSize;
// Fetch cache line
if (status == IcacheMissComplete) {
if (status == IcacheAccessComplete) {
cacheBlkValid = true;
status = Running;
@ -280,8 +320,8 @@ FrontEnd<Impl>::tick()
if (freeRegs <= 0)
status = RenameBlocked;
checkBE();
} else if (status == IcacheMissStall) {
DPRINTF(FE, "Still in Icache miss stall.\n");
} else if (status == IcacheWaitResponse || status == IcacheWaitRetry) {
DPRINTF(FE, "Still in Icache wait.\n");
icacheStallCycles++;
return;
}
@ -302,7 +342,7 @@ FrontEnd<Impl>::tick()
} else if (status == QuiescePending) {
DPRINTF(FE, "Waiting for quiesce to execute or get squashed.\n");
return;
} else if (status != IcacheMissComplete) {
} else if (status != IcacheAccessComplete) {
if (fetchCacheLineNextCycle) {
Fault fault = fetchCacheLine();
if (fault != NoFault) {
@ -313,7 +353,7 @@ FrontEnd<Impl>::tick()
fetchCacheLineNextCycle = false;
}
// If miss, stall until it returns.
if (status == IcacheMissStall) {
if (status == IcacheWaitResponse || status == IcacheWaitRetry) {
// Tell CPU to not tick me for now.
return;
}
@ -403,22 +443,16 @@ FrontEnd<Impl>::fetchCacheLine()
// Setup the memReq to do a read of the first isntruction's address.
// Set the appropriate read size and flags as well.
memReq = new MemReq();
memReq->asid = 0;
memReq->thread_num = 0;
memReq->data = new uint8_t[64];
memReq->tc = tc;
memReq->cmd = Read;
memReq->reset(fetch_PC, cacheBlkSize, flags);
memReq = new Request(0, fetch_PC, cacheBlkSize, flags,
fetch_PC, cpu->readCpuId(), 0);
// Translate the instruction request.
fault = cpu->translateInstReq(memReq);
fault = cpu->translateInstReq(memReq, thread);
// Now do the timing access to see whether or not the instruction
// exists within the cache.
if (icacheInterface && fault == NoFault) {
#if FULL_SYSTEM
if (fault == NoFault) {
#if 0
if (cpu->system->memctrl->badaddr(memReq->paddr) ||
memReq->flags & UNCACHEABLE) {
DPRINTF(FE, "Fetch: Bad address %#x (hopefully on a "
@ -428,30 +462,21 @@ FrontEnd<Impl>::fetchCacheLine()
}
#endif
memReq->completionEvent = NULL;
// Build packet here.
PacketPtr data_pkt = new Packet(memReq,
Packet::ReadReq, Packet::Broadcast);
data_pkt->dataStatic(cacheData);
memReq->time = curTick;
fault = cpu->mem->read(memReq, cacheData);
MemAccessResult res = icacheInterface->access(memReq);
// If the cache missed then schedule an event to wake
// up this stage once the cache miss completes.
if (icacheInterface->doEvents() && res != MA_HIT) {
memReq->completionEvent = new ICacheCompletionEvent(memReq, this);
status = IcacheMissStall;
cacheBlkValid = false;
DPRINTF(FE, "Cache miss.\n");
} else {
DPRINTF(FE, "Cache hit.\n");
cacheBlkValid = true;
// memcpy(cacheData, memReq->data, memReq->size);
if (!icachePort.sendTiming(data_pkt)) {
assert(retryPkt == NULL);
DPRINTF(Fetch, "Out of MSHRs!\n");
status = IcacheWaitRetry;
retryPkt = data_pkt;
cacheBlocked = true;
return NoFault;
}
status = IcacheWaitResponse;
}
// Note that this will set the cache block PC a bit earlier than it should
@ -564,7 +589,7 @@ FrontEnd<Impl>::handleFault(Fault &fault)
// instruction->setASID(tid);
instruction->setState(thread);
instruction->setThreadState(thread);
instruction->traceData = NULL;
@ -613,8 +638,8 @@ FrontEnd<Impl>::squash(const InstSeqNum &squash_num, const Addr &next_PC,
}
// Clear the icache miss if it's outstanding.
if (status == IcacheMissStall && icacheInterface) {
DPRINTF(FE, "Squashing outstanding Icache miss.\n");
if (status == IcacheWaitResponse) {
DPRINTF(FE, "Squashing outstanding Icache access.\n");
memReq = NULL;
}
@ -651,20 +676,22 @@ FrontEnd<Impl>::getInst()
template <class Impl>
void
FrontEnd<Impl>::processCacheCompletion(MemReqPtr &req)
FrontEnd<Impl>::processCacheCompletion(PacketPtr pkt)
{
DPRINTF(FE, "Processing cache completion\n");
// Do something here.
if (status != IcacheMissStall ||
req != memReq ||
if (status != IcacheWaitResponse ||
pkt->req != memReq ||
switchedOut) {
DPRINTF(FE, "Previous fetch was squashed.\n");
fetchIcacheSquashes++;
delete pkt->req;
delete pkt;
return;
}
status = IcacheMissComplete;
status = IcacheAccessComplete;
/* if (checkStall(tid)) {
fetchStatus[tid] = Blocked;
@ -676,6 +703,8 @@ FrontEnd<Impl>::processCacheCompletion(MemReqPtr &req)
// Reset the completion event to NULL.
// memReq->completionEvent = NULL;
delete pkt->req;
delete pkt;
memReq = NULL;
}
@ -696,6 +725,27 @@ FrontEnd<Impl>::addFreeRegs(int num_freed)
freeRegs = numPhysRegs;
}
template <class Impl>
void
FrontEnd<Impl>::recvRetry()
{
assert(cacheBlocked);
if (retryPkt != NULL) {
assert(status == IcacheWaitRetry);
if (icachePort.sendTiming(retryPkt)) {
status = IcacheWaitResponse;
retryPkt = NULL;
cacheBlocked = false;
}
} else {
// Access has been squashed since it was sent out. Just clear
// the cache being blocked.
cacheBlocked = false;
}
}
template <class Impl>
bool
FrontEnd<Impl>::updateStatus()
@ -774,7 +824,7 @@ FrontEnd<Impl>::getInstFromCacheline()
DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst),
inst_seq, cpu);
instruction->setState(thread);
instruction->setThreadState(thread);
DPRINTF(FE, "Instruction [sn:%lli] created, with PC %#x\n%s\n",
inst_seq, instruction->readPC(),
@ -898,24 +948,3 @@ FrontEnd<Impl>::dumpInsts()
buff_it++;
}
}
template <class Impl>
FrontEnd<Impl>::ICacheCompletionEvent::ICacheCompletionEvent(MemReqPtr &_req, FrontEnd *fe)
: Event(&mainEventQueue, Delayed_Writeback_Pri), req(_req), frontEnd(fe)
{
this->setFlags(Event::AutoDelete);
}
template <class Impl>
void
FrontEnd<Impl>::ICacheCompletionEvent::process()
{
frontEnd->processCacheCompletion(req);
}
template <class Impl>
const char *
FrontEnd<Impl>::ICacheCompletionEvent::description()
{
return "ICache completion event";
}

View file

@ -60,9 +60,9 @@ class LWBackEnd
typedef typename Impl::Params Params;
typedef typename Impl::DynInst DynInst;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::OzoneCPU OzoneCPU;
typedef typename Impl::FrontEnd FrontEnd;
typedef typename Impl::FullCPU::CommStruct CommStruct;
typedef typename Impl::OzoneCPU::CommStruct CommStruct;
struct SizeStruct {
int size;
@ -95,35 +95,13 @@ class LWBackEnd
const char *description();
};
/** LdWriteback event for a load completion. */
class LdWritebackEvent : public Event {
private:
/** Instruction that is writing back data to the register file. */
DynInstPtr inst;
/** Pointer to IEW stage. */
LWBackEnd *be;
bool dcacheMiss;
public:
/** Constructs a load writeback event. */
LdWritebackEvent(DynInstPtr &_inst, LWBackEnd *be);
/** Processes writeback event. */
virtual void process();
/** Returns the description of the writeback event. */
virtual const char *description();
void setDcacheMiss() { dcacheMiss = true; be->addDcacheMiss(inst); }
};
LWBackEnd(Params *params);
std::string name() const;
void regStats();
void setCPU(FullCPU *cpu_ptr);
void setCPU(OzoneCPU *cpu_ptr);
void setFrontEnd(FrontEnd *front_end_ptr)
{ frontEnd = front_end_ptr; }
@ -239,7 +217,7 @@ class LWBackEnd
void updateComInstStats(DynInstPtr &inst);
public:
FullCPU *cpu;
OzoneCPU *cpu;
FrontEnd *frontEnd;
@ -273,24 +251,6 @@ class LWBackEnd
RenameTable<Impl> renameTable;
private:
class DCacheCompletionEvent : public Event
{
private:
LWBackEnd *be;
public:
DCacheCompletionEvent(LWBackEnd *_be);
virtual void process();
virtual const char *description();
};
friend class DCacheCompletionEvent;
DCacheCompletionEvent cacheCompletionEvent;
MemInterface *dcacheInterface;
// General back end width. Used if the more specific isn't given.
int width;

View file

@ -28,9 +28,14 @@
* Authors: Kevin Lim
*/
#include "cpu/checker/cpu.hh"
#include "config/use_checker.hh"
#include "cpu/ozone/lw_back_end.hh"
#include "encumbered/cpu/full/op_class.hh"
#include "cpu/op_class.hh"
#if USE_CHECKER
#include "cpu/checker/cpu.hh"
#endif
template <class Impl>
void
@ -134,86 +139,11 @@ LWBackEnd<Impl>::replayMemInst(DynInstPtr &inst)
assert(found_inst);
}
template<class Impl>
LWBackEnd<Impl>::LdWritebackEvent::LdWritebackEvent(DynInstPtr &_inst,
LWBackEnd<Impl> *_be)
: Event(&mainEventQueue), inst(_inst), be(_be), dcacheMiss(false)
{
this->setFlags(Event::AutoDelete);
}
template<class Impl>
void
LWBackEnd<Impl>::LdWritebackEvent::process()
{
DPRINTF(BE, "Load writeback event [sn:%lli]\n", inst->seqNum);
// DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum);
//iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
// iewStage->wakeCPU();
if (be->isSwitchedOut())
return;
if (dcacheMiss) {
be->removeDcacheMiss(inst);
}
if (inst->isSquashed()) {
inst = NULL;
return;
}
if (!inst->isExecuted()) {
inst->setExecuted();
// Execute again to copy data to proper place.
inst->completeAcc();
}
// Need to insert instruction into queue to commit
be->instToCommit(inst);
//wroteToTimeBuffer = true;
// iewStage->activityThisCycle();
inst = NULL;
}
template<class Impl>
const char *
LWBackEnd<Impl>::LdWritebackEvent::description()
{
return "Load writeback event";
}
template <class Impl>
LWBackEnd<Impl>::DCacheCompletionEvent::DCacheCompletionEvent(LWBackEnd *_be)
: Event(&mainEventQueue, CPU_Tick_Pri), be(_be)
{
}
template <class Impl>
void
LWBackEnd<Impl>::DCacheCompletionEvent::process()
{
}
template <class Impl>
const char *
LWBackEnd<Impl>::DCacheCompletionEvent::description()
{
return "Cache completion event";
}
template <class Impl>
LWBackEnd<Impl>::LWBackEnd(Params *params)
: d2i(5, 5), i2e(5, 5), e2c(5, 5), numInstsToWB(5, 5),
trapSquash(false), tcSquash(false), cacheCompletionEvent(this),
dcacheInterface(params->dcacheInterface), width(params->backEndWidth),
exactFullStall(true)
trapSquash(false), tcSquash(false),
width(params->backEndWidth), exactFullStall(true)
{
numROBEntries = params->numROBEntries;
numInsts = 0;
@ -569,7 +499,7 @@ LWBackEnd<Impl>::regStats()
template <class Impl>
void
LWBackEnd<Impl>::setCPU(FullCPU *cpu_ptr)
LWBackEnd<Impl>::setCPU(OzoneCPU *cpu_ptr)
{
cpu = cpu_ptr;
LSQ.setCPU(cpu_ptr);
@ -639,7 +569,7 @@ LWBackEnd<Impl>::handleFault(Fault &fault, Tick latency)
// Consider holding onto the trap and waiting until the trap event
// happens for this to be executed.
fault->invoke(thread->getTCProxy());
fault->invoke(thread->getTC());
// Exit state update mode to avoid accidental updating.
thread->inSyscall = false;
@ -929,11 +859,6 @@ LWBackEnd<Impl>::executeInsts()
// at the commit stage.
if (inst->isMemRef() &&
(!inst->isDataPrefetch() && !inst->isInstPrefetch())) {
if (dcacheInterface->isBlocked()) {
// Should I move the instruction aside?
DPRINTF(BE, "Execute: dcache is blocked\n");
break;
}
DPRINTF(BE, "Execute: Initiating access for memory "
"reference.\n");
@ -941,7 +866,7 @@ LWBackEnd<Impl>::executeInsts()
LSQ.executeLoad(inst);
} else if (inst->isStore()) {
LSQ.executeStore(inst);
if (inst->req && !(inst->req->flags & LOCKED)) {
if (inst->req && !(inst->req->getFlags() & LOCKED)) {
inst->setExecuted();
instToCommit(inst);
@ -1078,7 +1003,7 @@ LWBackEnd<Impl>::commitInst(int inst_num)
thread->setPC(inst->readPC());
thread->setNextPC(inst->readNextPC());
inst->reachedCommit = true;
inst->setAtCommit();
// If the instruction is not executed yet, then it is a non-speculative
// or store inst. Signal backwards that it should be executed.
@ -1183,9 +1108,11 @@ LWBackEnd<Impl>::commitInst(int inst_num)
// Use checker prior to updating anything due to traps or PC
// based events.
#if USE_CHECKER
if (checker) {
checker->tick(inst);
checker->verify(inst);
}
#endif
if (inst_fault != NoFault) {
DPRINTF(BE, "Inst [sn:%lli] PC %#x has a fault\n",
@ -1200,9 +1127,12 @@ LWBackEnd<Impl>::commitInst(int inst_num)
} else if (inst_num != 0) {
DPRINTF(BE, "Will wait until instruction is head of commit group.\n");
return false;
} else if (checker && inst->isStore()) {
checker->tick(inst);
}
#if USE_CHECKER
else if (checker && inst->isStore()) {
checker->verify(inst);
}
#endif
thread->setInst(
static_cast<TheISA::MachInst>(inst->staticInst->machInst));
@ -1259,7 +1189,7 @@ LWBackEnd<Impl>::commitInst(int inst_num)
assert(!thread->inSyscall && !thread->trapPending);
oldpc = thread->readPC();
cpu->system->pcEventQueue.service(
thread->getTCProxy());
thread->getTC());
count++;
} while (oldpc != thread->readPC());
if (count > 1) {
@ -1346,7 +1276,7 @@ LWBackEnd<Impl>::squash(const InstSeqNum &sn)
(*insts_it)->setCanCommit();
(*insts_it)->removeInROB();
(*insts_it)->clearInROB();
for (int i = 0; i < (*insts_it)->numDestRegs(); ++i) {
DynInstPtr prev_dest = (*insts_it)->getPrevDestInst(i);
@ -1497,10 +1427,10 @@ LWBackEnd<Impl>::doSwitchOut()
template <class Impl>
void
LWBackEnd<Impl>::takeOverFrom(ThreadContext *old_xc)
LWBackEnd<Impl>::takeOverFrom(ThreadContext *old_tc)
{
switchedOut = false;
xcSquash = false;
tcSquash = false;
trapSquash = false;
numInsts = 0;
@ -1510,7 +1440,7 @@ LWBackEnd<Impl>::takeOverFrom(ThreadContext *old_xc)
switchedOut = false;
dispatchStatus = Running;
commitStatus = Running;
LSQ.takeOverFrom(old_xc);
LSQ.takeOverFrom(old_tc);
}
template <class Impl>

View file

@ -47,7 +47,7 @@
#include "sim/debug.hh"
#include "sim/sim_object.hh"
//class PageTable;
class MemObject;
/**
* Class that implements the actual LQ and SQ for each specific thread.
@ -64,7 +64,7 @@ template <class Impl>
class OzoneLWLSQ {
public:
typedef typename Impl::Params Params;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::OzoneCPU OzoneCPU;
typedef typename Impl::BackEnd BackEnd;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::IssueStruct IssueStruct;
@ -73,35 +73,6 @@ class OzoneLWLSQ {
typedef typename std::map<InstSeqNum, DynInstPtr>::iterator LdMapIt;
private:
class StoreCompletionEvent : public Event {
public:
/** Constructs a store completion event. */
StoreCompletionEvent(DynInstPtr &inst, BackEnd *be,
Event *wb_event, OzoneLWLSQ *lsq_ptr);
/** Processes the store completion event. */
void process();
/** Returns the description of this event. */
const char *description();
private:
/** The store index of the store being written back. */
DynInstPtr inst;
BackEnd *be;
/** The writeback event for the store. Needed for store
* conditionals.
*/
public:
Event *wbEvent;
bool miss;
private:
/** The pointer to the LSQ unit that issued the store. */
OzoneLWLSQ<Impl> *lsqPtr;
};
public:
/** Constructs an LSQ unit. init() must be called prior to use. */
OzoneLWLSQ();
@ -114,8 +85,7 @@ class OzoneLWLSQ {
std::string name() const;
/** Sets the CPU pointer. */
void setCPU(FullCPU *cpu_ptr)
{ cpu = cpu_ptr; }
void setCPU(OzoneCPU *cpu_ptr);
/** Sets the back-end stage pointer. */
void setBE(BackEnd *be_ptr)
@ -155,6 +125,10 @@ class OzoneLWLSQ {
/** Writes back stores. */
void writebackStores();
/** Completes the data access that has been returned from the
* memory system. */
void completeDataAccess(PacketPtr pkt);
// @todo: Include stats in the LSQ unit.
//void regStats();
@ -231,8 +205,8 @@ class OzoneLWLSQ {
/** Returns if the LSQ unit will writeback on this cycle. */
bool willWB() { return storeQueue.back().canWB &&
!storeQueue.back().completed/* &&
!dcacheInterface->isBlocked()*/; }
!storeQueue.back().completed &&
!isStoreBlocked; }
void switchOut();
@ -243,12 +217,21 @@ class OzoneLWLSQ {
bool switchedOut;
private:
/** Writes back the instruction, sending it to IEW. */
void writeback(DynInstPtr &inst, PacketPtr pkt);
/** Handles completing the send of a store to memory. */
void storePostSend(Packet *pkt, DynInstPtr &inst);
/** Completes the store at the specified index. */
void completeStore(int store_idx);
/** Handles doing the retry. */
void recvRetry();
private:
/** Pointer to the CPU. */
FullCPU *cpu;
OzoneCPU *cpu;
/** Pointer to the back-end stage. */
BackEnd *be;
@ -258,11 +241,13 @@ class OzoneLWLSQ {
class DcachePort : public Port
{
protected:
FullCPU *cpu;
OzoneCPU *cpu;
OzoneLWLSQ *lsq;
public:
DcachePort(const std::string &_name, FullCPU *_cpu)
: Port(_name), cpu(_cpu)
DcachePort(OzoneCPU *_cpu, OzoneLWLSQ *_lsq)
: Port(_lsq->name() + "-dport"), cpu(_cpu), lsq(_lsq)
{ }
protected:
@ -282,7 +267,7 @@ class OzoneLWLSQ {
};
/** Pointer to the D-cache. */
DcachePort dcachePort;
DcachePort *dcachePort;
/** Pointer to the page table. */
// PageTable *pTable;
@ -319,6 +304,48 @@ class OzoneLWLSQ {
typename std::list<DynInstPtr>::iterator lqIt;
};
/** Derived class to hold any sender state the LSQ needs. */
class LSQSenderState : public Packet::SenderState
{
public:
/** Default constructor. */
LSQSenderState()
: noWB(false)
{ }
/** Instruction who initiated the access to memory. */
DynInstPtr inst;
/** Whether or not it is a load. */
bool isLoad;
/** The LQ/SQ index of the instruction. */
int idx;
/** Whether or not the instruction will need to writeback. */
bool noWB;
};
/** Writeback event, specifically for when stores forward data to loads. */
class WritebackEvent : public Event {
public:
/** Constructs a writeback event. */
WritebackEvent(DynInstPtr &_inst, PacketPtr pkt, OzoneLWLSQ *lsq_ptr);
/** Processes the writeback event. */
void process();
/** Returns the description of this event. */
const char *description();
private:
/** Instruction whose results are being written back. */
DynInstPtr inst;
/** The packet that would have been sent to memory. */
PacketPtr pkt;
/** The pointer to the LSQ unit that issued the store. */
OzoneLWLSQ<Impl> *lsqPtr;
};
enum Status {
Running,
Idle,
@ -395,6 +422,12 @@ class OzoneLWLSQ {
/** The index of the above store. */
LQIt stallingLoad;
/** The packet that needs to be retried. */
PacketPtr retryPkt;
/** Whehter or not a store is blocked due to the memory system. */
bool isStoreBlocked;
/** Whether or not a load is blocked due to the memory system. It is
* cleared when this value is checked via loadBlocked().
*/
@ -470,7 +503,7 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
// too).
// @todo: Fix uncached accesses.
if (req->getFlags() & UNCACHEABLE &&
(inst != loadQueue.back() || !inst->reachedCommit)) {
(inst != loadQueue.back() || !inst->isAtCommit())) {
DPRINTF(OzoneLSQ, "[sn:%lli] Uncached load and not head of "
"commit/LSQ!\n",
inst->seqNum);
@ -532,17 +565,19 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
DPRINTF(OzoneLSQ, "Forwarding from store [sn:%lli] to load to "
"[sn:%lli] addr %#x, data %#x\n",
(*sq_it).inst->seqNum, inst->seqNum, req->vaddr, *(inst->memData));
/*
typename BackEnd::LdWritebackEvent *wb =
new typename BackEnd::LdWritebackEvent(inst,
be);
(*sq_it).inst->seqNum, inst->seqNum, req->getVaddr(),
*(inst->memData));
PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
data_pkt->dataStatic(inst->memData);
WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this);
// We'll say this has a 1 cycle load-store forwarding latency
// for now.
// FIXME - Need to make this a parameter.
// @todo: Need to make this a parameter.
wb->schedule(curTick);
*/
// Should keep track of stat for forwarded data
return NoFault;
} else if ((store_has_lower_limit && lower_load_has_store_part) ||
@ -575,7 +610,7 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
DPRINTF(OzoneLSQ, "Load-store forwarding mis-match. "
"Store [sn:%lli] to load addr %#x\n",
(*sq_it).inst->seqNum, req->vaddr);
(*sq_it).inst->seqNum, req->getVaddr());
return NoFault;
}
@ -597,8 +632,14 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
data_pkt->dataStatic(inst->memData);
LSQSenderState *state = new LSQSenderState;
state->isLoad = true;
state->idx = load_idx;
state->inst = inst;
data_pkt->senderState = state;
// if we have a cache, do cache access too
if (!dcachePort.sendTiming(data_pkt)) {
if (!dcachePort->sendTiming(data_pkt)) {
// There's an older load that's already going to squash.
if (isLoadBlocked && blockedLoadSeqNum < inst->seqNum)
return NoFault;

View file

@ -28,58 +28,105 @@
* Authors: Kevin Lim
*/
#include "config/use_checker.hh"
#include "arch/isa_traits.hh"
#include "base/str.hh"
#include "cpu/ozone/lw_lsq.hh"
#include "cpu/checker/cpu.hh"
template <class Impl>
OzoneLWLSQ<Impl>::StoreCompletionEvent::StoreCompletionEvent(DynInstPtr &_inst,
BackEnd *_be,
Event *wb_event,
OzoneLWLSQ<Impl> *lsq_ptr)
: Event(&mainEventQueue),
inst(_inst),
be(_be),
wbEvent(wb_event),
miss(false),
lsqPtr(lsq_ptr)
template<class Impl>
OzoneLWLSQ<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt,
OzoneLWLSQ *lsq_ptr)
: Event(&mainEventQueue), inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
{
this->setFlags(Event::AutoDelete);
}
template <class Impl>
template<class Impl>
void
OzoneLWLSQ<Impl>::StoreCompletionEvent::process()
OzoneLWLSQ<Impl>::WritebackEvent::process()
{
DPRINTF(OzoneLSQ, "Cache miss complete for store [sn:%lli]\n",
inst->seqNum);
//lsqPtr->removeMSHR(lsqPtr->storeQueue[storeIdx].inst->seqNum);
// lsqPtr->cpu->wakeCPU();
if (lsqPtr->isSwitchedOut()) {
if (wbEvent)
delete wbEvent;
return;
if (!lsqPtr->isSwitchedOut()) {
lsqPtr->writeback(inst, pkt);
}
delete pkt;
}
if (wbEvent) {
wbEvent->process();
delete wbEvent;
}
lsqPtr->completeStore(inst->sqIdx);
if (miss)
be->removeDcacheMiss(inst);
template<class Impl>
const char *
OzoneLWLSQ<Impl>::WritebackEvent::description()
{
return "Store writeback event";
}
template <class Impl>
const char *
OzoneLWLSQ<Impl>::StoreCompletionEvent::description()
Tick
OzoneLWLSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
{
return "LSQ store completion event";
panic("O3CPU model does not work with atomic mode!");
return curTick;
}
template <class Impl>
void
OzoneLWLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
{
panic("O3CPU doesn't expect recvFunctional callback!");
}
template <class Impl>
void
OzoneLWLSQ<Impl>::DcachePort::recvStatusChange(Status status)
{
if (status == RangeChange)
return;
panic("O3CPU doesn't expect recvStatusChange callback!");
}
template <class Impl>
bool
OzoneLWLSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
{
lsq->completeDataAccess(pkt);
return true;
}
template <class Impl>
void
OzoneLWLSQ<Impl>::DcachePort::recvRetry()
{
lsq->recvRetry();
}
template<class Impl>
void
OzoneLWLSQ<Impl>::completeDataAccess(PacketPtr pkt)
{
LSQSenderState *state = dynamic_cast<LSQSenderState *>(pkt->senderState);
DynInstPtr inst = state->inst;
DPRINTF(IEW, "Writeback event [sn:%lli]\n", inst->seqNum);
DPRINTF(Activity, "Activity: Writeback event [sn:%lli]\n", inst->seqNum);
//iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
if (isSwitchedOut() || inst->isSquashed()) {
delete state;
delete pkt;
return;
} else {
if (!state->noWB) {
writeback(inst, pkt);
}
if (inst->isStore()) {
completeStore(state->idx);
}
}
delete state;
delete pkt;
}
template <class Impl>
@ -109,8 +156,6 @@ OzoneLWLSQ<Impl>::init(Params *params, unsigned maxLQEntries,
usedPorts = 0;
cachePorts = params->cachePorts;
dcacheInterface = params->dcacheInterface;
loadFaultInst = storeFaultInst = memDepViolator = NULL;
blockedLoadSeqNum = 0;
@ -123,6 +168,24 @@ OzoneLWLSQ<Impl>::name() const
return "lsqunit";
}
template<class Impl>
void
OzoneLWLSQ<Impl>::setCPU(OzoneCPU *cpu_ptr)
{
cpu = cpu_ptr;
dcachePort = new DcachePort(cpu, this);
Port *mem_dport = mem->getPort("");
dcachePort->setPeer(mem_dport);
mem_dport->setPeer(dcachePort);
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setDcachePort(dcachePort);
}
#endif
}
template<class Impl>
void
OzoneLWLSQ<Impl>::clearLQ()
@ -481,6 +544,12 @@ OzoneLWLSQ<Impl>::writebackStores()
(*sq_it).canWB &&
usedPorts < cachePorts) {
if (isStoreBlocked) {
DPRINTF(OzoneLSQ, "Unable to write back any more stores, cache"
" is blocked!\n");
break;
}
DynInstPtr inst = (*sq_it).inst;
if ((*sq_it).size == 0 && !(*sq_it).completed) {
@ -495,48 +564,64 @@ OzoneLWLSQ<Impl>::writebackStores()
continue;
}
if (dcacheInterface && dcacheInterface->isBlocked()) {
DPRINTF(OzoneLSQ, "Unable to write back any more stores, cache"
" is blocked!\n");
break;
}
++usedPorts;
assert((*sq_it).req);
assert(!(*sq_it).committed);
Request *req = (*sq_it).req;
(*sq_it).committed = true;
MemReqPtr req = (*sq_it).req;
assert(!inst->memData);
inst->memData = new uint8_t[64];
memcpy(inst->memData, (uint8_t *)&(*sq_it).data,
req->getSize());
req->cmd = Write;
req->completionEvent = NULL;
req->time = curTick;
PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
data_pkt->dataStatic(inst->memData);
switch((*sq_it).size) {
case 1:
cpu->write(req, (uint8_t &)(*sq_it).data);
break;
case 2:
cpu->write(req, (uint16_t &)(*sq_it).data);
break;
case 4:
cpu->write(req, (uint32_t &)(*sq_it).data);
break;
case 8:
cpu->write(req, (uint64_t &)(*sq_it).data);
break;
default:
panic("Unexpected store size!\n");
}
if (!(req->flags & LOCKED)) {
(*sq_it).inst->setCompleted();
if (cpu->checker) {
cpu->checker->tick((*sq_it).inst);
LSQSenderState *state = new LSQSenderState;
state->isLoad = false;
state->idx = inst->sqIdx;
state->inst = inst;
data_pkt->senderState = state;
DPRINTF(OzoneLSQ, "D-Cache: Writing back store PC:%#x "
"to Addr:%#x, data:%#x [sn:%lli]\n",
(*sq_it).inst->readPC(),
req->getPaddr(), *(inst->memData),
inst->seqNum);
// @todo: Remove this SC hack once the memory system handles it.
if (req->getFlags() & LOCKED) {
if (req->getFlags() & UNCACHEABLE) {
req->setScResult(2);
} else {
if (cpu->lockFlag) {
req->setScResult(1);
} else {
req->setScResult(0);
// Hack: Instantly complete this store.
completeDataAccess(data_pkt);
--sq_it;
continue;
}
}
} else {
// Non-store conditionals do not need a writeback.
state->noWB = true;
}
if (!dcachePort->sendTiming(data_pkt)) {
// Need to handle becoming blocked on a store.
isStoreBlocked = true;
assert(retryPkt == NULL);
retryPkt = data_pkt;
} else {
storePostSend(data_pkt, inst);
--sq_it;
}
/*
DPRINTF(OzoneLSQ, "D-Cache: Writing back store idx:%i PC:%#x "
"to Addr:%#x, data:%#x [sn:%lli]\n",
inst->sqIdx,inst->readPC(),
@ -606,6 +691,7 @@ OzoneLWLSQ<Impl>::writebackStores()
} else {
panic("Must HAVE DCACHE!!!!!\n");
}
*/
}
// Not sure this should set it to 0.
@ -685,10 +771,6 @@ OzoneLWLSQ<Impl>::squash(const InstSeqNum &squashed_num)
SQIndices.push((*sq_it).inst->sqIdx);
(*sq_it).inst = NULL;
(*sq_it).canWB = 0;
if ((*sq_it).req) {
assert(!(*sq_it).req->completionEvent);
}
(*sq_it).req = NULL;
--stores;
storeQueue.erase(sq_it++);
@ -732,6 +814,72 @@ OzoneLWLSQ<Impl>::dumpInsts()
cprintf("\n");
}
template <class Impl>
void
OzoneLWLSQ<Impl>::storePostSend(Packet *pkt, DynInstPtr &inst)
{
if (isStalled() &&
inst->seqNum == stallingStoreIsn) {
DPRINTF(OzoneLSQ, "Unstalling, stalling store [sn:%lli] "
"load [sn:%lli]\n",
stallingStoreIsn, (*stallingLoad)->seqNum);
stalled = false;
stallingStoreIsn = 0;
be->replayMemInst((*stallingLoad));
}
if (!inst->isStoreConditional()) {
// The store is basically completed at this time. This
// only works so long as the checker doesn't try to
// verify the value in memory for stores.
inst->setCompleted();
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->verify(inst);
}
#endif
}
if (pkt->result != Packet::Success) {
DPRINTF(OzoneLSQ,"D-Cache Write Miss!\n");
DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
inst->seqNum);
//mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum);
//DPRINTF(OzoneLWLSQ, "Added MSHR. count = %i\n",mshrSeqNums.size());
// @todo: Increment stat here.
} else {
DPRINTF(OzoneLSQ,"D-Cache: Write Hit!\n");
DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
inst->seqNum);
}
}
template <class Impl>
void
OzoneLWLSQ<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
{
// Squashed instructions do not need to complete their access.
if (inst->isSquashed()) {
assert(!inst->isStore());
return;
}
if (!inst->isExecuted()) {
inst->setExecuted();
// Complete access to copy data to proper place.
inst->completeAcc(pkt);
}
// Need to insert instruction into queue to commit
be->instToCommit(inst);
}
template <class Impl>
void
OzoneLWLSQ<Impl>::completeStore(int store_idx)
@ -766,9 +914,18 @@ OzoneLWLSQ<Impl>::completeStore(int store_idx)
--stores;
inst->setCompleted();
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->tick(inst);
cpu->checker->verify(inst);
}
#endif
}
template <class Impl>
void
OzoneLWLSQ<Impl>::recvRetry()
{
panic("Unimplemented!");
}
template <class Impl>
@ -777,68 +934,6 @@ OzoneLWLSQ<Impl>::switchOut()
{
assert(storesToWB == 0);
switchedOut = true;
SQIt sq_it = --(storeQueue.end());
while (storesToWB > 0 &&
sq_it != storeQueue.end() &&
(*sq_it).inst &&
(*sq_it).canWB) {
DynInstPtr inst = (*sq_it).inst;
if ((*sq_it).size == 0 && !(*sq_it).completed) {
sq_it--;
continue;
}
// Store conditionals don't complete until *after* they have written
// back. If it's here and not yet sent to memory, then don't bother
// as it's not part of committed state.
if (inst->isDataPrefetch() || (*sq_it).committed) {
sq_it--;
continue;
} else if ((*sq_it).req->flags & LOCKED) {
sq_it--;
assert(!(*sq_it).canWB ||
((*sq_it).canWB && (*sq_it).req->flags & LOCKED));
continue;
}
assert((*sq_it).req);
assert(!(*sq_it).committed);
MemReqPtr req = (*sq_it).req;
(*sq_it).committed = true;
req->cmd = Write;
req->completionEvent = NULL;
req->time = curTick;
assert(!req->data);
req->data = new uint8_t[64];
memcpy(req->data, (uint8_t *)&(*sq_it).data, req->size);
DPRINTF(OzoneLSQ, "Switching out : Writing back store idx:%i PC:%#x "
"to Addr:%#x, data:%#x directly to memory [sn:%lli]\n",
inst->sqIdx,inst->readPC(),
req->paddr, *(req->data),
inst->seqNum);
switch((*sq_it).size) {
case 1:
cpu->write(req, (uint8_t &)(*sq_it).data);
break;
case 2:
cpu->write(req, (uint16_t &)(*sq_it).data);
break;
case 4:
cpu->write(req, (uint32_t &)(*sq_it).data);
break;
case 8:
cpu->write(req, (uint64_t &)(*sq_it).data);
break;
default:
panic("Unexpected store size!\n");
}
}
// Clear the queue to free up resources
storeQueue.clear();

View file

@ -50,7 +50,7 @@ class OzoneDynInst;
struct OzoneImpl {
typedef SimpleParams Params;
typedef OzoneCPU<OzoneImpl> OzoneCPU;
typedef OzoneCPU FullCPU;
typedef OzoneCPU CPUType;
// Would like to put these into their own area.
// typedef NullPredictor BranchPred;

View file

@ -30,7 +30,7 @@
#include "cpu/ozone/rename_table_impl.hh"
#include "cpu/ozone/ozone_impl.hh"
#include "cpu/ozone/simple_impl.hh"
//#include "cpu/ozone/simple_impl.hh"
template class RenameTable<OzoneImpl>;
template class RenameTable<SimpleImpl>;
//template class RenameTable<SimpleImpl>;

View file

@ -0,0 +1,452 @@
/*
* Copyright (c) 2006 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
*/
#include <string>
#include "cpu/checker/cpu.hh"
#include "cpu/inst_seq.hh"
#include "cpu/ozone/cpu_impl.hh"
#include "cpu/ozone/simple_impl.hh"
#include "cpu/ozone/simple_params.hh"
#include "mem/cache/base_cache.hh"
#include "sim/builder.hh"
#include "sim/process.hh"
#include "sim/sim_object.hh"
template
class OzoneCPU<SimpleImpl>;
class SimpleOzoneCPU : public OzoneCPU<SimpleImpl>
{
public:
SimpleOzoneCPU(SimpleParams *p)
: OzoneCPU<SimpleImpl>(p)
{ }
};
////////////////////////////////////////////////////////////////////////
//
// OzoneCPU Simulation Object
//
BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
Param<int> clock;
Param<int> numThreads;
#if FULL_SYSTEM
SimObjectParam<System *> system;
Param<int> cpu_id;
SimObjectParam<AlphaITB *> itb;
SimObjectParam<AlphaDTB *> dtb;
#else
SimObjectVectorParam<Process *> workload;
//SimObjectParam<PageTable *> page_table;
#endif // FULL_SYSTEM
SimObjectParam<FunctionalMemory *> mem;
SimObjectParam<BaseCPU *> checker;
Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache;
Param<unsigned> cachePorts;
Param<unsigned> width;
Param<unsigned> frontEndWidth;
Param<unsigned> backEndWidth;
Param<unsigned> backEndSquashLatency;
Param<unsigned> backEndLatency;
Param<unsigned> maxInstBufferSize;
Param<unsigned> numPhysicalRegs;
Param<unsigned> decodeToFetchDelay;
Param<unsigned> renameToFetchDelay;
Param<unsigned> iewToFetchDelay;
Param<unsigned> commitToFetchDelay;
Param<unsigned> fetchWidth;
Param<unsigned> renameToDecodeDelay;
Param<unsigned> iewToDecodeDelay;
Param<unsigned> commitToDecodeDelay;
Param<unsigned> fetchToDecodeDelay;
Param<unsigned> decodeWidth;
Param<unsigned> iewToRenameDelay;
Param<unsigned> commitToRenameDelay;
Param<unsigned> decodeToRenameDelay;
Param<unsigned> renameWidth;
Param<unsigned> commitToIEWDelay;
Param<unsigned> renameToIEWDelay;
Param<unsigned> issueToExecuteDelay;
Param<unsigned> issueWidth;
Param<unsigned> executeWidth;
Param<unsigned> executeIntWidth;
Param<unsigned> executeFloatWidth;
Param<unsigned> executeBranchWidth;
Param<unsigned> executeMemoryWidth;
Param<unsigned> iewToCommitDelay;
Param<unsigned> renameToROBDelay;
Param<unsigned> commitWidth;
Param<unsigned> squashWidth;
Param<std::string> predType;
Param<unsigned> localPredictorSize;
Param<unsigned> localCtrBits;
Param<unsigned> localHistoryTableSize;
Param<unsigned> localHistoryBits;
Param<unsigned> globalPredictorSize;
Param<unsigned> globalCtrBits;
Param<unsigned> globalHistoryBits;
Param<unsigned> choicePredictorSize;
Param<unsigned> choiceCtrBits;
Param<unsigned> BTBEntries;
Param<unsigned> BTBTagSize;
Param<unsigned> RASSize;
Param<unsigned> LQEntries;
Param<unsigned> SQEntries;
Param<unsigned> LFSTSize;
Param<unsigned> SSITSize;
Param<unsigned> numPhysIntRegs;
Param<unsigned> numPhysFloatRegs;
Param<unsigned> numIQEntries;
Param<unsigned> numROBEntries;
Param<bool> decoupledFrontEnd;
Param<int> dispatchWidth;
Param<int> wbWidth;
Param<unsigned> smtNumFetchingThreads;
Param<std::string> smtFetchPolicy;
Param<std::string> smtLSQPolicy;
Param<unsigned> smtLSQThreshold;
Param<std::string> smtIQPolicy;
Param<unsigned> smtIQThreshold;
Param<std::string> smtROBPolicy;
Param<unsigned> smtROBThreshold;
Param<std::string> smtCommitPolicy;
Param<unsigned> instShiftAmt;
Param<bool> defer_registration;
Param<bool> function_trace;
Param<Tick> function_trace_start;
END_DECLARE_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
INIT_PARAM(clock, "clock speed"),
INIT_PARAM(numThreads, "number of HW thread contexts"),
#if FULL_SYSTEM
INIT_PARAM(system, "System object"),
INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM(itb, "Instruction translation buffer"),
INIT_PARAM(dtb, "Data translation buffer"),
#else
INIT_PARAM(workload, "Processes to run"),
// INIT_PARAM(page_table, "Page table"),
#endif // FULL_SYSTEM
INIT_PARAM_DFLT(mem, "Memory", NULL),
INIT_PARAM_DFLT(checker, "Checker CPU", NULL),
INIT_PARAM_DFLT(max_insts_any_thread,
"Terminate when any thread reaches this inst count",
0),
INIT_PARAM_DFLT(max_insts_all_threads,
"Terminate when all threads have reached"
"this inst count",
0),
INIT_PARAM_DFLT(max_loads_any_thread,
"Terminate when any thread reaches this load count",
0),
INIT_PARAM_DFLT(max_loads_all_threads,
"Terminate when all threads have reached this load"
"count",
0),
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
INIT_PARAM_DFLT(cachePorts, "Cache Ports", 200),
INIT_PARAM_DFLT(width, "Width", 1),
INIT_PARAM_DFLT(frontEndWidth, "Front end width", 1),
INIT_PARAM_DFLT(backEndWidth, "Back end width", 1),
INIT_PARAM_DFLT(backEndSquashLatency, "Back end squash latency", 1),
INIT_PARAM_DFLT(backEndLatency, "Back end latency", 1),
INIT_PARAM_DFLT(maxInstBufferSize, "Maximum instruction buffer size", 16),
INIT_PARAM(numPhysicalRegs, "Number of physical registers"),
INIT_PARAM(decodeToFetchDelay, "Decode to fetch delay"),
INIT_PARAM(renameToFetchDelay, "Rename to fetch delay"),
INIT_PARAM(iewToFetchDelay, "Issue/Execute/Writeback to fetch"
"delay"),
INIT_PARAM(commitToFetchDelay, "Commit to fetch delay"),
INIT_PARAM(fetchWidth, "Fetch width"),
INIT_PARAM(renameToDecodeDelay, "Rename to decode delay"),
INIT_PARAM(iewToDecodeDelay, "Issue/Execute/Writeback to decode"
"delay"),
INIT_PARAM(commitToDecodeDelay, "Commit to decode delay"),
INIT_PARAM(fetchToDecodeDelay, "Fetch to decode delay"),
INIT_PARAM(decodeWidth, "Decode width"),
INIT_PARAM(iewToRenameDelay, "Issue/Execute/Writeback to rename"
"delay"),
INIT_PARAM(commitToRenameDelay, "Commit to rename delay"),
INIT_PARAM(decodeToRenameDelay, "Decode to rename delay"),
INIT_PARAM(renameWidth, "Rename width"),
INIT_PARAM(commitToIEWDelay, "Commit to "
"Issue/Execute/Writeback delay"),
INIT_PARAM(renameToIEWDelay, "Rename to "
"Issue/Execute/Writeback delay"),
INIT_PARAM(issueToExecuteDelay, "Issue to execute delay (internal"
"to the IEW stage)"),
INIT_PARAM(issueWidth, "Issue width"),
INIT_PARAM(executeWidth, "Execute width"),
INIT_PARAM(executeIntWidth, "Integer execute width"),
INIT_PARAM(executeFloatWidth, "Floating point execute width"),
INIT_PARAM(executeBranchWidth, "Branch execute width"),
INIT_PARAM(executeMemoryWidth, "Memory execute width"),
INIT_PARAM(iewToCommitDelay, "Issue/Execute/Writeback to commit "
"delay"),
INIT_PARAM(renameToROBDelay, "Rename to reorder buffer delay"),
INIT_PARAM(commitWidth, "Commit width"),
INIT_PARAM(squashWidth, "Squash width"),
INIT_PARAM(predType, "Type of branch predictor ('local', 'tournament')"),
INIT_PARAM(localPredictorSize, "Size of local predictor"),
INIT_PARAM(localCtrBits, "Bits per counter"),
INIT_PARAM(localHistoryTableSize, "Size of local history table"),
INIT_PARAM(localHistoryBits, "Bits for the local history"),
INIT_PARAM(globalPredictorSize, "Size of global predictor"),
INIT_PARAM(globalCtrBits, "Bits per counter"),
INIT_PARAM(globalHistoryBits, "Bits of history"),
INIT_PARAM(choicePredictorSize, "Size of choice predictor"),
INIT_PARAM(choiceCtrBits, "Bits of choice counters"),
INIT_PARAM(BTBEntries, "Number of BTB entries"),
INIT_PARAM(BTBTagSize, "Size of the BTB tags, in bits"),
INIT_PARAM(RASSize, "RAS size"),
INIT_PARAM(LQEntries, "Number of load queue entries"),
INIT_PARAM(SQEntries, "Number of store queue entries"),
INIT_PARAM(LFSTSize, "Last fetched store table size"),
INIT_PARAM(SSITSize, "Store set ID table size"),
INIT_PARAM(numPhysIntRegs, "Number of physical integer registers"),
INIT_PARAM(numPhysFloatRegs, "Number of physical floating point "
"registers"),
INIT_PARAM(numIQEntries, "Number of instruction queue entries"),
INIT_PARAM(numROBEntries, "Number of reorder buffer entries"),
INIT_PARAM_DFLT(decoupledFrontEnd, "Decoupled front end", true),
INIT_PARAM_DFLT(dispatchWidth, "Dispatch width", 0),
INIT_PARAM_DFLT(wbWidth, "Writeback width", 0),
INIT_PARAM_DFLT(smtNumFetchingThreads, "SMT Number of Fetching Threads", 1),
INIT_PARAM_DFLT(smtFetchPolicy, "SMT Fetch Policy", "SingleThread"),
INIT_PARAM_DFLT(smtLSQPolicy, "SMT LSQ Sharing Policy", "Partitioned"),
INIT_PARAM_DFLT(smtLSQThreshold,"SMT LSQ Threshold", 100),
INIT_PARAM_DFLT(smtIQPolicy, "SMT IQ Policy", "Partitioned"),
INIT_PARAM_DFLT(smtIQThreshold, "SMT IQ Threshold", 100),
INIT_PARAM_DFLT(smtROBPolicy, "SMT ROB Sharing Policy", "Partitioned"),
INIT_PARAM_DFLT(smtROBThreshold,"SMT ROB Threshold", 100),
INIT_PARAM_DFLT(smtCommitPolicy,"SMT Commit Fetch Policy", "RoundRobin"),
INIT_PARAM(instShiftAmt, "Number of bits to shift instructions by"),
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(function_trace, "Enable function trace"),
INIT_PARAM(function_trace_start, "Cycle to start function trace")
END_INIT_SIM_OBJECT_PARAMS(SimpleOzoneCPU)
CREATE_SIM_OBJECT(SimpleOzoneCPU)
{
SimpleOzoneCPU *cpu;
#if FULL_SYSTEM
// Full-system only supports a single thread for the moment.
int actual_num_threads = 1;
#else
// In non-full-system mode, we infer the number of threads from
// the workload if it's not explicitly specified.
int actual_num_threads =
numThreads.isValid() ? numThreads : workload.size();
if (workload.size() == 0) {
fatal("Must specify at least one workload!");
}
#endif
SimpleParams *params = new SimpleParams;
params->clock = clock;
params->name = getInstanceName();
params->numberOfThreads = actual_num_threads;
#if FULL_SYSTEM
params->system = system;
params->cpu_id = cpu_id;
params->itb = itb;
params->dtb = dtb;
#else
params->workload = workload;
// params->pTable = page_table;
#endif // FULL_SYSTEM
params->mem = mem;
params->checker = checker;
params->max_insts_any_thread = max_insts_any_thread;
params->max_insts_all_threads = max_insts_all_threads;
params->max_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads;
//
// Caches
//
params->icacheInterface = icache ? icache->getInterface() : NULL;
params->dcacheInterface = dcache ? dcache->getInterface() : NULL;
params->cachePorts = cachePorts;
params->width = width;
params->frontEndWidth = frontEndWidth;
params->backEndWidth = backEndWidth;
params->backEndSquashLatency = backEndSquashLatency;
params->backEndLatency = backEndLatency;
params->maxInstBufferSize = maxInstBufferSize;
params->numPhysicalRegs = numPhysIntRegs + numPhysFloatRegs;
params->decodeToFetchDelay = decodeToFetchDelay;
params->renameToFetchDelay = renameToFetchDelay;
params->iewToFetchDelay = iewToFetchDelay;
params->commitToFetchDelay = commitToFetchDelay;
params->fetchWidth = fetchWidth;
params->renameToDecodeDelay = renameToDecodeDelay;
params->iewToDecodeDelay = iewToDecodeDelay;
params->commitToDecodeDelay = commitToDecodeDelay;
params->fetchToDecodeDelay = fetchToDecodeDelay;
params->decodeWidth = decodeWidth;
params->iewToRenameDelay = iewToRenameDelay;
params->commitToRenameDelay = commitToRenameDelay;
params->decodeToRenameDelay = decodeToRenameDelay;
params->renameWidth = renameWidth;
params->commitToIEWDelay = commitToIEWDelay;
params->renameToIEWDelay = renameToIEWDelay;
params->issueToExecuteDelay = issueToExecuteDelay;
params->issueWidth = issueWidth;
params->executeWidth = executeWidth;
params->executeIntWidth = executeIntWidth;
params->executeFloatWidth = executeFloatWidth;
params->executeBranchWidth = executeBranchWidth;
params->executeMemoryWidth = executeMemoryWidth;
params->iewToCommitDelay = iewToCommitDelay;
params->renameToROBDelay = renameToROBDelay;
params->commitWidth = commitWidth;
params->squashWidth = squashWidth;
params->predType = predType;
params->localPredictorSize = localPredictorSize;
params->localCtrBits = localCtrBits;
params->localHistoryTableSize = localHistoryTableSize;
params->localHistoryBits = localHistoryBits;
params->globalPredictorSize = globalPredictorSize;
params->globalCtrBits = globalCtrBits;
params->globalHistoryBits = globalHistoryBits;
params->choicePredictorSize = choicePredictorSize;
params->choiceCtrBits = choiceCtrBits;
params->BTBEntries = BTBEntries;
params->BTBTagSize = BTBTagSize;
params->RASSize = RASSize;
params->LQEntries = LQEntries;
params->SQEntries = SQEntries;
params->SSITSize = SSITSize;
params->LFSTSize = LFSTSize;
params->numPhysIntRegs = numPhysIntRegs;
params->numPhysFloatRegs = numPhysFloatRegs;
params->numIQEntries = numIQEntries;
params->numROBEntries = numROBEntries;
params->decoupledFrontEnd = decoupledFrontEnd;
params->dispatchWidth = dispatchWidth;
params->wbWidth = wbWidth;
params->smtNumFetchingThreads = smtNumFetchingThreads;
params->smtFetchPolicy = smtFetchPolicy;
params->smtIQPolicy = smtIQPolicy;
params->smtLSQPolicy = smtLSQPolicy;
params->smtLSQThreshold = smtLSQThreshold;
params->smtROBPolicy = smtROBPolicy;
params->smtROBThreshold = smtROBThreshold;
params->smtCommitPolicy = smtCommitPolicy;
params->instShiftAmt = 2;
params->deferRegistration = defer_registration;
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
cpu = new SimpleOzoneCPU(params);
return cpu;
}
REGISTER_SIM_OBJECT("SimpleOzoneCPU", SimpleOzoneCPU)

View file

@ -37,8 +37,7 @@
class AlphaDTB;
class AlphaITB;
class FUPool;
class FunctionalMemory;
class MemInterface;
class MemObject;
class PageTable;
class Process;
class System;
@ -62,13 +61,13 @@ class SimpleParams : public BaseCPU::Params
//Page Table
PageTable *pTable;
FunctionalMemory *mem;
MemObject *mem;
//
// Caches
//
MemInterface *icacheInterface;
MemInterface *dcacheInterface;
// MemInterface *icacheInterface;
// MemInterface *dcacheInterface;
unsigned cachePorts;
unsigned width;

View file

@ -58,30 +58,23 @@ class FunctionalMemory;
template <class Impl>
struct OzoneThreadState : public ThreadState {
typedef typename ThreadContext::Status Status;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::CPUType CPUType;
typedef TheISA::MiscReg MiscReg;
#if FULL_SYSTEM
OzoneThreadState(FullCPU *_cpu, int _thread_num)
OzoneThreadState(CPUType *_cpu, int _thread_num)
: ThreadState(-1, _thread_num),
inSyscall(0), trapPending(0)
intrflag(0), inSyscall(0), trapPending(0)
{
memset(&regs, 0, sizeof(TheISA::RegFile));
miscRegFile.clear();
}
#else
OzoneThreadState(FullCPU *_cpu, int _thread_num, Process *_process, int _asid)
: ThreadState(-1, _thread_num, NULL, _process, _asid),
OzoneThreadState(CPUType *_cpu, int _thread_num, Process *_process,
int _asid, MemObject *mem)
: ThreadState(-1, _thread_num, _process, _asid, mem),
cpu(_cpu), inSyscall(0), trapPending(0)
{
memset(&regs, 0, sizeof(TheISA::RegFile));
}
OzoneThreadState(FullCPU *_cpu, int _thread_num,
int _asid)
: ThreadState(-1, _thread_num, NULL, NULL, _asid),
cpu(_cpu), inSyscall(0), trapPending(0)
{
memset(&regs, 0, sizeof(TheISA::RegFile));
miscRegFile.clear();
}
#endif
@ -91,9 +84,11 @@ struct OzoneThreadState : public ThreadState {
Addr nextPC;
TheISA::RegFile regs;
TheISA::MiscRegFile miscRegFile;
typename Impl::FullCPU *cpu;
int intrflag;
typename Impl::CPUType *cpu;
bool inSyscall;
@ -103,54 +98,24 @@ struct OzoneThreadState : public ThreadState {
ThreadContext *getTC() { return tc; }
#if !FULL_SYSTEM
Fault translateInstReq(Request *req)
{
return process->pTable->translate(req);
}
Fault translateDataReadReq(Request *req)
{
return process->pTable->translate(req);
}
Fault translateDataWriteReq(Request *req)
{
return process->pTable->translate(req);
}
#else
Fault translateInstReq(Request *req)
{
return cpu->itb->translate(req);
}
Fault translateDataReadReq(Request *req)
{
return cpu->dtb->translate(req, false);
}
Fault translateDataWriteReq(Request *req)
{
return cpu->dtb->translate(req, true);
}
#endif
MiscReg readMiscReg(int misc_reg)
{
return regs.readMiscReg(misc_reg);
return miscRegFile.readReg(misc_reg);
}
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{
return regs.readMiscRegWithEffect(misc_reg, fault, tc);
return miscRegFile.readRegWithEffect(misc_reg, fault, tc);
}
Fault setMiscReg(int misc_reg, const MiscReg &val)
{
return regs.setMiscReg(misc_reg, val);
return miscRegFile.setReg(misc_reg, val);
}
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
return regs.setMiscRegWithEffect(misc_reg, val, tc);
return miscRegFile.setRegWithEffect(misc_reg, val, tc);
}
uint64_t readPC()