Commits

Sam Mussmann  committed a4931fb

Add InstructionTracker -- still unsure about main simulation loop -- it doesn't work right now.

  • Participants
  • Parent commits 844b338

Comments (0)

Files changed (1)

 #!/usr/bin/env python
 
 import collections
+import string
 
 Instruction = collections.namedtuple('Instruction', ('opcode',
       'write_register', 'read_registers'))
 dependences.
 """
 
+class _InstructionTracker:
+  """Remembers where each instruction is in execution, and ultimately serves as
+    the state of the simulation loop.
+  """
+  cycle = 0
+  done = False
+  _next_instruction = 0
+  class _Instruction:
+    """ Internal representation of an instruction."""
+    history = list()
+    messages = set()
+    _new_state = None
+    cur_state = 'unissued'
+    states = set(('unissued', 'IS', 'reservation-station', 'queued-for-EX',
+          'EX', 'queued-for-WB', 'WB', 'waiting-for-commit', 'CM'))
+
+    def __init__(self, instruction, index, tracker, dependences):
+      self.instr = instruction
+      self.instr_index = index
+      self.tracker = tracker
+      self.write_tag = "{0}-{1}".format(self.instr.write_register,
+          self.instr_index)
+      self.dependences = dependences
+
+    def _set_state(self, state):
+      if state not in self.states:
+        raise Exception("Tried to set illegal state {0}".format(state))
+      self._new_state = state
+
+    def update(self):
+      if _new_state:
+        if _new_state[0] in string.uppercase:
+          history.append((_new_state, self.tracker.cycle))
+        self.cur_state = _new_state
+        
+    def issue(self):
+      self._set_state('IS')
+
+    def wait_in_reservation_station(self):
+      self._set_state('reservation-station')
+
+    def enqueue_for_execute(self):
+      self._set_state('queued-for-EX')
+
+    def execute(self):
+      self._set_state('EX')
+
+    def enqueue_for_writeback(self):
+      self._set_state('queued-for-WB')
+
+    def writeback(self):
+      self._set_state('WB')
+
+    def wait_for_commit(self):
+      self._set_state('waiting-for-commit')
+
+    def commit(self):
+      self._set_state('CM')
+
+    def ready_to_commit(self):
+      return self.cur_state in ('WB', 'waiting-for-commit')
+
+    def __str__(self):
+      return ('{0.opcode} {0.write-register} {0.read_registers} in state {1} '
+          'with pending state {2} dependences {3}'.format(self.instruction,
+            self.cur_state, self._new_state, self.dependences))
+
+  def __init__(self, instructions):
+    self.instructions = []
+
+    # figure out the RAW dependences and initialize the instructions list
+    dependence_state = {}
+    for i, instruction in enumerate(instructions):
+      dependences = list()
+      for register in instruction.read_registers:
+        if register in dependence_state:
+          dependences.append((state[register], register))
+      if instruction.write_register:
+        state[instruction.write_register] = i
+      self.instructions.append(_Instruction(instruction, i, self,
+            tuple(dependences)))
+
+  def issue_next(self, reorder_buffer, issue_stage):
+    if (self.next_instruction < len(self.instructions) and
+        not reorder_buffer.is_full()):
+      reorder_buffer.add(self._next_instruction)
+      self._next_instruction += 1
+      return self._next_instruction - 1
+    else:
+      return None
+
+  def update(self):
+    self.cycle += 1
+    for instruction in instructions:
+      instruction.update()
+    if instructions[-1].cur_state == 'CM':
+      self.done = True
+
 class _ReorderBuffer:
   """Mimics a reorder buffer.
 
     Holds instructions that are add()ed to it, lets you know if it is full, and
     can do a commit.
   """
-  def __init__(self, sim_state, length=1e6):
+  def __init__(self, instruction_tracker, length=1e6):
     self.storage = list()
     self.length = length  # Default arg is basically infinity
-    self.sim_state = sim_state
+    self.instruction_tracker = instruction_tracker
 
   def add(self, instruction_number):
     if self.is_full():
-      print "Reorder buffer just got too full!! Oops!"
+      raise Exception("Reorder buffer just got too full!! Oops!")
     self.storage.append(instruction_number)
 
   def is_full(self):
     if len(self.storage) == 0:
       return
     head = self.storage[0]
-    if self.sim_state.instructions[head].current_stage == 'WB':
-      self.sim_state.commit_instruction(head)
+    if self.instruction_tracker.instructions[head].ready_to_commit():
+      self.instruction_tracker.instructions[head].commit()
       self.storage.pop(0)
 
-
-
-
 def run(input_instructions):
   """This is the primary computation point of this module.
 
 
     Each instruction should be a tomasulo.Instruction.
   """
-  instruction_list = _annotate_RAW_dependences(input_instructions)
+  def issue(instruction):
+    instruction.issue
+  instruction_tracker = _InstructionTracker(input_instructions)
 
-  return instruction_list
+  while not instruction_tracker.done:
+    issue_stage
+# Issue next
 
-def _annotate_RAW_dependences(instruction_list):
-  """This function takes in a list of instructions, and returns the
-    instructions and their RAW dependences.
 
-    The input is a list of tomasulo.Instruction.
 
-    The output is a list of tomasulo._AnnotatedInstruction.
-  """
-  state = {}
-  output = []
-  for i, instruction in enumerate(instruction_list):
-    dependences = list()
-    for register in instruction.read_registers:
-      if register in state:
-        dependences.append((state[register], register))
-    if instruction.write_register:
-      state[instruction.write_register] = i
-    output.append(_AnnotatedInstruction(instruction.opcode,
-          instruction.write_register, instruction.read_registers,
-          tuple(dependences)))
-  print state
-  return output
+  return instruction_list