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()
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()
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()
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()
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"
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()