Rework how instructions are scheduled and executed.
authorKevin Lim <ktlim@umich.edu>
Tue, 23 May 2006 21:03:43 +0000 (17:03 -0400)
committerKevin Lim <ktlim@umich.edu>
Tue, 23 May 2006 21:03:43 +0000 (17:03 -0400)
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

cpu/o3/iew_impl.hh
cpu/o3/inst_queue.hh
cpu/o3/inst_queue_impl.hh

index 59f4055a6c06f9dad646ddc6885f0162f1c6ad51..c228501314ee4ccb3d7a599bf12a1428d8862a1c 100644 (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);
index 6bdf4ddc25f1b78feadb3c5303f072c3da2a50d9..518de73d9cfc5ad66c8f4b5c0eb41f31ea95b68d 100644 (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
index ed57ac257fc722fa98a34e012da7faa2bf5e4e78..412d5976893fa93a43419be5fa8d43132af64f4d 100644 (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.