Rework how instructions are scheduled and executed.

The "execute" portion of IEW is really just the last cycle of execution, at which point execute() gets called.  Execution begins inside the IQ, when it schedules FUs for specific instructions.  As a result, the Execute stage should just pull all completing instructions out of the IQ stage and execute them.
Limiting the number of writebacks outstanding must still be done.

cpu/o3/iew_impl.hh:
    Rework how instructions are scheduled and executed.  There shouldn't be a specific "width" from issue to execute because issue does the scheduling of the functional units (really the beginning of the execution).
cpu/o3/inst_queue.hh:
cpu/o3/inst_queue_impl.hh:
    Rework how instructions are scheduled and executed.

--HG--
extra : convert_revision : bbf1a8a4c0a2f2a938bdd78d74493048fd3b4b55
This commit is contained in:
Kevin Lim 2006-05-23 17:03:43 -04:00
parent c9ad4a15d6
commit 358cf1b117
3 changed files with 24 additions and 7 deletions

View file

@ -1232,13 +1232,14 @@ DefaultIEW<Impl>::executeInsts()
#endif
// Execute/writeback any instructions that are available.
int insts_to_execute = fromIssue->size;
int inst_num = 0;
for ( ; inst_num < issueWidth && fromIssue->insts[inst_num];
for (; inst_num < insts_to_execute;
++inst_num) {
DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
DynInstPtr inst = fromIssue->insts[inst_num];
DynInstPtr inst = instQueue.getInstToExecute();
DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n",
inst->readPC(), inst->threadNumber,inst->seqNum);

View file

@ -171,6 +171,8 @@ class InstructionQueue
*/
void insertBarrier(DynInstPtr &barr_inst);
DynInstPtr getInstToExecute();
/**
* Records the instruction as the producer of a register without
* adding it to the rest of the IQ.
@ -272,6 +274,8 @@ class InstructionQueue
/** List of all the instructions in the IQ (some of which may be issued). */
std::list<DynInstPtr> instList[Impl::MaxThreads];
std::list<DynInstPtr> instsToExecute;
/**
* Struct for comparing entries to be added to the priority queue. This
* gives reverse ordering to the instructions in terms of sequence

View file

@ -588,6 +588,16 @@ InstructionQueue<Impl>::insertBarrier(DynInstPtr &barr_inst)
insertNonSpec(barr_inst);
}
template <class Impl>
typename Impl::DynInstPtr
InstructionQueue<Impl>::getInstToExecute()
{
assert(!instsToExecute.empty());
DynInstPtr inst = instsToExecute.front();
instsToExecute.pop_front();
return inst;
}
template <class Impl>
void
InstructionQueue<Impl>::addToOrderList(OpClass op_class)
@ -662,9 +672,11 @@ InstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
// @todo: This could break if there's multiple multi-cycle ops
// finishing on this cycle. Maybe implement something like
// instToCommit in iew_impl.hh.
int &size = issueToExecuteQueue->access(0)->size;
issueToExecuteQueue->access(0)->size++;
instsToExecute.push_back(inst);
// int &size = issueToExecuteQueue->access(0)->size;
issueToExecuteQueue->access(0)->insts[size++] = inst;
// issueToExecuteQueue->access(0)->insts[size++] = inst;
}
// @todo: Figure out a better way to remove the squashed items from the
@ -690,9 +702,8 @@ InstructionQueue<Impl>::scheduleReadyInsts()
ListOrderIt order_it = listOrder.begin();
ListOrderIt order_end_it = listOrder.end();
int total_issued = 0;
int exec_queue_slot = i2e_info->size;
while (exec_queue_slot < totalWidth && total_issued < totalWidth &&
while (total_issued < totalWidth &&
order_it != order_end_it) {
OpClass op_class = (*order_it).queueType;
@ -733,8 +744,9 @@ InstructionQueue<Impl>::scheduleReadyInsts()
if (idx == -2 || idx != -1) {
if (op_latency == 1) {
i2e_info->insts[exec_queue_slot++] = issuing_inst;
// i2e_info->insts[exec_queue_slot++] = issuing_inst;
i2e_info->size++;
instsToExecute.push_back(issuing_inst);
// Add the FU onto the list of FU's to be freed next
// cycle if we used one.