From: Kevin Lim Date: Tue, 23 May 2006 21:03:43 +0000 (-0400) Subject: Rework how instructions are scheduled and executed. X-Git-Tag: m5_2.0_beta1~36^2~108^2~10^2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=358cf1b11765024309fe986262bb3a3d16c8a720;p=gem5.git 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 --- diff --git a/cpu/o3/iew_impl.hh b/cpu/o3/iew_impl.hh index 59f4055a6..c22850131 100644 --- a/cpu/o3/iew_impl.hh +++ b/cpu/o3/iew_impl.hh @@ -1232,13 +1232,14 @@ DefaultIEW::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); diff --git a/cpu/o3/inst_queue.hh b/cpu/o3/inst_queue.hh index 6bdf4ddc2..518de73d9 100644 --- a/cpu/o3/inst_queue.hh +++ b/cpu/o3/inst_queue.hh @@ -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 instList[Impl::MaxThreads]; + std::list instsToExecute; + /** * Struct for comparing entries to be added to the priority queue. This * gives reverse ordering to the instructions in terms of sequence diff --git a/cpu/o3/inst_queue_impl.hh b/cpu/o3/inst_queue_impl.hh index ed57ac257..412d59768 100644 --- a/cpu/o3/inst_queue_impl.hh +++ b/cpu/o3/inst_queue_impl.hh @@ -588,6 +588,16 @@ InstructionQueue::insertBarrier(DynInstPtr &barr_inst) insertNonSpec(barr_inst); } +template +typename Impl::DynInstPtr +InstructionQueue::getInstToExecute() +{ + assert(!instsToExecute.empty()); + DynInstPtr inst = instsToExecute.front(); + instsToExecute.pop_front(); + return inst; +} + template void InstructionQueue::addToOrderList(OpClass op_class) @@ -662,9 +672,11 @@ InstructionQueue::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::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::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.