def SYSCALL_Emulation(): simStats.stats.sysCalls = simStats.stats.sysCalls + 1 # count as control HWComponents.CONTROL.byteSize = False # byteOperation on memory HWComponents.CONTROL.writeHILO = False # writes to HI and LO registers HWComponents.CONTROL.lbu = False # memory return value is unsigned byte # specifies control code for ALU={0:ADD,1:SUB,2:AND,3:OR,4:NOR,5:XOR,6:SLT,7:SLTU,8:SLL,9:SRL,10:SRA,11:LUI,12:MUL,13:DIV,14:MULU,15:DIVU HWComponents.CONTROL.ALUop = 0 # ADD - pick anything HWComponents.CONTROL.isBranch = False # is any type of branch HWComponents.CONTROL.isJump = False # J, JAL = True -- gets PC from instruction HWComponents.CONTROL.isRegToPC = False # JR, JALR = True -- gets PC from reg HWComponents.CONTROL.isLink = False # JAL, JALR = True -- writes return address to $31 aka $ra HWComponents.CONTROL.branchSense = True # beq = True; bne = False HWComponents.CONTROL.memToReg = False # Does this instruction get its result from memory HWComponents.REGWritePort.writeEnable = False # Does this instruction write to a register? HWComponents.REGWritePort.address = HWComponents.CONTROL.RD # RD, RT, RA HWComponents.ALUPortB = HWComponents.REG[HWComponents.CONTROL.RT] HWComponents.MemWritePort.writeEnable = False # dispatch based on $v0 callCode=HWComponents.REG[2] if printVerboseOutput: print("Emulating SYSCALL functionality for SYSCALL code {:d}\n".format(callCode)) if 1 == callCode: # print integer service ival = HWComponents.REG[4] # get $a0 #convert to signed from unsigned if ival & 0x80000000: ival = -((~ival +1) & 0xFFFFFFFF) print("{:d}".format(ival),end='') elif 4 == callCode: # print string service strAddr = HWComponents.REG[4] # get $a0 success = False curChar = '1' while not curChar == 0: while False == success: MRval = HWComponents.DMEM.loadByteUnsigned(strAddr) curChar = MRval.value success = MRval.success if not curChar ==0: print("{:c}".format(curChar),end='') success = False strAddr = strAddr + 1 elif 10 == callCode: print("Emulating EXIT syscall, terminating simulation") simStats.stats.cycle = simStats.stats.cycle + 1 # treat this inst/cycle as completed before we exit simStats.stats.completed = simStats.stats.completed + 1 sfm.dump(simStats.stats) elif 34 == callCode: # print hex service ival = HWComponents.REG[4] # get $a0 print("{:#010x}".format(ival),end='') else: print("UNIMPLIMENTED SYSCALL! TERMINATING SIMULATION") sfm.dump(simStats.stats)
def decSpecialZero(self, instruction): # decode based on funct field if self.funct in self.f0DecFuncts: decodeFunc = self.f0DecFuncts[self.funct] else: print( "ILLEGAL INSTRUCTION: {:#010x} at PC: {:#010x}, opcode: {:#04x}" .format(fetchedInst, HWComponents.PC, self.opCode)) sfm.dump(simStats.stats) decodeFunc( instruction ) # set instruction-specific, data independent control fields
def setInstDependentControl(self, fetchedInst): # extract instruction fields self.opCode = fetchedInst >> 26 & 0x3F self.funct = fetchedInst & 0x3F self.imm16z = fetchedInst & 0xFFFF self.imm16s = (fetchedInst & 0xFFFF) | 0xFFFF0000 if ( fetchedInst >> 15 & 1) else fetchedInst & 0xFFFF self.imm16b = (fetchedInst & 0xFFFF) | 0xFFFF0000 if ( fetchedInst >> 15 & 1) else fetchedInst & 0xFFFF self.imm16b = self.imm16b << 2 & 0xFFFFFFFF self.RS = fetchedInst >> 21 & 0x1F self.RT = fetchedInst >> 16 & 0x1F self.RD = fetchedInst >> 11 & 0x1F self.SHAMT = fetchedInst >> 6 & 0x1F self.jTypePC = (HWComponents.PC + 4) & 0xF0000000 | (fetchedInst << 2 & 0x0FFFFFFC) HWComponents.ALUPortA = HWComponents.REG[ self.RS] # always pass through HWComponents.MemWritePort.value = HWComponents.REG[ self.RT] # always pass through if self.printVerboseOutput: print( "Presumptive RS read: {:#010x} from register {:#010x}".format( HWComponents.ALUPortA, self.RS)) # for pretty-printing instructions as they are decoded - not required for simulator operation if self.printVerboseOutput: self.prettyPrintDecodedInst(fetchedInst) # decode based on opcode if self.opCode in self.opDecFuncts: decodeFunc = self.opDecFuncts[self.opCode] else: print( "ILLEGAL INSTRUCTION: {:#010x} at PC: {:#010x}, opcode: {:#04x}" .format(fetchedInst, HWComponents.PC, self.opCode)) sfm.dump(simStats.stats) decodeFunc( fetchedInst ) # set instruction-specific, data independent control fields
def main(): print("Running P(SU) P(ython) S(imulator for a) S(ubset of) M(IPS)") while simStats.stats.cycle < sfm.cycleLimit and simStats.stats.completed < sfm.instLimit: doSimCycle(simStats.stats) doSimTick(simStats.stats) sfm.dump(simStats.stats)
def decSpecialOne(self, instruction): print("Decoding {:#010x} -- not supported!".format(instruction)) sfm.dump(simStats.stats)