Merge ktlim@zizzer.eecs.umich.edu:/bk/m5
into zamp.eecs.umich.edu:/z/ktlim2/m5 --HG-- extra : convert_revision : 8a558785c64b7c33e64523d3d887ea6e760c3d2b
This commit is contained in:
@@ -501,6 +501,8 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
|
||||
*/
|
||||
if (req->vaddr & (req->size - 1)) {
|
||||
fault(req, write ? MM_STAT_WR_MASK : 0);
|
||||
DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr,
|
||||
req->size);
|
||||
return Alignment_Fault;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,6 +286,13 @@ check()
|
||||
|
||||
Database::stats().sort(StatData::less);
|
||||
|
||||
#if defined(STATS_BINNING)
|
||||
if (MainBin::curBin() == NULL) {
|
||||
static MainBin mainBin("main bin");
|
||||
mainBin.activate();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i == end)
|
||||
return;
|
||||
|
||||
|
||||
@@ -2184,7 +2184,7 @@ class SumNode : public Node
|
||||
* binned. If the typedef is NoBin, nothing is binned. If it is
|
||||
* MainBin, then all stats are binned under that Bin.
|
||||
*/
|
||||
#if defined(FS_MEASURE) || defined(STATS_BINNING)
|
||||
#if defined(STATS_BINNING)
|
||||
typedef MainBin DefaultBin;
|
||||
#else
|
||||
typedef NoBin DefaultBin;
|
||||
|
||||
@@ -126,7 +126,7 @@ Text::output()
|
||||
using namespace Database;
|
||||
|
||||
ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
|
||||
if (bins().empty()) {
|
||||
if (bins().empty() || bins().size() == 1) {
|
||||
stat_list_t::const_iterator i, end = stats().end();
|
||||
for (i = stats().begin(); i != end; ++i)
|
||||
(*i)->visit(*this);
|
||||
|
||||
@@ -52,25 +52,12 @@ int maxThreadsPerCPU = 1;
|
||||
|
||||
extern void debug_break();
|
||||
#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
|
||||
{
|
||||
DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);
|
||||
@@ -94,12 +81,12 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
|
||||
//
|
||||
// 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
|
||||
@@ -108,7 +95,7 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
|
||||
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
|
||||
@@ -119,12 +106,12 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
|
||||
//
|
||||
// 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
|
||||
@@ -133,7 +120,7 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
|
||||
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
|
||||
@@ -142,18 +129,18 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,7 +159,7 @@ BaseCPU::~BaseCPU()
|
||||
void
|
||||
BaseCPU::init()
|
||||
{
|
||||
if (!deferRegistration)
|
||||
if (!params->deferRegistration)
|
||||
registerExecContexts();
|
||||
}
|
||||
|
||||
|
||||
@@ -90,28 +90,31 @@ class BaseCPU : public SimObject
|
||||
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
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#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"
|
||||
@@ -59,10 +60,8 @@ MemTest::MemTest(const string &name,
|
||||
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),
|
||||
@@ -74,12 +73,13 @@ MemTest::MemTest(const string &name,
|
||||
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;
|
||||
@@ -160,7 +160,8 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
|
||||
nextProgressMessage += progressInterval;
|
||||
}
|
||||
|
||||
comLoadEventQueue[0]->serviceEvents(numReads);
|
||||
if (numReads >= maxLoads)
|
||||
SimExit(curTick, "Maximum number of loads reached!");
|
||||
break;
|
||||
|
||||
case Write:
|
||||
@@ -402,8 +403,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
|
||||
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)
|
||||
|
||||
@@ -413,23 +413,17 @@ BEGIN_INIT_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)
|
||||
|
||||
@@ -440,8 +434,7 @@ CREATE_SIM_OBJECT(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)
|
||||
|
||||
@@ -26,20 +26,21 @@
|
||||
* 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:
|
||||
|
||||
@@ -55,8 +56,7 @@ class MemTest : public BaseCPU
|
||||
unsigned _percentSourceUnaligned,
|
||||
unsigned _percentDestUnaligned,
|
||||
Addr _traceAddr,
|
||||
Counter max_loads_any_thread,
|
||||
Counter max_loads_all_threads);
|
||||
Counter _max_loads);
|
||||
|
||||
// register statistics
|
||||
virtual void regStats();
|
||||
@@ -116,6 +116,7 @@ class MemTest : public BaseCPU
|
||||
Tick noResponseCycles;
|
||||
|
||||
uint64_t numReads;
|
||||
uint64_t maxLoads;
|
||||
Stats::Scalar<> numReadsStat;
|
||||
Stats::Scalar<> numWritesStat;
|
||||
Stats::Scalar<> numCopiesStat;
|
||||
@@ -146,7 +147,7 @@ class MemCompleteEvent : public Event
|
||||
virtual const char *description();
|
||||
};
|
||||
|
||||
#endif // __MEMTEST_HH__
|
||||
#endif // __CPU_MEMTEST_MEMTEST_HH__
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -75,15 +75,15 @@
|
||||
using namespace std;
|
||||
|
||||
|
||||
SimpleCPU::TickEvent::TickEvent(SimpleCPU *c)
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), multiplier(1)
|
||||
SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w)
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), width(w)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SimpleCPU::TickEvent::process()
|
||||
{
|
||||
int count = multiplier;
|
||||
int count = width;
|
||||
do {
|
||||
cpu->tick();
|
||||
} while (--count > 0 && cpu->status() == Running);
|
||||
@@ -97,8 +97,7 @@ SimpleCPU::TickEvent::description()
|
||||
|
||||
|
||||
SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
|
||||
: Event(&mainEventQueue),
|
||||
cpu(_cpu)
|
||||
: Event(&mainEventQueue), cpu(_cpu)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -113,52 +112,22 @@ SimpleCPU::CacheCompletionEvent::description()
|
||||
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)
|
||||
: 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)
|
||||
: 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), 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;
|
||||
@@ -841,7 +810,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
|
||||
SimObjectParam<BaseMem *> dcache;
|
||||
|
||||
Param<bool> defer_registration;
|
||||
Param<int> multiplier;
|
||||
Param<int> width;
|
||||
Param<bool> function_trace;
|
||||
Param<Tick> function_trace_start;
|
||||
|
||||
@@ -849,71 +818,67 @@ END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
|
||||
|
||||
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(multiplier, "clock multiplier", 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);
|
||||
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;
|
||||
|
||||
#ifdef FULL_SYSTEM
|
||||
params->itb = itb;
|
||||
params->dtb = dtb;
|
||||
params->mem = mem;
|
||||
params->system = system;
|
||||
#else
|
||||
params->process = workload;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
cpu->setTickMultiplier(multiplier);
|
||||
|
||||
SimpleCPU *cpu = new SimpleCPU(params);
|
||||
return cpu;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ class SimpleCPU : public BaseCPU
|
||||
struct TickEvent : public Event
|
||||
{
|
||||
SimpleCPU *cpu;
|
||||
int multiplier;
|
||||
int width;
|
||||
|
||||
TickEvent(SimpleCPU *c);
|
||||
TickEvent(SimpleCPU *c, int w);
|
||||
void process();
|
||||
const char *description();
|
||||
};
|
||||
@@ -94,12 +94,6 @@ class SimpleCPU : public BaseCPU
|
||||
tickEvent.squash();
|
||||
}
|
||||
|
||||
public:
|
||||
void setTickMultiplier(int multiplier)
|
||||
{
|
||||
tickEvent.multiplier = multiplier;
|
||||
}
|
||||
|
||||
private:
|
||||
Trace::InstRecord *traceData;
|
||||
|
||||
@@ -128,32 +122,24 @@ class SimpleCPU : public BaseCPU
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
Process *process;
|
||||
#endif
|
||||
|
||||
};
|
||||
SimpleCPU(Params *params);
|
||||
virtual ~SimpleCPU();
|
||||
|
||||
public:
|
||||
// execution context
|
||||
ExecContext *xc;
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ OptCPU::OptCPU(const string &name,
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -32,14 +32,14 @@
|
||||
* 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;
|
||||
@@ -47,8 +47,9 @@ 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;
|
||||
@@ -219,4 +220,4 @@ class OptCPU : public BaseCPU
|
||||
void tick();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __CPU_TRACE_OPT_CPU_HH__
|
||||
|
||||
@@ -47,7 +47,7 @@ TraceCPU::TraceCPU(const string &name,
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -32,14 +32,14 @@
|
||||
* 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;
|
||||
@@ -48,8 +48,9 @@ class MemTraceReader;
|
||||
/**
|
||||
* 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. */
|
||||
@@ -133,5 +134,5 @@ class TraceCompleteEvent : public Event
|
||||
virtual const char *description();
|
||||
};
|
||||
|
||||
#endif //__TRACE_CPU_HH__
|
||||
#endif // __CPU_TRACE_TRACE_CPU_HH__
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
* retains pointers to all its children so the children can communicate.
|
||||
*/
|
||||
|
||||
#ifndef __TSUNAMI_HH__
|
||||
#define __TSUNAMI_HH__
|
||||
#ifndef __DEV_TSUNAMI_HH__
|
||||
#define __DEV_TSUNAMI_HH__
|
||||
|
||||
#include "dev/platform.hh"
|
||||
|
||||
@@ -56,7 +56,6 @@ class System;
|
||||
class Tsunami : public Platform
|
||||
{
|
||||
public:
|
||||
|
||||
/** Max number of CPUs in a Tsunami */
|
||||
static const int Max_CPUs = 64;
|
||||
|
||||
@@ -67,15 +66,15 @@ class Tsunami : public Platform
|
||||
TsunamiIO *io;
|
||||
|
||||
/** Pointer to the Tsunami CChip.
|
||||
* The chip contains some configuration information and
|
||||
* all the interrupt mask and status registers
|
||||
*/
|
||||
* The chip contains some configuration information and
|
||||
* all the interrupt mask and status registers
|
||||
*/
|
||||
TsunamiCChip *cchip;
|
||||
|
||||
/** Pointer to the Tsunami PChip.
|
||||
* The pchip is the interface to the PCI bus, in our case
|
||||
* it does not have to do much.
|
||||
*/
|
||||
* The pchip is the interface to the PCI bus, in our case
|
||||
* it does not have to do much.
|
||||
*/
|
||||
TsunamiPChip *pchip;
|
||||
|
||||
int intr_sum_type[Tsunami::Max_CPUs];
|
||||
@@ -83,12 +82,12 @@ class Tsunami : public Platform
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor for the Tsunami Class.
|
||||
* @param name name of the object
|
||||
* @param con pointer to the console
|
||||
* @param intrcontrol pointer to the interrupt controller
|
||||
* @param intrFreq frequency that interrupts happen
|
||||
*/
|
||||
* Constructor for the Tsunami Class.
|
||||
* @param name name of the object
|
||||
* @param con pointer to the console
|
||||
* @param intrcontrol pointer to the interrupt controller
|
||||
* @param intrFreq frequency that interrupts happen
|
||||
*/
|
||||
Tsunami(const std::string &name, System *s, IntrControl *intctrl,
|
||||
PciConfigAll *pci, int intrFreq);
|
||||
|
||||
@@ -96,7 +95,7 @@ class Tsunami : public Platform
|
||||
* Return the interrupting frequency to AlphaAccess
|
||||
* @return frequency of RTC interrupts
|
||||
*/
|
||||
virtual Tick intrFrequency();
|
||||
virtual Tick intrFrequency();
|
||||
|
||||
/**
|
||||
* Cause the cpu to post a serial interrupt to the CPU.
|
||||
@@ -120,7 +119,7 @@ class Tsunami : public Platform
|
||||
|
||||
virtual Addr pciToDma(Addr pciAddr) const;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Serialize this object to the given output stream.
|
||||
* @param os The stream to serialize to.
|
||||
*/
|
||||
@@ -134,4 +133,4 @@ class Tsunami : public Platform
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
#endif // __TSUNAMI_HH__
|
||||
#endif // __DEV_TSUNAMI_HH__
|
||||
|
||||
@@ -176,7 +176,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
|
||||
if (regnum == TSDEV_CC_DRIR) {
|
||||
warn("accessing DRIR with 32 bit read, "
|
||||
"hopefully your just reading this for timing");
|
||||
*(uint64_t*)data = drir;
|
||||
*(uint32_t*)data = drir;
|
||||
} else
|
||||
panic("invalid access size(?) for tsunami register!\n");
|
||||
return No_Fault;
|
||||
|
||||
@@ -67,7 +67,6 @@ TsunamiIO::RTCEvent::process()
|
||||
schedule(curTick + ticksPerSecond/RTC_RATE);
|
||||
//Actually interrupt the processor here
|
||||
tsunami->cchip->postRTC();
|
||||
|
||||
}
|
||||
|
||||
const char *
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
* Tsunami Fake I/O Space mapping including RTC/timer interrupts
|
||||
*/
|
||||
|
||||
#ifndef __TSUNAMI_DMA_HH__
|
||||
#define __TSUNAMI_DMA_HH__
|
||||
#ifndef __DEV_TSUNAMI_IO_HH__
|
||||
#define __DEV_TSUNAMI_IO_HH__
|
||||
|
||||
#include "dev/io_device.hh"
|
||||
#include "base/range.hh"
|
||||
@@ -56,9 +56,11 @@ class TsunamiIO : public PioDevice
|
||||
|
||||
struct tm tm;
|
||||
|
||||
/** In Tsunami RTC only has two i/o ports one for data and one for address,
|
||||
* so you write the address and then read/write the data. This store the
|
||||
* address you are going to be reading from on a read.
|
||||
/**
|
||||
* In Tsunami RTC only has two i/o ports one for data and one for
|
||||
* address, so you write the address and then read/write the
|
||||
* data. This store the address you are going to be reading from
|
||||
* on a read.
|
||||
*/
|
||||
uint8_t RTCAddress;
|
||||
|
||||
@@ -132,38 +134,37 @@ class TsunamiIO : public PioDevice
|
||||
class RTCEvent : public Event
|
||||
{
|
||||
protected:
|
||||
/** A pointer back to tsunami to create interrupt the processor. */
|
||||
Tsunami* tsunami;
|
||||
/** A pointer back to tsunami to create interrupt the processor. */
|
||||
Tsunami* tsunami;
|
||||
public:
|
||||
/** RTC Event initializes the RTC event by scheduling an event
|
||||
* RTC_RATE times pre second. */
|
||||
RTCEvent(Tsunami* t);
|
||||
/** RTC Event initializes the RTC event by scheduling an event
|
||||
* RTC_RATE times pre second. */
|
||||
RTCEvent(Tsunami* t);
|
||||
|
||||
/**
|
||||
* Interrupth the processor and reschedule the event.
|
||||
* */
|
||||
virtual void process();
|
||||
/**
|
||||
* Interrupth the processor and reschedule the event.
|
||||
*/
|
||||
virtual void process();
|
||||
|
||||
/**
|
||||
* Return a description of this event.
|
||||
* @return a description
|
||||
*/
|
||||
virtual const char *description();
|
||||
/**
|
||||
* Return a description of this event.
|
||||
* @return a description
|
||||
*/
|
||||
virtual const char *description();
|
||||
|
||||
/**
|
||||
* Serialize this object to the given output stream.
|
||||
* @param os The stream to serialize to.
|
||||
*/
|
||||
virtual void serialize(std::ostream &os);
|
||||
/**
|
||||
* Serialize this object to the given output stream.
|
||||
* @param os The stream to serialize to.
|
||||
*/
|
||||
virtual void serialize(std::ostream &os);
|
||||
|
||||
|
||||
/**
|
||||
* Reconstruct the state of this object from a checkpoint.
|
||||
* @param cp The checkpoint use.
|
||||
* @param section The section name of this object
|
||||
*/
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
/**
|
||||
* Reconstruct the state of this object from a checkpoint.
|
||||
* @param cp The checkpoint use.
|
||||
* @param section The section name of this object
|
||||
*/
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
/** uip UpdateInProgess says that the rtc is updating, but we just fake it
|
||||
* by alternating it on every read of the bit since we are going to
|
||||
@@ -219,7 +220,6 @@ class TsunamiIO : public PioDevice
|
||||
*/
|
||||
uint32_t timerData;
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* Return the freqency of the RTC
|
||||
@@ -227,7 +227,6 @@ class TsunamiIO : public PioDevice
|
||||
*/
|
||||
Tick frequency() const { return RTC_RATE; }
|
||||
|
||||
|
||||
/**
|
||||
* Initialize all the data for devices supported by Tsunami I/O.
|
||||
* @param name name of this device.
|
||||
@@ -279,7 +278,6 @@ class TsunamiIO : public PioDevice
|
||||
*/
|
||||
virtual void serialize(std::ostream &os);
|
||||
|
||||
|
||||
/**
|
||||
* Reconstruct the state of this object from a checkpoint.
|
||||
* @param cp The checkpoint use.
|
||||
@@ -287,8 +285,7 @@ class TsunamiIO : public PioDevice
|
||||
*/
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
|
||||
Tick cacheAccess(MemReqPtr &req);
|
||||
};
|
||||
|
||||
#endif // __TSUNAMI_IO_HH__
|
||||
#endif // __DEV_TSUNAMI_IO_HH__
|
||||
|
||||
@@ -3,10 +3,7 @@ simobj MemTest(SimObject):
|
||||
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,
|
||||
|
||||
10
sim/main.cc
10
sim/main.cc
@@ -31,6 +31,8 @@
|
||||
///
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
@@ -107,7 +109,7 @@ abortHandler(int sigtype)
|
||||
}
|
||||
|
||||
/// Simulator executable name
|
||||
const char *myProgName = "";
|
||||
char *myProgName = "";
|
||||
|
||||
/// Show brief help message.
|
||||
void
|
||||
@@ -400,12 +402,6 @@ main(int argc, char **argv)
|
||||
// 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()) {
|
||||
|
||||
@@ -88,8 +88,6 @@ Process::Process(const string &name,
|
||||
fd_map[i] = -1;
|
||||
}
|
||||
|
||||
num_syscalls = 0;
|
||||
|
||||
// other parameters will be initialized when the program is loaded
|
||||
}
|
||||
|
||||
@@ -145,21 +143,28 @@ Process::registerExecContext(ExecContext *xc)
|
||||
execContexts.push_back(xc);
|
||||
|
||||
if (myIndex == 0) {
|
||||
// first exec context for this process... initialize & enable
|
||||
|
||||
// copy process's initial regs struct
|
||||
xc->regs = *init_regs;
|
||||
|
||||
// mark this context as active.
|
||||
// activate with zero delay so that we start ticking right
|
||||
// away on cycle 0
|
||||
xc->activate(0);
|
||||
}
|
||||
|
||||
// return CPU number to caller and increment available CPU count
|
||||
return myIndex;
|
||||
}
|
||||
|
||||
void
|
||||
Process::startup()
|
||||
{
|
||||
if (execContexts.empty())
|
||||
return;
|
||||
|
||||
// first exec context for this process... initialize & enable
|
||||
ExecContext *xc = execContexts[0];
|
||||
|
||||
// mark this context as active.
|
||||
// activate with zero delay so that we start ticking right
|
||||
// away on cycle 0
|
||||
xc->activate(0);
|
||||
}
|
||||
|
||||
void
|
||||
Process::replaceExecContext(ExecContext *xc, int xcIndex)
|
||||
|
||||
@@ -108,6 +108,8 @@ class Process : public SimObject
|
||||
int stdout_fd,
|
||||
int stderr_fd);
|
||||
|
||||
// post initialization startup
|
||||
virtual void startup();
|
||||
|
||||
protected:
|
||||
FunctionalMemory *memory;
|
||||
|
||||
@@ -156,7 +156,7 @@ if not onlyecho:
|
||||
job.cleandir(jobdir)
|
||||
else:
|
||||
os.mkdir(jobdir)
|
||||
jl.append(jobname)
|
||||
jl.append(jobname)
|
||||
joblist = jl
|
||||
|
||||
for jobname in joblist:
|
||||
|
||||
Reference in New Issue
Block a user