Commits

Sam Mussmann committed cacd488

Move cycle tracking out of InstructionTracker into main loop.

Comments (0)

Files changed (1)

 """
 
 class _InstructionTracker:
-  """Holds onto the state of each instruction as well as the overall state of the loop
+  """Holds onto the state of each instruction.
+
+  Therefore also knows which instruction(s) are next to issue and when the
+  instructions are all done executing.
   """
-  cycle = 0
   done = False
   _next_instruction = 0
 
   class _Instruction:
-    """ Internal representation of an instruction."""
+    """ Internal representation of an instruction.
+      
+    Tracks the state of the instruction and the pending state, and updates it
+    for the new cycle.  Also tracks how many unsatisfied dependences this
+    instruction currently has (when waiting in the reservation station) and
+    which instruction in the stream this is.
+
+    In addition, gives logging capabilities for the instruction to track things
+    like RAW dependences and structural hazards/dependences.
+    """
     _new_state = None
     cur_state = 'unissued'
     states = set(('unissued', 'IS', 'reservation-station', 'queued-for-EX',
           'EX', 'queued-for-WB', 'WB', 'waiting-for-commit', 'CM'))
     dependence_count = 0
 
-    def __init__(self, instruction, index, tracker):
+    def __init__(self, instruction, index):
       self.opcode = instruction.opcode
       self.write_register = instruction.write_register
       self.read_registers = instruction.read_registers
       self.index = index
-      self.tracker = tracker
       self.history = list()
       self.messages = set()
 
         raise Exception("Tried to set illegal state {0}".format(state))
       self._new_state = state
 
-    def update(self):
+    def update(self, new_cycle):
       if self. _new_state:
         if self._new_state in set(('IS', 'EX', 'WB', 'CM')):
-          self.history.append((self._new_state, self.tracker.cycle))
+          self.history.append((self._new_state, new_cycle))
         if self.cur_state == 'EX':
-          self.history.append(('EX-end', self.tracker.cycle - 1))
+          self.history.append(('EX-end', new_cycle - 1))
         self.cur_state = self._new_state
         self._new_state = None
         
       instruction.issue()
       self._next_instruction += 1
 
-  def update(self):
-    self.cycle += 1
+  def update(self, new_cycle):
     for instruction in self.instructions:
-      instruction.update()
+      instruction.update(new_cycle)
     if self.instructions[-1].cur_state == 'CM':
       self.done = True
-    if self.cycle > 1000:
+    if new_cycle > 1000:
       print "failed to stop"
       self.done = True
 
     def busy(self, cycle):
       return self.end_cycle and cycle < self.end_cycle
 
-    def update(self, instruction_tracker, cdb):
-      current_cycle = instruction_tracker.cycle
+    def update(self, instruction_tracker, cdb, current_cycle):
       if current_cycle == self.end_cycle:
         self.current_instruction.enqueue_for_writeback()
         cdb.append(self.current_instruction)
   def enqueue(self, instruction):
     self.opcode_map[instruction.opcode].enqueue(instruction)
 
-  def update(self, instruction_tracker, cdb):
+  def update(self, instruction_tracker, cdb, current_cycle):
     for fu in self.fu_list:
-      fu.update(instruction_tracker, cdb)
+      fu.update(instruction_tracker, cdb, current_cycle)
 
   def __repr__(self):
     return str(self)
 
     Each instruction should be a tomasulo.Instruction.
   """
+  cycle = 0
   instruction_tracker = _InstructionTracker(input_instructions)
   reorder_buffer = _ReorderBuffer()
   register_file = collections.defaultdict(lambda: None)
       register_file[instruction.write_register] = instruction.index
 
     # Deal with EX stage
-    functional_units.update(instruction_tracker, cdb)
+    functional_units.update(instruction_tracker, cdb, cycle)
 
     # Deal with WB stage
     if cdb:
     # Deal with CM stage
     reorder_buffer.commit(instruction_tracker)
 
-    instruction_tracker.update()
+    cycle += 1
+    instruction_tracker.update(cycle)
 
 # This is debug stuff to dump the state of various hardware pieces.  I'm
 # leaving it here should you need it to debug stuff.