Merge zizzer:/bk/newmem

into  zazzer.eecs.umich.edu:/.automount/zooks/y/ksewell/research/m5-sim/newmem-release

--HG--
extra : convert_revision : 9b5b1419e8e22bce16ed97fc02c2008ca0181afc
This commit is contained in:
Korey Sewell 2006-06-14 14:43:45 -04:00
commit 2a9becba44
24 changed files with 302 additions and 322 deletions

View file

@ -6,12 +6,14 @@
import os, optparse, sys import os, optparse, sys
import m5 import m5
from m5.objects import * from m5.objects import *
from FullO3Config import *
# parse command-line arguments # parse command-line arguments
parser = optparse.OptionParser(option_list=m5.standardOptions) parser = optparse.OptionParser(option_list=m5.standardOptions)
parser.add_option("-c", "--cmd", default="hello") parser.add_option("-c", "--cmd", default="hello")
parser.add_option("-t", "--timing", action="store_true") parser.add_option("-t", "--timing", action="store_true")
parser.add_option("-f", "--full", action="store_true")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
@ -31,6 +33,8 @@ mem = PhysicalMemory()
if options.timing: if options.timing:
cpu = TimingSimpleCPU() cpu = TimingSimpleCPU()
elif options.full:
cpu = DetailedCPU()
else: else:
cpu = AtomicSimpleCPU() cpu = AtomicSimpleCPU()
cpu.workload = process cpu.workload = process

View file

@ -59,8 +59,12 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId)
tc->setIntReg(16, cpuId); tc->setIntReg(16, cpuId);
tc->setIntReg(0, cpuId); tc->setIntReg(0, cpuId);
tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect()); AlphaFault *reset = new ResetFault;
tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + reset->vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst)); tc->setNextPC(tc->readPC() + sizeof(MachInst));
delete reset;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

View file

@ -659,11 +659,11 @@ decode OPCODE default Unknown::unknown() {
0xe000: rc({{ 0xe000: rc({{
Ra = xc->readIntrFlag(); Ra = xc->readIntrFlag();
xc->setIntrFlag(0); xc->setIntrFlag(0);
}}, IsNonSpeculative); }}, IsNonSpeculative, IsUnverifiable);
0xf000: rs({{ 0xf000: rs({{
Ra = xc->readIntrFlag(); Ra = xc->readIntrFlag();
xc->setIntrFlag(1); xc->setIntrFlag(1);
}}, IsNonSpeculative); }}, IsNonSpeculative, IsUnverifiable);
} }
#else #else
format FailUnimpl { format FailUnimpl {
@ -701,7 +701,7 @@ decode OPCODE default Unknown::unknown() {
}}, IsNonSpeculative); }}, IsNonSpeculative);
0x83: callsys({{ 0x83: callsys({{
xc->syscall(R0); xc->syscall(R0);
}}, IsNonSpeculative); }}, IsSerializeAfter, IsNonSpeculative);
// Read uniq reg into ABI return value register (r0) // Read uniq reg into ABI return value register (r0)
0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess); 0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess);
// Write uniq reg with value from ABI arg register (r16) // Write uniq reg with value from ABI arg register (r16)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2005 The Regents of The University of Michigan * Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -103,6 +103,8 @@ BaseDynInst<Impl>::initVars()
readyRegs = 0; readyRegs = 0;
instResult.integer = 0;
// May want to turn this into a bit vector or something. // May want to turn this into a bit vector or something.
completed = false; completed = false;
resultReady = false; resultReady = false;
@ -242,31 +244,7 @@ template <class Impl>
void void
BaseDynInst<Impl>::writeHint(Addr addr, int size, unsigned flags) BaseDynInst<Impl>::writeHint(Addr addr, int size, unsigned flags)
{ {
// Need to create a MemReq here so we can do a translation. This // Not currently supported.
// will casue a TLB miss trap if necessary... not sure whether
// that's the best thing to do or not. We don't really need the
// MemReq otherwise, since wh64 has no functional effect.
/*
MemReqPtr req = new MemReq(addr, thread->getXCProxy(), size, flags);
req->asid = asid;
fault = cpu->translateDataWriteReq(req);
if (fault == NoFault && !(req->flags & UNCACHEABLE)) {
// Record key MemReq parameters so we can generate another one
// just like it for the timing access without calling translate()
// again (which might mess up the TLB).
effAddr = req->vaddr;
physEffAddr = req->paddr;
memReqFlags = req->flags;
} else {
// ignore faults & accesses to uncacheable space... treat as no-op
effAddr = physEffAddr = MemReq::inval_addr;
}
storeSize = size;
storeData = 0;
*/
} }
/** /**
@ -276,22 +254,7 @@ template <class Impl>
Fault Fault
BaseDynInst<Impl>::copySrcTranslate(Addr src) BaseDynInst<Impl>::copySrcTranslate(Addr src)
{ {
/* // Not currently supported.
MemReqPtr req = new MemReq(src, thread->getXCProxy(), 64);
req->asid = asid;
// translate to physical address
Fault fault = cpu->translateDataReadReq(req);
if (fault == NoFault) {
thread->copySrcAddr = src;
thread->copySrcPhysAddr = req->paddr;
} else {
thread->copySrcAddr = 0;
thread->copySrcPhysAddr = 0;
}
return fault;
*/
return NoFault; return NoFault;
} }
@ -302,26 +265,7 @@ template <class Impl>
Fault Fault
BaseDynInst<Impl>::copy(Addr dest) BaseDynInst<Impl>::copy(Addr dest)
{ {
/* // Not currently supported.
uint8_t data[64];
FunctionalMemory *mem = thread->mem;
assert(thread->copySrcPhysAddr);
MemReqPtr req = new MemReq(dest, thread->getXCProxy(), 64);
req->asid = asid;
// translate to physical address
Fault fault = cpu->translateDataWriteReq(req);
if (fault == NoFault) {
Addr dest_addr = req->paddr;
// Need to read straight from memory since we have more than 8 bytes.
req->paddr = thread->copySrcPhysAddr;
mem->read(req, data);
req->paddr = dest_addr;
mem->write(req, data);
}
return fault;
*/
return NoFault; return NoFault;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2005 The Regents of The University of Michigan * Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -44,12 +44,6 @@
#include "cpu/static_inst.hh" #include "cpu/static_inst.hh"
#include "mem/packet.hh" #include "mem/packet.hh"
#include "sim/system.hh" #include "sim/system.hh"
/*
#include "encumbered/cpu/full/bpred_update.hh"
#include "encumbered/cpu/full/spec_memory.hh"
#include "encumbered/cpu/full/spec_state.hh"
#include "encumbered/mem/functional/main.hh"
*/
/** /**
* @file * @file
@ -202,10 +196,9 @@ class BaseDynInst : public FastAlloc, public RefCounted
Fault fault; Fault fault;
/** The memory request. */ /** The memory request. */
// MemReqPtr req;
Request *req; Request *req;
// Packet pkt;
/** Pointer to the data for the memory access. */
uint8_t *memData; uint8_t *memData;
/** The effective virtual address (lds & stores only). */ /** The effective virtual address (lds & stores only). */
@ -288,21 +281,6 @@ class BaseDynInst : public FastAlloc, public RefCounted
void initVars(); void initVars();
public: public:
/**
* @todo: Make this function work; currently it is a dummy function.
* @param fault Last fault.
* @param cmd Last command.
* @param addr Virtual address of access.
* @param p Memory accessed.
* @param nbytes Access size.
*/
// void
// trace_mem(Fault fault,
// MemCmd cmd,
// Addr addr,
// void *p,
// int nbytes);
/** Dumps out contents of this BaseDynInst. */ /** Dumps out contents of this BaseDynInst. */
void dump(); void dump();
@ -439,11 +417,13 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Returns the result of a floating point (double) instruction. */ /** Returns the result of a floating point (double) instruction. */
double readDoubleResult() { return instResult.dbl; } double readDoubleResult() { return instResult.dbl; }
/** Records an integer register being set to a value. */
void setIntReg(const StaticInst *si, int idx, uint64_t val) void setIntReg(const StaticInst *si, int idx, uint64_t val)
{ {
instResult.integer = val; instResult.integer = val;
} }
/** Records an fp register being set to a value. */
void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
{ {
if (width == 32) if (width == 32)
@ -454,16 +434,19 @@ class BaseDynInst : public FastAlloc, public RefCounted
panic("Unsupported width!"); panic("Unsupported width!");
} }
/** Records an fp register being set to a value. */
void setFloatReg(const StaticInst *si, int idx, FloatReg val) void setFloatReg(const StaticInst *si, int idx, FloatReg val)
{ {
instResult.fp = val; instResult.fp = val;
} }
/** Records an fp register being set to an integer value. */
void setFloatRegBits(const StaticInst *si, int idx, uint64_t val, int width) void setFloatRegBits(const StaticInst *si, int idx, uint64_t val, int width)
{ {
instResult.integer = val; instResult.integer = val;
} }
/** Records an fp register being set to an integer value. */
void setFloatRegBits(const StaticInst *si, int idx, uint64_t val) void setFloatRegBits(const StaticInst *si, int idx, uint64_t val)
{ {
instResult.integer = val; instResult.integer = val;
@ -590,14 +573,15 @@ class BaseDynInst : public FastAlloc, public RefCounted
void setNextPC(uint64_t val) void setNextPC(uint64_t val)
{ {
nextPC = val; nextPC = val;
// instResult.integer = val;
} }
/** Sets the ASID. */
void setASID(short addr_space_id) { asid = addr_space_id; } void setASID(short addr_space_id) { asid = addr_space_id; }
void setThread(unsigned tid) { threadNumber = tid; } /** Sets the thread id. */
void setTid(unsigned tid) { threadNumber = tid; }
void setState(ImplState *state) { thread = state; } void setThreadState(ImplState *state) { thread = state; }
/** Returns the thread context. /** Returns the thread context.
*/ */

View file

@ -85,6 +85,8 @@ CheckerCPU::CheckerCPU(Params *p)
#else #else
process = p->process; process = p->process;
#endif #endif
result.integer = 0;
} }
CheckerCPU::~CheckerCPU() CheckerCPU::~CheckerCPU()

View file

@ -92,11 +92,6 @@ Param<unsigned> commitToIEWDelay;
Param<unsigned> renameToIEWDelay; Param<unsigned> renameToIEWDelay;
Param<unsigned> issueToExecuteDelay; Param<unsigned> issueToExecuteDelay;
Param<unsigned> issueWidth; Param<unsigned> issueWidth;
Param<unsigned> executeWidth;
Param<unsigned> executeIntWidth;
Param<unsigned> executeFloatWidth;
Param<unsigned> executeBranchWidth;
Param<unsigned> executeMemoryWidth;
SimObjectParam<FUPool *> fuPool; SimObjectParam<FUPool *> fuPool;
Param<unsigned> iewToCommitDelay; Param<unsigned> iewToCommitDelay;
@ -213,11 +208,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
INIT_PARAM(issueToExecuteDelay, "Issue to execute delay (internal" INIT_PARAM(issueToExecuteDelay, "Issue to execute delay (internal"
"to the IEW stage)"), "to the IEW stage)"),
INIT_PARAM(issueWidth, "Issue width"), 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_DFLT(fuPool, "Functional unit pool", NULL), INIT_PARAM_DFLT(fuPool, "Functional unit pool", NULL),
INIT_PARAM(iewToCommitDelay, "Issue/Execute/Writeback to commit " INIT_PARAM(iewToCommitDelay, "Issue/Execute/Writeback to commit "
@ -344,11 +334,6 @@ CREATE_SIM_OBJECT(DerivAlphaFullCPU)
params->renameToIEWDelay = renameToIEWDelay; params->renameToIEWDelay = renameToIEWDelay;
params->issueToExecuteDelay = issueToExecuteDelay; params->issueToExecuteDelay = issueToExecuteDelay;
params->issueWidth = issueWidth; params->issueWidth = issueWidth;
params->executeWidth = executeWidth;
params->executeIntWidth = executeIntWidth;
params->executeFloatWidth = executeFloatWidth;
params->executeBranchWidth = executeBranchWidth;
params->executeMemoryWidth = executeMemoryWidth;
params->fuPool = fuPool; params->fuPool = fuPool;
params->iewToCommitDelay = iewToCommitDelay; params->iewToCommitDelay = iewToCommitDelay;

View file

@ -105,11 +105,6 @@ class AlphaSimpleParams : public BaseFullCPU::Params
unsigned renameToIEWDelay; unsigned renameToIEWDelay;
unsigned issueToExecuteDelay; unsigned issueToExecuteDelay;
unsigned issueWidth; unsigned issueWidth;
unsigned executeWidth;
unsigned executeIntWidth;
unsigned executeFloatWidth;
unsigned executeBranchWidth;
unsigned executeMemoryWidth;
FUPool *fuPool; FUPool *fuPool;
// //

View file

@ -365,11 +365,6 @@ class DefaultCommit
*/ */
unsigned renameWidth; unsigned renameWidth;
/** IEW width, in instructions. Used so ROB knows how many
* instructions to get from the IEW instruction queue.
*/
unsigned iewWidth;
/** Commit width, in instructions. */ /** Commit width, in instructions. */
unsigned commitWidth; unsigned commitWidth;

View file

@ -72,7 +72,6 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
renameToROBDelay(params->renameToROBDelay), renameToROBDelay(params->renameToROBDelay),
fetchToCommitDelay(params->commitToFetchDelay), fetchToCommitDelay(params->commitToFetchDelay),
renameWidth(params->renameWidth), renameWidth(params->renameWidth),
iewWidth(params->executeWidth),
commitWidth(params->commitWidth), commitWidth(params->commitWidth),
numThreads(params->numberOfThreads), numThreads(params->numberOfThreads),
switchPending(false), switchPending(false),
@ -205,19 +204,6 @@ DefaultCommit<Impl>::regStats()
.flags(total) .flags(total)
; ;
//
// Commit-Eligible instructions...
//
// -> The number of instructions eligible to commit in those
// cycles where we reached our commit BW limit (less the number
// actually committed)
//
// -> The average value is computed over ALL CYCLES... not just
// the BW limited cycles
//
// -> The standard deviation is computed only over cycles where
// we reached the BW limit
//
commitEligible commitEligible
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".COM:bw_limited") .name(name() + ".COM:bw_limited")
@ -434,7 +420,7 @@ DefaultCommit<Impl>::setNextStatus()
} }
} }
assert(squashes == squashCounter); squashCounter = squashes;
// If commit is currently squashing, then it will have activity for the // If commit is currently squashing, then it will have activity for the
// next cycle. Set its next status as active. // next cycle. Set its next status as active.
@ -539,8 +525,6 @@ DefaultCommit<Impl>::squashFromTrap(unsigned tid)
commitStatus[tid] = ROBSquashing; commitStatus[tid] = ROBSquashing;
cpu->activityThisCycle(); cpu->activityThisCycle();
++squashCounter;
} }
template <class Impl> template <class Impl>
@ -558,8 +542,6 @@ DefaultCommit<Impl>::squashFromTC(unsigned tid)
cpu->activityThisCycle(); cpu->activityThisCycle();
tcSquash[tid] = false; tcSquash[tid] = false;
++squashCounter;
} }
template <class Impl> template <class Impl>
@ -585,10 +567,12 @@ DefaultCommit<Impl>::tick()
if (rob->isDoneSquashing(tid)) { if (rob->isDoneSquashing(tid)) {
commitStatus[tid] = Running; commitStatus[tid] = Running;
--squashCounter;
} else { } else {
DPRINTF(Commit,"[tid:%u]: Still Squashing, cannot commit any" DPRINTF(Commit,"[tid:%u]: Still Squashing, cannot commit any"
"insts this cycle.\n", tid); "insts this cycle.\n", tid);
rob->doSquash(tid);
toIEW->commitInfo[tid].robSquashing = true;
wroteToTimeBuffer = true;
} }
} }
} }
@ -694,29 +678,7 @@ DefaultCommit<Impl>::commit()
while (threads != (*activeThreads).end()) { while (threads != (*activeThreads).end()) {
unsigned tid = *threads++; unsigned tid = *threads++;
/*
if (fromFetch->fetchFault && commitStatus[0] != TrapPending) {
// Record the fault. Wait until it's empty in the ROB.
// Then handle the trap. Ignore it if there's already a
// trap pending as fetch will be redirected.
fetchFault = fromFetch->fetchFault;
fetchFaultTick = curTick + fetchTrapLatency;
commitStatus[0] = FetchTrapPending;
DPRINTF(Commit, "Fault from fetch recorded. Will trap if the "
"ROB empties without squashing the fault.\n");
fetchTrapWait = 0;
}
// Fetch may tell commit to clear the trap if it's been squashed.
if (fromFetch->clearFetchFault) {
DPRINTF(Commit, "Received clear fetch fault signal\n");
fetchTrapWait = 0;
if (commitStatus[0] == FetchTrapPending) {
DPRINTF(Commit, "Clearing fault from fetch\n");
commitStatus[0] = Running;
}
}
*/
// Not sure which one takes priority. I think if we have // Not sure which one takes priority. I think if we have
// both, that's a bad sign. // both, that's a bad sign.
if (trapSquash[tid] == true) { if (trapSquash[tid] == true) {
@ -744,8 +706,6 @@ DefaultCommit<Impl>::commit()
commitStatus[tid] = ROBSquashing; commitStatus[tid] = ROBSquashing;
++squashCounter;
// If we want to include the squashing instruction in the squash, // If we want to include the squashing instruction in the squash,
// then use one older sequence number. // then use one older sequence number.
InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid]; InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];

View file

@ -515,7 +515,7 @@ DefaultDecode<Impl>::checkSignalsAndUpdate(unsigned tid)
// Check ROB squash signals from commit. // Check ROB squash signals from commit.
if (fromCommit->commitInfo[tid].robSquashing) { if (fromCommit->commitInfo[tid].robSquashing) {
DPRINTF(Decode, "[tid:%]: ROB is still squashing.\n",tid); DPRINTF(Decode, "[tid:%u]: ROB is still squashing.\n", tid);
// Continue to squash. // Continue to squash.
decodeStatus[tid] = Squashing; decodeStatus[tid] = Squashing;

View file

@ -421,6 +421,7 @@ class DefaultFetch
Stats::Scalar<> icacheStallCycles; Stats::Scalar<> icacheStallCycles;
/** Stat for total number of fetched instructions. */ /** Stat for total number of fetched instructions. */
Stats::Scalar<> fetchedInsts; Stats::Scalar<> fetchedInsts;
/** Total number of fetched branches. */
Stats::Scalar<> fetchedBranches; Stats::Scalar<> fetchedBranches;
/** Stat for total number of predicted branches. */ /** Stat for total number of predicted branches. */
Stats::Scalar<> predictedBranches; Stats::Scalar<> predictedBranches;

View file

@ -817,7 +817,7 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(unsigned tid)
// Check ROB squash signals from commit. // Check ROB squash signals from commit.
if (fromCommit->commitInfo[tid].robSquashing) { if (fromCommit->commitInfo[tid].robSquashing) {
DPRINTF(Fetch, "[tid:%u]: ROB is still squashing Thread %u.\n", tid); DPRINTF(Fetch, "[tid:%u]: ROB is still squashing.\n", tid);
// Continue to squash. // Continue to squash.
fetchStatus[tid] = Squashing; fetchStatus[tid] = Squashing;
@ -915,7 +915,11 @@ DefaultFetch<Impl>::fetch(bool &status_change)
bool fetch_success = fetchCacheLine(fetch_PC, fault, tid); bool fetch_success = fetchCacheLine(fetch_PC, fault, tid);
if (!fetch_success) { if (!fetch_success) {
if (cacheBlocked) {
++icacheStallCycles;
} else {
++fetchMiscStallCycles; ++fetchMiscStallCycles;
}
return; return;
} }
} else { } else {
@ -984,11 +988,11 @@ DefaultFetch<Impl>::fetch(bool &status_change)
DynInstPtr instruction = new DynInst(ext_inst, fetch_PC, DynInstPtr instruction = new DynInst(ext_inst, fetch_PC,
next_PC, next_PC,
inst_seq, cpu); inst_seq, cpu);
instruction->setThread(tid); instruction->setTid(tid);
instruction->setASID(tid); instruction->setASID(tid);
instruction->setState(cpu->thread[tid]); instruction->setThreadState(cpu->thread[tid]);
DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created " DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created "
"[sn:%lli]\n", "[sn:%lli]\n",
@ -1065,11 +1069,11 @@ DefaultFetch<Impl>::fetch(bool &status_change)
next_PC, next_PC,
inst_seq, cpu); inst_seq, cpu);
instruction->setPredTarg(next_PC + instSize); instruction->setPredTarg(next_PC + instSize);
instruction->setThread(tid); instruction->setTid(tid);
instruction->setASID(tid); instruction->setASID(tid);
instruction->setState(cpu->thread[tid]); instruction->setThreadState(cpu->thread[tid]);
instruction->traceData = NULL; instruction->traceData = NULL;

View file

@ -261,6 +261,9 @@ class DefaultIEW
/** Processes inputs and changes state accordingly. */ /** Processes inputs and changes state accordingly. */
void checkSignalsAndUpdate(unsigned tid); void checkSignalsAndUpdate(unsigned tid);
/** Removes instructions from rename from a thread's instruction list. */
void emptyRenameInsts(unsigned tid);
/** Sorts instructions coming from rename into lists separated by thread. */ /** Sorts instructions coming from rename into lists separated by thread. */
void sortInsts(); void sortInsts();
@ -390,11 +393,6 @@ class DefaultIEW
/** Width of issue, in instructions. */ /** Width of issue, in instructions. */
unsigned issueWidth; unsigned issueWidth;
/** Width of execute, in instructions. Might make more sense to break
* down into FP vs int.
*/
unsigned executeWidth;
/** Index into queue of instructions being written back. */ /** Index into queue of instructions being written back. */
unsigned wbNumInst; unsigned wbNumInst;
@ -439,14 +437,6 @@ class DefaultIEW
Stats::Scalar<> iewIQFullEvents; Stats::Scalar<> iewIQFullEvents;
/** Stat for number of times the LSQ becomes full. */ /** Stat for number of times the LSQ becomes full. */
Stats::Scalar<> iewLSQFullEvents; Stats::Scalar<> iewLSQFullEvents;
/** Stat for total number of executed instructions. */
Stats::Scalar<> iewExecutedInsts;
/** Stat for total number of executed load instructions. */
Stats::Vector<> iewExecLoadInsts;
/** Stat for total number of executed store instructions. */
// Stats::Scalar<> iewExecStoreInsts;
/** Stat for total number of squashed instructions skipped at execute. */
Stats::Scalar<> iewExecSquashedInsts;
/** Stat for total number of memory ordering violation events. */ /** Stat for total number of memory ordering violation events. */
Stats::Scalar<> memOrderViolationEvents; Stats::Scalar<> memOrderViolationEvents;
/** Stat for total number of incorrect predicted taken branches. */ /** Stat for total number of incorrect predicted taken branches. */
@ -456,28 +446,25 @@ class DefaultIEW
/** Stat for total number of mispredicted branches detected at execute. */ /** Stat for total number of mispredicted branches detected at execute. */
Stats::Formula branchMispredicts; Stats::Formula branchMispredicts;
/** Stat for total number of executed instructions. */
Stats::Scalar<> iewExecutedInsts;
/** Stat for total number of executed load instructions. */
Stats::Vector<> iewExecLoadInsts;
/** Stat for total number of squashed instructions skipped at execute. */
Stats::Scalar<> iewExecSquashedInsts;
/** Number of executed software prefetches. */ /** Number of executed software prefetches. */
Stats::Vector<> exeSwp; Stats::Vector<> iewExecutedSwp;
/** Number of executed nops. */ /** Number of executed nops. */
Stats::Vector<> exeNop; Stats::Vector<> iewExecutedNop;
/** Number of executed meomory references. */ /** Number of executed meomory references. */
Stats::Vector<> exeRefs; Stats::Vector<> iewExecutedRefs;
/** Number of executed branches. */ /** Number of executed branches. */
Stats::Vector<> exeBranches; Stats::Vector<> iewExecutedBranches;
// Stats::Vector<> issued_ops;
/*
Stats::Vector<> stat_fu_busy;
Stats::Vector2d<> stat_fuBusy;
Stats::Vector<> dist_unissued;
Stats::Vector2d<> stat_issued_inst_type;
*/
/** Number of instructions issued per cycle. */
Stats::Formula issueRate;
/** Number of executed store instructions. */ /** Number of executed store instructions. */
Stats::Formula iewExecStoreInsts; Stats::Formula iewExecStoreInsts;
// Stats::Formula issue_op_rate; /** Number of instructions executed per cycle. */
// Stats::Formula fu_busy_rate; Stats::Formula iewExecRate;
/** Number of instructions sent to commit. */ /** Number of instructions sent to commit. */
Stats::Vector<> iewInstsToCommit; Stats::Vector<> iewInstsToCommit;
/** Number of instructions that writeback. */ /** Number of instructions that writeback. */
@ -490,7 +477,6 @@ class DefaultIEW
* to resource contention. * to resource contention.
*/ */
Stats::Vector<> wbPenalized; Stats::Vector<> wbPenalized;
/** Number of instructions per cycle written back. */ /** Number of instructions per cycle written back. */
Stats::Formula wbRate; Stats::Formula wbRate;
/** Average number of woken instructions per writeback. */ /** Average number of woken instructions per writeback. */

View file

@ -52,7 +52,6 @@ DefaultIEW<Impl>::DefaultIEW(Params *params)
issueToExecuteDelay(params->issueToExecuteDelay), issueToExecuteDelay(params->issueToExecuteDelay),
issueReadWidth(params->issueWidth), issueReadWidth(params->issueWidth),
issueWidth(params->issueWidth), issueWidth(params->issueWidth),
executeWidth(params->executeWidth),
numThreads(params->numberOfThreads), numThreads(params->numberOfThreads),
switchedOut(false) switchedOut(false)
{ {
@ -94,6 +93,7 @@ DefaultIEW<Impl>::regStats()
using namespace Stats; using namespace Stats;
instQueue.regStats(); instQueue.regStats();
ldstQueue.regStats();
iewIdleCycles iewIdleCycles
.name(name() + ".iewIdleCycles") .name(name() + ".iewIdleCycles")
@ -139,20 +139,6 @@ DefaultIEW<Impl>::regStats()
.name(name() + ".iewLSQFullEvents") .name(name() + ".iewLSQFullEvents")
.desc("Number of times the LSQ has become full, causing a stall"); .desc("Number of times the LSQ has become full, causing a stall");
iewExecutedInsts
.name(name() + ".iewExecutedInsts")
.desc("Number of executed instructions");
iewExecLoadInsts
.init(cpu->number_of_threads)
.name(name() + ".iewExecLoadInsts")
.desc("Number of load instructions executed")
.flags(total);
iewExecSquashedInsts
.name(name() + ".iewExecSquashedInsts")
.desc("Number of squashed instructions skipped in execute");
memOrderViolationEvents memOrderViolationEvents
.name(name() + ".memOrderViolationEvents") .name(name() + ".memOrderViolationEvents")
.desc("Number of memory order violations"); .desc("Number of memory order violations");
@ -171,114 +157,105 @@ DefaultIEW<Impl>::regStats()
branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect; branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
exeSwp iewExecutedInsts
.name(name() + ".EXEC:insts")
.desc("Number of executed instructions");
iewExecLoadInsts
.init(cpu->number_of_threads)
.name(name() + ".EXEC:loads")
.desc("Number of load instructions executed")
.flags(total);
iewExecSquashedInsts
.name(name() + ".EXEC:squashedInsts")
.desc("Number of squashed instructions skipped in execute");
iewExecutedSwp
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".EXEC:swp") .name(name() + ".EXEC:swp")
.desc("number of swp insts executed") .desc("number of swp insts executed")
.flags(total) .flags(total);
;
exeNop iewExecutedNop
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".EXEC:nop") .name(name() + ".EXEC:nop")
.desc("number of nop insts executed") .desc("number of nop insts executed")
.flags(total) .flags(total);
;
exeRefs iewExecutedRefs
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".EXEC:refs") .name(name() + ".EXEC:refs")
.desc("number of memory reference insts executed") .desc("number of memory reference insts executed")
.flags(total) .flags(total);
;
exeBranches iewExecutedBranches
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".EXEC:branches") .name(name() + ".EXEC:branches")
.desc("Number of branches executed") .desc("Number of branches executed")
.flags(total) .flags(total);
;
issueRate
.name(name() + ".EXEC:rate")
.desc("Inst execution rate")
.flags(total)
;
issueRate = iewExecutedInsts / cpu->numCycles;
iewExecStoreInsts iewExecStoreInsts
.name(name() + ".EXEC:stores") .name(name() + ".EXEC:stores")
.desc("Number of stores executed") .desc("Number of stores executed")
.flags(total) .flags(total);
; iewExecStoreInsts = iewExecutedRefs - iewExecLoadInsts;
iewExecStoreInsts = exeRefs - iewExecLoadInsts;
/* iewExecRate
for (int i=0; i<Num_OpClasses; ++i) { .name(name() + ".EXEC:rate")
stringstream subname; .desc("Inst execution rate")
subname << opClassStrings[i] << "_delay"; .flags(total);
issue_delay_dist.subname(i, subname.str());
} iewExecRate = iewExecutedInsts / cpu->numCycles;
*/
//
// Other stats
//
iewInstsToCommit iewInstsToCommit
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".WB:sent") .name(name() + ".WB:sent")
.desc("cumulative count of insts sent to commit") .desc("cumulative count of insts sent to commit")
.flags(total) .flags(total);
;
writebackCount writebackCount
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".WB:count") .name(name() + ".WB:count")
.desc("cumulative count of insts written-back") .desc("cumulative count of insts written-back")
.flags(total) .flags(total);
;
producerInst producerInst
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".WB:producers") .name(name() + ".WB:producers")
.desc("num instructions producing a value") .desc("num instructions producing a value")
.flags(total) .flags(total);
;
consumerInst consumerInst
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".WB:consumers") .name(name() + ".WB:consumers")
.desc("num instructions consuming a value") .desc("num instructions consuming a value")
.flags(total) .flags(total);
;
wbPenalized wbPenalized
.init(cpu->number_of_threads) .init(cpu->number_of_threads)
.name(name() + ".WB:penalized") .name(name() + ".WB:penalized")
.desc("number of instrctions required to write to 'other' IQ") .desc("number of instrctions required to write to 'other' IQ")
.flags(total) .flags(total);
;
wbPenalizedRate wbPenalizedRate
.name(name() + ".WB:penalized_rate") .name(name() + ".WB:penalized_rate")
.desc ("fraction of instructions written-back that wrote to 'other' IQ") .desc ("fraction of instructions written-back that wrote to 'other' IQ")
.flags(total) .flags(total);
;
wbPenalizedRate = wbPenalized / writebackCount; wbPenalizedRate = wbPenalized / writebackCount;
wbFanout wbFanout
.name(name() + ".WB:fanout") .name(name() + ".WB:fanout")
.desc("average fanout of values written-back") .desc("average fanout of values written-back")
.flags(total) .flags(total);
;
wbFanout = producerInst / consumerInst; wbFanout = producerInst / consumerInst;
wbRate wbRate
.name(name() + ".WB:rate") .name(name() + ".WB:rate")
.desc("insts written-back per cycle") .desc("insts written-back per cycle")
.flags(total) .flags(total);
;
wbRate = writebackCount / cpu->numCycles; wbRate = writebackCount / cpu->numCycles;
} }
@ -456,16 +433,7 @@ DefaultIEW<Impl>::squash(unsigned tid)
skidBuffer[tid].pop(); skidBuffer[tid].pop();
} }
while (!insts[tid].empty()) { emptyRenameInsts(tid);
if (insts[tid].front()->isLoad() ||
insts[tid].front()->isStore() ) {
toRename->iewInfo[tid].dispatchedToLSQ++;
}
toRename->iewInfo[tid].dispatched++;
insts[tid].pop();
}
} }
template<class Impl> template<class Impl>
@ -799,10 +767,12 @@ DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid)
} }
if (fromCommit->commitInfo[tid].robSquashing) { if (fromCommit->commitInfo[tid].robSquashing) {
DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n"); DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid);
dispatchStatus[tid] = Squashing; dispatchStatus[tid] = Squashing;
emptyRenameInsts(tid);
wroteToTimeBuffer = true;
return; return;
} }
@ -851,6 +821,22 @@ DefaultIEW<Impl>::sortInsts()
} }
} }
template <class Impl>
void
DefaultIEW<Impl>::emptyRenameInsts(unsigned tid)
{
while (!insts[tid].empty()) {
if (insts[tid].front()->isLoad() ||
insts[tid].front()->isStore() ) {
toRename->iewInfo[tid].dispatchedToLSQ++;
}
toRename->iewInfo[tid].dispatched++;
insts[tid].pop();
}
}
template <class Impl> template <class Impl>
void void
DefaultIEW<Impl>::wakeCPU() DefaultIEW<Impl>::wakeCPU()
@ -1090,7 +1076,7 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
instQueue.recordProducer(inst); instQueue.recordProducer(inst);
exeNop[tid]++; iewExecutedNop[tid]++;
add_to_iq = false; add_to_iq = false;
} else if (inst->isExecuted()) { } else if (inst->isExecuted()) {
@ -1501,9 +1487,9 @@ DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
// //
#ifdef TARGET_ALPHA #ifdef TARGET_ALPHA
if (inst->isDataPrefetch()) if (inst->isDataPrefetch())
exeSwp[thread_number]++; iewExecutedSwp[thread_number]++;
else else
iewExecutedInsts++; iewIewExecutedcutedInsts++;
#else #else
iewExecutedInsts++; iewExecutedInsts++;
#endif #endif
@ -1512,13 +1498,13 @@ DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
// Control operations // Control operations
// //
if (inst->isControl()) if (inst->isControl())
exeBranches[thread_number]++; iewExecutedBranches[thread_number]++;
// //
// Memory operations // Memory operations
// //
if (inst->isMemRef()) { if (inst->isMemRef()) {
exeRefs[thread_number]++; iewExecutedRefs[thread_number]++;
if (inst->isLoad()) { if (inst->isLoad()) {
iewExecLoadInsts[thread_number]++; iewExecLoadInsts[thread_number]++;

View file

@ -474,12 +474,17 @@ class InstructionQueue
/** Stat for number of non-speculative instructions removed due to a squash. /** Stat for number of non-speculative instructions removed due to a squash.
*/ */
Stats::Scalar<> iqSquashedNonSpecRemoved; Stats::Scalar<> iqSquashedNonSpecRemoved;
// Also include number of instructions rescheduled and replayed.
/** Distribution of number of instructions in the queue. */ /** Distribution of number of instructions in the queue.
* @todo: Need to create struct to track the entry time for each
* instruction. */
Stats::VectorDistribution<> queueResDist; Stats::VectorDistribution<> queueResDist;
/** Distribution of the number of instructions issued. */ /** Distribution of the number of instructions issued. */
Stats::Distribution<> numIssuedDist; Stats::Distribution<> numIssuedDist;
/** Distribution of the cycles it takes to issue an instruction. */ /** Distribution of the cycles it takes to issue an instruction.
* @todo: Need to create struct to track the ready time for each
* instruction. */
Stats::VectorDistribution<> issueDelayDist; Stats::VectorDistribution<> issueDelayDist;
/** Number of times an instruction could not be issued because a /** Number of times an instruction could not be issued because a
@ -492,8 +497,7 @@ class InstructionQueue
/** Number of instructions issued per cycle. */ /** Number of instructions issued per cycle. */
Stats::Formula issueRate; Stats::Formula issueRate;
// Stats::Formula issue_stores;
// Stats::Formula issue_op_rate;
/** Number of times the FU was busy. */ /** Number of times the FU was busy. */
Stats::Vector<> fuBusy; Stats::Vector<> fuBusy;
/** Number of times the FU was busy per instruction issued. */ /** Number of times the FU was busy per instruction issued. */

View file

@ -289,22 +289,7 @@ InstructionQueue<Impl>::regStats()
.flags(total) .flags(total)
; ;
issueRate = iqInstsIssued / cpu->numCycles; issueRate = iqInstsIssued / cpu->numCycles;
/*
issue_stores
.name(name() + ".ISSUE:stores")
.desc("Number of stores issued")
.flags(total)
;
issue_stores = exe_refs - exe_loads;
*/
/*
issue_op_rate
.name(name() + ".ISSUE:op_rate")
.desc("Operation issue rate")
.flags(total)
;
issue_op_rate = issued_ops / numCycles;
*/
statFuBusy statFuBusy
.init(Num_OpClasses) .init(Num_OpClasses)
.name(name() + ".ISSUE:fu_full") .name(name() + ".ISSUE:fu_full")

View file

@ -62,6 +62,9 @@ class LSQ {
/** Returns the name of the LSQ. */ /** Returns the name of the LSQ. */
std::string name() const; std::string name() const;
/** Registers statistics of each LSQ unit. */
void regStats();
/** Sets the pointer to the list of active threads. */ /** Sets the pointer to the list of active threads. */
void setActiveThreads(std::list<unsigned> *at_ptr); void setActiveThreads(std::list<unsigned> *at_ptr);
/** Sets the CPU pointer. */ /** Sets the CPU pointer. */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2006 The Regents of The University of Michigan * Copyright (c) 2005-2006 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -106,6 +106,16 @@ LSQ<Impl>::name() const
return iewStage->name() + ".lsq"; return iewStage->name() + ".lsq";
} }
template<class Impl>
void
LSQ<Impl>::regStats()
{
//Initialize LSQs
for (int tid=0; tid < numThreads; tid++) {
thread[tid].regStats();
}
}
template<class Impl> template<class Impl>
void void
LSQ<Impl>::setActiveThreads(list<unsigned> *at_ptr) LSQ<Impl>::setActiveThreads(list<unsigned> *at_ptr)

View file

@ -77,6 +77,9 @@ class LSQUnit {
/** Returns the name of the LSQ unit. */ /** Returns the name of the LSQ unit. */
std::string name() const; std::string name() const;
/** Registers statistics. */
void regStats();
/** Sets the CPU pointer. */ /** Sets the CPU pointer. */
void setCPU(FullCPU *cpu_ptr); void setCPU(FullCPU *cpu_ptr);
@ -127,9 +130,6 @@ class LSQUnit {
void completeDataAccess(PacketPtr pkt); void completeDataAccess(PacketPtr pkt);
// @todo: Include stats in the LSQ unit.
//void regStats();
/** Clears all the entries in the LQ. */ /** Clears all the entries in the LQ. */
void clearLQ(); void clearLQ();
@ -443,25 +443,35 @@ class LSQUnit {
// Will also need how many read/write ports the Dcache has. Or keep track // Will also need how many read/write ports the Dcache has. Or keep track
// of that in stage that is one level up, and only call executeLoad/Store // of that in stage that is one level up, and only call executeLoad/Store
// the appropriate number of times. // the appropriate number of times.
/*
// total number of loads forwaded from LSQ stores
Stats::Vector<> lsq_forw_loads;
// total number of loads ignored due to invalid addresses /** Total number of loads forwaded from LSQ stores. */
Stats::Vector<> inv_addr_loads; Stats::Scalar<> lsqForwLoads;
// total number of software prefetches ignored due to invalid addresses /** Total number of loads ignored due to invalid addresses. */
Stats::Vector<> inv_addr_swpfs; Stats::Scalar<> invAddrLoads;
// total non-speculative bogus addresses seen (debug var) /** Total number of squashed loads. */
Counter sim_invalid_addrs; Stats::Scalar<> lsqSquashedLoads;
Stats::Vector<> fu_busy; //cumulative fu busy
// ready loads blocked due to memory disambiguation /** Total number of responses from the memory system that are
Stats::Vector<> lsq_blocked_loads; * ignored due to the instruction already being squashed. */
Stats::Scalar<> lsqIgnoredResponses;
/** Total number of squashed stores. */
Stats::Scalar<> lsqSquashedStores;
/** Total number of software prefetches ignored due to invalid addresses. */
Stats::Scalar<> invAddrSwpfs;
/** Ready loads blocked due to partial store-forwarding. */
Stats::Scalar<> lsqBlockedLoads;
/** Number of loads that were rescheduled. */
Stats::Scalar<> lsqRescheduledLoads;
/** Number of times the LSQ is blocked due to the cache. */
Stats::Scalar<> lsqCacheBlocked;
Stats::Scalar<> lsqInversion;
*/
public: public:
/** Executes the load at the given index. */ /** Executes the load at the given index. */
template <class T> template <class T>
@ -519,6 +529,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
if (req->getFlags() & UNCACHEABLE && if (req->getFlags() & UNCACHEABLE &&
(load_idx != loadHead || !load_inst->reachedCommit)) { (load_idx != loadHead || !load_inst->reachedCommit)) {
iewStage->rescheduleMemInst(load_inst); iewStage->rescheduleMemInst(load_inst);
++lsqRescheduledLoads;
return TheISA::genMachineCheckFault(); return TheISA::genMachineCheckFault();
} }
@ -598,7 +609,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
// @todo: Need to make this a parameter. // @todo: Need to make this a parameter.
wb->schedule(curTick); wb->schedule(curTick);
// Should keep track of stat for forwarded data ++lsqForwLoads;
return NoFault; return NoFault;
} else if ((store_has_lower_limit && lower_load_has_store_part) || } else if ((store_has_lower_limit && lower_load_has_store_part) ||
(store_has_upper_limit && upper_load_has_store_part) || (store_has_upper_limit && upper_load_has_store_part) ||
@ -626,6 +637,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
// Tell IQ/mem dep unit that this instruction will need to be // Tell IQ/mem dep unit that this instruction will need to be
// rescheduled eventually // rescheduled eventually
iewStage->rescheduleMemInst(load_inst); iewStage->rescheduleMemInst(load_inst);
++lsqRescheduledLoads;
// Do not generate a writeback event as this instruction is not // Do not generate a writeback event as this instruction is not
// complete. // complete.
@ -633,6 +645,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
"Store idx %i to load addr %#x\n", "Store idx %i to load addr %#x\n",
store_idx, req->getVaddr()); store_idx, req->getVaddr());
++lsqBlockedLoads;
return NoFault; return NoFault;
} }
} }
@ -660,6 +673,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
// if we have a cache, do cache access too // if we have a cache, do cache access too
if (!dcachePort->sendTiming(data_pkt)) { if (!dcachePort->sendTiming(data_pkt)) {
++lsqCacheBlocked;
// There's an older load that's already going to squash. // There's an older load that's already going to squash.
if (isLoadBlocked && blockedLoadSeqNum < load_inst->seqNum) if (isLoadBlocked && blockedLoadSeqNum < load_inst->seqNum)
return NoFault; return NoFault;

View file

@ -196,6 +196,47 @@ LSQUnit<Impl>::name() const
} }
} }
template<class Impl>
void
LSQUnit<Impl>::regStats()
{
lsqForwLoads
.name(name() + ".forwLoads")
.desc("Number of loads that had data forwarded from stores");
invAddrLoads
.name(name() + ".invAddrLoads")
.desc("Number of loads ignored due to an invalid address");
lsqSquashedLoads
.name(name() + ".squashedLoads")
.desc("Number of loads squashed");
lsqIgnoredResponses
.name(name() + ".ignoredResponses")
.desc("Number of memory responses ignored because the instruction is squashed");
lsqSquashedStores
.name(name() + ".squashedStores")
.desc("Number of stores squashed");
invAddrSwpfs
.name(name() + ".invAddrSwpfs")
.desc("Number of software prefetches ignored due to an invalid address");
lsqBlockedLoads
.name(name() + ".blockedLoads")
.desc("Number of blocked loads due to partial load-store forwarding");
lsqRescheduledLoads
.name(name() + ".rescheduledLoads")
.desc("Number of loads that were rescheduled");
lsqCacheBlocked
.name(name() + ".cacheBlocked")
.desc("Number of times an access to memory failed due to the cache being blocked");
}
template<class Impl> template<class Impl>
void void
LSQUnit<Impl>::clearLQ() LSQUnit<Impl>::clearLQ()
@ -618,7 +659,7 @@ LSQUnit<Impl>::writebackStores()
if (!dcachePort->sendTiming(data_pkt)) { if (!dcachePort->sendTiming(data_pkt)) {
// Need to handle becoming blocked on a store. // Need to handle becoming blocked on a store.
isStoreBlocked = true; isStoreBlocked = true;
++lsqCacheBlocked;
assert(retryPkt == NULL); assert(retryPkt == NULL);
retryPkt = data_pkt; retryPkt = data_pkt;
} else { } else {
@ -677,6 +718,7 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
loadTail = load_idx; loadTail = load_idx;
decrLdIdx(load_idx); decrLdIdx(load_idx);
++lsqSquashedLoads;
} }
if (isLoadBlocked) { if (isLoadBlocked) {
@ -723,6 +765,7 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
storeTail = store_idx; storeTail = store_idx;
decrStIdx(store_idx); decrStIdx(store_idx);
++lsqSquashedStores;
} }
} }
@ -782,6 +825,7 @@ LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
// Squashed instructions do not need to complete their access. // Squashed instructions do not need to complete their access.
if (inst->isSquashed()) { if (inst->isSquashed()) {
assert(!inst->isStore()); assert(!inst->isStore());
++lsqIgnoredResponses;
return; return;
} }
@ -858,6 +902,7 @@ LSQUnit<Impl>::recvRetry()
isStoreBlocked = false; isStoreBlocked = false;
} else { } else {
// Still blocked! // Still blocked!
++lsqCacheBlocked;
} }
} else if (isLoadBlocked) { } else if (isLoadBlocked) {
DPRINTF(LSQUnit, "Loads squash themselves and all younger insts, " DPRINTF(LSQUnit, "Loads squash themselves and all younger insts, "

View file

@ -1206,7 +1206,7 @@ DefaultRename<Impl>::checkSignalsAndUpdate(unsigned tid)
} }
DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename." DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename."
" Adding to front of list.", tid); " Adding to front of list.\n", tid);
serializeInst[tid] = NULL; serializeInst[tid] = NULL;

View file

@ -64,11 +64,34 @@ def AddToPath(path):
def setTraceFlags(option, opt_str, value, parser): def setTraceFlags(option, opt_str, value, parser):
objects.Trace.flags = value objects.Trace.flags = value
def setTraceStart(option, opt_str, value, parser):
objects.Trace.start = value
def clearPCSymbol(option, opt_str, value, parser):
objects.ExecutionTrace.pc_symbol = False
def clearPrintCycle(option, opt_str, value, parser):
objects.ExecutionTrace.print_cycle = False
def statsTextFile(option, opt_str, value, parser):
objects.Statistics.text_file = value
# Standard optparse options. Need to be explicitly included by the # Standard optparse options. Need to be explicitly included by the
# user script when it calls optparse.OptionParser(). # user script when it calls optparse.OptionParser().
standardOptions = [ standardOptions = [
optparse.make_option("--traceflags", type="string", action="callback", optparse.make_option("--traceflags", type="string", action="callback",
callback=setTraceFlags) callback=setTraceFlags),
optparse.make_option("--tracestart", type="int", action="callback",
callback=setTraceStart),
optparse.make_option("--nopcsymbol", action="callback",
callback=clearPCSymbol,
help="Turn off printing PC symbols in trace output"),
optparse.make_option("--noprintcycle", action="callback",
callback=clearPrintCycle,
help="Turn off printing cycles in trace output"),
optparse.make_option("--statsfile", type="string", action="callback",
callback=statsTextFile, metavar="FILE",
help="Sets the output file for the statistics")
] ]
# make a SmartDict out of the build options for our local use # make a SmartDict out of the build options for our local use

View file

@ -41,7 +41,7 @@
#include <libgen.h> #include <libgen.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <getopt.h>
#include <list> #include <list>
#include <string> #include <string>
@ -113,6 +113,31 @@ abortHandler(int sigtype)
#endif #endif
} }
/// Simulator executable name
char *myProgName = "";
/// Show brief help message.
void
showBriefHelp(ostream &out)
{
char *prog = basename(myProgName);
ccprintf(out, "Usage:\n");
ccprintf(out,
"%s [-p <path>] [-i ] [-h] <config file>\n"
"\n"
" -p, --path <path> prepends <path> to PYTHONPATH instead of using\n"
" built-in zip archive. Useful when developing/debugging\n"
" changes to built-in Python libraries, as the new Python\n"
" can be tested without building a new m5 binary.\n\n"
" -i, --interactive forces entry into interactive mode after the supplied\n"
" script is executed (just like the -i option to the\n"
" Python interpreter).\n\n"
" -h Prints this help\n\n"
" <configfile> config file name (ends in .py)\n\n",
prog);
}
const char *briefCopyright = const char *briefCopyright =
"Copyright (c) 2001-2006\n" "Copyright (c) 2001-2006\n"
@ -145,6 +170,9 @@ extern "C" { void init_main(); }
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
// Saze off program name
myProgName = argv[0];
sayHello(cerr); sayHello(cerr);
signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths
@ -161,9 +189,19 @@ main(int argc, char **argv)
char *pythonpath = argv[0]; char *pythonpath = argv[0];
bool interactive = false; bool interactive = false;
bool show_help = false;
bool getopt_done = false; bool getopt_done = false;
int opt_index = 0;
static struct option long_options[] = {
{"python", 1, 0, 'p'},
{"interactive", 0, 0, 'i'},
{"help", 0, 0, 'h'},
{0,0,0,0}
};
do { do {
switch (getopt(argc, argv, "+p:i")) { switch (getopt_long(argc, argv, "+p:ih", long_options, &opt_index)) {
// -p <path> prepends <path> to PYTHONPATH instead of // -p <path> prepends <path> to PYTHONPATH instead of
// using built-in zip archive. Useful when // using built-in zip archive. Useful when
// developing/debugging changes to built-in Python // developing/debugging changes to built-in Python
@ -180,6 +218,9 @@ main(int argc, char **argv)
interactive = true; interactive = true;
break; break;
case 'h':
show_help = true;
break;
case -1: case -1:
getopt_done = true; getopt_done = true;
break; break;
@ -189,6 +230,11 @@ main(int argc, char **argv)
} }
} while (!getopt_done); } while (!getopt_done);
if (show_help) {
showBriefHelp(cerr);
exit(1);
}
// Fix up argc & argv to hide arguments we just processed. // Fix up argc & argv to hide arguments we just processed.
// getopt() sets optind to the index of the first non-processed // getopt() sets optind to the index of the first non-processed
// argv element. // argv element.