class CPU: REG_WIDTH = 8 def __init__(self): self.clk = None self.bus = Bus(CPU.REG_WIDTH) self.memory_register = WideRegister(4) self.memory = Memory() self.register_a = WideRegister(CPU.REG_WIDTH) self.register_a_three_state = WideThreeState(CPU.REG_WIDTH) self.register_b = WideRegister(CPU.REG_WIDTH) self.register_b_three_state = WideThreeState(CPU.REG_WIDTH) self.alu = Alu(CPU.REG_WIDTH) self.out_register = WideRegister(CPU.REG_WIDTH) self.display = NumDisplay(CPU.REG_WIDTH) def eval(self): self.memory_register.clk = self.clk self.memory_register.d = self.bus.line[4:] self.memory_register.eval() self.memory.clk = self.clk self.memory.a = self.memory_register.q self.memory.d = self.bus.line self.memory.eval() self.bus.apply(self.memory.o) self.register_a.clk = self.clk self.register_a.d = self.bus.line self.register_a.enable = True self.register_a.eval() self.register_a_three_state.a = self.register_a.q self.register_a_three_state.eval() self.bus.apply(self.register_a_three_state.c) self.register_b.clk = self.clk self.register_b.d = self.bus.line self.register_b.enable = True self.register_b.eval() self.register_b_three_state.a = self.register_b.q self.register_b_three_state.eval() self.bus.apply(self.register_b_three_state.c) self.alu.a = self.register_a.q self.alu.b = self.register_b.q self.alu.eval() self.bus.apply(self.alu.x) self.out_register.clk = self.clk self.out_register.d = self.bus.line self.out_register.eval() self.display.a = self.out_register.d self.display.eval()
def __init__(self): self.clk = None self.bus = Bus(CPU.REG_WIDTH) self.memory_register = WideRegister(4) self.memory = Memory() self.register_a = WideRegister(CPU.REG_WIDTH) self.register_a_three_state = WideThreeState(CPU.REG_WIDTH) self.register_b = WideRegister(CPU.REG_WIDTH) self.register_b_three_state = WideThreeState(CPU.REG_WIDTH) self.alu = Alu(CPU.REG_WIDTH) self.out_register = WideRegister(CPU.REG_WIDTH) self.display = NumDisplay(CPU.REG_WIDTH)
def __init__(self): self.decoder = Decoder() self.alu = Alu() self.a_register = Register16Bit() self.d_register = Register16Bit() self.jump_decoder = JumpDecoder() self.pc = Pc() self.a_out = zero self.d_out = zero self.alu_out = zero self.jump_decoder_out = 0 self.a_or_c_instr_mux = Mux2Way16Bit() self.load_a_mux = Mux2Way1Bit() self.a_or_m_mux = Mux2Way16Bit() self.load_d_mux = Mux2Way1Bit() self.load_jump_mux = Mux2Way1Bit()
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 __init__(self, validator: Optional[Base]): self.validator = validator self.Addr = Signal(16) self.Din = Signal(8) self.Dout = Signal(8) self.RW = Signal(reset=1) # read=1, write=0 self.Rst = Signal() # registers self.registers = Registers(self.Din, self.Dout, self.Addr) self.buses = Buses(self.registers, self) self.reset = Reset(self) self.cycle = Signal(4) self.end_instr_flag = Signal() self.end_instr_addr = Signal(16) self.instruction_set = InstructionSet() self.alu = Alu(self)
class CPU: def __init__(self): self.decoder = Decoder() self.alu = Alu() self.a_register = Register16Bit() self.d_register = Register16Bit() self.jump_decoder = JumpDecoder() self.pc = Pc() self.a_out = zero self.d_out = zero self.alu_out = zero self.jump_decoder_out = 0 self.a_or_c_instr_mux = Mux2Way16Bit() self.load_a_mux = Mux2Way1Bit() self.a_or_m_mux = Mux2Way16Bit() self.load_d_mux = Mux2Way1Bit() self.load_jump_mux = Mux2Way1Bit() def compute(self, instr, mem_in): x, a, c1, c2, c3, c4, c5, c6, d1, d2, d3, j1, j2, j3 = self.decoder.compute( instr) a_in = self.a_or_c_instr_mux.compute(x, instr, self.alu_out) a_load = self.load_a_mux.compute(x, 1, d1) self.a_out = self.a_register.compute(a_in, a_load) a_or_m_mux_out = self.a_or_m_mux.compute(a, self.a_out, mem_in) self.alu_out = self.alu.compute(c1, c2, c3, c4, c5, c6, self.d_out, a_or_m_mux_out) self.jump_decoder_out = self.jump_decoder.compute( self.alu_out, j1, j2, j3) load_pc = self.load_jump_mux.compute(x, 0, self.jump_decoder_out) d_load = self.load_d_mux.compute(x, 0, d2) self.d_out = self.d_register.compute(self.alu_out, d_load) mem_dir = self.a_out return self.alu_out, load_pc, mem_dir
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()
def __init__(self, bus): bus.register(self) self._alu = Alu() return
def __init__(self): ###Input self.I_clk = I_clk = Signal() self.instruction = instruction = Signal(16) self.instructions = instructions = Array(Signal(16) for a in range(4)) self.en = en = Signal() self.dataA = dataA = Signal(16) self.dataB = dataB = Signal(16) self.selA = selA = Signal(3) self.selB = selB = Signal(3) self.selD = selD = Signal(3) self.dataIMM = dataIMM = Signal(16) self.dataDwe = dataDwe = Signal() self.aluop = aluop = Signal(5) self.PC = PC = Signal(16) self.dataResult = dataResult = Signal(16) self.dataWriteReg = dataWriteReg = Signal() self.shouldBranch = shouldBranch = Signal() self.en_regread = en_regread = Signal() self.en_regwrite = en_regwrite = Signal() self.en_decode = en_decode = Signal() self.en_alu = en_alu = Signal() self.reset = reset = Signal() i = Signal(2) self.ramWE = ramWE = Signal() self.ramAddr = ramAddr = Signal(16) self.ramRdata = ramRdata = Signal(16) self.ramWdata = ramWdata = Signal(16) self.nPC = nPC = Signal(16) self.PC = PC = Signal(16) self.pcop = pcop = Signal(2) self.in_pc = in_pc = Signal(16) pc=Pc_unit() self.submodules += pc ram=Ram2() self.submodules += ram alu=Alu() self.submodules += alu decoder=Decoder() self.submodules += decoder reg=Register_File() self.submodules += reg control=Control_Unit() self.submodules += control self.sync +=[ If(en_regwrite, i.eq(i+1), # instruction.eq(instructions[i]) ) ] self.comb += [ # instructions[0].eq(0x8902), # instructions[1].eq(0x0670), # instructions[2].eq(0x2a0c), # instructions[3].eq(0x2a0c), ram.I_clk.eq(I_clk), ram.I_we.eq(ramWE), ram.I_addr.eq(ramAddr), ram.I_data.eq(ramWdata), ramRdata.eq(ram.O_data), pc.I_clk.eq(I_clk), pc.I_nPC.eq(in_pc), pc.I_nPCop.eq(pcop), PC.eq(pc.O_PC), ramAddr.eq(PC), ramWdata.eq(0xffff), ramWE.eq(0), instruction.eq(ramRdata), If(reset, pcop.eq(0b11) ).Elif(control.O_state[4], pcop.eq(0b01) ).Else(pcop.eq(0b00)), # pcop.eq(0b01), # If(reset, # pcop.eq(0b11) # ).Elif(en_alu, # pcop.eq(0b01) # ).Else(pcop.eq(0b00)), control.I_reset.eq(reset), en_regwrite.eq(control.O_state[3]), en_regread.eq(control.O_state[1]), en_alu.eq(control.O_state[2]), en_decode.eq(control.O_state[0]), en.eq(1), alu.I_clk.eq(I_clk), # alu.I_en.eq(en_alu), alu.I_en.eq(1), alu.I_dataA.eq(dataA), alu.I_dataB.eq(dataB), alu.I_dataDwe.eq(dataDwe), alu.I_aluop.eq(aluop), alu.I_PC.eq(PC), alu.I_dataIMM.eq(dataIMM), dataResult.eq(alu.O_dataResult), dataWriteReg.eq(alu.O_dataWriteReg), shouldBranch.eq(alu.O_shouldBranch), decoder.I_en.eq(en_decode), selA.eq(decoder.O_selA), selB.eq(decoder.O_selB), selD.eq(decoder.O_selD), dataIMM.eq(decoder.O_dataIMM), dataDwe.eq(decoder.O_regDwe), aluop.eq(decoder.O_aluop), decoder.I_dataInst.eq(instruction), decoder.I_clk.eq(I_clk), reg.I_clk.eq(I_clk), reg.I_en.eq(en_regread | en_regwrite), reg.I_dataD.eq(dataResult), reg.I_selA.eq(selA), reg.I_selB.eq(selB), reg.I_selD.eq(selD), reg.I_we.eq(dataWriteReg & en_regwrite), dataA.eq(reg.O_dataA), dataB.eq(reg.O_dataB) ]
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()
def go(self, stdscr, infile): curses.noecho() curses.curs_set(0) stdscr.clear stdscr.refresh() stdscr.nodelay(True) if not curses.has_colors(): print("Color support required. Press any key to exit") curses.echo() curses.endwin() stdscr = None curses.init_pair(const.COLOR_PAIR_WHITE, curses.COLOR_WHITE, curses.COLOR_BLACK) curses.init_pair(const.COLOR_PAIR_RED, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(const.COLOR_PAIR_GREEN, curses.COLOR_GREEN, curses.COLOR_BLACK) curses.init_pair(const.COLOR_PAIR_YELLOW, curses.COLOR_YELLOW, curses.COLOR_BLACK) curses.init_pair(const.COLOR_PAIR_BLUE, curses.COLOR_CYAN, curses.COLOR_BLACK) row_height = (curses.LINES - 1) // 4 col_width = (curses.COLS - 1) // 4 components = { 'data_bus': DataBus( curses.newwin(row_height * 1, col_width * 1, row_height * 0, col_width * 0)), 'addr_bus': AddrBus( curses.newwin(row_height * 1, col_width * 1, row_height * 1, col_width * 0)), 'prog_cnt': ProgramCounter( curses.newwin(row_height * 1, col_width * 1, row_height * 1, col_width * 1)), 'mem': Memory( curses.newwin(row_height * 2, col_width * 2, row_height * 2, col_width * 0)), 'reg_a': Register( curses.newwin(row_height * 1, col_width * 1, row_height * 0, col_width * 1), 'Register A'), 'reg_b': Register( curses.newwin(row_height * 1, col_width * 1, row_height * 0, col_width * 3), 'Register B'), 'alu': Alu( curses.newwin(row_height * 1, col_width * 1, row_height * 0, col_width * 2)), 'output': Output( curses.newwin(row_height * 1, col_width * 1, row_height * 1, col_width * 3)), } components['mem'].load_mem_from_file(infile) help = Help( curses.newwin(row_height * 1, col_width * 2, row_height * 3, col_width * 2)) inst_dec = InstDecode( curses.newwin(row_height * 1, col_width * 2, row_height * 2, col_width * 2), components) clock = Clock(curses.newwin(row_height * 1, col_width * 1, row_height * 1, col_width * 2), decode=inst_dec) inst_dec.refresh() # clock.start() quit = False while quit == False: c = stdscr.getch() if c == ord('q') or c == ord('Q'): quit = True elif c == ord('p') or c == ord('P'): clock.pause_toggle() elif c == ord('h') or c == ord('H'): clock.halt() elif c == ord('a') or c == ord('A'): clock.change_speed(-1) elif c == ord('z') or c == ord('Z'): clock.change_speed(1) elif c == ord('o') or c == ord('O'): clock.manual_pulse() elif c == curses.KEY_UP: components['mem'].scroll_up() elif c == curses.KEY_DOWN: components['mem'].scroll_down() elif c == ord('r') or c == ord('R'): clock.reset() inst_dec.reset() components['mem'].load_mem_from_file(infile) inst_dec.refresh() clock.halt() curses.echo() curses.endwin() stdscr = None
def test_alu(): alu = Alu() # ZERO x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 1 nx = 0 zy = 1 ny = 0 f = 1 no = 0 out = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.zero(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} '\ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # ONE x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 1 nx = 1 zy = 1 ny = 1 f = 1 no = 1 out = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.one(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # MINUS ONE x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 1 nx = 1 zy = 1 ny = 0 f = 1 no = 0 out = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.minus_one(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # X x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 0 zy = 1 ny = 1 f = 0 no = 0 out = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.x(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # Y x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 1 nx = 1 zy = 0 ny = 0 f = 0 no = 0 out = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.y(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # NOT X x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 0 zy = 1 ny = 1 f = 0 no = 1 out = [0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.not_x(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # NOT Y x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 1 nx = 1 zy = 0 ny = 0 f = 0 no = 1 out = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.not_y(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # -X x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 0 zy = 1 ny = 1 f = 1 no = 1 out = [0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.minus_x(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # -Y x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 1 nx = 1 zy = 0 ny = 0 f = 1 no = 1 out = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.minus_y(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # X + 1 x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 1 zy = 1 ny = 1 f = 1 no = 1 out = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.x_plus_one(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # Y + 1 x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 1 nx = 1 zy = 0 ny = 1 f = 1 no = 1 out = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.y_plus_one(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # X - 1 x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 0 zy = 1 ny = 1 f = 1 no = 0 out = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.x_minus_one(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # Y - 1 x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 1 nx = 1 zy = 0 ny = 0 f = 1 no = 0 out = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.y_minus_one(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # X + Y x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 0 zy = 0 ny = 0 f = 1 no = 0 out = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.x_plus_y(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # X - Y x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 1 zy = 0 ny = 0 f = 1 no = 1 out = [0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.x_minus_y(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # Y - X x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 0 zy = 0 ny = 1 f = 1 no = 1 out = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.y_minus_x(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # X & Y x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 0 zy = 0 ny = 0 f = 0 no = 0 out = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.x_and_y(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2) # X | Y x = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] y = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] zx = 0 nx = 1 zy = 0 ny = 1 f = 0 no = 1 out = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] result = alu.compute(zx, nx, zy, ny, f, no, x, y) result2 = alu.x_or_y(x, y) assert result == out or result2 == out, 'Error, zx: {}, nx: {}, zy: {}, ny: {}, f: {}, no: {}, x: {}, y: {} ' \ 'should output: {} but got: {}, {}'.format(zx, nx, zy, ny, f, no, x, y, out, result, result2)
def test_alu(): alu = Alu(4) alu.enabled = True alu.a = [0, 1, 1, 0] alu.b = [0, 0, 0, 1] alu.o = [0, 0] alu.eval() assert alu.x == [0, 1, 1, 1] alu.o = [1, 0] alu.eval() assert alu.x == [0, 1, 0, 1] alu.enabled = False alu.eval() assert alu.x == [None, None, None, None]
class Core(Elaboratable): """ The core of the CPU """ def __init__(self, validator: Optional[Base]): self.validator = validator self.Addr = Signal(16) self.Din = Signal(8) self.Dout = Signal(8) self.RW = Signal(reset=1) # read=1, write=0 self.Rst = Signal() # registers self.registers = Registers(self.Din, self.Dout, self.Addr) self.buses = Buses(self.registers, self) self.reset = Reset(self) self.cycle = Signal(4) self.end_instr_flag = Signal() self.end_instr_addr = Signal(16) self.instruction_set = InstructionSet() self.alu = Alu(self) def ports(self) -> List[Signal]: return [self.Addr, self.Din, self.Dout, self.RW, self.Rst] def is_running(self, m: Module): return (self.reset.is_running(m) & self.registers.ccr[Ccr.RUN] & self.registers.ccr[Ccr.RUN_2]) def elaborate(self, platform: Platform) -> Module: m = Module() self.buses.setup(m) self.reset.setup(m) self.alu.setup(m) with m.If(self.end_instr_flag): m.d.ph1 += self.registers.pc.eq(self.end_instr_addr) m.d.ph1 += self.Addr.eq(self.end_instr_addr) m.d.ph1 += self.RW.eq(1) m.d.ph1 += self.cycle.eq(0) with m.If(self.is_running(m)): with m.If(self.cycle == 0): self.fetch(m) with m.Else(): self.execute(m) if self.validator: self.validator.init(m, self) self.validator.validate() return m def fetch(self, m: Module): m.d.ph1 += self.registers.instr.eq(self.Din) m.d.ph1 += self.cycle.eq(1) m.d.ph1 += self.RW.eq(1) self.next_pc_inc(m) def execute(self, m: Module): with m.Switch(self.registers.instr): for key, instr in self.instruction_set.instructions.items(): with m.Case(key): instr.implement(m, self) with m.Default(): self.halt(m) def halt(self, m: Module): m.d.ph1 += self.registers.ccr.eq(self.registers.ccr & 0b00111111) def incAddr(self, m: Module): self.buses.incdec16_inc(m) def decAddr(self, m: Module): self.buses.incdec16_dec(m) def next(self, m: Module, addr: Statement): m.d.comb += self.end_instr_addr.eq(addr) m.d.comb += self.end_instr_flag.eq(1) def pc_inc(self, m: Module): self.incAddr(m) self.buses.read_incdec16(m, self.registers.pc) def next_pc_inc(self, m: Module): self.pc_inc(m) self.next(m, self.buses.incdec16) def next_pc(self, m: Module): self.next(m, self.registers.pc)