def writeTestFrameToUSB(self,frameTitle,chipX,chipY,coreX,coreY,neuron): r''' 生成测试帧,写入USB设备;各参数都是字符串,需要先转为整数,其中frameTitle是二进制,其余是十进制。 ''' if frameTitle == '100000': frameOutNum = 5 elif frameTitle == '100100': frameOutNum = 160 elif frameTitle == '101000': frameOutNum = 304 frameTitle = int(frameTitle,2) chipX = int(chipX) chipY = int(chipY) coreX = int(coreX) coreY = int(coreY) neuron = int(neuron) frameData = numpy.zeros(1).astype('uint64') frameToWrite = numpy.zeros(8).astype('uint8') frameData[0] = (coreY<<40)+(frameTitle<<34)+(chipX<<29)+(chipY<<24)+\ (coreX<<19)+(coreY<<14)+(neuron<<4) frameData.dtype='uint8' for i in range(8): frameToWrite[i]=frameData[7-i] bytesOneTime = 16*1024 #每次发送数据的字节数,以全1补齐 bytesAppend = 255*(numpy.ones(bytesOneTime-8).astype('uint8')) if usbMethod.usbHandler.writeToUSB(bytes(frameToWrite)+bytes(bytesAppend)): frameToWrite.dtype = 'uint64' logging.info('Test in:'+'{:0>64b}'.format(frameToWrite[0])) outputInfoMethod.raiseInfo("Write test frame to chip successfully.") #time.sleep(0.01) #print(self.readTestFrameFromUSB(frameOutNum)) for b in self.readTestFrameFromUSB(frameOutNum): logging.info('Test out:'+''.join(['{:0>8b}'.format(outByte) for outByte in b])) else: outputInfoMethod.raiseError('Failed to write test frame.')
def writeWorkFrameToUSB(self,inputFrameNoList): timeBegin = time.time() print('Writting') logging.info('Input Frames') if self.fullInputFrameListReady: workFrame = bytes(0) #print(inputFrameNoList) #print(len(inputFrameNoList)) for no in inputFrameNoList: #***********************在fullInputFrame中查找当前输入的输入脉冲数据(类似查找表,以空间换时间,加速工作输入帧的生成)****************************** workFrame += self.fullInputFrameList[no] logging.info(''.join(['%02x' % b for b in self.fullInputFrameList[no]])) logging.info(self.originalFullInputFrameList[no]) workFrame += self.workStartFrame bytesOneTime = 24*1024 #每次发送24k字节的数据,最后不足24k的部分以全1补齐 length = len(workFrame) print('workFrame:', workFrame) print('length:', length) bytesAppend = 255*(numpy.ones(bytesOneTime-length).astype('uint8')) usbMethod.usbHandler.writeToUSB(workFrame+bytes(bytesAppend)) #print(array.array('B',workFrame)) #print(len(workFrame)) #print(bytesAppend) #print(len(bytesAppend)) else: outputInfoMethod.raiseError('FullInputFrameList not ready.') timeEnd = time.time() print('Write work frames:',timeEnd-timeBegin)
def readFromInputFile(self,filePath,netName): try: #with open(filePath,'r') as inputFile: with open('./configFiles/'+netName+'FullInputFrame.txt', 'r') as inputFile: #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #with open("configFiles/mnist_numFullInputFrame.txt",'r') as inputFile: #with open("configFiles/chepaiFullInputFrame.txt",'r') as inputFile: inputFrameData = inputFile.read().splitlines() self.fullInputFrameList = [] self.fullInputFrameListReady = False i = 0 length = len(inputFrameData) outputInfoMethod.raiseInfo("Reading "+netName+" input layer file.") while i < length: if inputFrameData[i] == 'begin': i += 1 #读取数据输入工作帧 while inputFrameData[i] != 'inputFrameEnd' and i < length: frameDataTemp = bytes(0) for j in range(int(len(inputFrameData[i])/40)): frameDataTemp += self.frameDataTo8Bytes(inputFrameData[i][(40*j):(40*(j+1))]) self.fullInputFrameList.append(frameDataTemp) self.originalFullInputFrameList.append(inputFrameData[i]) i += 1 i += 1 #读取启动工作帧 self.workStartFrame = bytes(0) while inputFrameData[i] != 'startFrameEnd' and i < length: frameDataTemp = bytes(0) for j in range(int(len(inputFrameData[i])/40)): frameDataTemp += self.frameDataTo8Bytes(inputFrameData[i][(40*j):(40*(j+1))]) self.workStartFrame += frameDataTemp i += 1 i += 1 else: i += 1 except BaseException as e: outputInfoMethod.raiseError("Failed to read input layer file.") outputInfoMethod.raiseError(str(e)) return False else: self.fullInputFrameListReady = True #print(self.fullInputFrameList) print(len(self.fullInputFrameList)) outputInfoMethod.raiseInfo("Read "+netName+" input layer file successfully.") return True
def writeConfigFrameToUSB(self,netName): r''' 把处理好的帧数据逐帧写入USB设备; netName参数为网络的名称,也是帧数据存储文件的名称; ''' try: frameData = numpy.load('./configFiles/'+netName+'Config.npy') #某些情况下需要降低发送速度,下面将配置帧分块发送; frameData = bytes(frameData) dataLength = len(frameData) bytesOneTime = 8*1024 #每次发送8k字节的数据,有效帧不足8k时,以全1补齐 bytesValidOneTime = 4*1024 #每次发送的数据中,有效帧的字节数 onesOneTime = bytes(255*(numpy.ones(bytesOneTime-bytesValidOneTime).astype('uint8'))) #每次发送的字节中,补充的全1的字节 framesOneTime = int(bytesValidOneTime/8) #每次发送的帧数,每帧是8个字节 i = 0 frameNum = 0 timeBegin = time.time() while (i+bytesValidOneTime) < dataLength: #time.sleep(0.001) if not usbMethod.usbHandler.writeToUSB(frameData[i:(i+bytesValidOneTime)]+onesOneTime) : return False i += bytesValidOneTime frameNum += framesOneTime #print(frameNum) if i < dataLength: bytesAppendNum = bytesOneTime - (dataLength-i) bytesAppend = 255*(numpy.ones(bytesAppendNum).astype('uint8')) usbMethod.usbHandler.writeToUSB(frameData[i:] + bytes(bytesAppend)) ''' usbMethod.usbHandler.writeToUSB(bytes(frameData)) ''' timeEnd = time.time() except BaseException as e: outputInfoMethod.raiseError("Failed to deploy the chip.") outputInfoMethod.raiseError(str(e)) return False else: outputInfoMethod.raiseInfo("Deployed the chip successfully with %.3f S." % (timeEnd-timeBegin)) return True
def readFromConfigFile(self,filePath,netName): r''' 把配置文件中的原始帧数据处理成可直接发送给USB设备的格式,并以.npy的格式存储,以备下次配置使用; 原始帧数据是以‘0’、‘1’字符串表示的40bytes的字符串,需要处理成8bytes长度的bytes类型; filePath参数为原始帧数据文件的路径,netName参数是网络名称,也是要存储的帧数据文件的名称; 帧数据文件以txt的格式存储,以一行'begin'标志帧数据块的开始,然后每一行的前40个字节包含了配置信息; 帧数据块最后以一行'end'标志结束; 帧数据块之外,以及每一行帧数据前40个字节之后可以添加注释。 ''' try: print('Reading config file.') with open(filePath,'r') as frameDataFile: frameData = frameDataFile.read().splitlines() frameDataNum = len(frameData) outputInfoMethod.raiseInfo("Transfroming config file ...") isInFrameBulk = False tempData = numpy.zeros(frameDataNum-2).astype('uint64') for i,line in enumerate(frameData): if isInFrameBulk: if line == 'end': isInFrameBulk = False else: #******************************************************** tempData[i-1] = int(self.frame40bTo64b_rever(line[0:40]),2) else: if line == 'begin': isInFrameBulk = True tempData.dtype = 'uint8' bytesFrameData = bytes(tempData) except BaseException as e: outputInfoMethod.raiseError("Failed to transform config file.") outputInfoMethod.raiseError(str(e)) else: outputInfoMethod.raiseInfo("Transfromed successfully.") numpy.save('./configFiles/'+netName+'Config.npy',numpy.array(bytesFrameData)) finally: return True
def writeToUSB(self, data): r"""Write data to usbDevice. The data parameter should be a sequence like type convertible to the array type (see array module). """ if self.usbReady: try: #print('!!!usb write data!!!') self.deviceW.write(self.outPoint.bEndpointAddress, data) except BaseException as e: outputInfoMethod.raiseError("Failed to write to USB.") outputInfoMethod.raiseError(str(e)) return False else: return True else: outputInfoMethod.raiseError("USB device is not ready.") return False
def readFromUSB(self, bulksNum=1): r"""Read data from usbDevice. The bulksNum parameter should be the amount of bulks to be readed. One bulk is wMaxPacketSize(512) bytes. The method returns the data readed as an array. If read nothing, return None. """ if self.usbReady: try: #tempData = self.inPoint.read(self.inPoint.wMaxPacketSize*bulksNum) tempData = self.deviceR.read( self.inPoint.bEndpointAddress, self.inPoint.wMaxPacketSize * bulksNum) return tempData except BaseException as e: outputInfoMethod.raiseError("Failed to read from USB.") outputInfoMethod.raiseError(str(e)) return None else: outputInfoMethod.raiseError("USB device is not ready.") return None
def findUSB(self, VID, PID): r''' 连接指定VID/PID的USB设备。 ''' if not self.usbReady: #查找usb設備 #self.device = list(usb.core.find(find_all=True)) #windows self.device = list( usb.core.find(idVendor=0x04B4, idProduct=0x00F1, find_all=True)) #linux usbDeviceNum = len(self.device) #print(usbDeviceNum) if usbDeviceNum == 0: self.usbReady = False outputInfoMethod.raiseError("Can not find the USB device!") #一块FPGA(下行+上行) elif usbDeviceNum == 1: self.deviceW = usb.core.find() self.deviceW.set_configuration() cfgW = self.deviceW.get_active_configuration() intfW = cfgW[(0, 0)] self.outPoint = usb.util.find_descriptor(intfW, # match the first OUT endpoint custom_match = lambda e: \ usb.util.endpoint_direction(e.bEndpointAddress) == \ usb.util.ENDPOINT_OUT) self.inPoint = usb.util.find_descriptor(intfW, # match the first IN endpoint custom_match = lambda e: \ usb.util.endpoint_direction(e.bEndpointAddress) == \ usb.util.ENDPOINT_IN) self.usbReady = True outputInfoMethod.raiseInfo("USB device-out is ready.") #两块FPGA(一块上行、一块下行) elif usbDeviceNum == 2: self.deviceW = self.device[0] #w_下行 self.deviceR = self.device[1] #e_上行 self.deviceW.set_configuration() cfgW = self.deviceW.get_active_configuration() intfW = cfgW[(0, 0)] self.deviceR.set_configuration() cfgR = self.deviceR.get_active_configuration() intfR = cfgR[(0, 0)] self.outPoint = usb.util.find_descriptor(intfW, # match the first OUT endpoint custom_match = lambda e: \ usb.util.endpoint_direction(e.bEndpointAddress) == \ usb.util.ENDPOINT_OUT) self.inPoint = usb.util.find_descriptor(intfR, # match the first IN endpoint custom_match = lambda e: \ usb.util.endpoint_direction(e.bEndpointAddress) == \ usb.util.ENDPOINT_IN) self.usbReady = True outputInfoMethod.raiseInfo("USB devices are ready.") else: self.usbReady = False outputInfoMethod.raiseError( "!!!There are more than 2 usb devices!!!") return self.usbReady else: return self.usbReady