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

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

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

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

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

    self.WBelements = [ self.dmMux ] 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self._connectCPUElements()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return self.nCycles

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

        return self.dataMemory.memory

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

        return self.registerFile.register

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

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

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

        self.nCycles += 1

        # The following is just a small sample implementation

        self.pc.writeOutput()

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

        self.pc.readInput()
Beispiel #11
0
    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
Beispiel #12
0
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)
Beispiel #13
0
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]
Beispiel #14
0
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)