Permalink
Browse files

final product

  • Loading branch information...
1 parent 59458c9 commit b930316bddc52372d5f146aa606580d3fe028c8d @maguire committed Dec 9, 2009
Showing with 46 additions and 27 deletions.
  1. +16 −14 Instruction.py
  2. +24 −13 PipelineSimulator.py
  3. +6 −0 run-simulator.py
View
@@ -51,60 +51,62 @@ def op(self):
@property
def dest(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's destination register """
return self.values['dest']
@property
def s1(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's first source register """
return self.values['s1']
@property
def s2(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's second source register """
return self.values['s2']
@property
def immed(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's immediate value """
return self.values['immed']
@property
def target(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's target value """
return self.values['target']
@property
def aluop(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's control to decide an alu operation """
return self.controls['aluop']
@property
def regRead(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's control to decide to read a register"""
return self.controls['regRead']
@property
def regWrite(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's control to decide to write a register """
return self.controls['regWrite']
@property
def readMem(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's control to decide to read memory """
return self.controls['readMem']
@property
def writeMem(self):
- """ Get this Instruction's name """
+ """ Get this Instruction's control to decide to write memory """
return self.controls['writeMem']
def __str__(self):
- str = "%s\t%s, %s, %s" % (self.values['op'],
- self.values['dest'],
- self.values['s1'],
- self.values['s2'] if self.values['s2'] else self.values['immed'])
+ str = "%s\t%s %s %s %s %s" % (self.values['op'],
+ self.values['dest'] if self.values['dest'] else "",
+ self.values['s1'] if self.values['s1'] else "",
+ self.values['s2'] if self.values['s2'] else "",
+ self.values['immed'] if self.values['immed'] else "",
+ self.values['target'] if self.values['target'] else "")
return str
def __repr__(self):
View
@@ -68,51 +68,58 @@ def step(self):
self.pipeline[0] = FetchStage(None, self)
#call advance on each instruction in the pipeline
- #TODO implement hazard control
for pi in self.pipeline:
pi.advance()
-
+ #now that everything is done, remove the register from
+ # the hazard list
if (self.pipeline[1].instr.regWrite) :
self.hazardList.pop(0)
self.checkDone()
- #TODO do not always update program counter, actually we should find a good way
- # to exit the program
+ #if we stalled our branched we didn't want to load a new
+ # so keep the program counter where it is
if self.stall or self.branched:
self.programCounter -= 4
self.branched = False
def checkDone(self):
+ """ Check if we are done and set __done variable """
self.__done = True
for pi in self.pipeline:
if pi.instr is not Nop:
self.__done = False
def run(self):
+ """ Run the simulator, call step until we are done """
while not self.__done:
self.step()
self.debug()
def getForwardVal(self, regName):
+ """ Forward the proper value based on the given register name
+ If the value is not ready, return "GAH"
+ """
if (self.pipeline[4] is not Nop
and self.pipeline[4].instr.result is not None
and self.pipeline[4].instr.dest == regName) :
return self.pipeline[4].instr.result
elif (self.pipeline[1] is not Nop
and self.pipeline[1].instr.dest == regName ):
return self.pipeline[1].instr.result
- else :
+ else :#this value used to be False, but python treats False and 0 the same
return "GAH"
-
+
+ ### DEBUGGING INFORMATION PRINTING ###
def debug(self):
print "######################## debug ###########################"
self.printStageCollection()
self.printRegFile()
print "\n<ProgramCounter>", self.programCounter
self.printPipeline()
- print "CPI : " , float(self.cycles) / float(self.instrCount)
- print "Hazard List : " , self.hazardList
+ print "<CPI> : " , float(self.cycles) / float(self.instrCount)
+ print "<Hazard List> : " , self.hazardList
+
def printPipeline(self):
print "\n<Pipeline>"
print repr(self.pipeline[0])
@@ -171,7 +178,11 @@ def advance(self):
if(self.instr.regRead):
self.instr.source1RegValue = self.simulator.registers[self.instr.s1]
- if self.instr.immed and not( self.instr.op == 'bne' or self.instr.op == 'beq' or self.instr.op =='lw' or self.instr.op =='sw'):
+ if (self.instr.immed and
+ #these instructions require special treatment
+ not( self.instr.op == 'bne' or self.instr.op == 'beq'
+ or self.instr.op =='lw' or self.instr.op =='sw')):
+ #check to see if it is a hex value
if "0x" in self.instr.immed:
self.instr.source2RegValue = int(self.instr.immed,16)
else :
@@ -222,7 +233,7 @@ def advance(self):
if self.instr.regWrite :
self.simulator.hazardList.append(self.instr.dest)
-
+ #calculate the offset of the lw and sw instructions
if self.instr.op == 'lw':
self.instr.source1RegValue = self.instr.source1RegValue + int(self.instr.immed)
elif self.instr.op == 'sw':
@@ -232,10 +243,10 @@ def advance(self):
# Set the other instructions currently in the pipeline to a Nop
self.simulator.pipeline[0] = FetchStage(Nop, self)
self.simulator.pipeline[2] = ReadStage(Nop, self)
- #TODO add special cases instead of just an eval (branch jump)
elif self.instr.op == 'bne':
if self.instr.source1RegValue != self.instr.source2RegValue:
- # Set the program counter to the target address
+ # Set the program counter to the target address
+ # subtract 8 to account for 2 instructions we have loaded into fetch and read
self.simulator.programCounter = self.simulator.programCounter + (int(self.instr.immed) * 4) - 8
# Set the other instructions currently in the pipeline to Nops
self.simulator.pipeline[0] = FetchStage(Nop, self)
@@ -276,7 +287,7 @@ def advance(self):
elif self.instr.readMem:
self.instr.result = self.simulator.mainmemory[self.instr.source1RegValue]
def __str__(self):
- return 'Main Memory\t'
+ return 'Main Memory'
class WriteStage(PipelineStage):
def advance(self):
View
6 run-simulator.py 100644 → 100755
@@ -1,3 +1,5 @@
+#!/usr/bin/python
+
import PipelineSimulator
import Instruction
import os
@@ -6,6 +8,10 @@
def main():
iparser = Instruction.InstructionParser()
pipelinesim = PipelineSimulator.PipelineSimulator(iparser.parseFile(sys.argv[1]))
+
+ filename = sys.argv[2] if len(sys.argv) > 2 else "debug.txt"
+ f = open(filename, 'w')
+ sys.stdout = f
pipelinesim.run()
if __name__ == "__main__":

0 comments on commit b930316

Please sign in to comment.