Merge zizzer.eecs.umich.edu:/bk/newmem

into  ahchoo.blinky.homelinux.org:/home/gblack/m5/newmem-o3-spec

--HG--
extra : convert_revision : 81269f094834f43b4e908321bfce2e031b39d2a4
This commit is contained in:
Gabe Black 2007-04-04 20:50:49 +00:00
commit a664017c2a
29 changed files with 170 additions and 288 deletions

View file

@ -55,7 +55,7 @@
#endif #endif
template <class Impl> template <class Impl>
AlphaO3CPU<Impl>::AlphaO3CPU(Params *params) : FullO3CPU<Impl>(params) AlphaO3CPU<Impl>::AlphaO3CPU(Params *params) : FullO3CPU<Impl>(this, params)
{ {
DPRINTF(O3CPU, "Creating AlphaO3CPU object.\n"); DPRINTF(O3CPU, "Creating AlphaO3CPU object.\n");
@ -124,17 +124,6 @@ AlphaO3CPU<Impl>::AlphaO3CPU(Params *params) : FullO3CPU<Impl>(params)
this->thread[i]->setFuncExeInst(0); this->thread[i]->setFuncExeInst(0);
} }
// Sets CPU pointers. These must be set at this level because the CPU
// pointers are defined to be the highest level of CPU class.
this->fetch.setCPU(this);
this->decode.setCPU(this);
this->rename.setCPU(this);
this->iew.setCPU(this);
this->commit.setCPU(this);
this->rob.setCPU(this);
this->regFile.setCPU(this);
lockAddr = 0; lockAddr = 0;
lockFlag = false; lockFlag = false;
} }

View file

@ -136,7 +136,7 @@ class DefaultCommit
public: public:
/** Construct a DefaultCommit with the given parameters. */ /** Construct a DefaultCommit with the given parameters. */
DefaultCommit(Params *params); DefaultCommit(O3CPU *_cpu, Params *params);
/** Returns the name of the DefaultCommit. */ /** Returns the name of the DefaultCommit. */
std::string name() const; std::string name() const;
@ -144,9 +144,6 @@ class DefaultCommit
/** Registers statistics. */ /** Registers statistics. */
void regStats(); void regStats();
/** Sets the CPU pointer. */
void setCPU(O3CPU *cpu_ptr);
/** Sets the list of threads. */ /** Sets the list of threads. */
void setThreads(std::vector<Thread *> &threads); void setThreads(std::vector<Thread *> &threads);

View file

@ -71,8 +71,9 @@ DefaultCommit<Impl>::TrapEvent::description()
} }
template <class Impl> template <class Impl>
DefaultCommit<Impl>::DefaultCommit(Params *params) DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, Params *params)
: squashCounter(0), : cpu(_cpu),
squashCounter(0),
iewToCommitDelay(params->iewToCommitDelay), iewToCommitDelay(params->iewToCommitDelay),
commitToIEWDelay(params->commitToIEWDelay), commitToIEWDelay(params->commitToIEWDelay),
renameToROBDelay(params->renameToROBDelay), renameToROBDelay(params->renameToROBDelay),
@ -96,7 +97,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
if (policy == "aggressive"){ if (policy == "aggressive"){
commitPolicy = Aggressive; commitPolicy = Aggressive;
// DPRINTF(Commit,"Commit Policy set to Aggressive."); DPRINTF(Commit,"Commit Policy set to Aggressive.");
} else if (policy == "roundrobin"){ } else if (policy == "roundrobin"){
commitPolicy = RoundRobin; commitPolicy = RoundRobin;
@ -105,11 +106,11 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
priority_list.push_back(tid); priority_list.push_back(tid);
} }
// DPRINTF(Commit,"Commit Policy set to Round Robin."); DPRINTF(Commit,"Commit Policy set to Round Robin.");
} else if (policy == "oldestready"){ } else if (policy == "oldestready"){
commitPolicy = OldestReady; commitPolicy = OldestReady;
// DPRINTF(Commit,"Commit Policy set to Oldest Ready."); DPRINTF(Commit,"Commit Policy set to Oldest Ready.");
} else { } else {
assert(0 && "Invalid SMT Commit Policy. Options Are: {Aggressive," assert(0 && "Invalid SMT Commit Policy. Options Are: {Aggressive,"
"RoundRobin,OldestReady}"); "RoundRobin,OldestReady}");
@ -225,20 +226,6 @@ DefaultCommit<Impl>::regStats()
; ;
} }
template <class Impl>
void
DefaultCommit<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
DPRINTF(Commit, "Commit: Setting CPU pointer.\n");
// Commit must broadcast the number of free entries it has at the start of
// the simulation, so it starts as active.
cpu->activateStage(O3CPU::CommitIdx);
trapLatency = cpu->cycles(trapLatency);
}
template <class Impl> template <class Impl>
void void
DefaultCommit<Impl>::setThreads(std::vector<Thread *> &threads) DefaultCommit<Impl>::setThreads(std::vector<Thread *> &threads)
@ -333,7 +320,12 @@ DefaultCommit<Impl>::initStage()
toIEW->commitInfo[i].emptyROB = true; toIEW->commitInfo[i].emptyROB = true;
} }
// Commit must broadcast the number of free entries it has at the
// start of the simulation, so it starts as active.
cpu->activateStage(O3CPU::CommitIdx);
cpu->activityThisCycle(); cpu->activityThisCycle();
trapLatency = cpu->cycles(trapLatency);
} }
template <class Impl> template <class Impl>

View file

@ -148,7 +148,7 @@ FullO3CPU<Impl>::DeallocateContextEvent::description()
} }
template <class Impl> template <class Impl>
FullO3CPU<Impl>::FullO3CPU(Params *params) FullO3CPU<Impl>::FullO3CPU(O3CPU *o3_cpu, Params *params)
: BaseO3CPU(params), : BaseO3CPU(params),
#if FULL_SYSTEM #if FULL_SYSTEM
itb(params->itb), itb(params->itb),
@ -156,19 +156,21 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
#endif #endif
tickEvent(this), tickEvent(this),
removeInstsThisCycle(false), removeInstsThisCycle(false),
fetch(params), fetch(o3_cpu, params),
decode(params), decode(o3_cpu, params),
rename(params), rename(o3_cpu, params),
iew(params), iew(o3_cpu, params),
commit(params), commit(o3_cpu, params),
regFile(params->numPhysIntRegs, params->numPhysFloatRegs), regFile(o3_cpu, params->numPhysIntRegs,
params->numPhysFloatRegs),
freeList(params->numberOfThreads, freeList(params->numberOfThreads,
TheISA::NumIntRegs, params->numPhysIntRegs, TheISA::NumIntRegs, params->numPhysIntRegs,
TheISA::NumFloatRegs, params->numPhysFloatRegs), TheISA::NumFloatRegs, params->numPhysFloatRegs),
rob(params->numROBEntries, params->squashWidth, rob(o3_cpu,
params->numROBEntries, params->squashWidth,
params->smtROBPolicy, params->smtROBThreshold, params->smtROBPolicy, params->smtROBThreshold,
params->numberOfThreads), params->numberOfThreads),

View file

@ -95,6 +95,7 @@ class FullO3CPU : public BaseO3CPU
typedef typename Impl::CPUPol CPUPolicy; typedef typename Impl::CPUPol CPUPolicy;
typedef typename Impl::Params Params; typedef typename Impl::Params Params;
typedef typename Impl::DynInstPtr DynInstPtr; typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::O3CPU O3CPU;
typedef O3ThreadState<Impl> Thread; typedef O3ThreadState<Impl> Thread;
@ -256,7 +257,7 @@ class FullO3CPU : public BaseO3CPU
public: public:
/** Constructs a CPU with the given parameters. */ /** Constructs a CPU with the given parameters. */
FullO3CPU(Params *params); FullO3CPU(O3CPU *o3_cpu, Params *params);
/** Destructor. */ /** Destructor. */
~FullO3CPU(); ~FullO3CPU();

View file

@ -86,7 +86,7 @@ class DefaultDecode
public: public:
/** DefaultDecode constructor. */ /** DefaultDecode constructor. */
DefaultDecode(Params *params); DefaultDecode(O3CPU *_cpu, Params *params);
/** Returns the name of decode. */ /** Returns the name of decode. */
std::string name() const; std::string name() const;
@ -94,9 +94,6 @@ class DefaultDecode
/** Registers statistics. */ /** Registers statistics. */
void regStats(); void regStats();
/** Sets CPU pointer. */
void setCPU(O3CPU *cpu_ptr);
/** Sets the main backwards communication time buffer pointer. */ /** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);

View file

@ -31,8 +31,9 @@
#include "cpu/o3/decode.hh" #include "cpu/o3/decode.hh"
template<class Impl> template<class Impl>
DefaultDecode<Impl>::DefaultDecode(Params *params) DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, Params *params)
: renameToDecodeDelay(params->renameToDecodeDelay), : cpu(_cpu),
renameToDecodeDelay(params->renameToDecodeDelay),
iewToDecodeDelay(params->iewToDecodeDelay), iewToDecodeDelay(params->iewToDecodeDelay),
commitToDecodeDelay(params->commitToDecodeDelay), commitToDecodeDelay(params->commitToDecodeDelay),
fetchToDecodeDelay(params->fetchToDecodeDelay), fetchToDecodeDelay(params->fetchToDecodeDelay),
@ -110,14 +111,6 @@ DefaultDecode<Impl>::regStats()
.prereq(decodeSquashedInsts); .prereq(decodeSquashedInsts);
} }
template<class Impl>
void
DefaultDecode<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
DPRINTF(Decode, "Setting CPU pointer.\n");
}
template<class Impl> template<class Impl>
void void
DefaultDecode<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) DefaultDecode<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)

View file

@ -160,7 +160,7 @@ class DefaultFetch
public: public:
/** DefaultFetch constructor. */ /** DefaultFetch constructor. */
DefaultFetch(Params *params); DefaultFetch(O3CPU *_cpu, Params *params);
/** Returns the name of fetch. */ /** Returns the name of fetch. */
std::string name() const; std::string name() const;
@ -171,9 +171,6 @@ class DefaultFetch
/** Returns the icache port. */ /** Returns the icache port. */
Port *getIcachePort() { return icachePort; } Port *getIcachePort() { return icachePort; }
/** Sets CPU pointer. */
void setCPU(O3CPU *cpu_ptr);
/** Sets the main backwards communication time buffer pointer. */ /** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);

View file

@ -110,8 +110,9 @@ DefaultFetch<Impl>::IcachePort::recvRetry()
} }
template<class Impl> template<class Impl>
DefaultFetch<Impl>::DefaultFetch(Params *params) DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, Params *params)
: branchPred(params), : cpu(_cpu),
branchPred(params),
predecoder(NULL), predecoder(NULL),
decodeToFetchDelay(params->decodeToFetchDelay), decodeToFetchDelay(params->decodeToFetchDelay),
renameToFetchDelay(params->renameToFetchDelay), renameToFetchDelay(params->renameToFetchDelay),
@ -163,6 +164,17 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
// Get the size of an instruction. // Get the size of an instruction.
instSize = sizeof(TheISA::MachInst); instSize = sizeof(TheISA::MachInst);
// Name is finally available, so create the port.
icachePort = new IcachePort(this);
icachePort->snoopRangeSent = false;
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setIcachePort(icachePort);
}
#endif
} }
template <class Impl> template <class Impl>
@ -262,32 +274,6 @@ DefaultFetch<Impl>::regStats()
branchPred.regStats(); branchPred.regStats();
} }
template<class Impl>
void
DefaultFetch<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
DPRINTF(Fetch, "Setting the CPU pointer.\n");
// Name is finally available, so create the port.
icachePort = new IcachePort(this);
icachePort->snoopRangeSent = false;
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setIcachePort(icachePort);
}
#endif
// Schedule fetch to get the correct PC from the CPU
// scheduleFetchStartupEvent(1);
// Fetch needs to start fetching instructions at the very beginning,
// so it must start up in active state.
switchToActive();
}
template<class Impl> template<class Impl>
void void
DefaultFetch<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer) DefaultFetch<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer)
@ -342,6 +328,13 @@ DefaultFetch<Impl>::initStage()
stalls[tid].iew = false; stalls[tid].iew = false;
stalls[tid].commit = false; stalls[tid].commit = false;
} }
// Schedule fetch to get the correct PC from the CPU
// scheduleFetchStartupEvent(1);
// Fetch needs to start fetching instructions at the very beginning,
// so it must start up in active state.
switchToActive();
} }
template<class Impl> template<class Impl>

View file

@ -115,7 +115,7 @@ class DefaultIEW
public: public:
/** Constructs a DefaultIEW with the given parameters. */ /** Constructs a DefaultIEW with the given parameters. */
DefaultIEW(Params *params); DefaultIEW(O3CPU *_cpu, Params *params);
/** Returns the name of the DefaultIEW stage. */ /** Returns the name of the DefaultIEW stage. */
std::string name() const; std::string name() const;
@ -129,9 +129,6 @@ class DefaultIEW
/** Returns the dcache port. */ /** Returns the dcache port. */
Port *getDcachePort() { return ldstQueue.getDcachePort(); } Port *getDcachePort() { return ldstQueue.getDcachePort(); }
/** Sets CPU pointer for IEW, IQ, and LSQ. */
void setCPU(O3CPU *cpu_ptr);
/** Sets main time buffer used for backwards communication. */ /** Sets main time buffer used for backwards communication. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
@ -367,16 +364,6 @@ class DefaultIEW
/** Scoreboard pointer. */ /** Scoreboard pointer. */
Scoreboard* scoreboard; Scoreboard* scoreboard;
public:
/** Instruction queue. */
IQ instQueue;
/** Load / store queue. */
LSQ ldstQueue;
/** Pointer to the functional unit pool. */
FUPool *fuPool;
private: private:
/** CPU pointer. */ /** CPU pointer. */
O3CPU *cpu; O3CPU *cpu;
@ -398,6 +385,14 @@ class DefaultIEW
void printAvailableInsts(); void printAvailableInsts();
public: public:
/** Instruction queue. */
IQ instQueue;
/** Load / store queue. */
LSQ ldstQueue;
/** Pointer to the functional unit pool. */
FUPool *fuPool;
/** Records if the LSQ needs to be updated on the next cycle, so that /** Records if the LSQ needs to be updated on the next cycle, so that
* IEW knows if there will be activity on the next cycle. * IEW knows if there will be activity on the next cycle.
*/ */

View file

@ -39,10 +39,11 @@
#include "cpu/o3/iew.hh" #include "cpu/o3/iew.hh"
template<class Impl> template<class Impl>
DefaultIEW<Impl>::DefaultIEW(Params *params) DefaultIEW<Impl>::DefaultIEW(O3CPU *_cpu, Params *params)
: issueToExecQueue(params->backComSize, params->forwardComSize), : issueToExecQueue(params->backComSize, params->forwardComSize),
instQueue(params), cpu(_cpu),
ldstQueue(params), instQueue(_cpu, this, params),
ldstQueue(_cpu, this, params),
fuPool(params->fuPool), fuPool(params->fuPool),
commitToIEWDelay(params->commitToIEWDelay), commitToIEWDelay(params->commitToIEWDelay),
renameToIEWDelay(params->renameToIEWDelay), renameToIEWDelay(params->renameToIEWDelay),
@ -64,9 +65,6 @@ DefaultIEW<Impl>::DefaultIEW(Params *params)
// Instruction queue needs the queue between issue and execute. // Instruction queue needs the queue between issue and execute.
instQueue.setIssueToExecuteQueue(&issueToExecQueue); instQueue.setIssueToExecuteQueue(&issueToExecQueue);
instQueue.setIEW(this);
ldstQueue.setIEW(this);
for (int i=0; i < numThreads; i++) { for (int i=0; i < numThreads; i++) {
dispatchStatus[i] = Running; dispatchStatus[i] = Running;
stalls[i].commit = false; stalls[i].commit = false;
@ -276,17 +274,6 @@ DefaultIEW<Impl>::initStage()
toRename->iewInfo[tid].freeLSQEntries = toRename->iewInfo[tid].freeLSQEntries =
ldstQueue.numFreeEntries(tid); ldstQueue.numFreeEntries(tid);
} }
}
template<class Impl>
void
DefaultIEW<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
DPRINTF(IEW, "Setting CPU pointer.\n");
instQueue.setCPU(cpu_ptr);
ldstQueue.setCPU(cpu_ptr);
cpu->activateStage(O3CPU::IEWIdx); cpu->activateStage(O3CPU::IEWIdx);
} }

View file

@ -110,7 +110,7 @@ class InstructionQueue
}; };
/** Constructs an IQ. */ /** Constructs an IQ. */
InstructionQueue(Params *params); InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params);
/** Destructs the IQ. */ /** Destructs the IQ. */
~InstructionQueue(); ~InstructionQueue();
@ -124,15 +124,9 @@ class InstructionQueue
/** Resets all instruction queue state. */ /** Resets all instruction queue state. */
void resetState(); void resetState();
/** Sets CPU pointer. */
void setCPU(O3CPU *_cpu) { cpu = _cpu; }
/** Sets active threads list. */ /** Sets active threads list. */
void setActiveThreads(std::list<unsigned> *at_ptr); void setActiveThreads(std::list<unsigned> *at_ptr);
/** Sets the IEW pointer. */
void setIEW(IEW *iew_ptr) { iewStage = iew_ptr; }
/** Sets the timer buffer between issue and execute. */ /** Sets the timer buffer between issue and execute. */
void setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2eQueue); void setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2eQueue);

View file

@ -64,8 +64,11 @@ InstructionQueue<Impl>::FUCompletion::description()
} }
template <class Impl> template <class Impl>
InstructionQueue<Impl>::InstructionQueue(Params *params) InstructionQueue<Impl>::InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr,
: fuPool(params->fuPool), Params *params)
: cpu(cpu_ptr),
iewStage(iew_ptr),
fuPool(params->fuPool),
numEntries(params->numIQEntries), numEntries(params->numIQEntries),
totalWidth(params->issueWidth), totalWidth(params->issueWidth),
numPhysIntRegs(params->numPhysIntRegs), numPhysIntRegs(params->numPhysIntRegs),
@ -122,11 +125,8 @@ InstructionQueue<Impl>::InstructionQueue(Params *params)
maxEntries[i] = part_amt; maxEntries[i] = part_amt;
} }
/*
DPRINTF(IQ, "IQ sharing policy set to Partitioned:" DPRINTF(IQ, "IQ sharing policy set to Partitioned:"
"%i entries per thread.\n",part_amt); "%i entries per thread.\n",part_amt);
*/
} else if (policy == "threshold") { } else if (policy == "threshold") {
iqPolicy = Threshold; iqPolicy = Threshold;
@ -139,10 +139,8 @@ InstructionQueue<Impl>::InstructionQueue(Params *params)
maxEntries[i] = thresholdIQ; maxEntries[i] = thresholdIQ;
} }
/*
DPRINTF(IQ, "IQ sharing policy set to Threshold:" DPRINTF(IQ, "IQ sharing policy set to Threshold:"
"%i entries per thread.\n",thresholdIQ); "%i entries per thread.\n",thresholdIQ);
*/
} else { } else {
assert(0 && "Invalid IQ Sharing Policy.Options Are:{Dynamic," assert(0 && "Invalid IQ Sharing Policy.Options Are:{Dynamic,"
"Partitioned, Threshold}"); "Partitioned, Threshold}");

View file

@ -57,7 +57,7 @@ class LSQ {
}; };
/** Constructs an LSQ with the given parameters. */ /** Constructs an LSQ with the given parameters. */
LSQ(Params *params); LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params);
/** Returns the name of the LSQ. */ /** Returns the name of the LSQ. */
std::string name() const; std::string name() const;
@ -74,10 +74,6 @@ class LSQ {
/** 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. */
void setCPU(O3CPU *cpu_ptr);
/** Sets the IEW stage pointer. */
void setIEW(IEW *iew_ptr);
/** Switches out the LSQ. */ /** Switches out the LSQ. */
void switchOut(); void switchOut();
/** Takes over execution from another CPU's thread. */ /** Takes over execution from another CPU's thread. */
@ -283,6 +279,12 @@ class LSQ {
template <class T> template <class T>
Fault write(RequestPtr req, T &data, int store_idx); Fault write(RequestPtr req, T &data, int store_idx);
/** The CPU pointer. */
O3CPU *cpu;
/** The IEW stage pointer. */
IEW *iewStage;
/** DcachePort class for this LSQ. Handles doing the /** DcachePort class for this LSQ. Handles doing the
* communication with the cache/memory. * communication with the cache/memory.
*/ */
@ -295,7 +297,7 @@ class LSQ {
public: public:
/** Default constructor. */ /** Default constructor. */
DcachePort(LSQ *_lsq) DcachePort(LSQ *_lsq)
: lsq(_lsq) : Port(_lsq->name() + "-dport"), lsq(_lsq)
{ } { }
bool snoopRangeSent; bool snoopRangeSent;
@ -341,12 +343,6 @@ class LSQ {
/** The LSQ units for individual threads. */ /** The LSQ units for individual threads. */
LSQUnit thread[Impl::MaxThreads]; LSQUnit thread[Impl::MaxThreads];
/** The CPU pointer. */
O3CPU *cpu;
/** The IEW stage pointer. */
IEW *iewStage;
/** List of Active Threads in System. */ /** List of Active Threads in System. */
std::list<unsigned> *activeThreads; std::list<unsigned> *activeThreads;

View file

@ -107,9 +107,11 @@ LSQ<Impl>::DcachePort::recvRetry()
} }
template <class Impl> template <class Impl>
LSQ<Impl>::LSQ(Params *params) LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params)
: dcachePort(this), LQEntries(params->LQEntries), : cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this),
SQEntries(params->SQEntries), numThreads(params->numberOfThreads), LQEntries(params->LQEntries),
SQEntries(params->SQEntries),
numThreads(params->numberOfThreads),
retryTid(-1) retryTid(-1)
{ {
dcachePort.snoopRangeSent = false; dcachePort.snoopRangeSent = false;
@ -129,20 +131,18 @@ LSQ<Impl>::LSQ(Params *params)
maxLQEntries = LQEntries; maxLQEntries = LQEntries;
maxSQEntries = SQEntries; maxSQEntries = SQEntries;
/*
DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
*/
} else if (policy == "partitioned") { } else if (policy == "partitioned") {
lsqPolicy = Partitioned; lsqPolicy = Partitioned;
//@todo:make work if part_amt doesnt divide evenly. //@todo:make work if part_amt doesnt divide evenly.
maxLQEntries = LQEntries / numThreads; maxLQEntries = LQEntries / numThreads;
maxSQEntries = SQEntries / numThreads; maxSQEntries = SQEntries / numThreads;
/*
DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
"%i entries per LQ | %i entries per SQ", "%i entries per LQ | %i entries per SQ",
maxLQEntries,maxSQEntries); maxLQEntries,maxSQEntries);
*/
} else if (policy == "threshold") { } else if (policy == "threshold") {
lsqPolicy = Threshold; lsqPolicy = Threshold;
@ -154,12 +154,10 @@ LSQ<Impl>::LSQ(Params *params)
//amount of the LSQ //amount of the LSQ
maxLQEntries = params->smtLSQThreshold; maxLQEntries = params->smtLSQThreshold;
maxSQEntries = params->smtLSQThreshold; maxSQEntries = params->smtLSQThreshold;
/*
DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
"%i entries per LQ | %i entries per SQ", "%i entries per LQ | %i entries per SQ",
maxLQEntries,maxSQEntries); maxLQEntries,maxSQEntries);
*/
} else { } else {
assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
"Partitioned, Threshold}"); "Partitioned, Threshold}");
@ -167,7 +165,8 @@ LSQ<Impl>::LSQ(Params *params)
//Initialize LSQs //Initialize LSQs
for (int tid=0; tid < numThreads; tid++) { for (int tid=0; tid < numThreads; tid++) {
thread[tid].init(params, this, maxLQEntries, maxSQEntries, tid); thread[tid].init(cpu, iew_ptr, params, this,
maxLQEntries, maxSQEntries, tid);
thread[tid].setDcachePort(&dcachePort); thread[tid].setDcachePort(&dcachePort);
} }
} }
@ -198,30 +197,6 @@ LSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
assert(activeThreads != 0); assert(activeThreads != 0);
} }
template<class Impl>
void
LSQ<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
dcachePort.setName(name());
for (int tid=0; tid < numThreads; tid++) {
thread[tid].setCPU(cpu_ptr);
}
}
template<class Impl>
void
LSQ<Impl>::setIEW(IEW *iew_ptr)
{
iewStage = iew_ptr;
for (int tid=0; tid < numThreads; tid++) {
thread[tid].setIEW(iew_ptr);
}
}
template <class Impl> template <class Impl>
void void
LSQ<Impl>::switchOut() LSQ<Impl>::switchOut()

View file

@ -73,8 +73,8 @@ class LSQUnit {
LSQUnit(); LSQUnit();
/** Initializes the LSQ unit with the specified number of entries. */ /** Initializes the LSQ unit with the specified number of entries. */
void init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries, void init(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params, LSQ *lsq_ptr,
unsigned maxSQEntries, unsigned id); unsigned maxLQEntries, unsigned maxSQEntries, unsigned id);
/** Returns the name of the LSQ unit. */ /** Returns the name of the LSQ unit. */
std::string name() const; std::string name() const;
@ -82,16 +82,8 @@ class LSQUnit {
/** Registers statistics. */ /** Registers statistics. */
void regStats(); void regStats();
/** Sets the CPU pointer. */
void setCPU(O3CPU *cpu_ptr);
/** Sets the IEW stage pointer. */
void setIEW(IEW *iew_ptr)
{ iewStage = iew_ptr; }
/** Sets the pointer to the dcache port. */ /** Sets the pointer to the dcache port. */
void setDcachePort(Port *dcache_port) void setDcachePort(Port *dcache_port);
{ dcachePort = dcache_port; }
/** Switches out LSQ unit. */ /** Switches out LSQ unit. */
void switchOut(); void switchOut();

View file

@ -57,6 +57,11 @@ LSQUnit<Impl>::WritebackEvent::process()
if (!lsqPtr->isSwitchedOut()) { if (!lsqPtr->isSwitchedOut()) {
lsqPtr->writeback(inst, pkt); lsqPtr->writeback(inst, pkt);
} }
if (pkt->senderState)
delete pkt->senderState;
delete pkt->req;
delete pkt; delete pkt;
} }
@ -80,10 +85,6 @@ LSQUnit<Impl>::completeDataAccess(PacketPtr pkt)
if (isSwitchedOut() || inst->isSquashed()) { if (isSwitchedOut() || inst->isSquashed()) {
iewStage->decrWb(inst->seqNum); iewStage->decrWb(inst->seqNum);
delete state;
delete pkt->req;
delete pkt;
return;
} else { } else {
if (!state->noWB) { if (!state->noWB) {
writeback(inst, pkt); writeback(inst, pkt);
@ -109,10 +110,13 @@ LSQUnit<Impl>::LSQUnit()
template<class Impl> template<class Impl>
void void
LSQUnit<Impl>::init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries, LSQUnit<Impl>::init(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params, LSQ *lsq_ptr,
unsigned maxSQEntries, unsigned id) unsigned maxLQEntries, unsigned maxSQEntries, unsigned id)
{ {
// DPRINTF(LSQUnit, "Creating LSQUnit%i object.\n",id); cpu = cpu_ptr;
iewStage = iew_ptr;
DPRINTF(LSQUnit, "Creating LSQUnit%i object.\n",id);
switchedOut = false; switchedOut = false;
@ -140,19 +144,6 @@ LSQUnit<Impl>::init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries,
blockedLoadSeqNum = 0; blockedLoadSeqNum = 0;
} }
template<class Impl>
void
LSQUnit<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setDcachePort(dcachePort);
}
#endif
}
template<class Impl> template<class Impl>
std::string std::string
LSQUnit<Impl>::name() const LSQUnit<Impl>::name() const
@ -209,6 +200,19 @@ LSQUnit<Impl>::regStats()
.desc("Number of times an access to memory failed due to the cache being blocked"); .desc("Number of times an access to memory failed due to the cache being blocked");
} }
template<class Impl>
void
LSQUnit<Impl>::setDcachePort(Port *dcache_port)
{
dcachePort = dcache_port;
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setDcachePort(dcachePort);
}
#endif
}
template<class Impl> template<class Impl>
void void
LSQUnit<Impl>::clearLQ() LSQUnit<Impl>::clearLQ()

View file

@ -51,6 +51,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU)
Param<int> clock; Param<int> clock;
Param<int> phase; Param<int> phase;
Param<int> numThreads; Param<int> numThreads;
Param<int> cpu_id;
Param<int> activity; Param<int> activity;
SimObjectVectorParam<Process *> workload; SimObjectVectorParam<Process *> workload;
@ -149,6 +150,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
INIT_PARAM(clock, "clock speed"), INIT_PARAM(clock, "clock speed"),
INIT_PARAM_DFLT(phase, "clock phase", 0), INIT_PARAM_DFLT(phase, "clock phase", 0),
INIT_PARAM(numThreads, "number of HW thread contexts"), INIT_PARAM(numThreads, "number of HW thread contexts"),
INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM_DFLT(activity, "Initial activity count", 0), INIT_PARAM_DFLT(activity, "Initial activity count", 0),
INIT_PARAM(workload, "Processes to run"), INIT_PARAM(workload, "Processes to run"),
@ -275,9 +277,11 @@ CREATE_SIM_OBJECT(DerivO3CPU)
MipsSimpleParams *params = new MipsSimpleParams; MipsSimpleParams *params = new MipsSimpleParams;
params->clock = clock; params->clock = clock;
params->phase = phase;
params->name = getInstanceName(); params->name = getInstanceName();
params->numberOfThreads = actual_num_threads; params->numberOfThreads = actual_num_threads;
params->cpu_id = cpu_id;
params->activity = activity; params->activity = activity;
params->workload = workload; params->workload = workload;

View file

@ -47,7 +47,7 @@
template <class Impl> template <class Impl>
MipsO3CPU<Impl>::MipsO3CPU(Params *params) MipsO3CPU<Impl>::MipsO3CPU(Params *params)
: FullO3CPU<Impl>(params) : FullO3CPU<Impl>(this, params)
{ {
DPRINTF(O3CPU, "Creating MipsO3CPU object.\n"); DPRINTF(O3CPU, "Creating MipsO3CPU object.\n");
@ -95,6 +95,7 @@ MipsO3CPU<Impl>::MipsO3CPU(Params *params)
// Give the thread the TC. // Give the thread the TC.
this->thread[i]->tc = tc; this->thread[i]->tc = tc;
this->thread[i]->setCpuId(params->cpu_id);
// Add the TC to the CPU's list of TC's. // Add the TC to the CPU's list of TC's.
this->threadContexts.push_back(tc); this->threadContexts.push_back(tc);
@ -104,17 +105,6 @@ MipsO3CPU<Impl>::MipsO3CPU(Params *params)
this->thread[i]->setFuncExeInst(0); this->thread[i]->setFuncExeInst(0);
} }
// Sets CPU pointers. These must be set at this level because the CPU
// pointers are defined to be the highest level of CPU class.
this->fetch.setCPU(this);
this->decode.setCPU(this);
this->rename.setCPU(this);
this->iew.setCPU(this);
this->commit.setCPU(this);
this->rob.setCPU(this);
this->regFile.setCPU(this);
lockAddr = 0; lockAddr = 0;
lockFlag = false; lockFlag = false;
} }

View file

@ -76,7 +76,7 @@ class PhysRegFile
* Constructs a physical register file with the specified amount of * Constructs a physical register file with the specified amount of
* integer and floating point registers. * integer and floating point registers.
*/ */
PhysRegFile(unsigned _numPhysicalIntRegs, PhysRegFile(O3CPU *_cpu, unsigned _numPhysicalIntRegs,
unsigned _numPhysicalFloatRegs); unsigned _numPhysicalFloatRegs);
//Everything below should be pretty well identical to the normal //Everything below should be pretty well identical to the normal
@ -268,9 +268,6 @@ class PhysRegFile
O3CPU *cpu; O3CPU *cpu;
public: public:
/** Sets the CPU pointer. */
void setCPU(O3CPU *cpu_ptr) { cpu = cpu_ptr; }
/** Number of physical integer registers. */ /** Number of physical integer registers. */
unsigned numPhysicalIntRegs; unsigned numPhysicalIntRegs;
/** Number of physical floating point registers. */ /** Number of physical floating point registers. */
@ -278,9 +275,9 @@ class PhysRegFile
}; };
template <class Impl> template <class Impl>
PhysRegFile<Impl>::PhysRegFile(unsigned _numPhysicalIntRegs, PhysRegFile<Impl>::PhysRegFile(O3CPU *_cpu, unsigned _numPhysicalIntRegs,
unsigned _numPhysicalFloatRegs) unsigned _numPhysicalFloatRegs)
: numPhysicalIntRegs(_numPhysicalIntRegs), : cpu(_cpu), numPhysicalIntRegs(_numPhysicalIntRegs),
numPhysicalFloatRegs(_numPhysicalFloatRegs) numPhysicalFloatRegs(_numPhysicalFloatRegs)
{ {
intRegFile = new IntReg[numPhysicalIntRegs]; intRegFile = new IntReg[numPhysicalIntRegs];

View file

@ -107,7 +107,7 @@ class DefaultRename
public: public:
/** DefaultRename constructor. */ /** DefaultRename constructor. */
DefaultRename(Params *params); DefaultRename(O3CPU *_cpu, Params *params);
/** Returns the name of rename. */ /** Returns the name of rename. */
std::string name() const; std::string name() const;
@ -115,9 +115,6 @@ class DefaultRename
/** Registers statistics. */ /** Registers statistics. */
void regStats(); void regStats();
/** Sets CPU pointer. */
void setCPU(O3CPU *cpu_ptr);
/** Sets the main backwards communication time buffer pointer. */ /** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);

View file

@ -37,8 +37,9 @@
#include "cpu/o3/rename.hh" #include "cpu/o3/rename.hh"
template <class Impl> template <class Impl>
DefaultRename<Impl>::DefaultRename(Params *params) DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, Params *params)
: iewToRenameDelay(params->iewToRenameDelay), : cpu(_cpu),
iewToRenameDelay(params->iewToRenameDelay),
decodeToRenameDelay(params->decodeToRenameDelay), decodeToRenameDelay(params->decodeToRenameDelay),
commitToRenameDelay(params->commitToRenameDelay), commitToRenameDelay(params->commitToRenameDelay),
renameWidth(params->renameWidth), renameWidth(params->renameWidth),
@ -164,14 +165,6 @@ DefaultRename<Impl>::regStats()
; ;
} }
template <class Impl>
void
DefaultRename<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
DPRINTF(Rename, "Setting CPU pointer.\n");
}
template <class Impl> template <class Impl>
void void
DefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) DefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)

View file

@ -82,17 +82,12 @@ class ROB
* @param _smtROBThreshold Max Resources(by %) a thread can have in the ROB. * @param _smtROBThreshold Max Resources(by %) a thread can have in the ROB.
* @param _numThreads The number of active threads. * @param _numThreads The number of active threads.
*/ */
ROB(unsigned _numEntries, unsigned _squashWidth, std::string smtROBPolicy, ROB(O3CPU *_cpu, unsigned _numEntries, unsigned _squashWidth,
unsigned _smtROBThreshold, unsigned _numThreads); std::string smtROBPolicy, unsigned _smtROBThreshold,
unsigned _numThreads);
std::string name() const; std::string name() const;
/** Function to set the CPU pointer, necessary due to which object the ROB
* is created within.
* @param cpu_ptr Pointer to the implementation specific full CPU object.
*/
void setCPU(O3CPU *cpu_ptr);
/** Sets pointer to the list of active threads. /** Sets pointer to the list of active threads.
* @param at_ptr Pointer to the list of active threads. * @param at_ptr Pointer to the list of active threads.
*/ */

View file

@ -35,10 +35,11 @@
#include <list> #include <list>
template <class Impl> template <class Impl>
ROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth, ROB<Impl>::ROB(O3CPU *_cpu, unsigned _numEntries, unsigned _squashWidth,
std::string _smtROBPolicy, unsigned _smtROBThreshold, std::string _smtROBPolicy, unsigned _smtROBThreshold,
unsigned _numThreads) unsigned _numThreads)
: numEntries(_numEntries), : cpu(_cpu),
numEntries(_numEntries),
squashWidth(_squashWidth), squashWidth(_squashWidth),
numInstsInROB(0), numInstsInROB(0),
numThreads(_numThreads) numThreads(_numThreads)
@ -66,7 +67,7 @@ ROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth,
} else if (policy == "partitioned") { } else if (policy == "partitioned") {
robPolicy = Partitioned; robPolicy = Partitioned;
// DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n");
//@todo:make work if part_amt doesnt divide evenly. //@todo:make work if part_amt doesnt divide evenly.
int part_amt = numEntries / numThreads; int part_amt = numEntries / numThreads;
@ -78,7 +79,7 @@ ROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth,
} else if (policy == "threshold") { } else if (policy == "threshold") {
robPolicy = Threshold; robPolicy = Threshold;
// DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); DPRINTF(Fetch, "ROB sharing policy set to Threshold\n");
int threshold = _smtROBThreshold;; int threshold = _smtROBThreshold;;
@ -90,20 +91,6 @@ ROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth,
assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic," assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic,"
"Partitioned, Threshold}"); "Partitioned, Threshold}");
} }
}
template <class Impl>
std::string
ROB<Impl>::name() const
{
return cpu->name() + ".rob";
}
template <class Impl>
void
ROB<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
// Set the per-thread iterators to the end of the instruction list. // Set the per-thread iterators to the end of the instruction list.
for (int i=0; i < numThreads;i++) { for (int i=0; i < numThreads;i++) {
@ -116,6 +103,13 @@ ROB<Impl>::setCPU(O3CPU *cpu_ptr)
tail = instList[0].end(); tail = instList[0].end();
} }
template <class Impl>
std::string
ROB<Impl>::name() const
{
return cpu->name() + ".rob";
}
template <class Impl> template <class Impl>
void void
ROB<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) ROB<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)

View file

@ -55,7 +55,7 @@
#endif #endif
template <class Impl> template <class Impl>
SparcO3CPU<Impl>::SparcO3CPU(Params *params) : FullO3CPU<Impl>(params) SparcO3CPU<Impl>::SparcO3CPU(Params *params) : FullO3CPU<Impl>(this, params)
{ {
DPRINTF(O3CPU, "Creating SparcO3CPU object.\n"); DPRINTF(O3CPU, "Creating SparcO3CPU object.\n");
@ -113,6 +113,7 @@ SparcO3CPU<Impl>::SparcO3CPU(Params *params) : FullO3CPU<Impl>(params)
#endif #endif
// Give the thread the TC. // Give the thread the TC.
this->thread[i]->tc = tc; this->thread[i]->tc = tc;
this->thread[i]->setCpuId(params->cpu_id);
// Add the TC to the CPU's list of TC's. // Add the TC to the CPU's list of TC's.
this->threadContexts.push_back(tc); this->threadContexts.push_back(tc);
@ -122,17 +123,6 @@ SparcO3CPU<Impl>::SparcO3CPU(Params *params) : FullO3CPU<Impl>(params)
this->thread[i]->setFuncExeInst(0); this->thread[i]->setFuncExeInst(0);
} }
// Sets CPU pointers. These must be set at this level because the CPU
// pointers are defined to be the highest level of CPU class.
this->fetch.setCPU(this);
this->decode.setCPU(this);
this->rename.setCPU(this);
this->iew.setCPU(this);
this->commit.setCPU(this);
this->rob.setCPU(this);
this->regFile.setCPU(this);
lockAddr = 0; lockAddr = 0;
lockFlag = false; lockFlag = false;
} }

View file

@ -52,9 +52,19 @@ Bus::getPort(const std::string &if_name, int idx)
} else } else
fatal("Default port already set\n"); fatal("Default port already set\n");
} }
int id;
if (if_name == "functional") {
if (!funcPort) {
id = maxId++;
funcPort = new BusPort(csprintf("%s-p%d-func", name(), id), this, id);
funcPortId = id;
interfaces[id] = funcPort;
}
return funcPort;
}
// if_name ignored? forced to be empty? // if_name ignored? forced to be empty?
int id = maxId++; id = maxId++;
assert(maxId < std::numeric_limits<typeof(maxId)>::max()); assert(maxId < std::numeric_limits<typeof(maxId)>::max());
BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id); BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
interfaces[id] = bp; interfaces[id] = bp;
@ -64,10 +74,15 @@ Bus::getPort(const std::string &if_name, int idx)
void void
Bus::deletePortRefs(Port *p) Bus::deletePortRefs(Port *p)
{ {
BusPort *bp = dynamic_cast<BusPort*>(p); BusPort *bp = dynamic_cast<BusPort*>(p);
if (bp == NULL) if (bp == NULL)
panic("Couldn't convert Port* to BusPort*\n"); panic("Couldn't convert Port* to BusPort*\n");
// If this is our one functional port
if (funcPort == bp)
return;
interfaces.erase(bp->getId()); interfaces.erase(bp->getId());
delete bp;
} }
/** Get the ranges of anyone other buses that we are connected to. */ /** Get the ranges of anyone other buses that we are connected to. */
@ -520,7 +535,7 @@ Bus::recvStatusChange(Port::Status status, int id)
m5::hash_map<short,BusPort*>::iterator intIter; m5::hash_map<short,BusPort*>::iterator intIter;
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
if (intIter->first != id) if (intIter->first != id && intIter->first != funcPortId)
intIter->second->sendStatusChange(Port::RangeChange); intIter->second->sendStatusChange(Port::RangeChange);
if (id != defaultId && defaultPort) if (id != defaultId && defaultPort)

View file

@ -63,6 +63,7 @@ class Bus : public MemObject
Event * drainEvent; Event * drainEvent;
static const int defaultId = -3; //Make it unique from Broadcast static const int defaultId = -3; //Make it unique from Broadcast
struct DevMap { struct DevMap {
@ -249,6 +250,9 @@ class Bus : public MemObject
/** Port that handles requests that don't match any of the interfaces.*/ /** Port that handles requests that don't match any of the interfaces.*/
BusPort *defaultPort; BusPort *defaultPort;
BusPort *funcPort;
int funcPortId;
/** Has the user specified their own default responder? */ /** Has the user specified their own default responder? */
bool responderSet; bool responderSet;
@ -266,7 +270,8 @@ class Bus : public MemObject
bool responder_set) bool responder_set)
: MemObject(n), busId(bus_id), clock(_clock), width(_width), : MemObject(n), busId(bus_id), clock(_clock), width(_width),
tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false), tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false),
maxId(0), defaultPort(NULL), responderSet(responder_set) maxId(0), defaultPort(NULL), funcPort(NULL), funcPortId(-4),
responderSet(responder_set)
{ {
//Both the width and clock period must be positive //Both the width and clock period must be positive
if (width <= 0) if (width <= 0)

View file

@ -1183,7 +1183,8 @@ Cache<TagStore,Coherence>::deletePortRefs(Port *p)
{ {
if (cpuSidePort == p || memSidePort == p) if (cpuSidePort == p || memSidePort == p)
panic("Can only delete functional ports\n"); panic("Can only delete functional ports\n");
// nothing else to do
delete p;
} }

View file

@ -51,7 +51,6 @@ Port::removeConn()
{ {
if (peer->getOwner()) if (peer->getOwner())
peer->getOwner()->deletePortRefs(peer); peer->getOwner()->deletePortRefs(peer);
delete peer;
peer = NULL; peer = NULL;
} }