class Test(unittest.TestCase): '''[nzco]''' def setUp(self): self.ALU = ALU() def testAnd(self): self.ALU.andALU(0x1111, 0x0000) self.assertEqual(0x1111, self.ALU.result) self.assertEqual(0x00, self.ALU.flags) def testOr(self): self.ALU.orALU(0xfff1, 0x0002) self.assertEqual(0xfff3, self.ALU.result) self.assertEqual(0x8, self.ALU.flags) def testNot(self): self.ALU.notALU(0xffff) self.assertEqual(0x0, self.ALU.result) self.assertEqual(0x4, self.ALU.flags) def testNegate(self): self.ALU.negate(0xffff) self.assertEqual(0x01, self.ALU.result) self.assertEqual(0x0, self.ALU.flags) def testSubtract(self): self.ALU.subtract(0x07, 0x02) self.assertEqual(5, self.ALU.result) self.assertEqual(0x02, self.ALU.flags)
def createImmFromSymbol(iNum, symbTable, symbol, immSize): desiredInstruction = symbTable[symbol] if (desiredInstruction == iNum): print('Error: symbol references current instruction') isNeg = False diff = desiredInstruction - iNum if (diff < 0): isNeg = True #create a bus of the immediate if (isNeg): binDiff = bin(diff)[3:] else: binDiff = bin(diff)[2:] lstBus = [] for bit in binDiff: lstBus.append(int(bit)) #adjust the size of the immediate if (len(lstBus) > immSize): print("Warning: sybol immediate greater than max immediate size") while (len(lstBus) < immSize): #sign extend lstBus.insert(0, 0) while (len(lstBus) > immSize): del lstBus[0] imm = Bus(0, lstBus) if (isNeg): twosComp = ALU() return twosComp.TwosComp(imm) return imm
class NextPCLogic: def __init__(self): self.adder = ALU() self.nextPC = None def performOp(self, uncondbranch, branch, aluZero, imm, currPC): if(uncondbranch or (branch and aluZero)): shiftedImm = self.shiftImm(imm) self.nextPC = self.adder.add(currPC, shiftedImm)[0] else: self.nextPC = self.adder.add(currPC, self.generateFour())[0] return self.nextPC def generateFour(self): return Bus(0, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 ]) def shiftImm(self, imm): newImm = Bus(64) newImm.set(0, 0) newImm.set(1, 0) i = 2 while(i < 64): newImm.set(i, imm.at(i-2)) i += 1 return newImm
def __init__(self): self.ALU = ALU() self.PC = Registro(0x0000) self.SP = Registro(0xf000) self.REGISTERS = Registros() self.halt = False self.INTE = False #if True not allow interruptions self.interruptionNumber = 0 self.I = 0 self.Indexes = ["B", "C", "D", "E", "H", "L", "M", "A"]
def main(): a = int("0x7fea", 16) b = int("0x2bc7", 16) a = format(a, "#018b") b = format(b, "#018b") print(int(b, 2)) print(int(a, 2)) A = ALU() c = A.Sub(b, a) print(A.neg) print(c)
def main(): global bus, ram, ppi, alu, cu bus = Bus() ram = RAM(0x0, 64) ppi = PPI(0x40) bus.AddMemoryPeripheral(ram, 0x0, 0x0+64*1024-1) bus.AddIOPeripheral(ppi, 0x40, 0x40+3) alu = ALU() cu = CU(alu, bus) ppi.SetInterruptCallPA(partial(cu.RST, 5.5, ppi)) ppi.SetInterruptCallPB(partial(cu.RST, 6.5, ppi)) openFile() i = 0 for wd in words: ram.Write(0x8000+i, wd) i += 1 #ram.Write(0x002C, 0x6F) #ram.Write(0x002D, 0xC9) ram.Write(0x002c, 0xdb) ram.Write(0x002d, 0x40) ram.Write(0x002e, 0xc9) cu.Reset() cu.SetPC(0x8000) thread = Thread(target=execute) thread.start() ppi.a = 0xbb while cu.running: pass # cmd = input("Enter a command: ") # if cmd == "quit": # cu.running = False # elif cmd == "stba": # ppi.StrobeA() # elif cmd == "stbb": # ppi.StrobeB() # elif cmd == "show": # print("") # alu.Show() # #print("\n") # #ram.Show() # print("\n") # ppi.Show() ram.ShowRange(parser.labels["TABLE"], parser.labels["TABLE"]+0x63) alu.Show()
def __init__(self, initialPC=Bus(64), IMem=Memory(True), DMem=Memory(False)): self.ALU = ALU() self.IMem = IMem self.DMem = DMem self.signExtender = SignExtender() self.regFile = RegisterFile() self.Control = Control() self.nextPCLogic = NextPCLogic() self.PC = initialPC self.aluZero = 0
def __init__(self, mem_size: int = 10000): """ The following is an abstraction for a bank of values such as valA, which will be used during each cycle. It's set up as an object to avoid circular import. """ self.ValBank = ValBank() """ The following are functional units like memory, registers, or flags """ self.Memory = Memory(mem_size) self.RegisterBank = RegisterBank() self.ZF = CCFlag("ZF") # zero flag self.OF = CCFlag("OF") # overflow flag self.SF = CCFlag("SF") # sign flag self.ErrorFlag = StateFlag("Error Flag", error_lib) self.StateFlag = StateFlag("State Flag", state_lib) self.ALU = ALU(self.ValBank, self.StateFlag, self.ErrorFlag, self.SF, self.OF, self.ZF) """ The following are functional abstractions of operations that the processor performs """ self.Fetcher = Fetcher(self.ValBank, self.RegisterBank, self.Memory, self.StateFlag, self.ErrorFlag) self.Decoder = Decoder(self.ValBank, self.RegisterBank, self.Memory) self.Executor = Executor(self.ValBank, self.ALU, self.OF, self.ZF, self.SF) self.Memorizer = Memorizer(self.ValBank, self.Memory) self.RegWriter = RegWriter(self.RegisterBank, self.ValBank) self.PCUpdater = PCUpdater(self.RegisterBank, self.ValBank)
def __init__(self, infile, outfile, num_registers=32): self.__disassembler = Disassembler() self.__input_file = infile self.__output_file = outfile self.__f = open('team13_out_pipeline.txt', 'w') self.__pc = 96 self.__cycle = 0 self.__memory = {} self.__last_inst = 0 self.pre_issue_size = 4 self.pre_alu_size = 2 self.pre_mem_size = 2 self.post_alu_size = 1 self.post_mem_size = 1 self.__pre_issue_buffer = deque(maxlen=self.pre_issue_size) self.__pre_mem_buffer = deque(maxlen=self.pre_mem_size) self.__pre_alu_buffer = deque(maxlen=self.pre_alu_size) self.__post_mem_buffer = deque(maxlen=self.post_mem_size) self.__post_alu_buffer = deque(maxlen=self.post_alu_size) self.__cache_to_load = deque(maxlen=2) self.__register_file = RegisterFile(num_registers) self.__wb = WriteBackUnit(self.__register_file) self.__cache = Cache(self.__memory) self.__alu = ALU() self.__mem = MemoryUnit(self.__cache) self.__if = IFUnit(self.__cache, self.__register_file) self.__iu = IssueUnit(self.__register_file, self.__pre_issue_buffer, self.__pre_mem_buffer, self.__pre_alu_buffer, self.__post_mem_buffer, self.__post_alu_buffer) self.__read_file()
def singleCyleCpu(instructions): #clk, Reset ''' 顶层模块 @param instructions: 指令数组 ''' opCode = Signal(intbv(0)[6:]) signal_32bit = [Signal(intbv(0)[32:]) for i in range(4)] Out1, Out2, curPC, Result = signal_32bit ALUOp = Signal(intbv(0)[3:]) ExtOut = Signal(intbv(0)[32:]) DMOut = Signal(intbv(0)[32:]) immediate = Signal(intbv(0)[16:]) signal_5bit = [Signal(intbv(0)[5:]) for i in range(3)] rs, rt, rd = signal_5bit signal_1bit = [Signal(intbv(0)[1:]) for i in range(13)] Reset, clk, zero, PCWre, PCSrc, ALUSrcB, ALUM2Reg,\ RegWre, InsMemRW, DataMemR, DataMemW, ExtSel, RegOut = signal_1bit clk = Signal(intbv(1)[1:]) clock = Clock(clk) alu = ALU(Out1, Out2, ExtOut, ALUSrcB, ALUOp, zero, Result, True) pc = PC(clk, Reset, PCWre, PCSrc, immediate, curPC, True) control = ControlUnit(opCode, zero, PCWre, ALUSrcB, ALUM2Reg, RegWre, InsMemRW, DataMemR, DataMemW, ExtSel, PCSrc, RegOut, ALUOp, True) datamemory = DataMemory(clk, Result, Out2, DataMemR, DataMemW, DMOut, True) insmem = instructionMemory(instructions, curPC, InsMemRW, opCode, rs, rt, rd, immediate, True) registerfile = registerFile(clk, RegWre, RegOut, rs, rt, rd, ALUM2Reg, Result, DMOut, Out1, Out2, True) ext = SignZeroExtend(immediate, ExtSel, ExtOut, True) @instance def stimulus(): Reset.next = 1 cycle = 1 while True: yield delay(1) print('-' * 90) print('cycle:' + str(cycle), 'clk:' + str(clk), 'opcode:' + '{0:06b}'.format(int(opCode)), 'Out1:' + str(Out1), 'Out2:' + str(Out2), 'curPc:' + str(curPC), 'Result:' + str(Result)) print('-' * 90, '\n') if not clk: cycle += 1 return instances()
def __init__(self, manufacturer, build_date, purpose, ram, clock, visualizations): super().__init__(manufacturer, build_date, purpose) self.ram = RAM(manufacturer, build_date, "Random access memory", 16, ram) #RAM self.alu = ALU(manufacturer, build_date, "Arithmetic and Logic unit") #ALU #clock self.clock = Clock(manufacturer, build_date, "This component manages the time", clock) #Registers self.a = Register(manufacturer, build_date, "Register A", 4, "") self.b = Register(manufacturer, build_date, "Register B", 4, "") self.c = Register(manufacturer, build_date, "Register C", 4, "") self.d = Register(manufacturer, build_date, "Register D", 4, "") self.pc = Register(manufacturer, build_date, "Program Counter", 4, 0) self.ir = Register(manufacturer, build_date, "Instruction Register", 4, "") self.irb = Register(manufacturer, build_date, "Instruction Register", 4, "") self.oR = ORegister(manufacturer, build_date, "Output Register", 4, "") self.visualizations = visualizations
def decode_step(self, index): self.Simulator.PC = ALU.addSubstract(self.Simulator.PC, 4, 0) inst = self.Simulator.InsMEM[index] if inst == 0: result = {'func': 'nop'} else: opCode = inst >> 26 opCode_front = opCode >> 3 opCode_back = opCode & 7 if opCode == 0: funct = inst & 63 funct_front = funct >> 3 funct_back = funct & 7 func = self.Funct_list[funct_front][funct_back] rs = (inst >> 21) & 31 rt = (inst >> 16) & 31 rd = (inst >> 11) & 31 sh = (inst >> 6) & 31 result = { 'func': func, 'rs': rs, 'rt': rt, 'rd': rd, 'shamt': sh } else: func = self.Opcode_list[opCode_front][opCode_back] if 'j' in func: j_add = (inst << 6) >> 6 & 0x3FFFFFF result = {'func': func, 'j_add': j_add} else: offset = inst & 0xFFFF if func[-1] == 'i': temp = struct.pack('>i', inst) offset = struct.unpack('>1h1h', temp)[1] rs = (inst >> 21) & 31 rt = (inst >> 16) & 31 result = { 'func': func, 'rs': rs, 'rt': rt, 'offset': offset } self.Simulator.DecodeAssem.decode(result) print(result) return self.Simulator.PC
def uRisc(srcFile, screenFlag): f = open(srcFile, 'r') Labels = dict() PC = ProgramCounter() A = ALU() fetchLabels(Labels, srcFile) for line in f: unpreparedI = [] unpreparedI = PC.ReadInstruction(line) if unpreparedI == [] or unpreparedI == "": continue I = Decode(unpreparedI, Labels) if I == None: continue else: PC.loadIR(I) PCMax = len(PC.IR) if 'l' in Labels: PCMax = Labels['l'] while True: if PC.PC == PCMax: break I = PC.InstructionFetch() PrevPC = PC.PC PC.UpdatePC() if I.instrType == 0b01: if I.opCode == 0b10100 or I.opCode == 0b10110: a = ReadFromRegister(I.RA) b = ReadFromRegister(I.RB) if I.opCode == 0b10100: WriteToRegister(I.RA, MEMORY[b]) #load else: MEMORY[a] = format(b, "#06x") #store else: a = ReadFromRegister(I.RA) b = ReadFromRegister(I.RB) A.Exe(I.opCode, I.RC, a, b) elif I.instrType == 0b10: WriteToRegister(I.RC, I.offset) elif I.instrType == 0b11: if I.R == 1: WriteToRegister(I.RC, I.offset, I.R) else: WriteToRegister(I.RC, I.offset, I.R) elif I.instrType == 0b00: #jumps jumpCond = None if I.opCode == 0b00: jumpCond = 0 elif I.opCode == 0b01: jumpCond = 1 elif I.opCode == 0b10: jumpCond = 1 #vai dar jump elif I.opCode == 0b11: if I.R == 0: WriteToRegister(7, format(PC.PC, "#016b")) #jump and link b = ReadFromRegister(I.RC) PC.UpdatePC(b) continue else: b = ReadFromRegister(I.RC) #jump register PC.UpdatePC(b) continue #determinando cond agora jump = None if I.cond != None: if I.cond == 0b100: jump = jumpCond == A.neg elif I.cond == 0b101: jump = jumpCond == A.zero elif I.cond == 0b110: jump = jumpCond == A.carry elif I.cond == 0b111: jump = jumpCond == A.negzero elif I.cond == 0b0: jump = True elif I.cond == 0b011: jump = jumpCond == A.overflow else: jump = True if jump: off = int(I.offset, 2) PC.UpdatePC(off) if screenFlag: screen(A, format(PrevPC, "#06x")) wait = input()
def operate(self): for line in self.ram1.d: print("-------------------------------------------------") print("Fetch:") print(f"La instrucción es: {self.ram1.d[line]}") self.delay1.tiempo() print("Decode:") for j in self.rom1.instructions: if self.ram1.d[line][0:4] == j: print(self.rom1.instructions[j]) print(self.ram1.d[line][5:10]) self.delay1.tiempo() print("Execute:") if self.rom1.instructions[j] == "LOAD_R0": self.rom1.valores() posicion = int(self.ram1.d[line][5:10]) self.register.getvalue(self.rom1.val[posicion]) self.register.r0() elif self.rom1.instructions[j] == "LOAD_R1": self.rom1.valores() posicion = int(self.ram1.d[line][5:10]) self.register.getvalue(self.rom1.val[posicion]) self.register.r1() elif self.rom1.instructions[j] == "OUTPUT": print(self.register.r1()) elif self.rom1.instructions[j] == "ADD": a = self.ram1.d[line][5:7] b = self.ram1.d[line][8:10] print(a) print(b) alu1 = ALU(self.register.R0, self.register.R1, 0) alu1.suma() self.register.getvalue(alu1.result) self.register.r1() elif self.rom1.instructions[j] == "SUB": a = self.ram1.d[line][5:7] b = self.ram1.d[line][8:10] print(a) print(b) alu1 = ALU(self.register.R0, self.register.R1, 0) alu1.resta() elif self.rom1.instructions[j] == "HALT": exit() elif self.rom1.instructions[j] == "AND": a = self.ram1.d[line][5:7] b = self.ram1.d[line][8:10] print(a) print(b) alu1 = ALU(self.register.R0, self.register.R1, 0) if alu1.And() == True: print("La siguiente operación lógica es verdadera") else: print("La operación es falsa") elif self.rom1.instructions[j] == "OR": a = self.ram1.d[line][5:7] b = self.ram1.d[line][8:10] print(a) print(b) alu1 = ALU(self.register.R0, self.register.R1, 0) if alu1.OR() == True: print("La siguiente operación lógica es verdadera") else: print("La operación es falsa") elif self.rom1.instructions[j] == "STORE_R0": rom1 = Rom() rom1.valores() self.rom1.val[line][8:10] = self.register.R0 print(self.rom1.val[line][8:10]) elif self.rom1.instructions[j] == "STORE_R0": rom1 = Rom() rom1.valores() self.rom1.val[line][8:10] = self.register.R1 print(self.rom1.val[line][8:10]) elif self.rom1.instructions[j] == "ILD_R0": self.rom1.valores() posicion = int(self.ram1.d[line][5:10]) self.register.getvalue(self.rom1.val[posicion]) self.register.r0() elif self.rom1.instructions[j] == "ILD_R1": self.rom1.valores() posicion = int(self.ram1.d[line][5:10]) self.register.getvalue(self.rom1.val[posicion]) self.register.r1() elif self.rom1.instructions[j] == "LOAD_R2": self.rom1.valores() posicion = int(self.ram1.d[line][5:10]) self.register.getvalue(self.rom1.val[posicion]) self.register.r2() elif self.rom1.instructions[j] == "LOAD_R3": pass print("-------------------------------------------------") self.delay1.tiempo()
class CU(IC): #attributes for CU ram = [None] * 16 alu = None running = None #registers a = None b = None c = None d = None #special register for output pc = None ir = None irb = None oR = None clock = None visualizations = None def __init__(self, manufacturer, build_date, purpose, ram, clock, visualizations): super().__init__(manufacturer, build_date, purpose) self.ram = RAM(manufacturer, build_date, "Random access memory", 16, ram) #RAM self.alu = ALU(manufacturer, build_date, "Arithmetic and Logic unit") #ALU #clock self.clock = Clock(manufacturer, build_date, "This component manages the time", clock) #Registers self.a = Register(manufacturer, build_date, "Register A", 4, "") self.b = Register(manufacturer, build_date, "Register B", 4, "") self.c = Register(manufacturer, build_date, "Register C", 4, "") self.d = Register(manufacturer, build_date, "Register D", 4, "") self.pc = Register(manufacturer, build_date, "Program Counter", 4, 0) self.ir = Register(manufacturer, build_date, "Instruction Register", 4, "") self.irb = Register(manufacturer, build_date, "Instruction Register", 4, "") self.oR = ORegister(manufacturer, build_date, "Output Register", 4, "") self.visualizations = visualizations # Intruction Set Table def OUTPUT(self, arg): pos = int(arg, 2) #convert binary to decimal data = self.ram.getData(pos) #retrieve data from RAM at position pos self.oR.setData(data) #set data into ORegister return "message loaded into ORegister" def LD_A(self, RAMLoc): pos = int(RAMLoc) data = self.ram.getData(pos) print(f"Succesfully loaded 'RAM[{pos}]={data}' into Register: A") self.a.setData(data) def LD_B(self, RAMLoc): pos = int(RAMLoc) data = self.ram.getData(pos) print(f"Succesfully loaded 'RAM[{pos}]={data}' into Register: B") self.b.setData(data) def AND(self, arg): letra1 = self.twoBitToRegLetter(arg[0]) letra2 = self.twoBitToRegLetter(arg[1]) value1 = letra1.getData() value2 = letra2.getData() comparison = self.alu.AND(value1, value2) # calls the alu logic operation 'or' print( f"Register {letra1}: {value1}\nRegister {letra2}: {value2}\And: {bool(comparison)}" ) return comparison def ILD_A(self, constant): constant = int(constant) self.a.setData(constant) print(f"Succesfuly loaded {self.a.getData()} into Register A") def STR_A(self, addr): data = self.a.getData() addr = int(addr) data = int(data) self.ram.setData(addr, data) print(f"Succesfuly wrote {self.a.getData()} into RAM address: {addr}") def STR_B(self, addr): data = self.b.getData() addr = int(addr) data = int(data) self.ram.setData(addr, data) print(f"Succesfuly wrote {self.b.getData()} into RAM address: {addr}") def OR(self, arg): reg1 = self.twoBitToRegLetter( arg[0]) # extracts the first 2-bit from the 8bit value reg2 = self.twoBitToRegLetter( arg[1]) # extracts the first 2-bit from the 8bit value value1 = reg1.getData() value2 = reg2.getData() comparison = self.alu.OR(reg1, reg2) # calls the alu logic operation 'or' print( f"Register {reg1}: {value1}\nRegister {reg2}: {value2}\Or: {bool(comparison)}" ) return comparison def ILD_B(self, constant): constant = int(constant) self.b.setData(constant) print(f"Succesfuly read {self.b.getData()} into Register B") def ADD(self, arg): reg1 = self.twoBitToRegLetter( arg[0]) # extracts the first 2-bit from the 8bit value reg2 = self.twoBitToRegLetter( arg[1]) # extracts the first 2-bit from the 8bit value value1 = reg1.getData() value2 = reg2.getData() addition = self.alu.ADD(value1, value2) reg2.setData(addition) print( f"Register {reg1}: {value1}\nRegister {reg2}: {value2}\Addition: {addition}" ) def SUB(self, arg): reg1 = self.twoBitToRegLetter( arg[0]) # extracts the first 2-bit from the 8bit value reg2 = self.twoBitToRegLetter( arg[1]) # extracts the first 2-bit from the 8bit value value1 = reg1.getData() value2 = reg2.getData() substraction = self.alu.SUB(value1, value2) reg2.setData(substraction) print( f"Register {reg1}: {value1}\nRegister {reg2}: {value2}\Substraction: {substraction}" ) def JMP(self, arg): self.pc.data = int(arg) def JMP_N(self, arg): if (self.alu.getNegative() == 1): self.JMP(arg) else: pass def ILD_C(self, constant): constant = int(constant) self.a.setData(constant) print(f"Succesfuly loaded {self.c.getData()} into Register C") def ILD_D(self, constant): constant = int(constant) self.a.setData(constant) print(f"Succesfuly loaded {self.d.getData()} into Register D") def reset(self): self.pc.data = 0 self.ir = self.irb self.running = False def HALT(self, data): print("HALTING...") self.reset() # Dictionary with commands and functions intructionSetTable = { "0000": OUTPUT, "OUTPUT": OUTPUT, "0001": LD_A, "LD_A": LD_A, "0010": LD_B, "LD_B": LD_B, "0011": AND, "AND": AND, "0100": ILD_A, "ILD_A": ILD_A, "0101": STR_A, "STR_A": STR_A, "0110": STR_B, "STR_B": STR_B, "0111": OR, "OR": OR, "1000": ILD_B, "ILD_B": ILD_B, "1001": ADD, "ADD": ADD, "1010": SUB, "SUB": SUB, "1011": JMP, "JMP": JMP, "1100": JMP_N, "JMP_N": JMP_N, "1101": ILD_C, "ILD_C": ILD_C, "ILD_D": ILD_D, "1110": ILD_D, "HALT": HALT, "1111": HALT } # Dictionary that returns for each 2bit code a letter corresponding to a reg def twoBitToRegLetter(self, param): if (param == "00" or param == "A"): return self.a if (param == "01" or param == "B"): return self.b if (param == "10" or param == "C"): return self.c if (param == "11" or param == "D"): return self.d # twoBitToRegLetter = { # "00": "a", # "A": "a", # "01": "b", # "B": "b", # "10": "c", # "C": "c", # "11": "d", # "D": "d" # } def getFunction(self, opcode): return self.intructionSetTable.get(opcode) """ def getRegLetter(self, twoBit): return self.twoBitToRegLetter.get(twoBit) """ def initBios(self, string): pass def startInstructions(self, codelines): for line in codelines: if (line[0] != "#"): self.fetch(line) self.clock.next() def run(self, codelines, pc=None): if pc: self.pc.data = pc self.running = True while self.running: self.startInstructions(codelines) def fetch(self, codeline): self.decode(codeline) def decode(self, lineOfCode): opcode = lineOfCode.split()[0] print(f"opcode: {opcode}") function = self.getFunction(opcode) print(f"function: {function}") print(f"PC: {self.pc.data}") self.pc.data += 1 self.ir = function if (len(lineOfCode.split()) == 3): arguments = lineOfCode.split()[1:] arguments = list(map(str, arguments)) print(f"Arguments: {arguments}") elif (len(lineOfCode.split()) == 2): arguments = lineOfCode.split()[1] else: arguments = None self.execute(function, arguments) def execute(self, function, param): function(self, param) def printStatus(self): return f"Running?: {bool(self.running)}"
def test_equal_fixed( dump_vcd ): run_test_vector_sim( ALU( 16 ), fixed_ET_vector, dump_vcd)
def test_add_random(dump_vcd): run_test_vector_sim( ALU(16), random_add_vector, dump_vcd )
from pymtl import * from ALU import ALU input_values = range(0, 255, 16) input_values.extend( [0]*3 ) model = ALU(16) model.elaborate() sim = SimulationTool( model ) sim.reset() for input_value in input_values: model.op1.value = input_value model.op2.value = input_value model.operation = 0 sim.print_line_trace() sim.cycle()
def test_invalid_operation( dump_vcd ): print "Testing invalid input" f = lambda x,y: 0 test_vector_table = alu_gen_random( 0x7, f ) run_test_vector_sim( ALU(16), test_vector_table, dump_vcd )
def __init__(self): self.adder = ALU() self.nextPC = None
def test_sub_fixed( dump_vcd ): run_test_vector_sim( ALU( 16 ), fixed_sub_vector, dump_vcd)
i += 1 return newImm if __name__ == '__main__': npl = NextPCLogic() #shiftedImm = 0x8 imm = Bus(0, [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 ]) #currPC = 0x8 currPC = Bus(0, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 ]) npl.performOp(1, 0, 1, imm, currPC).print('x') npl.performOp(0, 1, 1, imm, currPC).print('x') npl.performOp(0, 1, 0, imm, currPC).print('x') alu = ALU() four = npl.generateFour() zero = Bus(64) minusFour = alu.performOp(Bus(0, [0,0,1,1]), zero, four)[0] npl.performOp(1, 0, 0, minusFour, currPC).print('x')
def test_sub_random( dump_vcd ): run_test_vector_sim( ALU(16), random_sub_vector, dump_vcd )
def CPU(): # the main block which will connect all of our blocks ''' creating the nessecry signal to connect the blocks ''' enable, enable2, clock, RestClk, MEMread, MEMwrite, REGwrite, PCSrc, ALUMUXsig, MEMtoREG, zero, Branch = [ Signal(bool(0)) for i in range(12) ] instructionIN = Signal(intbv(0)[32:]) PCsignal = Signal(intbv(0, min=-1024)) PC_Mux_result = Signal(intbv(0, min=-1024)) PC_Branch_result = Signal(intbv(0, min=-1024)) PC_adder_result = Signal(intbv(0, min=-1024)) instruction = Signal(intbv(0)) rs1OUT, rs2OUT = [ Signal(intbv(0, min=-2**31, max=2**31)) for i in range(2) ] rd, rs1, rs2, ALUsig, MEMsignal = [Signal(intbv(0)[5:]) for i in range(5)] Mux_RB_result = Signal(intbv(0, min=-2**31, max=2**31)) imm = Signal(intbv(0, min=-2**31, max=2**31)) Mux_ALUsrc_result = Signal(intbv(0, min=-2**31, max=2**31)) ALUoutput = Signal(intbv(0, min=-2**31, max=2**31)) MEMoutput = Signal(intbv(0, min=-2**31, max=2**31)) PCclk = Signal(bool(0)) counter = Signal(intbv(0)) '''a clock specified for the PC to slow the process of sending an instruction (to prevent pipelining )''' @always(delay(25)) def clockGENpc(): PCclk.next = not PCclk '''a faster clock for the instructions ''' @always(delay(5)) def clockGEN(): if counter == 4: RestClk.next = 1 counter.next = 0 enable2.next = 1 else: RestClk.next = 0 counter.next = counter + 1 clock.next = not clock PCSrc.next = ( Branch & zero ) # an and gate updated by each clock to determine if the branch is taken or not '''<----------------------------connecting the blocks----------------------->''' PC_driver = pc(PCclk, PC_Mux_result, enable, PCsignal) Adder = adder(PCsignal, PC_adder_result) Adder_Branch = BranchAdder(PCsignal, imm, PC_Branch_result) Mux_pc = mux(PC_Mux_result, PC_adder_result, PC_Branch_result, PCSrc) Instruction_MEM = inst_memory(clock, enable, PCsignal, instructionIN, instruction, RestClk) DECODE = decoder(instruction, rs1, rs2, rd, imm) CONTROL = ControlUnit(instruction, ALUsig, ALUMUXsig, REGwrite, Branch, MEMwrite, MEMtoREG, MEMread, MEMsignal, clock, enable2, RestClk) Regsters = RegisterFile(rs1, rs2, rd, rs1OUT, rs2OUT, REGwrite, Mux_RB_result, clock, enable2, RestClk) Mux_ALUsrc = mux(Mux_ALUsrc_result, rs2OUT, imm, ALUMUXsig) Perform_operations = ALU(rs1OUT, Mux_ALUsrc_result, ALUsig, ALUoutput, zero, PCsignal) MEMaccess = MainMemory(ALUoutput, rs2OUT, MEMoutput, MEMwrite, MEMread, MEMsignal, clock, RestClk) Mux_RB = mux(Mux_RB_result, ALUoutput, MEMoutput, MEMtoREG) @instance def stimulate(): '''<---------------------start load the instructions into the instruction memory-------------------->''' enable.next = 0 # 1 instructionIN.next = 0b00011111010000000000001110010011 yield PCclk.posedge # 2 instructionIN.next = 0b00000000000000000000010110010011 yield PCclk.posedge # 3 instructionIN.next = 0b00000000000100000000011000010011 yield PCclk.posedge # 4 instructionIN.next = 0b00011111010000000000001100010011 yield PCclk.posedge # 5 instructionIN.next = 0b00000000101101100000011000110011 yield PCclk.posedge # 6 instructionIN.next = 0b00000000110000110010001000100011 yield PCclk.posedge # 7 instructionIN.next = 0b00000000010000110000001100010011 yield PCclk.posedge # 8 instructionIN.next = 0b00000000000101011000010110010011 yield PCclk.posedge # 9 instructionIN.next = 0b11111110011101011100100011100011 yield PCclk.posedge # 10 instructionIN.next = 0b00011111010000000000001100010011 yield PCclk.posedge # 11 instructionIN.next = 0b00000000110000110010000000100011 yield PCclk.posedge # 12 instructionIN.next = 0b00000000000000110010010100000011 yield PCclk.posedge '''<------------------------done loading the instructions ------------------------>''' enable.next = 1 # enable the the instructions memory and the PC to start running yield clock.negedge while True: # a while loop to print each instruction when it's executing print('time: ', now(), 'PC---->', int(PCsignal)) print( '_________________________________________________________________' '_______________________________________________________________________________' ) print( '\nthe instruction is : %s ||operands: rd: x%d , rs1: x%d , rs2: x%d , imm: %d ' % (bin(instruction, 32), int(rd), int(rs1), int(rs2), int(imm))) print( 'the signals are : ALUsignal: %s | ALUMUXsig: %s | REGwrite: %s | PCSrc: %s ' '| MEMwrite: %s | MEMtoREG: %s | MEMread: %s | MEMsignal: %s ' % (bin(ALUsig, 5), bin(ALUMUXsig, 1), bin(REGwrite, 1), bin(PCSrc, 1), bin(MEMwrite, 1), bin( MEMtoREG, 6), bin(MEMread, 1), bin(MEMsignal, 3))) print('PC Equals: ', int(PCsignal)) print( '______________________________________________________________________________________' '__________________________________________________________') yield PCclk.negedge return instances()
def execute(self): fileS = FileStream("test.txt", "", "", "", "") fileOpcode = FileStream("ins.txt", "", "", "", "") opcodesArray = [] fileS.processFile() opcodesArray = fileOpcode.readOpcodes() i = 0 result = 0 quot = 0 timearray = [] acc = 0 binStng = "" operationName = [] #for opcode in fileS.opcodes: while i < len(fileS.opcodes): currentOpcode = fileS.opcodes[i] if currentOpcode == opcodesArray[0]: operationName.append(opcodesArray[0]) if fileS.aarr[i] == "acc": self.printRegs(bin(acc)[2:].zfill(8), fileS.barr[i]) aluCtrl = ALU(acc, int(fileS.barr[i], 2), 0) elif fileS.barr[i] == "acc": self.printRegs(fileS.aarr[i], bin(acc)[2:].zfill(8)) aluCtrl = ALU(int(fileS.aarr[i], 2), acc, 0) else: self.printRegs(fileS.aarr[i], fileS.barr[i]) aluCtrl = ALU(int(fileS.aarr[i], 2), int(fileS.barr[i], 2), 0) start = timeit.default_timer() result = aluCtrl.add() binStng = bin(result)[2:].zfill(8) stop = timeit.default_timer() timearray.append(stop - start) print "The operation is ADD " print "The final result in binary is ", binStng print "The final result in decimal is ", result acc = result print "Accumulator value is ", acc print "Elapsed time is ", (stop - start) elif currentOpcode == opcodesArray[1]: operationName.append(opcodesArray[1]) if fileS.aarr[i] == "acc": self.printRegs(bin(acc)[2:].zfill(8), fileS.barr[i]) aluCtrl = ALU(acc, int(fileS.barr[i], 2), 0) elif fileS.barr[i] == "acc": self.printRegs(fileS.aarr[i], bin(acc)[2:].zfill(8)) aluCtrl = ALU(int(fileS.aarr[i], 2), acc, 0) else: self.printRegs(fileS.aarr[i], fileS.barr[i]) aluCtrl = ALU(int(fileS.aarr[i], 2), int(fileS.barr[i], 2), 0) start = timeit.default_timer() result = aluCtrl.subtract() binStng = bin(result)[2:].zfill(8) print "The operation is SUB " print "The final result in binary is ", binStng print "The final result in decimal is ", result acc = result print "Accumulator value is ", acc stop = timeit.default_timer() timearray.append(stop - start) print "Elapsed time is ", (stop - start) elif currentOpcode == opcodesArray[2]: operationName.append(opcodesArray[2]) if fileS.aarr[i] == "acc": self.printRegs(bin(acc)[2:].zfill(8), fileS.barr[i]) aluCtrl = ALU(acc, int(fileS.barr[i], 2), 0) elif fileS.barr[i] == "acc": self.printRegs(fileS.aarr[i], bin(acc)[2:].zfill(8)) aluCtrl = ALU(int(fileS.aarr[i], 2), acc, 0) else: self.printRegs(fileS.aarr[i], fileS.barr[i]) aluCtrl = ALU(int(fileS.aarr[i], 2), int(fileS.barr[i], 2), 0) start = timeit.default_timer() result = aluCtrl.multiply() binStng = bin(result)[2:].zfill(8) print "The operation is MUL " print "The final result in binary is ", binStng print "The final result in decimal is ", result acc = result print "Accumulator value is ", acc stop = timeit.default_timer() timearray.append(stop - start) print "Elapsed time is ", (stop - start) elif currentOpcode == opcodesArray[3]: operationName.append(opcodesArray[3]) if fileS.aarr[i] == "acc": self.printRegs(bin(acc)[2:].zfill(8), fileS.barr[i]) aluCtrl = ALU(acc, int(fileS.barr[i], 2), 0) elif fileS.barr[i] == "acc": self.printRegs(fileS.aarr[i], bin(acc)[2:].zfill(8)) aluCtrl = ALU(int(fileS.aarr[i], 2), acc, 0) else: self.printRegs(fileS.aarr[i], fileS.barr[i]) aluCtrl = ALU(int(fileS.aarr[i], 2), int(fileS.barr[i], 2), 0) start = timeit.default_timer() (result, quot) = aluCtrl.div() binStng = bin(result)[2:].zfill(8) print "The operation is DIV " print "The final Quotient in binary is ", binStng print "The final Quotient in decimal is ", result print "The final Remainder in binary is ", bin(quot)[2:].zfill( 8) print "The final Remainder in decimal is ", quot acc = result print "Accumulator value is ", acc stop = timeit.default_timer() timearray.append(stop - start) print "Elapsed time is ", (stop - start) elif currentOpcode == opcodesArray[4]: operationName.append(opcodesArray[4]) if fileS.aarr[i] == "acc": self.printRegs(bin(acc)[2:].zfill(8), fileS.barr[i]) aluCtrl = ALU(acc, int(fileS.barr[i], 2), 0) elif fileS.barr[i] == "acc": self.printRegs(fileS.aarr[i], bin(acc)[2:].zfill(8)) aluCtrl = ALU(int(fileS.aarr[i], 2), acc, 0) else: self.printRegs(fileS.aarr[i], fileS.barr[i]) aluCtrl = ALU(int(fileS.aarr[i], 2), int(fileS.barr[i], 2), 0) start = timeit.default_timer() result = aluCtrl.andop() binStng = bin(result)[2:].zfill(8) print "The operation is AND " print "The final result in binary is ", binStng print "The final result in decimal is ", result acc = result print "Accumulator value is ", acc stop = timeit.default_timer() timearray.append(stop - start) print "Elapsed time is ", (stop - start) elif currentOpcode == opcodesArray[5]: operationName.append(opcodesArray[5]) if fileS.aarr[i] == "acc": self.printRegs(bin(acc)[2:].zfill(8), fileS.barr[i]) aluCtrl = ALU(acc, int(fileS.barr[i], 2), 0) elif fileS.barr[i] == "acc": self.printRegs(fileS.aarr[i], bin(acc)[2:].zfill(8)) aluCtrl = ALU(int(fileS.aarr[i], 2), acc, 0) else: self.printRegs(fileS.aarr[i], fileS.barr[i]) aluCtrl = ALU(int(fileS.aarr[i], 2), int(fileS.barr[i], 2), 0) start = timeit.default_timer() result = aluCtrl.orop() binStng = bin(result)[2:].zfill(8) print "The operation is OR " print "The final result in binary is ", binStng print "The final result in decimal is ", result acc = result print "Accumulator value is ", acc stop = timeit.default_timer() timearray.append(stop - start) print "Elapsed time is ", (stop - start) elif currentOpcode == opcodesArray[6]: operationName.append(opcodesArray[6]) if fileS.aarr[i] == "acc": self.printRegs(bin(acc)[2:].zfill(8), fileS.barr[i]) aluCtrl = ALU(acc, int(fileS.barr[i], 2), 0) elif fileS.barr[i] == "acc": self.printRegs(fileS.aarr[i], bin(acc)[2:].zfill(8)) aluCtrl = ALU(int(fileS.aarr[i], 2), acc, 0) else: self.printRegs(fileS.aarr[i], fileS.barr[i]) aluCtrl = ALU(int(fileS.aarr[i], 2), int(fileS.barr[i], 2), 0) start = timeit.default_timer() result = aluCtrl.xorop() binStng = bin(result)[2:].zfill(8) print "The operation is XOR " print "The final result in binary is ", binStng print "The final result in decimal is ", result acc = result print "Accumulator value is ", acc stop = timeit.default_timer() timearray.append(stop - start) print "Elapsed time is ", (stop - start) elif currentOpcode == opcodesArray[9]: port = '/dev/ttyACM0' ard = serial.Serial(port, 9600, timeout=6) readvalue = [] readvalue.append(ard.read()) readvalue.append(ard.read()) readvalue.append(ard.read()) readval = ''.join(readvalue) acc = int(readval) time.sleep(3) #elif currentOpcode==opcodesArray[8]: elif currentOpcode == opcodesArray[10]: addrin = fileS.aarr[i] datain = acc port = '/dev/ttyACM0' ard = serial.Serial(port, 9600, timeout=6) iter = 0 while (iter < 1): # Serial write section setTempCar1 = addrin setTempCar2 = acc ard.flush() setTemp1 = str(setTempCar1) setTemp2 = str(setTempCar2) print("Python value sent: ") print(setTemp2) ard.write(setTemp2) time.sleep(4) # Serial read section iter = iter + 1 else: print "Exiting" exit() elif currentOpcode == opcodesArray[7]: operationName.append(opcodesArray[7]) print "Jumping" start = timeit.default_timer() jmpIndex = fileS.aarr.index(fileS.barr[i]) i = jmpIndex stop = timeit.default_timer() timearray.append(stop - start) print "Elapsed time is ", (stop - start) elif currentOpcode == opcodesArray[8]: continue i = i + 1 print "\n" return timearray
class CPU: def __init__(self): self.ALU = ALU() self.PC = Registro(0x0000) self.SP = Registro(0xf000) self.REGISTERS = Registros() self.halt = False self.INTE = False #if True not allow interruptions self.interruptionNumber = 0 self.I = 0 self.Indexes = ["B", "C", "D", "E", "H", "L", "M", "A"] def setInterruptionNumber(self, number): self.interruptionNumber = number def getStatus(self): return self.halt def setStatus(self, halt): self.halt = halt def getALU(self): return self.ALU def getPC(self): return self.PC.getValue() def getSP(self): return self.SP.getValue() def getRegister(self, index): return self.REGISTERS.getRegister(index) def getRegisters(self): return self.REGISTERS def setRegister(self, index, value): self.REGISTERS.setRegister(index, value) def setPC(self, value, Mem): self.PC.setValue(value % Mem.getSize()) def setSP(self, value, Mem): self.SP.setValue(value % Mem.getSize()) def plusOnePC(self, Mem): self.PC.setValue((self.getPC() + 1) % Mem.getSize()) def execute(self, Mem, Ports): pc = self.getPC() self.I = Mem.getMemory(pc) I = self.I if I in [0x00, 0x10, 0x20, 0x30, 0x08, 0x18, 0x28, 0x38]: self.NOP(Mem) elif I == 0x07: self.RLC(Mem) elif I == 0x17: self.RAL(Mem) elif I == 0x0f: self.RRC(Mem) elif I == 0x1f: self.RAR(Mem) elif I in [0x06, 0x0e, 0x16, 0x1e, 0x26, 0x2e, 0x36, 0x3e]: self.MVI(Mem) elif I == 0xce: self.ACI(Mem) elif I == 0xc6: self.ADI(Mem) elif I == 0xd6: self.SUI(Mem) elif I == 0xde: self.SBI(Mem) elif I == 0xe6: self.ANI(Mem) elif I == 0xee: self.XRI(Mem) elif I == 0xf6: self.ORI(Mem) elif I == 0x2f: self.CMA(Mem) elif I == 0x27: self.DAA(Mem) elif I == 0x3a: self.LDA(Mem) elif I == 0xe3: self.XTHL(Mem) elif I == 0xc3: self.JMP(Mem) elif I == 0xda: self.JC(Mem) elif I == 0xd2: self.JNC(Mem) elif I == 0xfa: self.JM(Mem) elif I == 0xf2: self.JP(Mem) elif I == 0xe2: self.JPO(Mem) elif I == 0xea: self.JPE(Mem) elif I == 0xca: self.JZ(Mem) elif I == 0xc2: self.JNZ(Mem) elif I == 0xe9: self.PCHL(Mem) elif I == 0x2a: self.LHLD(Mem) elif I == 0x22: self.SHLD(Mem) elif I == 0xeb: self.XCHG(Mem) elif I == 0xcd: self.CALL(Mem) elif I == 0xdc: self.CC(Mem) elif I == 0xd4: self.CNC(Mem) elif I == 0xf4: self.CP(Mem) elif I == 0xfc: self.CM(Mem) elif I == 0xec: self.CPE(Mem) elif I == 0xe4: self.CPO(Mem) elif I == 0xc4: self.CNZ(Mem) elif I == 0xcc: self.CZ(Mem) elif I == 0xc9: self.RET(Mem) elif I == 0xd8: self.RC(Mem) elif I == 0xd0: self.RNC(Mem) elif I == 0xc8: self.RZ(Mem) elif I == 0xc0: self.RNZ(Mem) elif I == 0xf0: self.RP(Mem) elif I == 0xf8: self.RM(Mem) elif I == 0xe8: self.RPE(Mem) elif I == 0xe0: self.RPO(Mem) elif I == 0xf3: self.DI(Mem) elif I == 0xfb: self.EI(Mem) elif I == 0xf9: self.SPHL(Mem) elif I == 0xdb: self.IN(Mem, Ports) elif I == 0x3f: self.CMC(Mem) elif I == 0xfe: self.CPI(Mem) elif I == 0x37: self.STC(Mem) elif I == 0x32: self.STA(Mem) elif I == 0xd3: self.OUT(Mem, Ports) elif I in [0x0a, 0x1a]: self.LDAX(Mem) elif I in [0x01, 0x11, 0x21, 0x31]: self.LXI(Mem) elif I in [0x02, 0x12]: self.STAX(Mem) elif I in [0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c]: self.INR(Mem) elif I in [0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d]: self.DCR(Mem) elif I in [0xc7, 0xcf, 0xd7, 0xdf, 0xe7, 0xef, 0xf7, 0xff]: self.RST(Mem) elif I in [0xc5, 0xd5, 0xe5, 0xf5]: self.PUSH(Mem) elif I in [0xc1, 0xd1, 0xe1, 0xf1]: self.POP(Mem) elif I in [0x03, 0x13, 0x23, 0x33]: self.INX(Mem) elif I in [0x0b, 0x1b, 0x2b, 0x3b]: self.DCX(Mem) elif I in [0x09, 0x19, 0x29, 0x39]: self.DAD(Mem) elif I in range(0xb8, 0xc0): self.CMP(Mem) elif I in range(0x98, 0xa0): self.SBB(Mem) elif I in range(0x88, 0x90): self.ADC(Mem) elif I in range(0x80, 0x88): self.ADD(Mem) elif I in range(0x90, 0x98): self.SUB(Mem) elif I in range(0xa0, 0xa8): self.ANA(Mem) elif I in range(0xa8, 0xb0): self.XRA(Mem) elif I in range(0xb0, 0xb8): self.ORA(Mem) elif I in range(0x40, 0x76) or I in range(0x77, 0x80): self.MOV(Mem) elif I == 0x76: self.HALT() else: print("Opcode desconocido") #self.NOP(Mem) if self.INTE: self.hardware_restart(Mem, self.interruptionNumber) self.EI(Mem) return def getInterruptionNumber(self): return (self.I & 0x0038) >> 3 def hardware_restart(self, Mem, numberOfInterruption): bitshift = self.I & 0xc7 self.I = Mem.getMemory(bitshift) | (numberOfInterruption << 3) self.RST(Mem) #DDDSSS def getSSS(self, value): return (value & 0x07) def getDDD(self, value): return (value & 0x38) >> 3 # --XX---- def getXXPushPop(self, value): return (value & 0x30) >> 4 def HALT(self): print("HALT") self.halt = True def NOP(self, Mem): print("NO OP") self.plusOnePC(Mem) def MOV(self, Mem): print("MOV") r = self.getDDD(self.I) s = self.getSSS(self.I) if r != 6 and s != 6: self.setRegister(self.Indexes[r], self.getRegister(self.Indexes[s])) elif r != 6 and s == 6: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) position = self.ALU.doMemoryPair() yy = Mem.getMemory(position) self.setRegister(self.Indexes[r], yy) elif r == 6 and s != 6: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) position = self.ALU.doMemoryPair() yy = self.getRegister(self.Indexes[s]) Mem.setMemory(position, yy) self.plusOnePC(Mem) def MVI(self, Mem): print("MVI") r = self.getDDD(self.I) self.plusOnePC(Mem) xx = Mem.getMemory(self.getPC()) if (r is not 6): # b c d e h l m a self.setRegister(self.Indexes[r], xx) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) Mem.setMemory(self.ALU.doMemoryPair(), xx) self.plusOnePC(Mem) def ADD(self, Mem): print("ADD") r = self.getSSS(self.I) if (r is not 6): self.ALU.setOP2(self.getRegister(self.Indexes[r])) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) self.ALU.setOP2(Mem.getMemory(self.ALU.doMemoryPair)) self.ALU.setOP1(self.getRegister("A")) self.setRegister("A", self.ALU.ADD()) self.plusOnePC(Mem) def ADI(self, Mem): print("ADI") self.ALU.setOP1(self.getRegister("A")) self.plusOnePC(Mem) self.ALU.setOP2(Mem.getMemory(self.getPC())) self.setRegister("A", self.ALU.ADD()) self.plusOnePC(Mem) def ANI(self, Mem): print("ANI") self.ALU.setOP1(self.getRegister("A")) self.plusOnePC(Mem) self.ALU.setOP2(Mem.getMemory(self.getPC())) self.setRegister("A", self.ALU.AND()) self.plusOnePC(Mem) def ANA(self, Mem): print("ANA") r = self.getSSS(self.I) if r is not 6: self.ALU.setOP2(self.getRegister(self.Indexes[r])) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) self.ALU.setOP2(Mem.getMemory(self.ALU.doMemoryPair())) self.ALU.setOP1(self.getRegister("A")) self.setRegister("A", self.ALU.AND()) self.plusOnePC(Mem) def SUB(self, Mem): print("SUB") r = self.getSSS(self.I) if (r is not 6): self.ALU.setOP2(self.getRegister(self.Indexes[r])) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) self.ALU.setOP2(Mem.getMemory(self.ALU.doMemoryPair())) self.ALU.setOP1(self.getRegister("A")) self.setRegister("A", self.ALU.SUB()) self.plusOnePC(Mem) def CMP(self, Mem): print("CMP") r = self.getSSS(self.I) if (r is not 6): self.ALU.setOP2(self.getRegister(self.Indexes[r])) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) self.ALU.setOP2(Mem.getMemory(self.ALU.doMemoryPair())) #probably set flags on 0 c Ac self.ALU.setOP1(self.getRegister("A")) self.ALU.SUB() self.plusOnePC(Mem) def CPI(self, Mem): print("CPI") self.ALU.setOP1(self.getRegister("A")) self.plusOnePC(Mem) self.ALU.setOP2(Mem.getMemory(self.getPC())) self.ALU.SUB() self.plusOnePC(Mem) def SBI(self, Mem): print("SBI") self.plusOnePC(Mem) yy = Mem.getMemory(self.getPC()) self.ALU.setOP1(yy) self.ALU.setOP2(self.getRegister("A")) carry = 0 if self.ALU.getFlags().getFlag("C"): carry = 1 self.setRegister("A", self.ALU.SUB(carry=carry)) self.plusOnePC(Mem) def ORI(self, Mem): print("ORI") self.ALU.setOP1(self.getRegister("A")) self.plusOnePC(Mem) self.ALU.setOP2(Mem.getMemory(self.getPC())) self.setRegister("A", self.ALU.OR()) self.plusOnePC(Mem) def ORA(self, Mem): print("ORA") r = self.getSSS(self.I) if r is not 6: self.ALU.setOP2(self.getRegister(self.Indexes[r])) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) self.ALU.setOP2(Mem.getMemory(self.ALU.doMemoryPair())) self.ALU.setOP1(self.getRegister("A")) self.setRegister("A", self.ALU.OR()) self.plusOnePC(Mem) def CMA(self, Mem): print("CMA") self.ALU.setOP1(self.getRegister("A")) self.setRegister("A", self.ALU.NOT()) self.plusOnePC(Mem) def XRI(self, Mem): print("XRI") self.ALU.setOP1(self.getRegister("A")) self.plusOnePC(Mem) self.ALU.setOP2(Mem.getMemory(self.getPC())) self.setRegister("A", self.ALU.XOR()) self.plusOnePC(Mem) def XRA(self, Mem): print("XRA") r = self.getSSS(self.I) if r is not 6: self.ALU.setOP2(self.getRegister(self.Indexes[r])) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) self.ALU.setOP2(Mem.getMemory(self.ALU.doMemoryPair())) self.ALU.setOP1(self.getRegister("A")) self.setRegister("A", self.ALU.XOR()) self.plusOnePC(Mem) def DAA(self, Mem): print("DAA") self.ALU.setOP1(self.getRegister("A")) self.setRegister("A", self.ALU.BCD()) self.plusOnePC(Mem) def RLC(self, Mem): print("RLC") A = self.getRegister("A") self.ALU.setOP1(A) self.setRegister("A", self.ALU.RLC()) self.plusOnePC(Mem) def RAL(self, Mem): print("RAL") A = self.getRegister("A") C = (A & 0x80) >> 7 self.ALU.getFlags().setFlag("C", C) F = self.ALU.getFlags().getFlag("C") A = (A << 1) & 0xff self.setRegister("A", A | F) self.plusOnePC(Mem) def RRC(self, Mem): print("RRC") A = self.getRegister("A") self.ALU.setOP1(A) self.setRegister("A", self.ALU.RRC()) self.plusOnePC(Mem) def RAR(self, Mem): print("RAR") A = self.getRegister("A") C = (A & 0x01) self.ALU.getFlags().setFlag("C", C) F = self.ALU.getFlags().getFlag("C") A = (A >> 1) & 0xff self.setRegister("A", A | (F << 7)) self.plusOnePC(Mem) def DecodeAluPair(self, value): high = (value & 0xFF00) >> 8 low = (value & 0x00FF) return high, low def DecodeRegisterPair(self, I): return (I & 0x30) >> 4 def INX(self, Mem): print("INCX") r = self.DecodeRegisterPair(self.I) #bc, de, hl if (r == 0): self.ALU.setOP1(self.getRegister("B")) self.ALU.setOP2(self.getRegister("C")) B, C = self.DecodeAluPair(self.ALU.INX()) self.setRegister("B", B) self.setRegister("C", C) elif r == 1: self.ALU.setOP1(self.getRegister("D")) self.ALU.setOP2(self.getRegister("E")) D, E = self.DecodeAluPair(self.ALU.INX()) self.setRegister("D", D) self.setRegister("E", E) elif r == 2: self.ALU.setOP1(self.getRegister("H")) self.ALU.setOP2(self.getRegister("L")) H, L = self.DecodeAluPair(self.ALU.INX()) self.setRegister("H", H) self.setRegister("L", L) else: self.ALU.setOP1(self.SP.getValue()) catcher = self.ALU.INX(False) self.SP.setValue(catcher) self.plusOnePC(Mem) def DCX(self, Mem): print("DCX") r = self.DecodeRegisterPair(self.I) #bc, de, hl if (r == 0): self.ALU.setOP1(self.getRegister("B")) self.ALU.setOP2(self.getRegister("C")) B, C = self.DecodeAluPair(self.ALU.DCX()) self.setRegister("B", B) self.setRegister("C", C) elif r == 1: self.ALU.setOP1(self.getRegister("D")) self.ALU.setOP2(self.getRegister("E")) D, E = self.DecodeAluPair(self.ALU.DCX()) self.setRegister("D", D) self.setRegister("E", E) elif r == 2: self.ALU.setOP1(self.getRegister("H")) self.ALU.setOP2(self.getRegister("L")) H, L = self.DecodeAluPair(self.ALU.DCX()) self.setRegister("H", H) self.setRegister("L", L) else: self.ALU.setOP1(self.SP.getValue()) catcher = self.ALU.DCX(False) self.SP.setValue(catcher) self.plusOnePC(Mem) def regPairMask(self, I): return (I & 0x10) >> 4 def LDAX(self, Mem): print("LDAX") I = self.I r = self.regPairMask(I) memPos = 0 if r == 0: self.ALU.setOP1(self.getRegister("B")) self.ALU.setOP2(self.getRegister("C")) else: self.ALU.setOP1(self.getRegister("D")) self.ALU.setOP2(self.getRegister("E")) memPos = self.ALU.doMemoryPair() self.setRegister("A", Mem.getMemory(memPos)) self.plusOnePC(Mem) def STAX(self, Mem): print("STAX") I = self.I r = self.regPairMask(I) memPos = 0 if r == 0: self.ALU.setOP1(self.getRegister("B")) self.ALU.setOP2(self.getRegister("C")) memPos = self.ALU.doMemoryPair() else: self.ALU.setOP1(self.getRegister("D")) self.ALU.setOP2(self.getRegister("E")) memPos = self.ALU.doMemoryPair() Mem.setMemory(memPos, self.getRegister("A")) self.plusOnePC(Mem) def JMP(self, Mem): print("JMP") qq = Mem.getMemory(self.getPC() + 1) pp = Mem.getMemory(self.getPC() + 2) self.ALU.setOP1(pp) self.ALU.setOP2(qq) newPC = self.ALU.doMemoryPair() self.ALU.getFlags().setFlag("C", True) self.setPC(newPC, Mem) def JC(self, Mem): print("JC") if (self.ALU.getFlags().getFlag("C")): self.JMP(Mem) else: self.setPC((self.getPC() + 3), Mem) def JNC(self, Mem): print("JNC") if (self.ALU.getFlags().getFlag("C")): self.setPC((self.getPC() + 3), Mem) else: self.JMP(Mem) def JP(self, Mem): print("JP") if (self.ALU.getFlags().getFlag("S")): self.setPC((self.getPC() + 3), Mem) else: self.JMP(Mem) def JM(self, Mem): print("JM") if (self.ALU.getFlags().getFlag("S")): self.JMP(Mem) else: self.setPC((self.getPC() + 3), Mem) def JPO(self, Mem): print("JPO") if (self.ALU.getFlags().getFlag("P")): self.setPC((self.getPC() + 3), Mem) else: self.JMP(Mem) def JPE(self, Mem): print("JPE") if (self.ALU.getFlags().getFlag("P")): self.JMP(Mem) else: self.setPC((self.getPC() + 3), Mem) def JZ(self, Mem): print("JZ") if (self.ALU.getFlags().getFlag("Z")): self.JMP(Mem) else: self.setPC((self.getPC() + 3), Mem) def JNZ(self, Mem): print("JNZ") if (self.ALU.getFlags().getFlag("Z")): self.setPC((self.getPC() + 3), Mem) else: self.JMP(Mem) def PCHL(self, Mem): print("PCHL") H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) position = self.ALU.doMemoryPair() self.setPC(position, Mem) def LHLD(self, Mem): print("LHLD") self.plusOnePC(Mem) qq = Mem.getMemory(self.getPC()) self.plusOnePC(Mem) pp = Mem.getMemory(self.getPC()) self.ALU.setOP1(pp) self.ALU.setOP2(qq) ppqq = self.ALU.doMemoryPair() xx = Mem.getMemory(ppqq) yy = Mem.getMemory(ppqq + 1) self.setRegister("H", yy) self.setRegister("L", xx) self.plusOnePC(Mem) def SHLD(self, Mem): print("SHLD") self.plusOnePC(Mem) qq = Mem.getMemory(self.getPC()) self.plusOnePC(Mem) pp = Mem.getMemory(self.getPC()) self.ALU.setOP1(pp) self.ALU.setOP2(qq) ppqq = self.ALU.doMemoryPair() H = self.getRegister("H") L = self.getRegister("L") Mem.setMemory(ppqq, L) Mem.setMemory(ppqq + 1, H) self.plusOnePC(Mem) def XCHG(self, Mem): print("XCHG") D = self.getRegister("D") E = self.getRegister("E") self.setRegister("D", self.getRegister("H")) self.setRegister("E", self.getRegister("L")) self.setRegister("H", D) self.setRegister("L", E) self.plusOnePC(Mem) def SPHL(self, Mem): print("SPHL") H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) position = self.ALU.doMemoryPair() self.setSP(position, Mem) self.plusOnePC(Mem) def PUSH(self, Mem): print("PUSH") I = self.I r = self.getXXPushPop(I) self.setSP(self.getSP() - 2, Mem) qq = 0 pp = 0 if r == 0: qq = self.getRegister("C") pp = self.getRegister("B") elif r == 1: qq = self.getRegister("E") pp = self.getRegister("D") elif r == 2: qq = self.getRegister("L") pp = self.getRegister("H") elif r == 3: PSW = self.ALU.getFlags().getPSWRegister() qq = PSW pp = self.getRegister("A") Mem.setMemory(self.getSP(), qq) Mem.setMemory(self.getSP() + 1, pp) self.plusOnePC(Mem) def POP(self, Mem): print("POP") I = self.I r = self.getXXPushPop(I) sp = self.getSP() YY = Mem.getMemory(sp) XX = Mem.getMemory(sp + 1) if r == 0: self.setRegister("C", YY) self.setRegister("B", XX) elif r == 1: self.setRegister("E", YY) self.setRegister("D", XX) elif r == 2: self.setRegister("L", YY) self.setRegister("H", XX) elif r == 3: print("listYY", YY) binValue = bin(YY)[2:] var = "" if len(binValue) < 8: for i in range(8 - len(binValue)): var += "0" var += binValue self.ALU.getFlags().setPSWRegister(list(var)) self.setRegister("A", XX) self.setSP(sp + 2, Mem) self.plusOnePC(Mem) def CALL(self, Mem): print("CALL") self.setSP(self.getSP() - 2, Mem) self.plusOnePC(Mem) qq = Mem.getMemory(self.getPC()) #PC+1) self.plusOnePC(Mem) pp = Mem.getMemory(self.getPC()) #PC+2) self.plusOnePC(Mem) mm, mPlus3 = self.DecodeAluPair(self.getPC()) # mmmm+3 Mem.setMemory(self.getSP(), mPlus3) Mem.setMemory(self.getSP() + 1, mm) self.ALU.setOP1(pp) self.ALU.setOP2(qq) newPC = self.ALU.doMemoryPair() self.setPC(newPC, Mem) return def CC(self, Mem): print("CC") if self.ALU.getFlags().getFlag("C"): self.CALL(Mem) else: self.setPC(self.getPC() + 3, Mem) def CNC(self, Mem): print("CNC") if self.ALU.getFlags().getFlag("C"): self.setPC(self.getPC() + 3, Mem) else: self.CALL(Mem) def CZ(self, Mem): print("CZ") if self.ALU.getFlags().getFlag("Z"): self.CALL(Mem) else: self.setPC(self.getPC() + 3, Mem) def CNZ(self, Mem): print("CNZ") if self.ALU.getFlags().getFlag("Z"): self.CALL(Mem) else: self.setPC(self.getPC() + 3, Mem) def CP(self, Mem): print("CP") if self.ALU.getFlags().getFlag("S"): self.setPC(self.getPC() + 3, Mem) else: self.CALL(Mem) def CM(self, Mem): print("CM") if self.ALU.getFlags().getFlag("S"): self.CALL(Mem) else: self.setPC(self.getPC() + 3, Mem) def CPE(self, Mem): print("CPE") if self.ALU.getFlags().getFlag("P"): self.CALL(Mem) else: self.setPC(self.getPC() + 3, Mem) def CPO(self, Mem): print("CPO") if self.ALU.getFlags().getFlag("P"): self.setPC(self.getPC() + 3, Mem) else: self.CALL(Mem) def RET(self, Mem): print("RET") sp = self.getSP() qq = Mem.getMemory(sp) pp = Mem.getMemory(sp + 1) self.ALU.setOP1(pp) self.ALU.setOP2(qq) self.setPC(self.ALU.doMemoryPair(), Mem) self.setSP(sp + 2, Mem) def RC(self, Mem): print("RC") if self.ALU.getFlags().getFlag("C"): self.RET(Mem) else: self.plusOnePC(Mem) def RNC(self, Mem): print("RNC") if self.ALU.getFlags().getFlag("C"): self.RET(Mem) else: self.plusOnePC(Mem) def RZ(self, Mem): print("RZ") if self.ALU.getFlags().getFlag("Z"): self.RET(Mem) else: self.plusOnePC(Mem) def RNZ(self, Mem): print("RNZ") if self.ALU.getFlags().getFlag("Z"): self.RET(Mem) else: self.plusOnePC(Mem) def RP(self, Mem): print("RP") if self.ALU.getFlags().getFlag("S"): self.RET(Mem) else: self.plusOnePC(Mem) def RM(self, Mem): print("RM") if self.ALU.getFlags().getFlag("S"): self.RET(Mem) else: self.plusOnePC(Mem) def RPE(self, Mem): print("RPE") if self.ALU.getFlags().getFlag("P"): self.RET(Mem) else: self.plusOnePC(Mem) def RPO(self, Mem): print("RPO") if self.ALU.getFlags().getFlag("P"): self.RET(Mem) else: self.plusOnePC(Mem) def DI(self, Mem): print("DI") self.INTE = True self.plusOnePC(Mem) def EI(self, Mem): print("EI") self.INTE = False self.plusOnePC(Mem) def IN(self, Mem, Ports): print("IN") self.plusOnePC(Mem) yy = Mem.getMemory(self.getPC()) xx = Ports.getPort(yy) self.setRegister("A", xx) self.plusOnePC(Mem) def OUT(self, Mem, Ports): print("OUT") self.plusOnePC(Mem) yy = Mem.getMemory(self.getPC()) xx = self.getRegister("A") Ports.setPort(yy, xx) self.plusOnePC(Mem) def RST(self, Mem): print("RST") self.setSP(self.getSP() - 2, Mem) mmmmp2 = self.getPC() + 2 mm, mp2 = self.DecodeAluPair(mmmmp2) Mem.setMemory(self.getSP(), mp2) Mem.setMemory(self.getSP() + 1, mm) self.setPC(self.getInterruptionNumber(), Mem) def CMC(self, Mem): print("CMC") if self.getALU().getFlags().getFlag("C"): self.getALU().getFlags().setFlag("C", False) else: self.getALU().getFlags().setFlag("C", True) self.plusOnePC(Mem) def DAD(self, Mem): print("DAD") I = self.I xx = self.getXXPushPop(I) if xx == 0: y1 = self.getRegister("B") y2 = self.getRegister("C") elif xx == 1: y1 = self.getRegister("D") y2 = self.getRegister("E") elif xx == 3: y1 = self.getRegister("H") y2 = self.getRegister("L") else: y1, y2 = self.DecodeAluPair(self.getSP()) self.ALU.setOP1(self.getRegister("H")) self.ALU.setOP2(y1) self.setRegister("H", self.ALU.ADD()) self.ALU.setOP1(self.getRegister("L")) self.ALU.setOP2(y2) self.setRegister("L", self.ALU.ADD()) self.plusOnePC(Mem) def DCR(self, Mem): print("DCR") I = self.I r = self.getDDD(I) B = 0 if self.ALU.getFlags().getFlag("C") else 1 if r is not 6: self.ALU.setOP1(self.getRegister(self.Indexes[r])) self.ALU.setOP2(0x01) self.setRegister(self.Indexes[r], self.ALU.SUB(B)) else: self.ALU.setOP1(self.getRegister("H")) self.ALU.setOP2(self.getRegister("L")) ppqq = self.ALU.doMemoryPair() self.ALU.setOP1(Mem.getMemory(ppqq)) self.ALU.setOP2(0x01) Mem.setMemory(ppqq, self.ALU.SUB(B)) self.plusOnePC(Mem) def INR(self, Mem): print("INR") I = self.I r = self.getDDD(I) if r is not 6: self.ALU.setOP1(self.getRegister(self.Indexes[r])) self.ALU.setOP2(0x01) self.setRegister(self.Indexes[r], self.ALU.ADD()) else: self.ALU.setOP1(self.getRegister("H")) self.ALU.setOP2(self.getRegister("L")) ppqq = self.ALU.doMemoryPair() self.ALU.setOP1(Mem.getMemory(ppqq)) self.ALU.setOP2(0x01) Mem.setMemory(ppqq, self.ALU.ADD()) self.plusOnePC(Mem) def LDA(self, Mem): print("LDA") self.plusOnePC(Mem) qq = Mem.getMemory(self.getPC()) self.plusOnePC(Mem) pp = Mem.getMemory(self.getPC()) self.ALU.setOP1(pp) self.ALU.setOP2(qq) ppqq = self.ALU.doMemoryPair() self.setRegister("A", Mem.getMemory(ppqq)) self.plusOnePC(Mem) def LXI(self, Mem): print("LXI") I = self.I xx = self.getXXPushPop(I) self.plusOnePC(Mem) qq = Mem.getMemory(self.getPC()) self.plusOnePC(Mem) pp = Mem.getMemory(self.getPC()) if xx == 0: self.setRegister("B", pp) self.setRegister("C", qq) elif xx == 1: self.setRegister("D", pp) self.setRegister("E", qq) elif xx == 2: self.setRegister("H", pp) self.setRegister("L", qq) else: self.ALU.setOP1(pp) self.ALU.setOP2(qq) self.setSP(self.ALU.doMemoryPair(), Mem) self.plusOnePC(Mem) def STA(self, Mem): print("STA") self.plusOnePC(Mem) qq = Mem.getMemory(self.getPC()) self.plusOnePC(Mem) pp = Mem.getMemory(self.getPC()) self.ALU.setOP1(pp) self.ALU.setOP1(qq) ppqq = self.ALU.doMemoryPair() Mem.setMemory(ppqq, self.getRegister("A")) self.plusOnePC(Mem) def STC(self, Mem): print("STC") self.ALU.getFlags().setFlag("C", True) self.plusOnePC(Mem) def XTHL(self, Mem): print("XTHL") ssss = self.getSP() rr = Mem.getMemory(ssss) t1 = self.getRegister("H") ss = Mem.getMemory(ssss + 1) t2 = self.getRegister("L") pp, qq = t1, t2 self.setRegister("H", rr) self.setRegister("L", ss) Mem.setMemory(ssss, pp) Mem.setMemory(ssss + 1, qq) self.plusOnePC(Mem) def ACI(self, Mem): print("ACI") C = 0 if self.ALU.getFlags().getFlag("C"): C = 1 xx = self.getRegister("A") self.plusOnePC(Mem) yy = Mem.getMemory(self.getPC()) self.ALU.setOP1(C) self.ALU.setOP2(xx) self.ALU.setOP1(self.ALU.ADD()) self.ALU.setOP2(yy) self.setRegister("A", self.ALU.ADD()) self.plusOnePC(Mem) def ADC(self, Mem): print("ADC") I = self.I sss = self.getSSS(I) C = 0 if self.ALU.getFlags().getFlag("C"): C = 1 xx = self.getRegister("A") if sss is not 6: yy = self.getRegister(self.Indexes[sss]) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) ppqq = self.ALU.doMemoryPair() yy = Mem.getMemory(ppqq) self.ALU.setOP1(C) self.ALU.setOP2(xx) self.ALU.setOP1(self.ALU.ADD()) self.ALU.setOP2(yy) self.setRegister("A", self.ALU.ADD()) self.plusOnePC(Mem) def SBB(self, Mem): print("SBB") I = self.I sss = self.getSSS(I) B = 0 if self.ALU.getFlags().getFlag("C"): B = 1 xx = self.getRegister("A") if sss is not 6: yy = self.getRegister(self.Indexes[sss]) else: H = self.getRegister("H") L = self.getRegister("L") self.ALU.setOP1(H) self.ALU.setOP2(L) ppqq = self.ALU.doMemoryPair() yy = Mem.getMemory(ppqq) self.ALU.setOP1(xx) self.ALU.setOP2(yy) self.setRegister("A", self.ALU.SUB(B)) self.plusOnePC(Mem) def SUI(self, Mem): print("SUI") self.ALU.setOP1(self.getRegister("A")) self.plusOnePC(Mem) self.ALU.setOP2(Mem.getMemory(self.getPC())) self.setRegister("A", self.ALU.SUB()) self.plusOnePC(Mem)
def test_less_than_fixed( dump_vcd ): run_test_vector_sim( ALU( 16 ), fixed_LT_vector, dump_vcd)
def setUp(self): self.ALU = ALU()
class SimplifiedSuperScalarSimulator: def __init__(self, infile, outfile, num_registers=32): self.__disassembler = Disassembler() self.__input_file = infile self.__output_file = outfile self.__f = open('team13_out_pipeline.txt', 'w') self.__pc = 96 self.__cycle = 0 self.__memory = {} self.__last_inst = 0 self.pre_issue_size = 4 self.pre_alu_size = 2 self.pre_mem_size = 2 self.post_alu_size = 1 self.post_mem_size = 1 self.__pre_issue_buffer = deque(maxlen=self.pre_issue_size) self.__pre_mem_buffer = deque(maxlen=self.pre_mem_size) self.__pre_alu_buffer = deque(maxlen=self.pre_alu_size) self.__post_mem_buffer = deque(maxlen=self.post_mem_size) self.__post_alu_buffer = deque(maxlen=self.post_alu_size) self.__cache_to_load = deque(maxlen=2) self.__register_file = RegisterFile(num_registers) self.__wb = WriteBackUnit(self.__register_file) self.__cache = Cache(self.__memory) self.__alu = ALU() self.__mem = MemoryUnit(self.__cache) self.__if = IFUnit(self.__cache, self.__register_file) self.__iu = IssueUnit(self.__register_file, self.__pre_issue_buffer, self.__pre_mem_buffer, self.__pre_alu_buffer, self.__post_mem_buffer, self.__post_alu_buffer) self.__read_file() def __read_file(self): """ Reads the designated input file and stores each line as a decimal integer """ pc = 96 with open(self.__input_file, 'r') as f: for line in f: self.__memory[pc] = int(line, 2) if int(line, 2) == Disassembler.break_inst: self.__last_inst = pc pc += 4 def __update_space(self): self.__pre_issue_space = self.pre_issue_size - len( self.__pre_issue_buffer) self.__pre_alu_space = self.pre_alu_size - len(self.__pre_alu_buffer) self.__pre_mem_space = self.pre_mem_size - len(self.__pre_mem_buffer) self.__post_alu_space = self.post_alu_size - len( self.__post_alu_buffer) self.__post_mem_space = self.post_mem_size - len( self.__post_mem_buffer) def __are_buffers_empty(self): self.__update_space() # print self.__pre_issue_space, \ # self.__pre_alu_space, \ # self.__pre_mem_space, \ # self.__post_alu_space, \ # self.__post_mem_space return self.__pre_issue_space == 4 and \ self.__pre_alu_space == 2 and \ self.__pre_mem_space == 2 and \ self.__post_alu_space == 1 and \ self.__post_mem_space == 1 def run(self): run = True while run: run = False self.__cycle += 1 print self.__cycle # Run WriteBackUnit if len(self.__post_mem_buffer) > 0: wb_in = self.__post_mem_buffer.popleft() self.__wb.run(wb_in, 'mem') if len(self.__post_alu_buffer) > 0: wb_in = self.__post_alu_buffer.popleft() self.__wb.run(wb_in, 'alu') self.__update_space() # Run ALU # If pre-buffer not empty and post-buffer not full if len(self.__pre_alu_buffer) > 0 and self.__post_alu_space > 0: alu_in = self.__pre_alu_buffer.popleft() alu_out = self.__alu.run(alu_in) self.__post_alu_buffer.append(alu_out) run = True self.__update_space() # Run MemoryUnit # If pre-buffer not empty and post-buffer not full if len(self.__pre_mem_buffer) > 0 and self.__post_mem_space > 0: mem_in = self.__pre_mem_buffer.popleft() mem_out = self.__mem.run(mem_in) if not mem_out: self.__cache_to_load.append(mem_in['rn_val'] + mem_in['offset']) elif mem_out is not None: self.__post_mem_buffer.append(mem_out) run = True self.__update_space() # Run Issue Unit (twice) # TODO Hazard detection if len(self.__pre_issue_buffer) > 0: self.__iu.run(self.__pre_mem_space, self.__pre_alu_space) run = True self.__update_space() # Run IF Unit # If pre-issue buffer not full result = True if self.__pc < self.__last_inst: if self.__pre_issue_space == 0: continue elif self.__pre_issue_space == 1: result = self.__if.run(self.__pc, 1) else: result = self.__if.run(self.__pc, 2) if not result: self.__cache_to_load.append(self.__pc) else: insts = result[0] self.__pc = result[1] for inst in insts: self.__pre_issue_buffer.append(inst) run = True self.__update_space() self.__print_state() while len(self.__cache_to_load) > 0: address = self.__cache_to_load.popleft() self.__cache.load(address) def __print_buffer(self, buffer): for i in range(buffer.maxlen): try: item = '[' + buffer[i]['assembly'] + ']' except IndexError: item = '' if item == '': self.__f.write('\tEntry {}:\n'.format(i, item)) else: self.__f.write('\tEntry {}:\t{}\n'.format(i, item)) def __print_buffers(self): self.__f.write('Pre-Issue Buffer:\n') self.__print_buffer(self.__pre_issue_buffer) self.__f.write('Pre_ALU Queue:\n') self.__print_buffer(self.__pre_alu_buffer) self.__f.write('Post_ALU Queue:\n') self.__print_buffer(self.__post_alu_buffer) self.__f.write('Pre_MEM Queue:\n') self.__print_buffer(self.__pre_mem_buffer) self.__f.write('Post_MEM Queue:\n') self.__print_buffer(self.__post_mem_buffer) self.__f.write('\n') def __print_registers(self): self.__f.write('Registers\n') for i in range(4): self.__f.write('R{:02d}:'.format(i * 8)) for j in range(8): value = self.__register_file.read_register(i * 8 + j) self.__f.write('\t{}'.format(value)) self.__f.write('\n') self.__f.write('\n') def __print_cache(self): self.__f.write('Cache\n') for s, set in enumerate(self.__cache.get_cache()): self.__f.write('Set {}: LRU={}\n'.format(s, set['lru'])) for b, block in enumerate(set['blocks']): valid = int(block['valid']) dirty = int(block['dirty']) tag = int(block['tag']) if block['tag'] is not None else '0' content1 = '{0:032b}'.format(block['content'][0]) if ( block['content'][0] != 0 and block['content'][0] is not None) else '0' content2 = '{0:032b}'.format(block['content'][1]) if ( block['content'][1] != 0 and block['content'][1] is not None) else '0' self.__f.write('\tEntry {}:[({},{},{})<{},{}>]\n'.format( b, valid, dirty, tag, content1, content2)) self.__f.write('\n') def __print_memory(self): self.__f.write('Data\n') # Filter data out of memory data = dict(self.__memory) for a in range(96, self.__last_inst + 4, 4): del data[a] # Fix stupid formatting, thanks Greg if len(data) > 0: # Add 0s from beginning to first first_data = min(data.keys()) for a in range(self.__last_inst + 4, first_data, 4): data[a] = 0 # Add 0s from last to end of line last_data = max(data.keys()) a = last_data + 4 while (a - first_data) % 8 != 0: data[a] = 0 a += 4 # Print useful information addresses = list(data.keys()) addresses.sort() for i, addr in enumerate(addresses): if i % 8 == 0: self.__f.write('\n{}:\t{}'.format(addr, data[addr])) else: self.__f.write('\t{}'.format(data[addr])) self.__f.write('\n' * 2) def __print_state(self): self.__f.write('-' * 20 + '\n') self.__f.write('Cycle:{}\n\n'.format(self.__cycle)) self.__print_buffers() self.__print_registers() self.__print_cache() self.__print_memory()
def test_less_than_random( dump_vcd ): run_test_vector_sim( ALU(16), random_LT_vector, dump_vcd )
def test_equal_random( dump_vcd ): run_test_vector_sim( ALU(16), random_ET_vector, dump_vcd )
def test_and_fixed( dump_vcd ): run_test_vector_sim( ALU( 16 ), fixed_and_vector, dump_vcd)