def handle_one_request(self):
        try:
            # read the first line from request
            request_line = self.rfile.readline()
            words = request_line.strip().split()
            if len(words) != 3:
                self.send_error_response(400, "Invalid HTTP request")
                return
            self.verb, self.path, _ = words
            add_access_log(self.verb + " " + self.path)
            # read the header lines
            self.headers = mimetools.Message(self.rfile, 0)
            connection_type = self.headers.get("Connection", "")
            if connection_type == "close":
                self.close_connection = True
            elif connection_type == "keep-alive":
                self.close_connection = False

            # delegate body handling to mux
            handler = Mux().get_handler(self.path)
            if not handler:
                self.send_error_response(404, "File Not Found")
                return
            handler.handle_request(self)
            if not self.wfile.closed:
                self.wfile.flush()
                self.wfile.close()

            # If the request handler write some error messages, record them in log
            if self.error.tell():
                self.error.seek(0)
                add_error_log(self.error.read())
        except Exception, e:
            add_error_log(str(e))
            self.close_connection = True
Exemple #2
0
	def __init__(self, memoryFile):
		self.nCycles = 0 # Used to hold number of clock cycles spent executing instructions

		# Fetch
		self.PCMux	  = Mux()
		self.ProgramC   = PC(long(0xbfc00200))
		self.InstMem	= InstructionMemory(memoryFile)
		self.IFadder	= Add()
		self.JMux	   = Mux()
		self.IFaddconst = Constant(4)
		self.IF_ID_Wall = Wall()
		self.fetchgroup = {}

		# Decode
		self.register   = RegisterFile()
		self.signext	= SignExtender()
		self.control	= ControlElement()
		self.jmpCalc	= JumpCalc()
		self.ID_EX_Wall = Wall()

		# Execute
		self.EXadder	= Add()
		self.shiftL	 = LeftShifter()
		self.ALogicUnit = ALU()
		self.ALUSrcMux  = Mux()
		self.RegDstMux  = Mux()
		self.ALUctrl	= AluControl()
		self.EX_MEM_Wall= Wall()

		# Memory
		self.storage	= DataMemory(memoryFile)
		self.brnch	  = Branch()
		self.MEM_WB_Wall= Wall()

		# Write Back
		self.WBmux = Mux()

		self.ProgramC
		self.elements1 = [self.InstMem, self.IFaddconst, self.IFadder, self.PCMux, self.JMux]
		self.elements2 = [self.control, self.register, self.signext, self.jmpCalc]
		self.elements3 = [self.shiftL, self.ALUSrcMux, self.RegDstMux, self.ALUctrl, self.ALogicUnit, self.EXadder]
		self.elements4 = [self.brnch, self.storage]
		self.elementsboot = [self.IFaddconst, self.IFadder, self.InstMem,
							 self.IF_ID_Wall, self.register, self.signext, self.control, self.jmpCalc,
							 self.ID_EX_Wall, self.RegDstMux, self.shiftL, self.EXadder, self.ALUSrcMux, self.ALUctrl, self.ALogicUnit,
							 self.EX_MEM_Wall, self.brnch, self.storage,
							 self.MEM_WB_Wall, self.WBmux, self.PCMux, self.JMux]
		self.walls = [self.MEM_WB_Wall, self.EX_MEM_Wall, self.ID_EX_Wall, self.IF_ID_Wall]


		self._connectCPUElements()
Exemple #3
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()
    def __init__(self, memoryFile):
        self.nCycles = 0  # Used to hold number of clock cycles spent executing instructions

        self.dataMemory = DataMemory(memoryFile)
        self.instructionMemory = InstructionMemory(memoryFile)
        self.registerFile = RegisterFile()

        self.constant3 = Constant(3)
        self.constant4 = Constant(4)
        self.randomControl = RandomControl()
        self.mux = Mux()
        self.adder = Add()
        self.pc = PC(0xbfc00000)  # hard coded "boot" address

        self.elements = [
            self.constant3, self.constant4, self.randomControl, self.adder,
            self.mux
        ]

        self._connectCPUElements()
Exemple #5
0
    print '\n--> Error: not correct input!\n--> Usage: python polony_sequencing.py config.txt\n'
    sys.exit()

config = ConfigParser.ConfigParser(
)  # Create configuration file parser object.
config.read(sys.argv[1])  # Fill it in with configuration parameters from file.
logger = Logger(config)  # Initialize logger object.

#---------------------------- Device(s) initialization ---------------------------------

t0 = time.time()  # Get current time.
print '\n'
logger.info('***\t*\t--> Device testing started - test.py')  # Test start.

serial_port = Serial_port(config, logger)  # Initialize serial port object.
mux = Mux(logger)  # Initialize mux object.

syringe_pump = Syringe_pump(config, serial_port,
                            logger)  # Initialize syringe pump object.
rotary_valve = Rotary_valve(config, serial_port,
                            logger)  # Initialize rotary valve object.
temperature_control = Temperature_control(
    config, serial_port, logger)  # Initialize temperature controller object.

#---------------------------------------------------------------------------------------
#								TEMPERATURE CONTROL
#---------------------------------------------------------------------------------------

mux.set_to_temperature_control1(
)  # Switch communication to temperature controller 1.
mux.set_to_temperature_control2(
Exemple #6
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()
Exemple #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 = 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()
Exemple #8
0
if len(sys.argv) < 2:
    print '\n--> Error: not correct input!\n--> Usage: python polony_sequencing.py config.txt\n'
    sys.exit()

config = ConfigParser.ConfigParser()    # Create configuration file parser object.
config.read(sys.argv[1])                # Fill it in with configuration parameters from file.
logger = Logger(config)                 # Initialize logger object. 

#---------------------------- Device(s) initialization -----------------------
    
t0 = time.time()                            # Get current time.
print '\n'
logger.info('***\t*\t--> Device testing started - test.py') # Test start.

serial_port = Serial_port(config, logger)   # Initialize serial port object.
mux = Mux(logger)                           # Initialize mux object.

# Initialize syringe pump object.
syringe_pump = Syringe_pump(config, serial_port, logger)
# Initialize rotary valve object.
rotary_valve = Rotary_valve(config, serial_port, logger)
# Initialize temperature controller object.
temperature_control = Temperature_control(config, serial_port, logger)

#-----------------------------------------------------------------------------
#                               TEMPERATURE CONTROL                 
#-----------------------------------------------------------------------------

mux.set_to_temperature_control1()           # Switch communication to temperature controller 1.
mux.set_to_temperature_control2()           # Switch communication to temperature controller 2.
Exemple #9
0
  def __init__(self, memoryFile):
    self.nCycles = 0 # Used to hold number of clock cycles spent executing instructions
    
    self.dataMemory = DataMemory(memoryFile)
    self.instructionMemory = InstructionMemory(memoryFile)
    self.registerFile = RegisterFile()
    self.alu = ALU()
    self.mainControl = MainControl()
    self.splitter = Splitter()
    self.signExtender = SignExtender()
    self.andGate = AndGate()
    self.breaker = Breaker()

    self.constant4 = Constant(4)
    # self.randomControl = RandomControl()
    self.pcMux1 = Mux()
    self.pcMux2 = Mux()
    self.regMux = Mux()
    self.aluMux = Mux()
    self.resultMux = Mux()
    self.luiMux = Mux()

    self.adder = Add()
    self.branchAdder = Add()

    self.jumpAddress = JMPAddress()
    self.shiftBranch = LeftShiftTwo()
    self.shiftJump = LeftShiftTwo()

    self.pc = PC(hex(0xbfc00000))  # hard coded "boot" address
    
    self.elements = [self.constant4, self.adder, self.instructionMemory, self.breaker, self.splitter,
                     self.shiftJump, self.mainControl, self.regMux, self.signExtender, self.luiMux, self.registerFile,
                     self.jumpAddress, self.shiftBranch, self.branchAdder, self.aluMux, self.alu, self.dataMemory,
                     self.andGate, self.pcMux1, self.pcMux2, self.resultMux, self.registerFile, self.pc]
    
    self._connectCPUElements()
Exemple #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 = 0 # Used to hold number of clock cycles spent executing instructions
    
    self.dataMemory = DataMemory(memoryFile)
    self.instructionMemory = InstructionMemory(memoryFile)
    self.registerFile = RegisterFile()
    self.alu = ALU()
    self.mainControl = MainControl()
    self.splitter = Splitter()
    self.signExtender = SignExtender()
    self.andGate = AndGate()
    self.breaker = Breaker()

    self.constant4 = Constant(4)
    # self.randomControl = RandomControl()
    self.pcMux1 = Mux()
    self.pcMux2 = Mux()
    self.regMux = Mux()
    self.aluMux = Mux()
    self.resultMux = Mux()
    self.luiMux = Mux()

    self.adder = Add()
    self.branchAdder = Add()

    self.jumpAddress = JMPAddress()
    self.shiftBranch = LeftShiftTwo()
    self.shiftJump = LeftShiftTwo()

    self.pc = PC(hex(0xbfc00000))  # hard coded "boot" address
    
    self.elements = [self.constant4, self.adder, self.instructionMemory, self.breaker, self.splitter,
                     self.shiftJump, self.mainControl, self.regMux, self.signExtender, self.luiMux, self.registerFile,
                     self.jumpAddress, self.shiftBranch, self.branchAdder, self.aluMux, self.alu, self.dataMemory,
                     self.andGate, self.pcMux1, self.pcMux2, self.resultMux, self.registerFile, self.pc]
    
    self._connectCPUElements()
    
  def _connectCPUElements(self):
    
    self.constant4.connect(
      [],
      ['constant'],
      [],
      []
    )
    
    self.adder.connect(
      [(self.pc, 'pcAddress'), (self.constant4, 'constant')],
      ['sum'],
      [],
      []
    )
    
    self.pcMux2.connect(
      [(self.pcMux1, "ResultMux2"), (self.jumpAddress, "Result")],
      ['muxOut'],
      [(self.mainControl, "JmpCtrl")],
      []
    )
    
    self.pc.connect(
      [(self.pcMux2, 'muxOut')],
      ['pcAddress'],
      [],
      []
    )

    self.instructionMemory.connect(
      [(self.pc, "pcAddress")],
      ["instruction"],
      [],
      []
    )

    self.splitter.connect(
      [(self.breaker, "Instruction")],
      ["31-0", "25-21", "20-16", "15-11", "15-0", "25-0"],
      [],
      []
    )

    self.mainControl.connect(
      [(self.splitter, "31-0")],
      [],
      [],
      ["RegDst", "RegWrite", "ALUSrc", "ALUOp", "MemWrite", "MemtoReg", "MemRead", "ALUType", "AndGate", "JmpCtrl",
       "LuiCtrl"]
    )

    self.regMux.connect(
      [(self.splitter, "20-16"), (self.splitter, "15-11")],
      ["WReg"],
      [(self.mainControl, "RegDst")],
      []
    )

    self.registerFile.connect(
      [(self.splitter, "25-21"), (self.splitter, "20-16"), (self.regMux, "WReg"), (self.resultMux, "WriteData")],
      ["Read1", "Read2"],
      [(self.mainControl, "RegWrite")],
      []
    )

    self.signExtender.connect(
      [(self.splitter, "15-0")],
      ["ExtendedValue"],
      [],
      []
    )

    self.aluMux.connect(
      [(self.registerFile, "Read2"), (self.luiMux, "LuiOutput")],
      ["RightOp"],
      [(self.mainControl, "ALUSrc")],
      []
    )

    self.alu.connect(
      [(self.registerFile, "Read1"), (self.aluMux, "RightOp")],
      ["Result"],
      [(self.mainControl, "ALUOp"), (self.mainControl, "ALUSrc")],
      ["Zero"]
    )

    self.dataMemory.connect(
      [(self.alu, "Result"), (self.registerFile, "Read2")],
      ["ReadData"],
      [(self.mainControl, "MemWrite"), (self.mainControl, "MemRead")],
      []
    )

    self.resultMux.connect(
      [(self.alu, "Result"), (self.dataMemory, "ReadData")],
      ["WriteData"],
      [(self.mainControl, "MemtoReg")],
      []
    )

    self.andGate.connect(
      [],
      [],
      [(self.mainControl, "AndGate"), (self.alu, "Zero")],
      ["PCMuxSelect"]
    )

    self.shiftBranch.connect(
      [(self.signExtender, "ExtendedValue")],
      ["ShiftedValue"],
      [],
      []
    )

    self.branchAdder.connect(
      [(self.adder, "sum"), (self.shiftBranch, "ShiftedValue")],
      ["branchSum"],
      [],
      []
    )

    self.pcMux1.connect(
      [(self.adder, "sum"), (self.branchAdder, "branchSum")],
      ["ResultMux2"],
      [(self.andGate, "PCMuxSelect")],
      []
    )

    self.shiftJump.connect(
      [(self.splitter, "25-0")],
      ["ShiftedValue"],
      [],
      []
    )

    self.jumpAddress.connect(
      [(self.shiftJump, "ShiftedValue"), (self.adder, "sum")],
      ["Result"],
      [],
      []
    )

    self.breaker.connect(
      [(self.instructionMemory, "instruction")],
      ["Instruction"],
      [],
      []
    )

    self.luiMux.connect(
      [(self.signExtender, "ExtendedValue"), (self.splitter, "15-0")],
      ["LuiOutput"],
      [(self.mainControl, "LuiCtrl")],
      []
    )
    
  def clockCycles(self):
    '''Returns the number of clock cycles spent executing instructions.'''
    
    return self.nCycles
  
  def dataMemory(self):
    '''Returns dictionary, mapping memory addresses to data, holding
    data memory after instructions have finished executing.'''
    
    return self.dataMemory.memory
  
  def registerFile(self):
    '''Returns dictionary, mapping register numbers to data, holding
    register file after instructions have finished executing.'''
    
    return self.registerFile.register
  
  #def printDataMemory(self):
    #self.dataMemory.printAll()
  
  #def printRegisterFile(self):
    #self.registerFile.printAll()
  
  def tick(self):
    '''Execute one clock cycle of pipeline.'''
    
    self.nCycles += 1
    
    # The following is just a small sample implementation
    
    self.pc.writeOutput()
    
    for elem in self.elements:
      elem.readControlSignals()
      elem.readInput()
      elem.writeOutput()
      elem.setControlSignals()
    
    self.pc.readInput()
Exemple #11
0
    def fit_layer(input_nodes_labels, mux_dict, used_lut_objects):
        """
        This function performs the fitting of a layer with a given number of inputs

        It starts with the highest mux-size that can be implemented and then checks if any sequential combination of
        inputs nodes can be fit into the mux. It proceeds to use this mux in the final layout and continue on the
        remaining inputs
        :param input_nodes_labels: 2D matrix where each row is the label for an input node
        :param mux_dict:
        :param used_lut_objects: the list of lut objects used till now
        :return: used_list: the LUTS used in this layer
        :return output_nodes_labels: 2D matrix for lables for the output nodes
        """

        output_nodes_labels = input_nodes_labels
        L = input_nodes_labels.shape[1]
        num_of_inputs = input_nodes_labels.shape[0]
        is_used = [False] * num_of_inputs
        used_list = list()
        count = 0

        available_muxes = sorted(mux_dict.keys())  # implementable mux-sizes in increasing order of the size

        deactivated_label = [-1] * L  # label to be used for deactivated output nodes
        dummy_input_label = [2] * L  # label for dummy input node

        # print(' Available muxes - %r' % available_muxes)
        while count < num_of_inputs:  # loop till we have not covered all inputs on some mux
            try:
                mux_size = available_muxes.pop()  # get the highest size mux available
                # print('fitting mux of size %d' % mux_size)
            except IndexError as e:
                # No muxes are available
                # just pass along the inputs through the layer
                # print(e.args)
                # print('no available mux')
                return used_list, output_nodes_labels

            # try to fit a subset of the inputs to the mux of given size
            mux_candidate_inputs = np.empty((mux_size, L))  # candidate nodes for fitting the mux

            for i in range(0, num_of_inputs):
                k = i
                inp_count = 0
                used_inp_list = list()
                while inp_count < mux_size and k < num_of_inputs:
                    if is_used[k] is False:
                        mux_candidate_inputs[inp_count, :] = input_nodes_labels[k, :]
                        inp_count += 1
                        used_inp_list.append(k)
                    k += 1
                # print('input node labels - %r' % mux_candidate_inputs)
                while inp_count < mux_size:
                    mux_candidate_inputs[inp_count, :] = dummy_input_label
                    inp_count += 1
                # print('checking for inputs - %r' % used_inp_list)
                # print('input node labels - %r' % mux_candidate_inputs)
                # print('getting mux params')
                mux_params = Mux.get_mux_params(mux_candidate_inputs, mux_size)
                # print(mux_params)
                if mux_params is not None:
                    # print('mux op label')
                    # print(mux_params[1])
                    # hence implementable

                    lut_list = mux_dict.pop(mux_size)
                    if lut_list is None:
                        break

                    # setting used flags for input nodes
                    for index in used_inp_list:
                        is_used[index] = True

                    used_lut = lut_list.pop(0)  # get the smallest sized lut which can implement the required mux
                    used_list.append(used_lut)

                    select_lines = mux_params[0]
                    output_node_label = mux_params[1]

                    lut = Lut(used_lut, mux_candidate_inputs, select_lines, output_node_label)
                    used_lut_objects.append(lut)

                    output_nodes_labels[used_inp_list[0], :] = output_node_label
                    for j in range(1, len(used_inp_list)):
                        output_nodes_labels[used_inp_list[j], :] = deactivated_label

                    count += len(used_inp_list)
                    if len(lut_list) != 0:
                        # print('adding back the mux')
                        mux_dict[mux_size] = lut_list
                        available_muxes.append(mux_size)
                    break
            if count == num_of_inputs - 1:
                break

        # deleting useless output_nodes_labels
        deactivated_nodes = list()
        for i in range(num_of_inputs):
            if np.array_equal(output_nodes_labels[i, :], deactivated_label):
                deactivated_nodes.append(i)

        output_nodes_labels = np.delete(output_nodes_labels, deactivated_nodes, 0)

        return used_list, output_nodes_labels
Exemple #12
0
    def __init__(self, memoryFile):

        self.nCycles = 0  # Used to hold number of clock cycles spent executing instructions

        self.datamemory = DataMemory(memoryFile)
        self.instructionmemory = InstructionMemory(memoryFile)
        self.registerfile = RegisterFile()

        self.constant4 = Constant(4)

        self.alu = Alu()
        self.controlunit = ControlUnit()
        self.shift2 = Shift2()
        self.shift16 = Shift16()
        self.signextend = SignExtend()
        self.alterand = Alterand()
        self.altershift = Altershift()

        self.mux_writereg = Mux()  # 6 multiplexors
        self.mux_regoutput = Mux()
        self.mux_jump = Mux()
        self.mux_branch = Mux()
        self.mux_datamem = Mux()
        self.mux_shift16 = Mux()

        self.adderpc = Add()  # 2 adders
        self.addershift = Add()
        self.pc = PC(0xbfc00000)  # hard coded "boot" address

        self.elements = [
            self.constant4, self.adderpc, self.instructionmemory,
            self.controlunit, self.altershift, self.mux_writereg,
            self.registerfile, self.shift16, self.signextend, self.shift2,
            self.addershift, self.mux_regoutput, self.alu, self.alterand,
            self.mux_branch, self.mux_jump, self.datamemory, self.mux_datamem,
            self.mux_shift16, self.registerfile
        ]

        self._connectCPUElements()
Exemple #13
0
class MySimulator():
    '''Main class for MIPS pipeline simulator.
    
    Provides the main method tick(), which runs pipeline
    for one clock cycle.
    
    '''
    def __init__(self, memoryFile):

        self.nCycles = 0  # Used to hold number of clock cycles spent executing instructions

        self.datamemory = DataMemory(memoryFile)
        self.instructionmemory = InstructionMemory(memoryFile)
        self.registerfile = RegisterFile()

        self.constant4 = Constant(4)

        self.alu = Alu()
        self.controlunit = ControlUnit()
        self.shift2 = Shift2()
        self.shift16 = Shift16()
        self.signextend = SignExtend()
        self.alterand = Alterand()
        self.altershift = Altershift()

        self.mux_writereg = Mux()  # 6 multiplexors
        self.mux_regoutput = Mux()
        self.mux_jump = Mux()
        self.mux_branch = Mux()
        self.mux_datamem = Mux()
        self.mux_shift16 = Mux()

        self.adderpc = Add()  # 2 adders
        self.addershift = Add()
        self.pc = PC(0xbfc00000)  # hard coded "boot" address

        self.elements = [
            self.constant4, self.adderpc, self.instructionmemory,
            self.controlunit, self.altershift, self.mux_writereg,
            self.registerfile, self.shift16, self.signextend, self.shift2,
            self.addershift, self.mux_regoutput, self.alu, self.alterand,
            self.mux_branch, self.mux_jump, self.datamemory, self.mux_datamem,
            self.mux_shift16, self.registerfile
        ]

        self._connectCPUElements()

    def _connectCPUElements(self):

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

        self.controlunit.connect(
            [(self.instructionmemory, 'ins_31-26'),
             (self.instructionmemory, 'ins_5-0')], [], [], [
                 'regdst', 'jump', 'branch', 'memread', 'memtoreg', 'aluop',
                 'memwrite', 'alusrc', 'regwrite', 'branchnotequal', 'loadui'
             ])

        self.adderpc.connect([(self.pc, 'pcaddress'),
                              (self.constant4, 'constant')], ['sum_pc'], [],
                             [])

        self.instructionmemory.connect([(self.pc, 'pcaddress')], [
            'ins_31-26', 'ins_25-21', 'ins_20-16', 'ins_15-11', 'ins_15-0',
            'ins_5-0', 'ins_25-0'
        ], [], [])

        self.altershift.connect([(self.instructionmemory, 'ins_25-0'),
                                 (self.adderpc, 'sum_pc')], ['jump_address'],
                                [], [])

        self.signextend.connect([(self.instructionmemory, 'ins_15-0')],
                                ['signextend_result'], [], [])

        self.shift2.connect([(self.signextend, 'signextend_result')],
                            ['shift2_result'], [], [])
        self.addershift.connect([(self.adderpc, 'sum_pc'),
                                 (self.shift2, 'shift2_result')],
                                ['sum_addershift'], [], [])
        self.mux_branch.connect([(self.adderpc, 'sum_pc'),
                                 (self.addershift, 'sum_addershift')],
                                ['mux_branch_result'],
                                [(self.alterand, 'alterand_result')], [])

        self.mux_jump.connect([(self.mux_branch, 'mux_branch_result'),
                               (self.altershift, 'jump_address')],
                              ['mux_jump_result'],
                              [(self.controlunit, 'jump')], [])
        self.alterand.connect([], [], [(self.controlunit, 'branch'),
                                       (self.controlunit, 'branchnotequal'),
                                       (self.alu, 'alu_zero_result')],
                              ['alterand_result'])

        self.mux_writereg.connect([(self.instructionmemory, 'ins_20-16'),
                                   (self.instructionmemory, 'ins_15-11')],
                                  ['mux_writereg_result'],
                                  [(self.controlunit, 'regdst')], [])

        self.registerfile.connect([(self.instructionmemory, 'ins_25-21'),
                                   (self.instructionmemory, 'ins_20-16'),
                                   (self.mux_writereg, 'mux_writereg_result'),
                                   (self.mux_shift16, 'mux_shift16_result')],
                                  ['reg_data1', 'reg_data2'],
                                  [(self.controlunit, 'regwrite')], [])

        self.mux_regoutput.connect([(self.registerfile, 'reg_data2'),
                                    (self.signextend, 'signextend_result')],
                                   ['mux_regoutput_result'],
                                   [(self.controlunit, 'alusrc')], [])
        self.alu.connect([(self.registerfile, 'reg_data1'),
                          (self.mux_regoutput, 'mux_regoutput_result')],
                         ['alu_result'], [(self.controlunit, 'aluop')],
                         ['alu_zero_result'])
        self.datamemory.connect([(self.alu, 'alu_result'),
                                 (self.registerfile, 'reg_data2')],
                                ['datamemory_result'],
                                [(self.controlunit, 'memwrite'),
                                 (self.controlunit, 'memread')], [])

        self.mux_datamem.connect([(self.alu, 'alu_result'),
                                  (self.datamemory, 'datamemory_result')],
                                 ['mux_datamemory_result'],
                                 [(self.controlunit, 'memtoreg')], [])

        self.mux_shift16.connect([(self.mux_datamem, 'mux_datamemory_result'),
                                  (self.shift16, 'shift16_result')],
                                 ['mux_shift16_result'],
                                 [(self.controlunit, 'loadui')], [])

        self.shift16.connect([(self.instructionmemory, 'ins_15-0')],
                             ['shift16_result'], [], [])

        self.pc.connect([(self.mux_jump, 'mux_jump_result')], ['pcaddress'],
                        [], [])

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

        return self.nCycles

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

        return self.dataMemory.memory

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

        return self.registerfile.register

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

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

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

        self.nCycles += 1

        # The following is just a small sample implementation

        self.pc.writeOutput()

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

        self.pc.readInput()
Exemple #14
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

		# Fetch
		self.PCMux	  = Mux()
		self.ProgramC   = PC(long(0xbfc00200))
		self.InstMem	= InstructionMemory(memoryFile)
		self.IFadder	= Add()
		self.JMux	   = Mux()
		self.IFaddconst = Constant(4)
		self.IF_ID_Wall = Wall()
		self.fetchgroup = {}

		# Decode
		self.register   = RegisterFile()
		self.signext	= SignExtender()
		self.control	= ControlElement()
		self.jmpCalc	= JumpCalc()
		self.ID_EX_Wall = Wall()

		# Execute
		self.EXadder	= Add()
		self.shiftL	 = LeftShifter()
		self.ALogicUnit = ALU()
		self.ALUSrcMux  = Mux()
		self.RegDstMux  = Mux()
		self.ALUctrl	= AluControl()
		self.EX_MEM_Wall= Wall()

		# Memory
		self.storage	= DataMemory(memoryFile)
		self.brnch	  = Branch()
		self.MEM_WB_Wall= Wall()

		# Write Back
		self.WBmux = Mux()

		self.ProgramC
		self.elements1 = [self.InstMem, self.IFaddconst, self.IFadder, self.PCMux, self.JMux]
		self.elements2 = [self.control, self.register, self.signext, self.jmpCalc]
		self.elements3 = [self.shiftL, self.ALUSrcMux, self.RegDstMux, self.ALUctrl, self.ALogicUnit, self.EXadder]
		self.elements4 = [self.brnch, self.storage]
		self.elementsboot = [self.IFaddconst, self.IFadder, self.InstMem,
							 self.IF_ID_Wall, self.register, self.signext, self.control, self.jmpCalc,
							 self.ID_EX_Wall, self.RegDstMux, self.shiftL, self.EXadder, self.ALUSrcMux, self.ALUctrl, self.ALogicUnit,
							 self.EX_MEM_Wall, self.brnch, self.storage,
							 self.MEM_WB_Wall, self.WBmux, self.PCMux, self.JMux]
		self.walls = [self.MEM_WB_Wall, self.EX_MEM_Wall, self.ID_EX_Wall, self.IF_ID_Wall]


		self._connectCPUElements()

	def _connectCPUElements(self):
		# IF
		self.PCMux.connect(
			[(self.IFadder, "adderout"), (self.EX_MEM_Wall, "adderoutput")],
			["PCmuxoutput"],
			[(self.brnch, "PCSrc")],
			[]
		)

		self.JMux.connect(
			[(self.PCMux, "PCmuxoutput"), (self.jmpCalc, "output")],
			["output"],
			[(self.control, "Jump")],
			[]
		)

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

		self.ProgramC.connect(
			[(self.JMux, "output")],
			["output"],
			[],
			[]
		)

		self.InstMem.connect(
			[(self.ProgramC, "output")],
			["opcode", "rs", "rt", "rd", "shamt", "funct", "imm", "addr"],
			[],
			[]
		)

		self.IFadder.connect(
			[(self.ProgramC, "output"), (self.IFaddconst, "constant")],
			["adderout"],
			[],
			[]
		)

		self.IF_ID_Wall.connect(
			[(self.InstMem, "opcode"),(self.InstMem, "rs"),
			(self.InstMem, "rt"),(self.InstMem, "rd"),
			(self.InstMem, "shamt"), (self.InstMem, "funct"),
			(self.InstMem, "imm"), (self.InstMem, "addr"),
			(self.IFadder, "adderout")],
			["opcode", "rs", "rt", "rd",
			 "shamt", "funct", "imm", "addr",
			 "adderout"],
			[],
			[]
		)
		# IF
		# ID
		self.register.connect(
			[(self.IF_ID_Wall, "rs"), (self.IF_ID_Wall, "rt"),
			 (self.MEM_WB_Wall, "regdstoutput"), (self.WBmux, "output")],
			["Reg1", "Reg2"],
			[(self.MEM_WB_Wall, "RegWrite")],
			[]
		)

		self.signext.connect(
			[(self.IF_ID_Wall, "imm")],
			["extended"],
			[],
			[]
		)

		self.control.connect(
			[(self.IF_ID_Wall, "opcode")],
			[],
			[],
			["RegDst", "RegWrite", "ALUSrc", "MemtoReg",
			 "MemWrite", "MemRead", "Branch", "ALUOp", "Jump"]
		)

		self.jmpCalc.connect(
			[(self.IF_ID_Wall, "addr"), (self.IF_ID_Wall, "adderout")],
			["output"],
			[],
			[]
		)

		self.ID_EX_Wall.connect(
			[(self.register, "Reg1"), (self.register, "Reg2"),
			(self.signext, "extended"), (self.jmpCalc, "output"),
			(self.IF_ID_Wall, "adderout"), (self.IF_ID_Wall, "funct"),
			(self.IF_ID_Wall, "rd"), (self.IF_ID_Wall, "addr"),
			(self.IF_ID_Wall, "rt")],
			["Reg1", "Reg2", "extended", "output",
			 "adderout", "funct", "rd", "addr", "rt"],
			[(self.control, "RegDst"), (self.control, "RegWrite"),
			(self.control, "ALUSrc"), (self.control, "MemtoReg"),
			(self.control, "MemWrite"), (self.control, "MemRead"),
			(self.control, "Branch"), (self.control, "ALUOp"),
			(self.control, "Jump")],
			["RegDst", "RegWrite", "ALUSrc", "MemtoReg",
			 "MemWrite", "MemRead", "Branch", "ALUOp", "Jump"]
		)
		#ID
		#EX

		self.EXadder.connect(
			[(self.ID_EX_Wall, "adderout"), (self.shiftL, "shifted")],
			["output"],
			[],
			[]
		)

		self.shiftL.connect(
			[(self.ID_EX_Wall, "extended")],
			["shifted"],
			[],
			[]
		)

		self.ALogicUnit.connect(
			[(self.ID_EX_Wall, "Reg1"), (self.ALUSrcMux, "output")],
			["result"],
			[(self.ALUctrl, "ALUctrlsig")],
			["zero"]
		)

		self.ALUSrcMux.connect(
			[(self.ID_EX_Wall, "Reg2"), (self.ID_EX_Wall, "extended")],
			["output"],
			[(self.ID_EX_Wall, "ALUSrc")],
			[]
		)

		self.RegDstMux.connect(
			[(self.ID_EX_Wall, "rt"), (self.ID_EX_Wall, "rd")],
			["RegDstoutput"],
			[(self.ID_EX_Wall, "RegDst")],
			[]
		)

		self.ALUctrl.connect(
			[(self.ID_EX_Wall, "funct")],
			[],
			[(self.ID_EX_Wall, "ALUOp")],
			["ALUctrlsig"]
		)

		self.EX_MEM_Wall.connect(
			[(self.EXadder, "output"), (self.ALogicUnit, "result"),
			 (self.ID_EX_Wall, "rt"), (self.RegDstMux, "RegDstoutput")],
			["adderoutput", "result", "rt", "regdstoutput"],
			[(self.ID_EX_Wall, "RegWrite"), (self.ID_EX_Wall, "MemtoReg"),
			 (self.ID_EX_Wall, "MemWrite"), (self.ID_EX_Wall, "MemRead"),
			 (self.ID_EX_Wall, "Branch"), (self.ALogicUnit, "zero")],
			["RegWrite", "MemtoReg", "MemWrite", "MemRead", "Branch", "zero"]
		)
		#EX
		#MEM

		self.storage.connect(
			[(self.EX_MEM_Wall, "result"), (self.EX_MEM_Wall, "rt")],
			["data"],
			[(self.EX_MEM_Wall, "MemWrite"), (self.EX_MEM_Wall, "MemRead")],
			[]
		)

		self.brnch.connect(
			[],
			[],
			[(self.EX_MEM_Wall, "Branch"), (self.EX_MEM_Wall, "zero")],
			["PCSrc"]
		)


		self.MEM_WB_Wall.connect(
			[(self.EX_MEM_Wall, "adderoutput"), (self.storage, "data"),
			 (self.EX_MEM_Wall, "regdstoutput")],
			["adderoutput", "data", "regdstoutput"],
			[(self.EX_MEM_Wall, "RegWrite"), (self.EX_MEM_Wall, "MemtoReg")],
			["RegWrite", "MemtoReg"]
		)
		#MEM
		#WB
		self.WBmux.connect(
			[(self.MEM_WB_Wall, "adderoutput"), (self.MEM_WB_Wall, "data")],
			["output"],
			[(self.MEM_WB_Wall, "MemtoReg")],
			[]
		)

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

		return self.nCycles

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

		return self.dataMemory.memory

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

		return self.registerFile.register

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

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

	def bootup(self):
		self.ProgramC.writeOutput()

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

		self.ProgramC.readInput()


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

		self.nCycles += 1
		

		self.ProgramC.writeOutput()

		for elem in self.walls:
			elem.writeOutput()
			elem.setControlSignals()

		self.WBmux.readControlSignals()
		self.WBmux.readInput()
		self.WBmux.writeOutput()
		self.WBmux.setControlSignals()

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

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

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

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

		for elem in self.walls:
			elem.readControlSignals()
			elem.readInput()

		self.register.printAll()
		self.ProgramC.readInput()
		print "number of cycles", self.nCycles, "\n"
class MIPSSimulator():
    '''Main class for MIPS pipeline simulator.
    
    Provides the main method tick(), which runs pipeline
    for one clock cycle.
    
    '''
    def __init__(self, memoryFile):
        self.nCycles = 0  # Used to hold number of clock cycles spent executing instructions

        self.dataMemory = DataMemory(memoryFile)
        self.instructionMemory = InstructionMemory(memoryFile)
        self.registerFile = RegisterFile()

        self.constant3 = Constant(3)
        self.constant4 = Constant(4)
        self.randomControl = RandomControl()
        self.mux = Mux()
        self.adder = Add()
        self.pc = PC(0xbfc00000)  # hard coded "boot" address

        self.elements = [
            self.constant3, self.constant4, self.randomControl, self.adder,
            self.mux
        ]

        self._connectCPUElements()

    def _connectCPUElements(self):
        self.constant3.connect([], ['constant'], [], [])

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

        self.randomControl.connect([], [], [], ['randomSignal'])

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

        self.mux.connect([(self.adder, 'sum'),
                          (self.constant3, 'constant')], ['muxOut'],
                         [(self.randomControl, 'randomSignal')], [])

        self.pc.connect([(self.mux, 'muxOut')], ['pcAddress'], [], [])

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

        return self.nCycles

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

        return self.dataMemory.memory

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

        return self.registerFile.register

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

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

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

        self.nCycles += 1

        # The following is just a small sample implementation

        self.pc.writeOutput()

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

        self.pc.readInput()