int maxThreadsPerCPU = 1;
#ifdef FULL_SYSTEM
-BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- System *_system, Tick freq,
- bool _function_trace, Tick _function_trace_start)
- : SimObject(_name), frequency(freq), checkInterrupts(true),
- deferRegistration(_def_reg), number_of_threads(_number_of_threads),
- system(_system)
+BaseCPU::BaseCPU(Params *p)
+ : SimObject(p->name), frequency(p->freq), checkInterrupts(true),
+ params(p), number_of_threads(p->numberOfThreads), system(p->system)
#else
-BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- bool _function_trace, Tick _function_trace_start)
- : SimObject(_name), deferRegistration(_def_reg),
- number_of_threads(_number_of_threads)
+BaseCPU::BaseCPU(Params *p)
+ : SimObject(p->name), params(p), number_of_threads(p->numberOfThreads)
#endif
{
// add self to global list of CPUs
//
// set up instruction-count-based termination events, if any
//
- if (max_insts_any_thread != 0)
+ if (p->max_insts_any_thread != 0)
for (int i = 0; i < number_of_threads; ++i)
- new SimExitEvent(comInstEventQueue[i], max_insts_any_thread,
+ new SimExitEvent(comInstEventQueue[i], p->max_insts_any_thread,
"a thread reached the max instruction count");
- if (max_insts_all_threads != 0) {
+ if (p->max_insts_all_threads != 0) {
// allocate & initialize shared downcounter: each event will
// decrement this when triggered; simulation will terminate
// when counter reaches 0
for (int i = 0; i < number_of_threads; ++i)
new CountedExitEvent(comInstEventQueue[i],
"all threads reached the max instruction count",
- max_insts_all_threads, *counter);
+ p->max_insts_all_threads, *counter);
}
// allocate per-thread load-based event queues
//
// set up instruction-count-based termination events, if any
//
- if (max_loads_any_thread != 0)
+ if (p->max_loads_any_thread != 0)
for (int i = 0; i < number_of_threads; ++i)
- new SimExitEvent(comLoadEventQueue[i], max_loads_any_thread,
+ new SimExitEvent(comLoadEventQueue[i], p->max_loads_any_thread,
"a thread reached the max load count");
- if (max_loads_all_threads != 0) {
+ if (p->max_loads_all_threads != 0) {
// allocate & initialize shared downcounter: each event will
// decrement this when triggered; simulation will terminate
// when counter reaches 0
for (int i = 0; i < number_of_threads; ++i)
new CountedExitEvent(comLoadEventQueue[i],
"all threads reached the max load count",
- max_loads_all_threads, *counter);
+ p->max_loads_all_threads, *counter);
}
#ifdef FULL_SYSTEM
#endif
functionTracingEnabled = false;
- if (_function_trace) {
+ if (p->functionTrace) {
functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
currentFunctionStart = currentFunctionEnd = 0;
- functionEntryTick = _function_trace_start;
+ functionEntryTick = p->functionTraceStart;
- if (_function_trace_start == 0) {
+ if (p->functionTraceStart == 0) {
functionTracingEnabled = true;
} else {
Event *e =
new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
true);
- e->schedule(_function_trace_start);
+ e->schedule(p->functionTraceStart);
}
}
}
void
BaseCPU::init()
{
- if (!deferRegistration)
+ if (!params->deferRegistration)
registerExecContexts();
}
virtual void haltContext(int thread_num) {}
public:
-
+ struct Params
+ {
+ std::string name;
+ int numberOfThreads;
+ bool deferRegistration;
+ Counter max_insts_any_thread;
+ Counter max_insts_all_threads;
+ Counter max_loads_any_thread;
+ Counter max_loads_all_threads;
+ Tick freq;
+ bool functionTrace;
+ Tick functionTraceStart;
#ifdef FULL_SYSTEM
- BaseCPU(const std::string &_name, int _number_of_threads, bool _def_reg,
- Counter max_insts_any_thread, Counter max_insts_all_threads,
- Counter max_loads_any_thread, Counter max_loads_all_threads,
- System *_system, Tick freq,
- bool _function_trace = false, Tick _function_trace_start = 0);
-#else
- BaseCPU(const std::string &_name, int _number_of_threads, bool _def_reg,
- Counter max_insts_any_thread = 0,
- Counter max_insts_all_threads = 0,
- Counter max_loads_any_thread = 0,
- Counter max_loads_all_threads = 0,
- bool _function_trace = false, Tick _function_trace_start = 0);
+ System *system;
#endif
+ };
+
+ const Params *params;
+ BaseCPU(Params *params);
virtual ~BaseCPU();
virtual void init();
virtual void regStats();
- bool deferRegistration;
void registerExecContexts();
/// Prepare for another CPU to take over execution. Called by
#include "base/misc.hh"
#include "base/statistics.hh"
+#include "cpu/exec_context.hh"
#include "cpu/memtest/memtest.hh"
#include "mem/cache/base_cache.hh"
#include "mem/functional_mem/main_memory.hh"
unsigned _percentSourceUnaligned,
unsigned _percentDestUnaligned,
Addr _traceAddr,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads)
- : BaseCPU(name, 1, true, 0, 0, max_loads_any_thread,
- max_loads_all_threads),
+ Counter _max_loads)
+ : SimObject(name),
tickEvent(this),
cacheInterface(_cache_interface),
mainMem(main_mem),
progressInterval(_progressInterval),
nextProgressMessage(_progressInterval),
percentSourceUnaligned(_percentSourceUnaligned),
- percentDestUnaligned(percentDestUnaligned)
+ percentDestUnaligned(percentDestUnaligned),
+ maxLoads(_max_loads)
{
vector<string> cmd;
cmd.push_back("/bin/ls");
vector<string> null_vec;
- xc = new ExecContext(this ,0,mainMem,0);
+ xc = new ExecContext(NULL, 0, mainMem, 0);
blockSize = cacheInterface->getBlockSize();
blockAddrMask = blockSize - 1;
nextProgressMessage += progressInterval;
}
- comLoadEventQueue[0]->serviceEvents(numReads);
+ if (numReads >= maxLoads)
+ SimExit(curTick, "Maximum number of loads reached!");
break;
case Write:
Param<unsigned> percent_source_unaligned;
Param<unsigned> percent_dest_unaligned;
Param<Addr> trace_addr;
- Param<Counter> max_loads_any_thread;
- Param<Counter> max_loads_all_threads;
+ Param<Counter> max_loads;
END_DECLARE_SIM_OBJECT_PARAMS(MemTest)
INIT_PARAM(cache, "L1 cache"),
INIT_PARAM(main_mem, "hierarchical memory"),
INIT_PARAM(check_mem, "check memory"),
- INIT_PARAM_DFLT(memory_size, "memory size", 65536),
- INIT_PARAM_DFLT(percent_reads, "target read percentage", 65),
- INIT_PARAM_DFLT(percent_copies, "target copy percentage", 0),
- INIT_PARAM_DFLT(percent_uncacheable, "target uncacheable percentage", 10),
- INIT_PARAM_DFLT(progress_interval,
- "progress report interval (in accesses)", 1000000),
- INIT_PARAM_DFLT(percent_source_unaligned, "percent of copy source address "
- "that are unaligned", 50),
- INIT_PARAM_DFLT(percent_dest_unaligned, "percent of copy dest address "
- "that are unaligned", 50),
- INIT_PARAM_DFLT(trace_addr, "address to trace", 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(memory_size, "memory size"),
+ INIT_PARAM(percent_reads, "target read percentage"),
+ INIT_PARAM(percent_copies, "target copy percentage"),
+ INIT_PARAM(percent_uncacheable, "target uncacheable percentage"),
+ INIT_PARAM(progress_interval, "progress report interval (in accesses)"),
+ INIT_PARAM(percent_source_unaligned,
+ "percent of copy source address that are unaligned"),
+ INIT_PARAM(percent_dest_unaligned,
+ "percent of copy dest address that are unaligned"),
+ INIT_PARAM(trace_addr, "address to trace"),
+ INIT_PARAM(max_loads, "terminate when we have reached this load count")
END_INIT_SIM_OBJECT_PARAMS(MemTest)
check_mem, memory_size, percent_reads, percent_copies,
percent_uncacheable, progress_interval,
percent_source_unaligned, percent_dest_unaligned,
- trace_addr, max_loads_any_thread,
- max_loads_all_threads);
+ trace_addr, max_loads);
}
REGISTER_SIM_OBJECT("MemTest", MemTest)
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __MEMTEST_HH__
-#define __MEMTEST_HH__
+#ifndef __CPU_MEMTEST_MEMTEST_HH__
+#define __CPU_MEMTEST_MEMTEST_HH__
#include <set>
#include "base/statistics.hh"
-#include "cpu/base_cpu.hh"
-#include "cpu/exec_context.hh"
#include "mem/functional_mem/functional_memory.hh"
#include "mem/mem_interface.hh"
+#include "sim/eventq.hh"
+#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
-class MemTest : public BaseCPU
+class ExecContext;
+class MemTest : public SimObject
{
public:
unsigned _percentSourceUnaligned,
unsigned _percentDestUnaligned,
Addr _traceAddr,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads);
+ Counter _max_loads);
// register statistics
virtual void regStats();
Tick noResponseCycles;
uint64_t numReads;
+ uint64_t maxLoads;
Stats::Scalar<> numReadsStat;
Stats::Scalar<> numWritesStat;
Stats::Scalar<> numCopiesStat;
virtual const char *description();
};
-#endif // __MEMTEST_HH__
+#endif // __CPU_MEMTEST_MEMTEST_HH__
return "SimpleCPU cache completion event";
}
-#ifdef FULL_SYSTEM
-SimpleCPU::SimpleCPU(const string &_name,
- System *_system,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- AlphaITB *itb, AlphaDTB *dtb,
- FunctionalMemory *mem,
- MemInterface *icache_interface,
- MemInterface *dcache_interface,
- bool _def_reg, Tick freq,
- bool _function_trace, Tick _function_trace_start,
- int width)
- : BaseCPU(_name, /* number_of_threads */ 1, _def_reg,
- max_insts_any_thread, max_insts_all_threads,
- max_loads_any_thread, max_loads_all_threads,
- _system, freq, _function_trace, _function_trace_start),
-#else
-SimpleCPU::SimpleCPU(const string &_name, Process *_process,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- MemInterface *icache_interface,
- MemInterface *dcache_interface,
- bool _def_reg,
- bool _function_trace, Tick _function_trace_start,
- int width)
- : BaseCPU(_name, /* number_of_threads */ 1, _def_reg,
- max_insts_any_thread, max_insts_all_threads,
- max_loads_any_thread, max_loads_all_threads,
- _function_trace, _function_trace_start),
-#endif
- tickEvent(this, width), xc(NULL), cacheCompletionEvent(this)
+SimpleCPU::SimpleCPU(Params *p)
+ : BaseCPU(p), tickEvent(this, p->width), xc(NULL),
+ cacheCompletionEvent(this)
{
_status = Idle;
#ifdef FULL_SYSTEM
- xc = new ExecContext(this, 0, system, itb, dtb, mem);
+ xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
// initialize CPU, including PC
TheISA::initCPU(&xc->regs);
#else
- xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0);
+ xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
#endif // !FULL_SYSTEM
- icacheInterface = icache_interface;
- dcacheInterface = dcache_interface;
+ icacheInterface = p->icache_interface;
+ dcacheInterface = p->dcache_interface;
memReq = new MemReq();
memReq->xc = xc;
BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
- 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(max_insts_any_thread,
+ "terminate when any thread reaches this inst count"),
+ INIT_PARAM(max_insts_all_threads,
+ "terminate when all threads have reached this inst count"),
+ INIT_PARAM(max_loads_any_thread,
+ "terminate when any thread reaches this load count"),
+ INIT_PARAM(max_loads_all_threads,
+ "terminate when all threads have reached this load count"),
#ifdef FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
INIT_PARAM(dtb, "Data TLB"),
INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
- INIT_PARAM_DFLT(mult, "system clock multiplier", 1),
+ INIT_PARAM(mult, "system clock multiplier"),
#else
INIT_PARAM(workload, "processes to run"),
#endif // FULL_SYSTEM
- INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL),
- INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL),
- INIT_PARAM_DFLT(defer_registration, "defer registration with system "
- "(for sampling)", false),
-
- INIT_PARAM_DFLT(width, "cpu width", 1),
- INIT_PARAM_DFLT(function_trace, "Enable function trace", false),
- INIT_PARAM_DFLT(function_trace_start, "Cycle to start function trace", 0)
+ 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(width, "cpu width"),
+ INIT_PARAM(function_trace, "Enable function trace"),
+ INIT_PARAM(function_trace_start, "Cycle to start function trace")
END_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
CREATE_SIM_OBJECT(SimpleCPU)
{
- SimpleCPU *cpu;
#ifdef FULL_SYSTEM
if (mult != 1)
panic("processor clock multiplier must be 1\n");
+#endif
- cpu = new SimpleCPU(getInstanceName(), system,
- max_insts_any_thread, max_insts_all_threads,
- max_loads_any_thread, max_loads_all_threads,
- itb, dtb, mem,
- (icache) ? icache->getInterface() : NULL,
- (dcache) ? dcache->getInterface() : NULL,
- defer_registration,
- ticksPerSecond * mult,
- function_trace, function_trace_start,
- width);
-#else
-
- cpu = new SimpleCPU(getInstanceName(), workload,
- max_insts_any_thread, max_insts_all_threads,
- max_loads_any_thread, max_loads_all_threads,
- (icache) ? icache->getInterface() : NULL,
- (dcache) ? dcache->getInterface() : NULL,
- defer_registration,
- function_trace, function_trace_start,
- width);
+ SimpleCPU::Params *params = new SimpleCPU::Params();
+ params->name = getInstanceName();
+ params->numberOfThreads = 1;
+ 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;
+ params->deferRegistration = defer_registration;
+ params->freq = ticksPerSecond;
+ params->functionTrace = function_trace;
+ params->functionTraceStart = function_trace_start;
+ params->icache_interface = (icache) ? icache->getInterface() : NULL;
+ params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;
+ params->width = width;
-#endif // FULL_SYSTEM
+#ifdef FULL_SYSTEM
+ params->itb = itb;
+ params->dtb = dtb;
+ params->mem = mem;
+ params->system = system;
+#else
+ params->process = workload;
+#endif
+ SimpleCPU *cpu = new SimpleCPU(params);
return cpu;
}
}
};
+ public:
+ struct Params : public BaseCPU::Params
+ {
+ MemInterface *icache_interface;
+ MemInterface *dcache_interface;
+ int width;
#ifdef FULL_SYSTEM
-
- SimpleCPU(const std::string &_name,
- System *_system,
- Counter max_insts_any_thread, Counter max_insts_all_threads,
- Counter max_loads_any_thread, Counter max_loads_all_threads,
- AlphaITB *itb, AlphaDTB *dtb, FunctionalMemory *mem,
- MemInterface *icache_interface, MemInterface *dcache_interface,
- bool _def_reg, Tick freq,
- bool _function_trace, Tick _function_trace_start, int width);
-
+ AlphaITB *itb;
+ AlphaDTB *dtb;
+ FunctionalMemory *mem;
#else
-
- SimpleCPU(const std::string &_name, Process *_process,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- MemInterface *icache_interface, MemInterface *dcache_interface,
- bool _def_reg,
- bool _function_trace, Tick _function_trace_start, int width);
-
+ Process *process;
#endif
-
+ };
+ SimpleCPU(Params *params);
virtual ~SimpleCPU();
+ public:
// execution context
ExecContext *xc;
int block_size,
int cache_size,
int _assoc)
- : BaseCPU(name, 1, true), tickEvent(this), trace(_trace),
+ : SimObject(name), tickEvent(this), trace(_trace),
numBlks(cache_size/block_size), assoc(_assoc), numSets(numBlks/assoc),
setMask(numSets - 1)
{
* trace to access a fully associative cache with optimal replacement.
*/
-#ifndef __OPT_CPU_HH__
-#define __OPT_CPU_HH__
+#ifndef __CPU_TRACE_OPT_CPU_HH__
+#define __CPU_TRACE_OPT_CPU_HH__
#include <vector>
-#include "cpu/base_cpu.hh"
#include "mem/mem_req.hh" // for MemReqPtr
#include "sim/eventq.hh" // for Event
+#include "sim/sim_object.hh"
// Forward Declaration
class MemTraceReader;
/**
* A CPU object to simulate a fully-associative cache with optimal replacement.
*/
-class OptCPU : public BaseCPU
+class OptCPU : public SimObject
{
+ private:
typedef int RefIndex;
typedef std::vector<RefIndex> L3Table;
void tick();
};
-#endif
+#endif // __CPU_TRACE_OPT_CPU_HH__
MemInterface *icache_interface,
MemInterface *dcache_interface,
MemTraceReader *data_trace)
- : BaseCPU(name, 4, true), icacheInterface(icache_interface),
+ : SimObject(name), icacheInterface(icache_interface),
dcacheInterface(dcache_interface),
dataTrace(data_trace), outstandingRequests(0), tickEvent(this)
{
* provided memory hierarchy.
*/
-#ifndef __TRACE_CPU_HH__
-#define __TRACE_CPU_HH__
+#ifndef __CPU_TRACE_TRACE_CPU_HH__
+#define __CPU_TRACE_TRACE_CPU_HH__
#include <string>
-#include "cpu/base_cpu.hh"
#include "mem/mem_req.hh" // for MemReqPtr
#include "sim/eventq.hh" // for Event
+#include "sim/sim_object.hh"
// Forward declaration.
class MemInterface;
/**
* A cpu object for running memory traces through a memory hierarchy.
*/
-class TraceCPU : public BaseCPU
+class TraceCPU : public SimObject
{
+ private:
/** Interface for instruction trace requests, if any. */
MemInterface *icacheInterface;
/** Interface for data trace requests, if any. */
virtual const char *description();
};
-#endif //__TRACE_CPU_HH__
+#endif // __CPU_TRACE_TRACE_CPU_HH__
cache = Param.BaseCache("L1 cache")
check_mem = Param.FunctionalMemory("check memory")
main_mem = Param.FunctionalMemory("hierarchical memory")
- max_loads_all_threads = Param.Counter(0,
- "terminate when all threads have reached this load count")
- max_loads_any_thread = Param.Counter(0,
- "terminate when any thread reaches this load count")
+ max_loads = Param.Counter("number of loads to execute")
memory_size = Param.Int(65536, "memory size")
percent_copies = Param.Percent(0, "target copy percentage")
percent_dest_unaligned = Param.Percent(50,
// Reset to put the stats in a consistent state.
Stats::reset();
- // Nothing to simulate if we don't have at least one CPU somewhere.
- if (BaseCPU::numSimulatedCPUs() == 0) {
- cerr << "Fatal: no CPUs to simulate." << endl;
- exit(1);
- }
-
warn("Entering event queue. Starting simulation...\n");
SimStartup();
while (!mainEventQueue.empty()) {