Example #1
0
class MIPSSimulator():
  '''Main class for MIPS pipeline simulator.
  
  Provides the main method tick(), which runs pipeline
  for one clock cycle.
  
  '''
  def __init__(self, memoryFile):
    self.nCycles = 0 # Used to hold number of clock cycles spent executing instructions
    
    self.adder              = Add()
    self.branchAdder        = Add()
    self.alu                = Alu()
    self.aluControl         = AluControl()
    self.branchNE           = BranchNotEqual()
    self.branch             = Branch()
    self.constant           = Constant(4)
    self.control            = Control()
    self.dataMemory         = DataMemory(memoryFile)
    self.instructionMemory  = InstructionMemory(memoryFile)
    self.regMux             = Mux()
    self.aluMux             = Mux()
    self.dmMux              = Mux()
    self.branchMux          = Mux()
    self.jmpMux             = Mux()
    self.registerFile       = RegisterFile()
    self.shiftLeft2         = ShiftLeft2()
    self.signExtend         = SignExtend()
    self.jump               = Jump()
    self.leftShift2         = ShiftLeft2()
    self.leftShift2Jump     = ShiftLeft2Jump()

    self.IFID = IFID()
    self.IDEX = IDEX()
    self.EXMEM = EXMEM()
    self.MEMWB = MEMWB()

    self.pc = PC(0xbfc00200) # hard coded "boot" address
    
    self.IFIDelements = [ self.constant, self.branchMux, self.jmpMux, self.instructionMemory, self.adder ]

    self.IDEXelements = [ self.control, self.registerFile, self.signExtend, self.leftShift2Jump, self.jump ]

    self.EXMEMelements = [ self.regMux, self.aluControl, self.aluMux, self.alu, self.shiftLeft2, self.branchAdder, self.branchNE, self.branch ]
    
    self.MEMWBelements = [ self.dataMemory ]

    self.WBelements = [ self.dmMux ] 

    self.elements = [ self.IFIDelements, self.IDEXelements, self.EXMEMelements, self.WBelements]

    self.pipes = [ self.IFID, self.IDEX, self.EXMEM, self.MEMWB]
    
    self._connectCPUElements()
    
  def _connectCPUElements(self):
    ###################### IFID elements ###############################
    self.pc.connect(
      [(self.jmpMux, 'newAddr')],
      ['address'],
      [],
      []
      )

    self.constant.connect(
      [],
      ['Constant'],
      [],
      []
      )

    self.branchMux.connect(
      [(self.adder, 'toBranchSignal'), (self.EXMEM, 'branchMuxIn')],
      ['branchMuxOutput'],
      [(self.EXMEM, 'branchMuxControl')],
      []
      )

    self.jmpMux.connect(
      [(self.branchMux, 'branchMuxOutput'), (self.IDEX, 'newAddr')],
      ['newAddr'],
      [(self.IDEX, 'jump')],
      []
      )

    self.instructionMemory.connect(
      [(self.pc, 'address')],
      ['op', 'rs', 'rt', 'rd', 'shamt', 'funct'],
      [],
      []
      )

    self.adder.connect(
      [(self.pc, 'address'), (self.constant, 'Constant')],
      ['sum'],
      [],
      []
      )

    ###################### IDEX elements ###############################
    self.control.connect(
      [(self.IFID, 'op')],
      [],
      [],
      ['regDst', 'aluSrc', 'memtoReg', 'regWrite', 'memRead', 'memWrite', 'branch', 'aluOp1', 'aluOp0', 'bne', 'jump']
      )

    self.registerFile.connect(
      [(self.IFID, 'rs'), (self.IFID, 'rt'), (self.MEMWB, 'writeReg'), (self.dmMux, 'writeData')],
      ['rd1', 'rd2'],
      [(self.MEMWB, 'regWrite')],
      []
      )
    
    self.signExtend.connect(
      [(self.IFID, 'rd'), (self.IFID, 'shamt'), (self.IFID, 'funct')],
      ['aluMuxIn'],
      [],
      []
      )
    
    self.leftShift2Jump.connect(
      [(self.IFID, 'rs'), (self.IFID, 'rt'), (self.IFID, 'rd'), (self.IFID, 'shamt'), (self.IFID, 'funct')],
      ['jumpaddr'],
      [],
      []
      )
    
    self.jump.connect(
      [(self.leftShift2Jump, 'jumpaddr'), (self.IFID, 'sum')],
      ['newAddr'],
      [],
      []
      )
    ###################### EXMEM elements ###############################
    self.regMux.connect(
      [(self.IDEX, 'rt'), (self.IDEX, 'rd')],
      ['regMuxOutput'],
      [(self.IDEX, 'regDst')],
      []
      )
    self.aluControl.connect(
      [(self.IDEX, 'funct')],
      [],
      [(self.IDEX, 'aluOp1'), (self.IDEX, 'aluOp0')],
      ['aluOutSignal']
      )
    self.aluMux.connect(
      [(self.IDEX, 'rd2'), (self.IDEX, 'aluMuxIn')],
      ['aluSecIn'],
      [(self.IDEX, 'aluSrc')],
      []
      )
    self.alu.connect(
      [(self.IDEX, 'rd1'), (self.aluMux, 'aluSecIn')],
      ['aluOutput'],
      [(self.aluControl, 'aluOutSignal')],
      ['zero']
      )

    self.shiftLeft2.connect(
      [(self.IDEX, 'aluMuxIn')],
      ['toAdder'],
      [],
      []
      )
    self.branchAdder.connect(
      [(self.IDEX, 'sum'), (self.shiftLeft2, 'toAdder')],
      ['branchMuxIn'],
      [],
      []
      )
    self.branchNE.connect(
      [],
      [],
      [(self.IDEX, 'bne'), (self.alu, 'zero')],
      ['toBranchSignal']
      )
    self.branch.connect(
      [],
      [],
      [(self.IDEX, 'branch'), (self.alu, 'zero')],
      ['branchMuxControl']
      )
    ###################### MEMWB elements ###############################

    self.dataMemory.connect(
      [(self.EXMEM, 'aluOutput'), (self.EXMEM, 'rd2')],
      ['toFinalMux'],
      [(self.EXMEM, 'memRead'), (self.EXMEM, 'memWrite')],
      []
      )

    ###################### WB elements ###############################
    self.dmMux.connect(
      [(self.MEMWB, 'aluOutput'), (self.MEMWB, 'toFinalMux')],
      ['writeData'],
      [(self.MEMWB, 'memtoReg')],
      []
      )

    ###################### PIPE elements ###############################
    self.IFID.connect(
      [(self.adder, 'sum'), (self.instructionMemory, 'op'),
       (self.instructionMemory, 'rs'), (self.instructionMemory, 'rt'),
       (self.instructionMemory, 'rd'), (self.instructionMemory, 'shamt'),
       (self.instructionMemory, 'funct')],
      ['sum', 'op', 'rs', 'rt', 'rd', 'shamt', 'funct'],
      [],
      []
      )
    
    self.IDEX.connect(
      [(self.IFID, 'sum'), (self.IFID, 'op'), (self.IFID, 'rt'), 
      (self.IFID, 'rd'), (self.IFID, 'shamt'), (self.IFID, 'funct'),
       (self.registerFile, 'rd1'), (self.registerFile, 'rd2'), (self.signExtend, 'aluMuxIn'),
       (self.jump, 'newAddr') ],
      ['sum', 'op', 'rt', 'rd', 'shamt', 'funct', 'rd1', 'rd2', 'aluMuxIn', 'newAddr' ],
      [(self.control, 'regDst'), (self.control, 'aluSrc'), (self.control, 'memtoReg'), (self.control, 'regWrite'),
       (self.control, 'memRead'), (self.control, 'memWrite'), (self.control, 'branch'),
       (self.control, 'aluOp1'), (self.control, 'aluOp0'), (self.control, 'bne'), (self.control, 'jump')],
      ['regDst', 'aluSrc', 'memtoReg', 'regWrite', 'memRead', 'memWrite', 'branch', 'aluOp1', 'aluOp0', 'bne', 'jump']
      )
    
    self.EXMEM.connect(
      [(self.IDEX, 'rd2'), (self.alu, 'aluOutput'), (self.regMux, 'writeReg'), (self.branchAdder, 'branchMuxIn')],
      ['rd2', 'aluOutput', 'writeReg', 'branchMuxIn'],
      [(self.IDEX, 'memtoReg'), (self.IDEX, 'memtoRead'), (self.IDEX, 'memWrite'), (self.branch ,'branchMuxControl'), (self.IDEX, 'regWrite')],
      ['memtoReg', 'memtoRead', 'memWrite', 'branchMuxControl', 'regWrite']
      )
    
    self.MEMWB.connect(
      [(self.EXMEM, 'writeReg'), (self.EXMEM, 'aluOutput'), (self.EXMEM, 'toFinalMux')],
      ['writeReg', 'aluOutput', 'toFinalMux'],
      [(self.EXMEM, 'memtoReg'), (self.EXMEM, 'regWrite')],
      ['memtoReg', 'regWrite']
      )

  def clockCycles(self):
    '''Returns the number of clock cycles spent executing instructions.'''
    
    return self.nCycles
  
  def dataMemory(self):
    '''Returns dictionary, mapping memory addresses to data, holding
    data memory after instructions have finished executing.'''
    
    return self.dataMemory.memory
  
  def registerFile(self):
    '''Returns dictionary, mapping register numbers to data, holding
    register file after instructions have finished executing.'''
    
    return self.registerFile.register
  
  def printDataMemory(self):
    self.dataMemory.printAll()
  
  def printRegisterFile(self):
    self.registerFile.printAll()
  
  def tick(self):
    '''Execute one clock cycle of pipeline.'''
    
    self.nCycles += 1
    
    # The following is just a small sample implementation
    
    self.pc.writeOutput()
    
    for elem in self.elements:
      for e in elem:
        e.readControlSignals()
        e.readInput()
        e.writeOutput()
        e.setControlSignals()
    
    self.pc.readInput()
Example #2
0
class MIPSSimulator():
    '''Main class for MIPS pipeline simulator.
  
  Provides the main method tick(), which runs pipeline
  for one clock cycle.
  
  '''
    def __init__(self, memoryFile):
        self.nCycles = 1  # Used to hold number of clock cycles spent executing instructions

        self.adder = Add()
        self.branchAdder = Add()
        self.alu = Alu()
        self.aluControl = AluControl()
        self.branchNE = BranchNotEqual()
        self.branch = Branch()
        self.constant = Constant(4)
        self.control = Control()
        self.dataMemory = DataMemory(memoryFile)
        self.instructionMemory = InstructionMemory(memoryFile)
        self.regMux = Mux()
        self.aluMux = Mux()
        self.dmMux = Mux()
        self.branchMux = Mux()
        self.jmpMux = Mux()
        self.registerFile = RegisterFile()
        self.shiftLeft2 = ShiftLeft2()
        self.signExtend = SignExtend()
        self.jump = Jump()
        self.leftShift2 = ShiftLeft2()
        self.leftShift2Jump = ShiftLeft2Jump()

        self.pc = PC(0xbfc00000)  # hard coded "boot" address

        self.elements = [
            self.constant, self.adder, self.instructionMemory, self.control,
            self.regMux, self.leftShift2Jump, self.jump, self.registerFile,
            self.signExtend, self.shiftLeft2, self.branchAdder, self.aluMux,
            self.aluControl, self.alu, self.branchNE, self.branch,
            self.branchMux, self.jmpMux, self.dataMemory, self.dmMux
        ]

        self._connectCPUElements()

    def _connectCPUElements(self):
        self.pc.connect([(self.jmpMux, 'newAddress')], ['address'], [], [])

        self.constant.connect([], ['constant'], [], [])

        self.adder.connect([(self.constant, 'constant'), (self.pc, 'address')],
                           ['sum'], [], [])

        self.instructionMemory.connect(
            [(self.pc, 'address')], ['op', 'rs', 'rt', 'rd', 'shamt', 'funct'],
            [], [])

        self.control.connect([(self.instructionMemory, 'op')], [], [], [
            'regDst', 'aluSrc', 'memtoReg', 'regWrite', 'memRead', 'memWrite',
            'branch', 'aluOp1', 'aluOp0', 'bne', 'jump'
        ])

        self.regMux.connect([(self.instructionMemory, 'rt'),
                             (self.instructionMemory, 'rd')], ['wrSignal'],
                            [(self.control, 'regDst')], [])

        self.leftShift2Jump.connect([(self.instructionMemory, 'rs'),
                                     (self.instructionMemory, 'rt'),
                                     (self.instructionMemory, 'rd'),
                                     (self.instructionMemory, 'shamt'),
                                     (self.instructionMemory, 'funct')],
                                    ['jmpAddress'], [], [])

        self.jump.connect([(self.leftShift2Jump, 'jmpAddress'),
                           (self.adder, 'sum')], ['newJmp'], [], [])

        self.registerFile.connect([(self.instructionMemory, 'rs'),
                                   (self.instructionMemory, 'rt'),
                                   (self.regMux, 'wrSignal'),
                                   (self.dmMux, 'regWrite')], ['rd1', 'rd2'],
                                  [(self.control, 'regWrite')], [])

        self.signExtend.connect([(self.instructionMemory, 'rd'),
                                 (self.instructionMemory, 'shamt'),
                                 (self.instructionMemory, 'funct')],
                                ['extendedOutput'], [], [])

        self.shiftLeft2.connect([(self.signExtend, 'extendedOutput')],
                                ['toBAdder'], [], [])

        self.branchAdder.connect([(self.adder, 'sum'),
                                  (self.shiftLeft2, 'toBAdder')],
                                 ['bAdderResult'], [], [])

        self.aluMux.connect([(self.registerFile, 'rd1'),
                             (self.signExtend, 'extendedOutput')], ['toAlu'],
                            [(self.control, 'aluSrc')], [])

        self.aluControl.connect([(self.instructionMemory, 'funct')], [],
                                [(self.control, 'aluOp0'),
                                 (self.control, 'aluOp1')],
                                ['aluControlSignal'])

        self.alu.connect([(self.registerFile, 'rd1'),
                          (self.aluMux, 'toAlu')], ['aluResult'],
                         [(self.aluControl, 'aluControlSignal')], ['zero'])

        self.branchNE.connect([], [], [(self.control, 'bne'),
                                       (self.alu, 'zero')], ['inverted'])

        self.branch.connect([], [], [(self.control, 'branch'),
                                     (self.branchNE, 'inverted')],
                            ['branched'])

        self.branchMux.connect([(self.adder, 'sum'),
                                (self.branchAdder, 'bAdderResult')],
                               ['bMuxOutput'], [(self.branch, 'branched')], [])

        self.jmpMux.connect([(self.branchMux, 'bMuxOutput'),
                             (self.jump, 'newJmp')], ['newAddress'],
                            [(self.control, 'jump')], [])

        self.dataMemory.connect([(self.alu, 'aluResult'),
                                 (self.registerFile, 'rd2')], ['rd'],
                                [(self.control, 'memWrite'),
                                 (self.control, 'memRead')], [])

        self.dmMux.connect([(self.dataMemory, 'rd'), (self.alu, 'aluResult')],
                           ['regWrite'], [(self.control, 'memtoReg')], [])

    def clockCycles(self):
        '''Returns the number of clock cycles spent executing instructions.'''

        return self.nCycles

    def dataMemory(self):
        '''Returns dictionary, mapping memory addresses to data, holding
    data memory after instructions have finished executing.'''

        return self.dataMemory.memory

    def registerFile(self):
        '''Returns dictionary, mapping register numbers to data, holding
    register file after instructions have finished executing.'''

        return self.registerFile.register

    def printDataMemory(self):
        self.dataMemory.printAll()

    def printRegisterFile(self):
        self.registerFile.printAll()

    def tick(self):
        '''Execute one clock cycle of pipeline.'''

        self.nCycles += 1

        # The following is just a small sample implementation

        self.pc.writeOutput()

        for elem in self.elements:
            elem.readControlSignals()
            elem.readInput()
            elem.writeOutput()
            elem.setControlSignals()

        self.pc.readInput()
Example #3
0
class MIPSSimulator():
  '''Main class for MIPS pipeline simulator.
  
  Provides the main method tick(), which runs pipeline
  for one clock cycle.
  
  '''
  def __init__(self, memoryFile):
    self.nCycles = 0 # Used to hold number of clock cycles spent executing instructions
    
    self.dataMemory = DataMemory(memoryFile)
    self.instructionMemory = InstructionMemory(memoryFile)
    self.registerFile = RegisterFile()
    self.alu = ALU()
    self.mainControl = MainControl()
    self.splitter = Splitter()
    self.signExtender = SignExtender()
    self.andGate = AndGate()
    self.breaker = Breaker()

    self.constant4 = Constant(4)
    # self.randomControl = RandomControl()
    self.pcMux1 = Mux()
    self.pcMux2 = Mux()
    self.regMux = Mux()
    self.aluMux = Mux()
    self.resultMux = Mux()
    self.luiMux = Mux()

    self.adder = Add()
    self.branchAdder = Add()

    self.jumpAddress = JMPAddress()
    self.shiftBranch = LeftShiftTwo()
    self.shiftJump = LeftShiftTwo()

    self.pc = PC(hex(0xbfc00000))  # hard coded "boot" address
    
    self.elements = [self.constant4, self.adder, self.instructionMemory, self.breaker, self.splitter,
                     self.shiftJump, self.mainControl, self.regMux, self.signExtender, self.luiMux, self.registerFile,
                     self.jumpAddress, self.shiftBranch, self.branchAdder, self.aluMux, self.alu, self.dataMemory,
                     self.andGate, self.pcMux1, self.pcMux2, self.resultMux, self.registerFile, self.pc]
    
    self._connectCPUElements()
    
  def _connectCPUElements(self):
    
    self.constant4.connect(
      [],
      ['constant'],
      [],
      []
    )
    
    self.adder.connect(
      [(self.pc, 'pcAddress'), (self.constant4, 'constant')],
      ['sum'],
      [],
      []
    )
    
    self.pcMux2.connect(
      [(self.pcMux1, "ResultMux2"), (self.jumpAddress, "Result")],
      ['muxOut'],
      [(self.mainControl, "JmpCtrl")],
      []
    )
    
    self.pc.connect(
      [(self.pcMux2, 'muxOut')],
      ['pcAddress'],
      [],
      []
    )

    self.instructionMemory.connect(
      [(self.pc, "pcAddress")],
      ["instruction"],
      [],
      []
    )

    self.splitter.connect(
      [(self.breaker, "Instruction")],
      ["31-0", "25-21", "20-16", "15-11", "15-0", "25-0"],
      [],
      []
    )

    self.mainControl.connect(
      [(self.splitter, "31-0")],
      [],
      [],
      ["RegDst", "RegWrite", "ALUSrc", "ALUOp", "MemWrite", "MemtoReg", "MemRead", "ALUType", "AndGate", "JmpCtrl",
       "LuiCtrl"]
    )

    self.regMux.connect(
      [(self.splitter, "20-16"), (self.splitter, "15-11")],
      ["WReg"],
      [(self.mainControl, "RegDst")],
      []
    )

    self.registerFile.connect(
      [(self.splitter, "25-21"), (self.splitter, "20-16"), (self.regMux, "WReg"), (self.resultMux, "WriteData")],
      ["Read1", "Read2"],
      [(self.mainControl, "RegWrite")],
      []
    )

    self.signExtender.connect(
      [(self.splitter, "15-0")],
      ["ExtendedValue"],
      [],
      []
    )

    self.aluMux.connect(
      [(self.registerFile, "Read2"), (self.luiMux, "LuiOutput")],
      ["RightOp"],
      [(self.mainControl, "ALUSrc")],
      []
    )

    self.alu.connect(
      [(self.registerFile, "Read1"), (self.aluMux, "RightOp")],
      ["Result"],
      [(self.mainControl, "ALUOp"), (self.mainControl, "ALUSrc")],
      ["Zero"]
    )

    self.dataMemory.connect(
      [(self.alu, "Result"), (self.registerFile, "Read2")],
      ["ReadData"],
      [(self.mainControl, "MemWrite"), (self.mainControl, "MemRead")],
      []
    )

    self.resultMux.connect(
      [(self.alu, "Result"), (self.dataMemory, "ReadData")],
      ["WriteData"],
      [(self.mainControl, "MemtoReg")],
      []
    )

    self.andGate.connect(
      [],
      [],
      [(self.mainControl, "AndGate"), (self.alu, "Zero")],
      ["PCMuxSelect"]
    )

    self.shiftBranch.connect(
      [(self.signExtender, "ExtendedValue")],
      ["ShiftedValue"],
      [],
      []
    )

    self.branchAdder.connect(
      [(self.adder, "sum"), (self.shiftBranch, "ShiftedValue")],
      ["branchSum"],
      [],
      []
    )

    self.pcMux1.connect(
      [(self.adder, "sum"), (self.branchAdder, "branchSum")],
      ["ResultMux2"],
      [(self.andGate, "PCMuxSelect")],
      []
    )

    self.shiftJump.connect(
      [(self.splitter, "25-0")],
      ["ShiftedValue"],
      [],
      []
    )

    self.jumpAddress.connect(
      [(self.shiftJump, "ShiftedValue"), (self.adder, "sum")],
      ["Result"],
      [],
      []
    )

    self.breaker.connect(
      [(self.instructionMemory, "instruction")],
      ["Instruction"],
      [],
      []
    )

    self.luiMux.connect(
      [(self.signExtender, "ExtendedValue"), (self.splitter, "15-0")],
      ["LuiOutput"],
      [(self.mainControl, "LuiCtrl")],
      []
    )
    
  def clockCycles(self):
    '''Returns the number of clock cycles spent executing instructions.'''
    
    return self.nCycles
  
  def dataMemory(self):
    '''Returns dictionary, mapping memory addresses to data, holding
    data memory after instructions have finished executing.'''
    
    return self.dataMemory.memory
  
  def registerFile(self):
    '''Returns dictionary, mapping register numbers to data, holding
    register file after instructions have finished executing.'''
    
    return self.registerFile.register
  
  #def printDataMemory(self):
    #self.dataMemory.printAll()
  
  #def printRegisterFile(self):
    #self.registerFile.printAll()
  
  def tick(self):
    '''Execute one clock cycle of pipeline.'''
    
    self.nCycles += 1
    
    # The following is just a small sample implementation
    
    self.pc.writeOutput()
    
    for elem in self.elements:
      elem.readControlSignals()
      elem.readInput()
      elem.writeOutput()
      elem.setControlSignals()
    
    self.pc.readInput()
Example #4
0
class MySimulator():
    '''Main class for MIPS pipeline simulator.
    
    Provides the main method tick(), which runs pipeline
    for one clock cycle.
    
    '''
    def __init__(self, memoryFile):

        self.nCycles = 0  # Used to hold number of clock cycles spent executing instructions

        self.datamemory = DataMemory(memoryFile)
        self.instructionmemory = InstructionMemory(memoryFile)
        self.registerfile = RegisterFile()

        self.constant4 = Constant(4)

        self.alu = Alu()
        self.controlunit = ControlUnit()
        self.shift2 = Shift2()
        self.shift16 = Shift16()
        self.signextend = SignExtend()
        self.alterand = Alterand()
        self.altershift = Altershift()

        self.mux_writereg = Mux()  # 6 multiplexors
        self.mux_regoutput = Mux()
        self.mux_jump = Mux()
        self.mux_branch = Mux()
        self.mux_datamem = Mux()
        self.mux_shift16 = Mux()

        self.adderpc = Add()  # 2 adders
        self.addershift = Add()
        self.pc = PC(0xbfc00000)  # hard coded "boot" address

        self.elements = [
            self.constant4, self.adderpc, self.instructionmemory,
            self.controlunit, self.altershift, self.mux_writereg,
            self.registerfile, self.shift16, self.signextend, self.shift2,
            self.addershift, self.mux_regoutput, self.alu, self.alterand,
            self.mux_branch, self.mux_jump, self.datamemory, self.mux_datamem,
            self.mux_shift16, self.registerfile
        ]

        self._connectCPUElements()

    def _connectCPUElements(self):

        self.constant4.connect([], ['constant'], [], [])

        self.controlunit.connect(
            [(self.instructionmemory, 'ins_31-26'),
             (self.instructionmemory, 'ins_5-0')], [], [], [
                 'regdst', 'jump', 'branch', 'memread', 'memtoreg', 'aluop',
                 'memwrite', 'alusrc', 'regwrite', 'branchnotequal', 'loadui'
             ])

        self.adderpc.connect([(self.pc, 'pcaddress'),
                              (self.constant4, 'constant')], ['sum_pc'], [],
                             [])

        self.instructionmemory.connect([(self.pc, 'pcaddress')], [
            'ins_31-26', 'ins_25-21', 'ins_20-16', 'ins_15-11', 'ins_15-0',
            'ins_5-0', 'ins_25-0'
        ], [], [])

        self.altershift.connect([(self.instructionmemory, 'ins_25-0'),
                                 (self.adderpc, 'sum_pc')], ['jump_address'],
                                [], [])

        self.signextend.connect([(self.instructionmemory, 'ins_15-0')],
                                ['signextend_result'], [], [])

        self.shift2.connect([(self.signextend, 'signextend_result')],
                            ['shift2_result'], [], [])
        self.addershift.connect([(self.adderpc, 'sum_pc'),
                                 (self.shift2, 'shift2_result')],
                                ['sum_addershift'], [], [])
        self.mux_branch.connect([(self.adderpc, 'sum_pc'),
                                 (self.addershift, 'sum_addershift')],
                                ['mux_branch_result'],
                                [(self.alterand, 'alterand_result')], [])

        self.mux_jump.connect([(self.mux_branch, 'mux_branch_result'),
                               (self.altershift, 'jump_address')],
                              ['mux_jump_result'],
                              [(self.controlunit, 'jump')], [])
        self.alterand.connect([], [], [(self.controlunit, 'branch'),
                                       (self.controlunit, 'branchnotequal'),
                                       (self.alu, 'alu_zero_result')],
                              ['alterand_result'])

        self.mux_writereg.connect([(self.instructionmemory, 'ins_20-16'),
                                   (self.instructionmemory, 'ins_15-11')],
                                  ['mux_writereg_result'],
                                  [(self.controlunit, 'regdst')], [])

        self.registerfile.connect([(self.instructionmemory, 'ins_25-21'),
                                   (self.instructionmemory, 'ins_20-16'),
                                   (self.mux_writereg, 'mux_writereg_result'),
                                   (self.mux_shift16, 'mux_shift16_result')],
                                  ['reg_data1', 'reg_data2'],
                                  [(self.controlunit, 'regwrite')], [])

        self.mux_regoutput.connect([(self.registerfile, 'reg_data2'),
                                    (self.signextend, 'signextend_result')],
                                   ['mux_regoutput_result'],
                                   [(self.controlunit, 'alusrc')], [])
        self.alu.connect([(self.registerfile, 'reg_data1'),
                          (self.mux_regoutput, 'mux_regoutput_result')],
                         ['alu_result'], [(self.controlunit, 'aluop')],
                         ['alu_zero_result'])
        self.datamemory.connect([(self.alu, 'alu_result'),
                                 (self.registerfile, 'reg_data2')],
                                ['datamemory_result'],
                                [(self.controlunit, 'memwrite'),
                                 (self.controlunit, 'memread')], [])

        self.mux_datamem.connect([(self.alu, 'alu_result'),
                                  (self.datamemory, 'datamemory_result')],
                                 ['mux_datamemory_result'],
                                 [(self.controlunit, 'memtoreg')], [])

        self.mux_shift16.connect([(self.mux_datamem, 'mux_datamemory_result'),
                                  (self.shift16, 'shift16_result')],
                                 ['mux_shift16_result'],
                                 [(self.controlunit, 'loadui')], [])

        self.shift16.connect([(self.instructionmemory, 'ins_15-0')],
                             ['shift16_result'], [], [])

        self.pc.connect([(self.mux_jump, 'mux_jump_result')], ['pcaddress'],
                        [], [])

    def clockCycles(self):
        '''Returns the number of clock cycles spent executing instructions.'''

        return self.nCycles

    def dataMemory(self):
        '''Returns dictionary, mapping memory addresses to data, holding
        data memory after instructions have finished executing.'''

        return self.dataMemory.memory

    def registerFile(self):
        '''Returns dictionary, mapping register numbers to data, holding
        register file after instructions have finished executing.'''

        return self.registerfile.register

    def printDataMemory(self):
        self.dataMemory.printAll()

    def printRegisterFile(self):
        self.registerfile.printAll()

    def tick(self):
        '''Execute one clock cycle of pipeline.'''

        self.nCycles += 1

        # The following is just a small sample implementation

        self.pc.writeOutput()

        for elem in self.elements:
            elem.readControlSignals()
            elem.readInput()
            elem.writeOutput()
            elem.setControlSignals()

        self.pc.readInput()
Example #5
0
class MIPSSimulator():
	'''Main class for MIPS pipeline simulator.

	Provides the main method tick(), which runs pipeline

	for one clock cycle.
	'''
	def __init__(self, memoryFile):
		self.nCycles = 0 # Used to hold number of clock cycles spent executing instructions

		# Fetch
		self.PCMux	  = Mux()
		self.ProgramC   = PC(long(0xbfc00200))
		self.InstMem	= InstructionMemory(memoryFile)
		self.IFadder	= Add()
		self.JMux	   = Mux()
		self.IFaddconst = Constant(4)
		self.IF_ID_Wall = Wall()
		self.fetchgroup = {}

		# Decode
		self.register   = RegisterFile()
		self.signext	= SignExtender()
		self.control	= ControlElement()
		self.jmpCalc	= JumpCalc()
		self.ID_EX_Wall = Wall()

		# Execute
		self.EXadder	= Add()
		self.shiftL	 = LeftShifter()
		self.ALogicUnit = ALU()
		self.ALUSrcMux  = Mux()
		self.RegDstMux  = Mux()
		self.ALUctrl	= AluControl()
		self.EX_MEM_Wall= Wall()

		# Memory
		self.storage	= DataMemory(memoryFile)
		self.brnch	  = Branch()
		self.MEM_WB_Wall= Wall()

		# Write Back
		self.WBmux = Mux()

		self.ProgramC
		self.elements1 = [self.InstMem, self.IFaddconst, self.IFadder, self.PCMux, self.JMux]
		self.elements2 = [self.control, self.register, self.signext, self.jmpCalc]
		self.elements3 = [self.shiftL, self.ALUSrcMux, self.RegDstMux, self.ALUctrl, self.ALogicUnit, self.EXadder]
		self.elements4 = [self.brnch, self.storage]
		self.elementsboot = [self.IFaddconst, self.IFadder, self.InstMem,
							 self.IF_ID_Wall, self.register, self.signext, self.control, self.jmpCalc,
							 self.ID_EX_Wall, self.RegDstMux, self.shiftL, self.EXadder, self.ALUSrcMux, self.ALUctrl, self.ALogicUnit,
							 self.EX_MEM_Wall, self.brnch, self.storage,
							 self.MEM_WB_Wall, self.WBmux, self.PCMux, self.JMux]
		self.walls = [self.MEM_WB_Wall, self.EX_MEM_Wall, self.ID_EX_Wall, self.IF_ID_Wall]


		self._connectCPUElements()

	def _connectCPUElements(self):
		# IF
		self.PCMux.connect(
			[(self.IFadder, "adderout"), (self.EX_MEM_Wall, "adderoutput")],
			["PCmuxoutput"],
			[(self.brnch, "PCSrc")],
			[]
		)

		self.JMux.connect(
			[(self.PCMux, "PCmuxoutput"), (self.jmpCalc, "output")],
			["output"],
			[(self.control, "Jump")],
			[]
		)

		self.IFaddconst.connect(
			[],
			['constant'],
			[],
			[]
		)

		self.ProgramC.connect(
			[(self.JMux, "output")],
			["output"],
			[],
			[]
		)

		self.InstMem.connect(
			[(self.ProgramC, "output")],
			["opcode", "rs", "rt", "rd", "shamt", "funct", "imm", "addr"],
			[],
			[]
		)

		self.IFadder.connect(
			[(self.ProgramC, "output"), (self.IFaddconst, "constant")],
			["adderout"],
			[],
			[]
		)

		self.IF_ID_Wall.connect(
			[(self.InstMem, "opcode"),(self.InstMem, "rs"),
			(self.InstMem, "rt"),(self.InstMem, "rd"),
			(self.InstMem, "shamt"), (self.InstMem, "funct"),
			(self.InstMem, "imm"), (self.InstMem, "addr"),
			(self.IFadder, "adderout")],
			["opcode", "rs", "rt", "rd",
			 "shamt", "funct", "imm", "addr",
			 "adderout"],
			[],
			[]
		)
		# IF
		# ID
		self.register.connect(
			[(self.IF_ID_Wall, "rs"), (self.IF_ID_Wall, "rt"),
			 (self.MEM_WB_Wall, "regdstoutput"), (self.WBmux, "output")],
			["Reg1", "Reg2"],
			[(self.MEM_WB_Wall, "RegWrite")],
			[]
		)

		self.signext.connect(
			[(self.IF_ID_Wall, "imm")],
			["extended"],
			[],
			[]
		)

		self.control.connect(
			[(self.IF_ID_Wall, "opcode")],
			[],
			[],
			["RegDst", "RegWrite", "ALUSrc", "MemtoReg",
			 "MemWrite", "MemRead", "Branch", "ALUOp", "Jump"]
		)

		self.jmpCalc.connect(
			[(self.IF_ID_Wall, "addr"), (self.IF_ID_Wall, "adderout")],
			["output"],
			[],
			[]
		)

		self.ID_EX_Wall.connect(
			[(self.register, "Reg1"), (self.register, "Reg2"),
			(self.signext, "extended"), (self.jmpCalc, "output"),
			(self.IF_ID_Wall, "adderout"), (self.IF_ID_Wall, "funct"),
			(self.IF_ID_Wall, "rd"), (self.IF_ID_Wall, "addr"),
			(self.IF_ID_Wall, "rt")],
			["Reg1", "Reg2", "extended", "output",
			 "adderout", "funct", "rd", "addr", "rt"],
			[(self.control, "RegDst"), (self.control, "RegWrite"),
			(self.control, "ALUSrc"), (self.control, "MemtoReg"),
			(self.control, "MemWrite"), (self.control, "MemRead"),
			(self.control, "Branch"), (self.control, "ALUOp"),
			(self.control, "Jump")],
			["RegDst", "RegWrite", "ALUSrc", "MemtoReg",
			 "MemWrite", "MemRead", "Branch", "ALUOp", "Jump"]
		)
		#ID
		#EX

		self.EXadder.connect(
			[(self.ID_EX_Wall, "adderout"), (self.shiftL, "shifted")],
			["output"],
			[],
			[]
		)

		self.shiftL.connect(
			[(self.ID_EX_Wall, "extended")],
			["shifted"],
			[],
			[]
		)

		self.ALogicUnit.connect(
			[(self.ID_EX_Wall, "Reg1"), (self.ALUSrcMux, "output")],
			["result"],
			[(self.ALUctrl, "ALUctrlsig")],
			["zero"]
		)

		self.ALUSrcMux.connect(
			[(self.ID_EX_Wall, "Reg2"), (self.ID_EX_Wall, "extended")],
			["output"],
			[(self.ID_EX_Wall, "ALUSrc")],
			[]
		)

		self.RegDstMux.connect(
			[(self.ID_EX_Wall, "rt"), (self.ID_EX_Wall, "rd")],
			["RegDstoutput"],
			[(self.ID_EX_Wall, "RegDst")],
			[]
		)

		self.ALUctrl.connect(
			[(self.ID_EX_Wall, "funct")],
			[],
			[(self.ID_EX_Wall, "ALUOp")],
			["ALUctrlsig"]
		)

		self.EX_MEM_Wall.connect(
			[(self.EXadder, "output"), (self.ALogicUnit, "result"),
			 (self.ID_EX_Wall, "rt"), (self.RegDstMux, "RegDstoutput")],
			["adderoutput", "result", "rt", "regdstoutput"],
			[(self.ID_EX_Wall, "RegWrite"), (self.ID_EX_Wall, "MemtoReg"),
			 (self.ID_EX_Wall, "MemWrite"), (self.ID_EX_Wall, "MemRead"),
			 (self.ID_EX_Wall, "Branch"), (self.ALogicUnit, "zero")],
			["RegWrite", "MemtoReg", "MemWrite", "MemRead", "Branch", "zero"]
		)
		#EX
		#MEM

		self.storage.connect(
			[(self.EX_MEM_Wall, "result"), (self.EX_MEM_Wall, "rt")],
			["data"],
			[(self.EX_MEM_Wall, "MemWrite"), (self.EX_MEM_Wall, "MemRead")],
			[]
		)

		self.brnch.connect(
			[],
			[],
			[(self.EX_MEM_Wall, "Branch"), (self.EX_MEM_Wall, "zero")],
			["PCSrc"]
		)


		self.MEM_WB_Wall.connect(
			[(self.EX_MEM_Wall, "adderoutput"), (self.storage, "data"),
			 (self.EX_MEM_Wall, "regdstoutput")],
			["adderoutput", "data", "regdstoutput"],
			[(self.EX_MEM_Wall, "RegWrite"), (self.EX_MEM_Wall, "MemtoReg")],
			["RegWrite", "MemtoReg"]
		)
		#MEM
		#WB
		self.WBmux.connect(
			[(self.MEM_WB_Wall, "adderoutput"), (self.MEM_WB_Wall, "data")],
			["output"],
			[(self.MEM_WB_Wall, "MemtoReg")],
			[]
		)

	def clockCycles(self):
		'''Returns the number of clock cycles spent executing instructions.'''

		return self.nCycles

	def dataMemory(self):
		'''Returns dictionary, mapping memory addresses to data, holding
		data memory after instructions have finished executing.'''

		return self.dataMemory.memory

	def registerFile(self):
		'''Returns dictionary, mapping register numbers to data, holding
		register file after instructions have finished executing.'''

		return self.registerFile.register

	def printDataMemory(self):
		self.dataMemory.printAll()

	def printRegisterFile(self):
		self.registerFile.printAll()

	def bootup(self):
		self.ProgramC.writeOutput()

		for elem in self.elementsboot:
			elem.readControlSignals()
			elem.readInput()
			elem.writeOutput()
			elem.setControlSignals()

		self.ProgramC.readInput()


	def tick(self):
		'''Execute one clock cycle of pipeline.'''

		self.nCycles += 1
		

		self.ProgramC.writeOutput()

		for elem in self.walls:
			elem.writeOutput()
			elem.setControlSignals()

		self.WBmux.readControlSignals()
		self.WBmux.readInput()
		self.WBmux.writeOutput()
		self.WBmux.setControlSignals()

		for elem in self.elements4:
			elem.readControlSignals()
			elem.readInput()
			elem.writeOutput()
			elem.setControlSignals()

		for elem in self.elements3:
			elem.readControlSignals()
			elem.readInput()
			elem.writeOutput()
			elem.setControlSignals()

		for elem in self.elements2:
			elem.readControlSignals()
			elem.readInput()
			elem.writeOutput()
			elem.setControlSignals()

		for elem in self.elements1:
			elem.readControlSignals()
			elem.readInput()
			elem.writeOutput()
			elem.setControlSignals()

		for elem in self.walls:
			elem.readControlSignals()
			elem.readInput()

		self.register.printAll()
		self.ProgramC.readInput()
		print "number of cycles", self.nCycles, "\n"
Example #6
0
class MIPSSimulator():
    '''Main class for MIPS pipeline simulator.
    
    Provides the main method tick(), which runs pipeline
    for one clock cycle.
    
    '''
    def __init__(self, memoryFile):
        self.nCycles = 0  # Used to hold number of clock cycles spent executing instructions

        self.dataMemory = DataMemory(memoryFile)
        self.instructionMemory = InstructionMemory(memoryFile)
        self.registerFile = RegisterFile()

        self.constant3 = Constant(3)
        self.constant4 = Constant(4)
        self.randomControl = RandomControl()
        self.mux = Mux()
        self.adder = Add()
        self.pc = PC(0xbfc00000)  # hard coded "boot" address

        self.elements = [
            self.constant3, self.constant4, self.randomControl, self.adder,
            self.mux
        ]

        self._connectCPUElements()

    def _connectCPUElements(self):
        self.constant3.connect([], ['constant'], [], [])

        self.constant4.connect([], ['constant'], [], [])

        self.randomControl.connect([], [], [], ['randomSignal'])

        self.adder.connect([(self.pc, 'pcAddress'),
                            (self.constant4, 'constant')], ['sum'], [], [])

        self.mux.connect([(self.adder, 'sum'),
                          (self.constant3, 'constant')], ['muxOut'],
                         [(self.randomControl, 'randomSignal')], [])

        self.pc.connect([(self.mux, 'muxOut')], ['pcAddress'], [], [])

    def clockCycles(self):
        '''Returns the number of clock cycles spent executing instructions.'''

        return self.nCycles

    def dataMemory(self):
        '''Returns dictionary, mapping memory addresses to data, holding
        data memory after instructions have finished executing.'''

        return self.dataMemory.memory

    def registerFile(self):
        '''Returns dictionary, mapping register numbers to data, holding
        register file after instructions have finished executing.'''

        return self.registerFile.register

    def printDataMemory(self):
        self.dataMemory.printAll()

    def printRegisterFile(self):
        self.registerFile.printAll()

    def tick(self):
        '''Execute one clock cycle of pipeline.'''

        self.nCycles += 1

        # The following is just a small sample implementation

        self.pc.writeOutput()

        for elem in self.elements:
            elem.readControlSignals()
            elem.readInput()
            elem.writeOutput()
            elem.setControlSignals()

        self.pc.readInput()