def __init__(self, iop_name, addr_base, addr_range, gpio_uix, mb_program, intr_pin=None, intr_ack_gpio=None): """Create a new _IOP object. Parameters ---------- iop_name : str The name of the IP corresponding to the I/O Processor. addr_base : int The base address for the MMIO. addr_range : int The address range for the MMIO. gpio_uix : int The user index of the GPIO, starting from 0. mb_program : str The Microblaze program loaded for the IOP. """ self.iop_name = iop_name self.mb_program = mb_program self.state = 'IDLE' self.gpio = GPIO(GPIO.get_gpio_pin(gpio_uix), "out") self.mmio = MMIO(addr_base, addr_range) if intr_pin and intr_ack_gpio: self.interrupt = _IOPInterruptEvent(intr_pin, intr_ack_gpio) self.program()
def __init__(self, bitfile, **kwargs): """Initializes a new sharedmemOverlay object. """ # The following lines do some path searching to enable a # PYNQ-Like API for Overlays. For example, without these # lines you cannot call sharedmemOverlay('sharedmem.bit') because # sharedmem.bit is not on the bitstream search path. The # following lines fix this for any non-PYNQ Overlay # # You can safely reuse, and ignore the following lines # # Get file path of the current class (i.e. /opt/python3.6/<...>/sharedmem.py) file_path = os.path.abspath(inspect.getfile(inspect.currentframe())) # Get directory path of the current class (i.e. /opt/python3.6/<...>/sharedmem/) dir_path = os.path.dirname(file_path) # Update the bitfile path to search in dir_path bitfile = os.path.join(dir_path, bitfile) # Upload the bitfile (and parse the colocated .tcl script) super().__init__(bitfile, **kwargs) # Manually define the GPIO pin that drives reset self.__resetPin = GPIO(GPIO.get_gpio_pin(0), "out") self.nreset() # Define a Register object at address 0x0 of the mmult address space # We will use this to set bits and start the core (see start()) # Do NOT write to __ap_ctrl unless __resetPin has been set to __NRESET_VALUE self.__ap_ctrl = Register(self.mmultCore.mmio.base_addr, 32) self.__a_offset = Register( self.mmultCore.mmio.base_addr + self.__MMULT_ADDR_A_DATA, 32) self.__bt_offset = Register( self.mmultCore.mmio.base_addr + self.__MMULT_ADDR_BT_DATA, 32) self.__c_offset = Register( self.mmultCore.mmio.base_addr + self.__MMULT_ADDR_C_DATA, 32) self.xlnk = Xlnk()
def __init__(self, description, gpio_name=None): """Return a new Audio object based on the hierarchy description. Parameters ---------- description : dict The hierarchical description of the hierarchy gpio_name : str The name of the audio path selection GPIO. If None then the GPIO pin in the hierarchy is used, otherwise the gpio_name is searched in the list of pins on the hierarchy and the PL.gpio_dict. """ super().__init__(description) if gpio_name is None: if len(self._gpio) == 0: raise RuntimeError('Could not find audio path select GPIO.') elif len(self._gpio) > 1: raise RuntimeError('Multiple possible audio path select GPIO.') pin_name = next(iter(self._gpio.keys())) self.gpio = getattr(self, pin_name) else: if gpio_name in self._gpio: self.gpio = getattr(self, gpio_name) elif gpio_name in PL.gpio_dict: pin = GPIO.get_gpio_pin(PL.gpio_dict[gpio_name]['index']) self.gpio = GPIO(pin, 'out') else: raise RuntimeError('Provided gpio_name not found.') self._ffi = cffi.FFI() self._libaudio = self._ffi.dlopen(LIB_SEARCH_PATH + "/sources/libaudio.so") self._ffi.cdef("""unsigned int Xil_Out32(unsigned int Addr, unsigned int Value);""") self._ffi.cdef("""unsigned int Xil_In32(unsigned int Addr);""") self._ffi.cdef("""void record(unsigned int BaseAddr, unsigned int * BufAddr, unsigned int Num_Samles_32Bit);""") self._ffi.cdef("""void playinit(unsigned int BaseAddr, unsigned int * BufAddr, unsigned int Num_Samles_32Bit);""") self._ffi.cdef("""void playend(unsigned int BaseAddr, unsigned int * BufAddr, unsigned int Num_Samles_32Bit);""") self._ffi.cdef("""void play(unsigned int BaseAddr, unsigned int * BufAddr, unsigned int Num_Samles_32Bit);""") self._ffi.cdef("""void recordinit(unsigned int BaseAddr, unsigned int * BufAddr, unsigned int Num_Samles_32Bit);""") char_adrp = self._ffi.from_buffer(self.mmio.mem) self._uint_adrpv = self._ffi.cast('unsigned int', char_adrp) self.buffer = numpy.zeros(0).astype(numpy.int) self.sample_rate = 0 self.sample_len = 0
def __init__(self, bitfile, **kwargs): """ Constructor (load the bit file) """ file_path = os.path.abspath(inspect.getfile(inspect.currentframe())) dir_path = os.path.dirname(file_path) bitfile = os.path.join(dir_path, bitfile) super().__init__(bitfile, **kwargs) # Manually define the GPIO pin that drives reset self.__resetPin = GPIO(GPIO.get_gpio_pin(0), "out") self.nreset() # For convenience self.__hough = self.image_processing.hough_accel_0 self.__dma = self.image_processing.axi_dma_0 # Define a Register object at address 0x00 of the overlay address space base_addr = self.__hough.mmio.base_addr self.__ap_ctrl = Register(base_addr, 32) self.__outrho_offset = Register(base_addr + self.__OUTRHO_ADDR, 32) self.__outtheta_offset = Register(base_addr + self.__OUTTHETA_ADDR, 32) self.__num_of_lines_offset = Register(base_addr + self.__NUM_OF_LINES_ADDR, 32) self.__segments_offset = Register(base_addr + self.__LINES_SEGMENTS_ADDR, 32) self.__num_of_segments_offset = Register(base_addr + self.__NUM_OF_SEGMENTS_ADDR, 32) # DMA transfer engine self.__xlnk = Xlnk() # Memory pre-allocation self.__cma_rho = self.__xlnk.cma_array(self.__LINES, np.single) self.__cma_theta = self.__xlnk.cma_array(self.__LINES, np.single) self.__cma_numoflines = self.__xlnk.cma_array(1, np.int32) self.__cma_segments = self.__xlnk.cma_array((self.__SEGMENTS, 4), np.int32) self.__cma_numofsegments = self.__xlnk.cma_array(1, np.int32) self.__cmabuf_dest = self.__xlnk.cma_array((self.__HEIGHT, self.__WIDTH, 3), np.uint8) # public self.frame = self.__xlnk.cma_array((self.__HEIGHT, self.__WIDTH, 3), np.uint8) # Write address of M_AXI to HLS core self.__outrho_offset[31:0] = self.__xlnk.cma_get_phy_addr(self.__cma_rho.pointer) self.__outtheta_offset[31:0] = self.__xlnk.cma_get_phy_addr(self.__cma_theta.pointer) self.__num_of_lines_offset[31:0] = self.__xlnk.cma_get_phy_addr(self.__cma_numoflines.pointer) self.__segments_offset[31:0] = self.__xlnk.cma_get_phy_addr(self.__cma_segments.pointer) self.__num_of_segments_offset[31:0] = self.__xlnk.cma_get_phy_addr(self.__cma_numofsegments.pointer) # Performs the computation for the first time to avoid bad behavior on the first call. # For a small number of segments, maybe not all segments will be detected if we don't # call the HoughLines function for the first time here. self.frame[:] = cv2.imread(dir_path+'/star.png') self.HoughLines(20,30,80,5,30)
def __init__(self, intr_pin, intr_ack_gpio): """Create a new _MBInterruptEvent object Parameters ---------- intr_pin : str Name of the interrupt pin for the Microblaze. intr_ack_gpio : int Number of the GPIO pin used to clear the interrupt. """ self.interrupt = Interrupt(intr_pin) self.gpio = GPIO(GPIO.get_gpio_pin(intr_ack_gpio), "out")
def bypass_stop(self): """Stop streaming input to output directly. Parameters ---------- None Returns ------- None """ gpio_idx = GPIO.get_gpio_pin(PL.gpio_dict["audio_path_sel/Din"][0]) gpio_pin = GPIO(gpio_idx, 'out') gpio_pin.write(0) del gpio_pin
def bypass_start(self): """Stream audio controller input directly to output. Parameters ---------- None Returns ------- None """ gpio_idx = GPIO.get_gpio_pin(PL.gpio_dict["audio_path_sel/Din"][0]) gpio_pin = GPIO(gpio_idx, 'out') gpio_pin.write(1) del gpio_pin
def clk(self,index): """Generate one rising edge clock cycle at the specified bit position. Parameters ---------- index : integer value indicating bit position The bit position ranges from 0 to 31 corresponding to Dout_00 to Dout_31. """ if index not in range (0, 32): raise ValueError("bit number must be between 0 and 31.") else: clkpin = GPIO(GPIO.get_gpio_pin(index), 'out') clkpin.write(1) clkpin.write(0)
def bit_write(self,index,value): """Write a value to the specified bit position. Parameters ---------- index : integer value indicating bit position The bit position ranges from 0 to 31 corresponding to Dout_00 to Dout_31. value : integer The value to be written, valid value being 0 or 1. """ if index not in range (0, 32): raise ValueError("bit number must be between 0 and 31.") else: bitwrite = GPIO(GPIO.get_gpio_pin(index), 'out') bitwrite.write(value)
def bit_read(self,index): """Read a value from the specified bit position. Parameters ---------- index : integer value indicating bit position The bit position ranges from 0 to 31 corresponding to Dout_00 to Dout_31. Returns ------- integer Read value. """ if index not in range (0, 32): raise ValueError("bit number must be between 0 and 31.") else: bitread = GPIO(GPIO.get_gpio_pin(index+32), 'in') result=bitread.read() return result
def __init__(self, bitfile, **kwargs): super().__init__(bitfile, **kwargs) if self.is_loaded(): self.iop_pmoda.mbtype = "Pmod" self.iop_pmodb.mbtype = "Pmod" self.iop_arduino.mbtype = "Arduino" self.iop_rpi.mbtype = "Rpi" self.PMODA = self.iop_pmoda.mb_info self.PMODB = self.iop_pmodb.mb_info self.ARDUINO = self.iop_arduino.mb_info self.RPI = self.iop_rpi.mb_info self.pin_select = GPIO( GPIO.get_gpio_pin(self.gpio_dict['pmoda_rp_pin_sel']['index']), "out") self.audio = self.audio_codec_ctrl_0 self.audio.configure() self.leds = self.leds_gpio.channel1 self.switches = self.switches_gpio.channel1 self.buttons = self.btns_gpio.channel1 self.leds.setlength(4) self.switches.setlength(2) self.buttons.setlength(4) self.leds.setdirection("out") self.switches.setdirection("in") self.buttons.setdirection("in") self.rgbleds = ([None] * 4) + [pynq.lib.RGBLED(i) for i in range(4, 6)] self.trace_rpi = TraceAnalyzer( self.trace_analyzer_pi.description['ip'], PYNQZ2_RPI_SPECIFICATION) self.trace_pmoda = TraceAnalyzer( self.trace_analyzer_pi.description['ip'], PYNQZ2_PMODA_SPECIFICATION) self.trace_pmodb = TraceAnalyzer( self.trace_analyzer_pmodb.description['ip'], PYNQZ2_PMODB_SPECIFICATION)
def __init__(self, ip='SEG_d_axi_pdm_1_S_AXI_reg', rst="audio_path_sel"): """Return a new Audio object. The PL is queried to get the base address and length. Parameters ---------- ip : str The name of the IP required for the audio driver. rst : str The name of the GPIO pins used as reset for the audio driver. """ if ip not in PL.ip_dict: raise LookupError("No such audio IP in the overlay.") if rst not in PL.gpio_dict: raise LookupError("No such reset pin in the overlay.") self.mmio = MMIO(PL.ip_dict[ip][0], PL.ip_dict[ip][1]) self.gpio = GPIO(GPIO.get_gpio_pin(PL.gpio_dict[rst][0]), 'out') self._ffi = cffi.FFI() self._libaudio = self._ffi.dlopen(LIB_SEARCH_PATH + "/libaudio.so") self._ffi.cdef("""unsigned int Xil_Out32(unsigned int Addr, unsigned int Value);""") self._ffi.cdef("""unsigned int Xil_In32(unsigned int Addr);""") self._ffi.cdef("""void _Pynq_record(unsigned int BaseAddr, unsigned int * BufAddr, unsigned int Num_Samles_32Bit);""") self._ffi.cdef("""void _Pynq_play(unsigned int BaseAddr, unsigned int * BufAddr, unsigned int Num_Samles_32Bit);""") char_adrp = self._ffi.from_buffer(self.mmio.mem) self._uint_adrpv = self._ffi.cast('unsigned int', char_adrp) self.buffer = numpy.zeros(0).astype(numpy.int) self.sample_rate = 0 self.sample_len = 0
def __init__(self, iop_name, addr_base, addr_range, gpio_uix, mb_program): """Create a new _IOP object. Parameters ---------- iop_name : str The name of the IP corresponding to the I/O Processor. addr_base : str The base address for the MMIO in hex format. addr_range : str The address range for the MMIO in hex format. gpio_uix : int The user index of the GPIO, starting from 0. mb_program : str The Microblaze program loaded for the IOP. """ self.iop_name = iop_name self.mb_program = iop_const.BIN_LOCATION + mb_program self.state = 'IDLE' self.gpio = GPIO(GPIO.get_gpio_pin(gpio_uix), "out") self.mmio = MMIO(int(addr_base, 16), int(addr_range,16)) self.program()
def __init__(self, odir, bitfile, **kwargs): """Initializes a new UcsdOverlay object. """ # The following lines do some path searching to enable a PYNQ-Like API # for Overlays. For example, without these lines you cannot call # myFabulousOverlay('myFabulousOverlay.bit') because # myFabulousOverlay.bit is not on the bitstream search path. The # following lines fix this for any non-PYNQ Overlay # # You can safely reuse, and ignore the following lines # # Get file path of the current class (i.e. /opt/python3.6/<...>/sharedmem.py) file_path = os.path.abspath(inspect.getfile(inspect.currentframe())) # Get directory path of the current class (i.e. /opt/python3.6/<...>/sharedmem/) dir_path = os.path.dirname(file_path) # Update the bitfile path to search in dir_path bitfile = os.path.join(dir_path, odir, bitfile) # Upload the bitfile (and parse the colocated .tcl script) super().__init__(bitfile, **kwargs) # Manually define the GPIO pin that drives reset self.__resetPin = GPIO(GPIO.get_gpio_pin(0), "out") self.nreset() self._xlnk = Xlnk()
def __init__(self, iop_name, addr_base, addr_range, gpio_uix, mb_program): """Create a new _IOP object. Parameters ---------- iop_name : str The name of the IP corresponding to the I/O Processor. addr_base : int The base address for the MMIO. addr_range : int The address range for the MMIO. gpio_uix : int The user index of the GPIO, starting from 0. mb_program : str The Microblaze program loaded for the IOP. """ self.iop_name = iop_name self.mb_program = iop_const.BIN_LOCATION + mb_program self.state = 'IDLE' self.gpio = GPIO(GPIO.get_gpio_pin(gpio_uix), "out") self.mmio = MMIO(addr_base, addr_range) self.program()
testBinFileList = sys.argv[2:] coredesign = Overlay(vivadoBitFile) for testBinFile in testBinFileList: print("---------TEST ON ", testBinFile, "---------") ## STEP1 write test bin file to BRAM with open(testBinFile, 'rb') as f: size = os.path.getsize(testBinFile) print("Instruction Number: ", size/4) for i in range (0, int(size/4)*4, 4): coredesign.axi_bram_ctrl_1.write(i, struct.unpack('I', f.read(4))[0]) ## STEP2 reset and run CPU reset = GPIO(GPIO.get_gpio_pin(1), 'out') coredesign.axi_bram_ctrl_0.write(0x0, 0x0) reset.write(1) time.sleep(1) reset.write(0) hitGoodTrap = GPIO(GPIO.get_gpio_pin(0), 'in') timeOut = True for i in range(maxRunTime): if hitGoodTrap.read()==1: timeOut = False break time.sleep(1) print("Have waited %ds for fpga to finish" % i) ## STEP3 summary result
def __init__(self, r, g, b): self.r = GPIO(GPIO.get_gpio_pin(r), 'out') self.g = GPIO(GPIO.get_gpio_pin(g), 'out') self.b = GPIO(GPIO.get_gpio_pin(b), 'out')
def __init__(self, mb_info, mb_program, force=False): """Create a new Microblaze object. It looks for active instances on the same Microblaze, and prevents users from silently reloading the Microblaze program. Users are notified with an exception if a program is already running on the selected Microblaze, to prevent unwanted behavior. Two cases: 1. No previous Microblaze program loaded in the system, or users want to request another instance using the same program. No exception will be raised in this case. 2. There is a previous Microblaze program loaded in the system. Users want to request another instance with a different program. An exception will be raised. Note ---- When a Microblaze program is already loaded in the system, and users want to instantiate another object using a different Microblaze program, users are in danger of losing existing objects. Parameters ---------- mb_info : dict A dictionary storing Microblaze information, such as the IP name and the reset name. mb_program : str The Microblaze program loaded for the processor. Raises ------ RuntimeError When another Microblaze program is already loaded. Examples -------- The `mb_info` is a dictionary storing Microblaze information: >>> mb_info = {'ip_name': 'mb_bram_ctrl_1', 'rst_name': 'mb_reset_1', 'intr_pin_name': 'iop1/dff_en_reset_0/q', 'intr_ack_name': 'mb_1_intr_ack'} """ ip_dict = PL.ip_dict gpio_dict = PL.gpio_dict intr_dict = PL.interrupt_pins # Check program path if not os.path.isfile(mb_program): raise ValueError('{} does not exist.'.format(mb_program)) # Get IP information ip_name = mb_info['ip_name'] if ip_name not in ip_dict.keys(): raise ValueError("No such IP {}.".format(ip_name)) addr_base = ip_dict[ip_name]['phys_addr'] addr_range = ip_dict[ip_name]['addr_range'] ip_state = ip_dict[ip_name]['state'] # Get reset information rst_name = mb_info['rst_name'] if rst_name not in gpio_dict.keys(): raise ValueError("No such reset pin {}.".format(rst_name)) gpio_uix = gpio_dict[rst_name]['index'] # Get interrupt pin information if 'intr_pin_name' in mb_info: intr_pin_name = mb_info['intr_pin_name'] if intr_pin_name not in intr_dict.keys(): raise ValueError( "No such interrupt pin {}.".format(intr_pin_name)) else: intr_pin_name = None # Get interrupt ACK information if 'intr_ack_name' in mb_info: intr_ack_name = mb_info['intr_ack_name'] if intr_ack_name not in gpio_dict.keys(): raise ValueError( "No such interrupt ACK {}.".format(intr_ack_name)) intr_ack_gpio = gpio_dict[intr_ack_name]['index'] else: intr_ack_gpio = None # Set basic attributes self.ip_name = ip_name self.rst_name = rst_name self.mb_program = mb_program self.state = 'IDLE' self.reset_pin = GPIO(GPIO.get_gpio_pin(gpio_uix), "out") self.mmio = MMIO(addr_base, addr_range) # Check to see if Microblaze in user if (ip_state is not None) and (ip_state != mb_program): if force: self.reset() else: raise RuntimeError( 'Another program {} already running.'.format(ip_state)) # Set optional attributes if (intr_pin_name is not None) and (intr_ack_gpio is not None): self.interrupt = MBInterruptEvent(intr_pin_name, intr_ack_gpio) else: self.interrupt = None # Reset, program, and run self.program()