def re(a, b): """ Returns True if `a` matches the regular expression given by `b`. Unfortunately, the call signature of re.match(pat, name) is different from the other binary operators, which are usually `a lt b ==> lt(a, b) ==> a < b`, Note that `fnmatchcase(name, pat)` follows the "correct" order. """ return _match(b, a)
def _pull_consts_from_header(verbose=True): consts = [] lineno = 0 with open(_HEADER_PATH,'r') as hfile: hfile.seek(0) for hline in hfile: lineno += 1 try: groups = _match(_REGEX_HEADER_CONST,hline).groups() except AttributeError: continue try: g0, g1 = groups #custom excluded consts if _on_exclude_list(g0): continue val = str(hex(int(g1,16)) if 'x' in g1 else int(g1)) consts.append((g0,val)) if verbose: print(' ',_HEADER_NAME + ':' + str(lineno)+ ': '+ g0, val) except ValueError: raise TOSDB_SetupError("invalid header const value", str(g0)) except Exception as e: raise TOSDB_SetupError("couldn't extract const from regex match", e.args) return consts
def _pull_consts_from_header(verbose=True): consts = {} lineno = 0 with open(_HEADER_PATH, 'r') as hfile: hfile.seek(0) for hline in hfile: lineno += 1 try: groups = _match(_REGEX_HEADER_CONST, hline).groups() except AttributeError: continue try: g0, g1 = groups val = str(hex(int(g1, 16)) if 'x' in g1 else int(g1)) consts[g0] = val if verbose: print('', _HEADER_PATH + ':' + str(lineno) + ': ' + groups[0], val) except ValueError: raise TOSDB_SetupError("invalid header const value", str(g0)) except Exception as e: raise TOSDB_SetupError( "couldn't extract const from regex match", e.args) return consts
def _str_clean(*strings): fin = [] for s in strings: tmp = '' if not _match(_REGEX_LETTER, s): s = 'X_' + s for sub in _split(_REGEX_NON_ALNUM, s): tmp += sub fin.append(tmp) return fin
def decode(self, table): if _match('[01]{64}', table) is None: raise NameError('Bad Table') table_number_dict = self._table_number_dict(table) table_number = 0 for j in range(6): table_number += table_number_dict[j] % 2 * 2**(5 - j) return table_number
def encode(self, table, number): if _match('[01]{' + str(self.POW_DIMESNION) + '}', table) is None: raise NameError('Bad Table') number = int(number) if number < 0 or number > self.POW_DIMESNION: raise NameError('Bad Number') index_number = self._table_number(table) ^ number if table[index_number] == '0': return table[:index_number] + '1' + table[index_number + 1:] else: return table[:index_number] + '0' + table[index_number + 1:]
def encode(self, table, number): if _match('[01]{64}', table) is None: raise NameError('Bad Table') number = int(number) if number < 0 or number > 63: raise NameError('Bad Number') table_number_dict = self._table_number_dict(table) number_bin = self._to_bin(number) index_number = 0 for j in range(6): if int(number_bin[j]) != table_number_dict[j] % 2: index_number += 2**(5 - j) if table[index_number] == '0': return table[:index_number] + '1' + table[index_number + 1:] else: return table[:index_number] + '0' + table[index_number + 1:]
def _reset_fpga(self): """ Reset FPGA including FPGA image. """ list_apps = _run([self._xmutil, 'listapps'], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if list_apps.returncode or search(r'error', list_apps.stdout): raise RuntimeError(list_apps.stdout) image_name = '' for line in list_apps.stdout.splitlines(): m = _match(r'\s*(.+?)\s+', line) if m: image_name = m.group(1) if not image_name: print('No loaded bitstream to reset') return self._program_fpga(image_name + ".som")
def _build_error_lookup(consts): errcs = {} for (k,v) in consts: if _match("TOSDB_ERROR_.+", k): errcs[v] = k.lstrip('TOSDB_') return errcs
class FpgaDriver(_FpgaDriverBase): """ Generates functions to use XRT with accelize_drm.DrmManager. Args: fpga_slot_id (int): FPGA slot ID. fpga_image (str): Path to ".xclbin" binary to use to program FPGA. drm_ctrl_base_addr (int): DRM Controller base address. log_dir (path-like object): directory where XRT will output log file. """ _name = _match(r'_(.+)\.py', _basename(__file__)).group(1) _reglock = _Lock() @staticmethod def _get_xrt_lib(): """ Detect XRT installation path: """ for prefix in (_environ.get("XILINX_XRT", "/opt/xilinx/xrt"), '/usr', '/usr/local'): if _isfile(_join(prefix, 'bin', 'xbutil')): return prefix raise RuntimeError('Unable to find Xilinx XRT') @staticmethod def _get_driver(): """ Get FPGA driver Returns: ctypes.CDLL: FPGA driver. """ xrt_path = FpgaDriver._get_xrt_lib() if _isfile(_join(xrt_path, 'lib', 'libxrt_aws.so')): print('Loading XRT API library for AWS targets') fpga_library = _cdll.LoadLibrary( _join(xrt_path, 'lib', 'libxrt_aws.so')) elif _isfile(_join(xrt_path, 'lib', 'libxrt_core.so')): print('Loading XRT API library for Xilinx targets') fpga_library = _cdll.LoadLibrary( _join(xrt_path, 'lib', 'libxrt_core.so')) else: raise RuntimeError('Unable to find Xilinx XRT Library') return fpga_library @staticmethod def _get_xbutil(): xrt_path = FpgaDriver._get_xrt_lib() _xbutil_path = _join(xrt_path, 'bin', 'awssak') if not _isfile(_xbutil_path): _xbutil_path = _join(xrt_path, 'bin', 'xbutil') if not _isfile(_xbutil_path): raise RuntimeError('Unable to find Xilinx XRT Board Utility') return _xbutil_path @property def _xbutil(self): return self._get_xbutil() def _get_lock(self): """ Get a lock on the FPGA driver """ def create_lock(): return XrtLock(self) return create_lock def _clear_fpga(self): """ Clear FPGA """ clear_fpga = _run( ['fpga-clear-local-image', '-S', str(self._fpga_slot_id)], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if clear_fpga.returncode: raise RuntimeError(clear_fpga.stdout) print('FPGA cleared') def _program_fpga(self, fpga_image): """ Program the FPGA with the specified image. Args: fpga_image (str): FPGA image. """ # Vitis does not reprogram a FPGA that has already the bitstream. # So to force it we write another bitstream first. clear_image = _join(SCRIPT_DIR, 'clear.awsxclbin') load_image = _run([ self._xbutil, 'program', '-d', str(self._fpga_slot_id), '-p', clear_image ], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if load_image.returncode: raise RuntimeError(load_image.stdout) print('Cleared AWS XRT slot #%d' % self._fpga_slot_id) # Now load the real image fpga_image = _realpath(_fsdecode(fpga_image)) load_image = _run([ self._xbutil, 'program', '-d', str(self._fpga_slot_id), '-p', fpga_image ], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if load_image.returncode: raise RuntimeError(load_image.stdout) print('Programmed AWS XRT slot #%d with FPGA image %s' % (self._fpga_slot_id, fpga_image)) def _reset_fpga(self): """ Reset FPGA including FPGA image. """ reset_image = _run( [self._xbutil, 'reset', '-d', str(self._fpga_slot_id)], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if reset_image.returncode: raise RuntimeError(reset_image.stdout) def _init_fpga(self): """ Initialize FPGA handle with driver library. """ # Find all devices xcl_probe = self._fpga_library.xclProbe xcl_probe.restype = _c_uint # Devices count if xcl_probe() < 1: raise RuntimeError("xclProbe does not found devices") # Open device xcl_open = self._fpga_library.xclOpen xcl_open.restype = _POINTER(_c_void_p) # Device handle xcl_open.argtypes = ( _c_uint, # deviceIndex _c_char_p, # logFileName _c_int, # level ) log_file = _join(self._log_dir, 'slot_%d_xrt.log' % self._fpga_slot_id) device_handle = xcl_open( self._fpga_slot_id, log_file.encode(), 3 # XCL_ERROR ) if not device_handle: raise RuntimeError("xclOpen failed to open device") self._fpga_handle = device_handle def _get_read_register_callback(self): """ Read register callback. Returns: function: Read register callback """ xcl_read = self._fpga_library.xclRead xcl_read.restype = _c_size_t # read size or error code xcl_read.argtypes = ( _c_void_p, # handle _c_int, # space _c_uint64, # offset _c_void_p, # hostBuf _c_size_t # size ) self._fpga_read_register = xcl_read def read_register(register_offset, returned_data, driver=self): """ Read register. Args: register_offset (int): Offset returned_data (int pointer): Return data. driver (accelize_drm.fpga_drivers._aws_xrt.FpgaDriver): Keep a reference to driver. """ with driver._fpga_read_register_lock(): size_or_error = driver._fpga_read_register( driver._fpga_handle, 2, # XCL_ADDR_KERNEL_CTRL driver._drm_ctrl_base_addr + register_offset, returned_data, 4 # 4 bytes ) # Return 0 return code if read size else return error code return size_or_error if size_or_error != 4 else 0 return read_register def _get_write_register_callback(self): """ Write register callback. Returns: function: Write register callback """ xcl_write = self._fpga_library.xclWrite xcl_write.restype = _c_size_t # written size or error code xcl_write.argtypes = ( _c_void_p, # handle _c_int, # space _c_uint64, # offset _c_char_p, # hostBuf _c_size_t # size ) self._fpga_write_register = xcl_write def write_register(register_offset, data_to_write, driver=self): """ Write register. Args: register_offset (int): Offset data_to_write (int): Data to write. driver (accelize_drm.fpga_drivers._aws_xrt.FpgaDriver): Keep a reference to driver. """ with driver._fpga_write_register_lock(): size_or_error = driver._fpga_write_register( driver._fpga_handle, 2, # XCL_ADDR_KERNEL_CTRL driver._drm_ctrl_base_addr + register_offset, data_to_write.to_bytes(4, byteorder="little"), 4 # 4 bytes ) # Return 0 return code if written size else return error code return size_or_error if size_or_error != 4 else 0 return write_register
class FpgaDriver(_FpgaDriverBase): """ Generates functions to use AWS FPGA F1 with accelize_drm.DrmManager. Args: fpga_slot_id (int): FPGA slot ID. fpga_image (str): AGFI or AFI to use to program FPGA. drm_ctrl_base_addr (int): DRM Controller base address. log_dir (path-like object): Unused with this driver. """ _name = _match(r'_(.+)\.py', _basename(__file__)).group(1) @staticmethod def _get_driver(): """ Get FPGA driver Returns: ctypes.CDLL: FPGA driver. """ # Load AWS FPGA library fpga_library = _cdll.LoadLibrary("libfpga_mgmt.so") fpga_pci_init = fpga_library.fpga_pci_init fpga_pci_init.restype = _c_int # return code if fpga_pci_init(): raise RuntimeError('Unable to initialize the "fpga_pci" library') return fpga_library @staticmethod def _get_lock(): """ Get a lock on the FPGA driver """ return _Lock def _clear_fpga(self): """ Clear FPGA """ clear_fpga = _run( ['fpga-clear-local-image', '-S', str(self._fpga_slot_id)], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if clear_fpga.returncode: raise RuntimeError(clear_fpga.stdout) def _program_fpga(self, fpga_image): """ Program the FPGA with the specified image. Args: fpga_image (str): FPGA image. """ retries = 3 while True: load_image = _run([ 'fpga-load-local-image', '-S', str(self._fpga_slot_id), '-I', fpga_image ], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if load_image.returncode == 0: break elif ("-110" in load_image.stdout) and (retries != 0): retries -= 1 print('Retry programming') else: raise RuntimeError(load_image.stdout) def _reset_fpga(self): """ Reset FPGA including FPGA image. """ reset_image = _run( ['fpga-clear-local-image', '-S', str(self._fpga_slot_id), '-H'], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if reset_image.returncode: raise RuntimeError(reset_image.stdout) def _init_fpga(self): """ Initialize FPGA handle with driver library. """ # Set FPGA handle to default value self._fpga_handle = _c_int(-1) # PCI_BAR_HANDLE_INIT # Attach FPGA fpga_pci_attach = self._fpga_library.fpga_pci_attach fpga_pci_attach.restype = _c_int # return code fpga_pci_attach.argtypes = ( _c_int, # slot_id _c_int, # pf_id _c_int, # bar_id _c_uint32, # flags _POINTER(_c_int) # handle ) if fpga_pci_attach( self._fpga_slot_id, 0, # FPGA_APP_PF 0, # APP_PF_BAR0 0, _byref(self._fpga_handle)): raise RuntimeError("Unable to attach to the AFI on slot ID %s" % self._fpga_slot_id) def _get_read_register_callback(self): """ Read register callback. Returns: function: Read register callback """ fpga_pci_peek = self._fpga_library.fpga_pci_peek fpga_pci_peek.restype = _c_int # return code fpga_pci_peek.argtypes = ( _c_int, # handle _c_uint64, # offset _POINTER(_c_uint32) # value ) self._fpga_read_register = fpga_pci_peek def read_register(register_offset, returned_data, driver=self): """ Read register. Args: register_offset (int): Offset returned_data (int pointer): Return data. driver (accelize_drm.fpga_drivers._aws_f1.FpgaDriver): Keep a reference to driver. """ with driver._fpga_read_register_lock(): return driver._fpga_read_register( driver._fpga_handle, driver._drm_ctrl_base_addr + register_offset, returned_data) return read_register def _get_write_register_callback(self): """ Write register callback. Returns: function: Write register callback """ fpga_pci_poke = self._fpga_library.fpga_pci_poke fpga_pci_poke.restype = _c_int # return code fpga_pci_poke.argtypes = ( _c_int, # handle _c_uint64, # offset _c_uint32 # value ) self._fpga_write_register = fpga_pci_poke def write_register(register_offset, data_to_write, driver=self): """ Write register. Args: register_offset (int): Offset data_to_write (int): Data to write. driver (accelize_drm.fpga_drivers._aws_f1.FpgaDriver): Keep a reference to driver. """ with driver._fpga_write_register_lock(): return driver._fpga_write_register( driver._fpga_handle, driver._drm_ctrl_base_addr + register_offset, data_to_write) return write_register
def ire(a, b): """ Returns True if `a.lower()` matches the regular expression given by `b.lower()`.""" a, b = to_lower(a), to_lower(b) return _match(b, a)
def decode(self, table): if _match('[01]{' + str(self.POW_DIMESNION) + '}', table) is None: raise NameError('Bad Table') return self._table_number(table)
def _on_exclude_list(h): for exc in HEADER_PREFIX_EXCLUDES: if _match(exc, h): return True return False
def ire(a, b): """ Returns True if `a.lower()` matches the regular expression given by `b.lower()`.""" return _match(b.lower(), a.lower())
def _build_error_lookup(consts): errcs = {} for (k, v) in consts: if _match("TOSDB_ERROR_.+", k): errcs[v] = k.lstrip('TOSDB_') return errcs
class FpgaDriver(_FpgaDriverBase): """ Generates functions to use XRT with accelize_drm.DrmManager. Args: fpga_slot_id (int): FPGA slot ID. fpga_image (str): Path to ".xclbin" binary to use to program FPGA. drm_ctrl_base_addr (int): DRM Controller base address. log_dir (path-like object): directory where XRT will output log file. """ _name = _match(r'_(.+)\.py', _basename(__file__)).group(1) _reglock = _Lock() @staticmethod def _get_xrt_lib(): """ Detect XRT installation path: """ for prefix in (_environ.get("XILINX_XRT", "/opt/xilinx/xrt"), '/usr', '/usr/local'): if _isfile(_join(prefix, 'bin', 'xbutil')): return prefix raise RuntimeError('Unable to find Xilinx XRT') @staticmethod def _get_driver(): """ Get FPGA driver Returns: ctypes.CDLL: FPGA driver. """ xrt_path = FpgaDriver._get_xrt_lib() if _isfile(_join(xrt_path, 'lib', 'libxrt_aws.so')): print('Loading XRT API library for AWS targets') fpga_library = _cdll.LoadLibrary( _join(xrt_path, 'lib', 'libxrt_aws.so')) elif _isfile(_join(xrt_path, 'lib', 'libxrt_core.so')): print('Loading XRT API library for Xilinx targets') fpga_library = _cdll.LoadLibrary( _join(xrt_path, 'lib', 'libxrt_core.so')) else: raise RuntimeError('Unable to find Xilinx XRT Library') return fpga_library @staticmethod def _get_xbutil(): xrt_path = FpgaDriver._get_xrt_lib() _xbutil_path = _join(xrt_path, 'bin', 'awssak') if not _isfile(_xbutil_path): _xbutil_path = _join(xrt_path, 'bin', 'xbutil') if not _isfile(_xbutil_path): raise RuntimeError('Unable to find Xilinx XRT Board Utility') return _xbutil_path @property def _xbutil(self): return self._get_xbutil() def _get_lock(self): """ Get a lock on the FPGA driver """ return _Lock def _clear_fpga(self): """ Clear FPGA """ ''' clear_fpga = _run( ['fpga-clear-local-image', '-S', str(self._fpga_slot_id)], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if clear_fpga.returncode: raise RuntimeError(clear_fpga.stdout) ''' print('FPGA cleared') def _program_fpga(self, fpga_image): """ Program the FPGA with the specified image. Args: fpga_image (str): FPGA image. """ ''' # Vitis does not reprogram a FPGA that has already the bitstream. # So to force it we write another bitstream first. clear_image = _join(SCRIPT_DIR, 'clear.awsxclbin') load_image = _run( [self._xbutil, 'program', '-d', str(self._fpga_slot_id), '-p', clear_image], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if load_image.returncode: raise RuntimeError(load_image.stdout) # Now load the real image fpga_image = _realpath(_fsdecode(fpga_image)) load_image = _run( [self._xbutil, 'program', '-d', str(self._fpga_slot_id), '-p', fpga_image], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if load_image.returncode: raise RuntimeError(load_image.stdout) ''' # Init global specific variables self.shm_pages = list() self.ctrl_sw_exec = None # Start Controller SW fpga_image = '' if not _isfile(fpga_image): pass # raise RuntimeError('Controller SW executable path is invald: ', fpga_image) # self.ctrl_sw_exec = Popen([self.ctrl_sw_exec, self._fpga_image], shell=False, stdout=_PIPE, stderr=_STDOUT) print('Programmed AWS SoM with', self.ctrl_sw_exec) def _reset_fpga(self): """ Reset FPGA including FPGA image. """ ''' reset_image = _run( [self._xbutil, 'reset', '-d', str(self._fpga_slot_id)], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if reset_image.returncode: raise RuntimeError(reset_image.stdout) ''' pass def _init_fpga(self): """ Initialize FPGA handle with driver library. """ ''' # Find all devices xcl_probe = self._fpga_library.xclProbe xcl_probe.restype = _c_uint # Devices count if xcl_probe() < 1: raise RuntimeError("xclProbe does not found devices") # Open device xcl_open = self._fpga_library.xclOpen xcl_open.restype = _POINTER(_c_void_p) # Device handle xcl_open.argtypes = ( _c_uint, # deviceIndex _c_char_p, # logFileName _c_int, # level ) log_file = _join(self._log_dir, 'slot_%d_xrt.log' % self._fpga_slot_id) device_handle = xcl_open( self._fpga_slot_id, log_file.encode(), 3 # XCL_ERROR ) if not device_handle: raise RuntimeError("xclOpen failed to open device") self._fpga_handle = device_handle ''' # Connect to Shared Memory self.shm_pages = list() for i in range(1, 7): key = ipc.ftok(SHM_PATH, i) shm = ipc.SharedMemory(key, 0, 0) shm.attach(0, 0) self.shm_pages.append(shm) print('Connected to Shared Memory') def _uninit_fpga(self): import signal # Release access to shared memory for shm in self.shm_pages: shm.detach() print('Disconnected from Shared Memory') if self.ctrl_sw_exec: self.ctrl_sw_exec.send_signal(signal.SIGINT) self.ctrl_sw_exec.wait() print('Terminate DRM') def int_to_bytes(x: int) -> bytes: return x.to_bytes((x.bit_length() + 7) // 8, 'little', signed=False) def int_from_bytes(xbytes: bytes) -> int: return int.from_bytes(xbytes, 'big') def _get_read_register_callback(self): """ Read register callback. Returns: function: Read register callback """ ''' xcl_read = self._fpga_library.xclRead xcl_read.restype = _c_size_t # read size or error code xcl_read.argtypes = ( _c_void_p, # handle _c_int, # space _c_uint64, # offset _c_void_p, # hostBuf _c_size_t # size ) self._fpga_read_register = xcl_read ''' def read_register(register_offset, returned_data, driver=self): """ Read register. Args: register_offset (int): Offset returned_data (int pointer): Return data. driver (accelize_drm.fpga_drivers._aws_xrt.FpgaDriver): Keep a reference to driver. """ with driver._fpga_read_register_lock(): if register_offset >= 0x10000: ''' size_or_error = driver._fpga_read_register( driver._fpga_handle, 2, # XCL_ADDR_KERNEL_CTRL driver._drm_ctrl_base_addr + register_offset, returned_data, 4 # 4 bytes ) ret = size_or_error if size_or_error != 4 else 0 ''' return 0 raise RuntimeError( 'Reading from Activator is not supported in Emu-HW') else: page_index = bytes_to_int(driver.shm_pages[0].read(4, 0)) if register_offset == 0: reg_value = page_index else: shm = driver.shm_pages[page_index] reg_value = bytes_to_int(shm.read(4, register_offset)) # print('Read @%08X: 0x%08X' % (register_offset, reg_value)) returned_data.contents.value = reg_value ret = 0 return ret return read_register def _get_write_register_callback(self): """ Write register callback. Returns: function: Write register callback """ xcl_write = self._fpga_library.xclWrite xcl_write.restype = _c_size_t # written size or error code xcl_write.argtypes = ( _c_void_p, # handle _c_int, # space _c_uint64, # offset _c_char_p, # hostBuf _c_size_t # size ) self._fpga_write_register = xcl_write def write_register(register_offset, data_to_write, driver=self): """ Write register. Args: register_offset (int): Offset data_to_write (int): Data to write. driver (accelize_drm.fpga_drivers._aws_xrt.FpgaDriver): Keep a reference to driver. """ with driver._fpga_read_register_lock(): if register_offset >= 0x10000: ''' size_or_error = driver._fpga_write_register( driver._fpga_handle, 2, # XCL_ADDR_KERNEL_CTRL driver._drm_ctrl_base_addr + register_offset, data_to_write.to_bytes(4, byteorder="little"), 4 # 4 bytes ) ret = size_or_error if size_or_error != 4 else 0 ''' return 0 raise RuntimeError( 'Writing to Activator is not supported in Emu-HW') else: page_index = bytes_to_int(driver.shm_pages[0].read(4, 0)) if register_offset == 0: driver.shm_pages[0].write(int_to_bytes(data_to_write), 0) else: shm = driver.shm_pages[page_index] shm.write(int_to_bytes(data_to_write), register_offset) # print('Wrote @%08X: 0x%08X' % (register_offset, data_to_write)) ret = 0 # Return 0 return code if written size else return error code return ret return write_register
def _on_exclude_list(h): for exc in HEADER_PREFIX_EXCLUDES: if _match(exc,h): return True return False
class FpgaDriver(_FpgaDriverBase): """ Generates functions to use XRT with accelize_drm.DrmManager. Args: fpga_slot_id (int): FPGA slot ID. fpga_image (str): Path to ".xclbin" binary to use to program FPGA. drm_ctrl_base_addr (int): DRM Controller base address. log_dir (path-like object): directory where XRT will output log file. """ _name = _match(r'_(.+)\.py', _basename(__file__)).group(1) _reglock = _Lock() @staticmethod def _get_xrt_lib(): """ Detect XRT installation path: """ prefix = '/usr' if _isfile(_join(prefix, 'bin', 'xbutil')): return prefix raise RuntimeError('Unable to find Xilinx XRT') @staticmethod def _get_driver(): """ Get FPGA driver Returns: ctypes.CDLL: FPGA driver. """ xrt_path = FpgaDriver._get_xrt_lib() if _isfile(_join(xrt_path, 'lib', 'libxrt_core.so')): print('Loading XRT API library for SoM targets') fpga_library = _cdll.LoadLibrary( _join(xrt_path, 'lib', 'libxrt_core.so')) else: raise RuntimeError('Unable to find Xilinx XRT Library') return fpga_library @staticmethod def _get_xbutil(): xrt_path = FpgaDriver._get_xrt_lib() _xbutil_path = _join(xrt_path, 'bin', 'xmutil') if not _isfile(_xbutil_path): raise RuntimeError('Unable to find Xilinx XRT Board Utility') return _xbutil_path @property def _xmutil(self): return self._get_xbutil() def _get_lock(self): """ Get a lock on the FPGA driver """ def create_lock(): return XrtLock(self) return create_lock def _clear_fpga(self): """ Clear FPGA """ clear_fpga = _run([self._xmutil, 'unloadapp'], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if clear_fpga.returncode: raise RuntimeError(clear_fpga.stdout) print('FPGA cleared') def _program_fpga(self, fpga_image): """ Program the FPGA with the specified image. Args: fpga_image (str): FPGA image. """ # Must clear the FPGA first #self._clear_fpga() # Now load the bitstream image_name = splitext(fpga_image)[0] load_image = _run([self._xmutil, 'loadapp', image_name], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if load_image.returncode or search(r'error', load_image.stdout): raise RuntimeError(load_image.stdout) print('Programmed SoM XRT with FPGA image %s' % fpga_image) def _reset_fpga(self): """ Reset FPGA including FPGA image. """ list_apps = _run([self._xmutil, 'listapps'], stderr=_STDOUT, stdout=_PIPE, universal_newlines=True, check=False) if list_apps.returncode or search(r'error', list_apps.stdout): raise RuntimeError(list_apps.stdout) image_name = '' for line in list_apps.stdout.splitlines(): m = _match(r'\s*(.+?)\s+', line) if m: image_name = m.group(1) if not image_name: print('No loaded bitstream to reset') return self._program_fpga(image_name + ".som") def _init_fpga(self): """ Initialize FPGA handle with XRT and OpenCL libraries. """ image_name = splitext(self._fpga_image)[0] dev = cl.get_platforms()[0].get_devices() binary = open( _join('/lib', 'firmware', 'xilinx', image_name, image_name + '.xclbin'), 'rb').read() ctx = cl.Context(dev_type=cl.device_type.ALL) prg = cl.Program(ctx, dev, [binary]) prg.build() # Find all devices xcl_probe = self._fpga_library.xclProbe xcl_probe.restype = _c_uint # Devices count if xcl_probe() < 1: raise RuntimeError("xclProbe does not found devices") # Open device xcl_open = self._fpga_library.xclOpen xcl_open.restype = _POINTER(_c_void_p) # Device handle xcl_open.argtypes = ( _c_uint, # deviceIndex _c_char_p, # logFileName _c_int, # level ) log_file = _join(self._log_dir, 'slot_%d_xrt.log' % self._fpga_slot_id) device_handle = xcl_open( self._fpga_slot_id, log_file.encode(), 3 # XCL_ERROR ) if not device_handle: raise RuntimeError("xclOpen failed to open device") self._fpga_handle = device_handle def _uninit_fpga(self): pass def _get_read_register_callback(self): """ Read register callback. Returns: function: Read register callback """ xcl_read = self._fpga_library.xclRead xcl_read.restype = _c_size_t # read size or error code xcl_read.argtypes = ( _c_void_p, # handle _c_int, # space _c_uint64, # offset _c_void_p, # hostBuf _c_size_t # size ) self._fpga_read_register = xcl_read def read_register(register_offset, returned_data, driver=self): """ Read register. Args: register_offset (int): Offset returned_data (int pointer): Return data. driver (accelize_drm.fpga_drivers._aws_xrt.FpgaDriver): Keep a reference to driver. """ with driver._fpga_read_register_lock(): size_or_error = driver._fpga_read_register( driver._fpga_handle, 2, # XCL_ADDR_KERNEL_CTRL driver._drm_ctrl_base_addr + register_offset, returned_data, 4 # 4 bytes ) # Return 0 return code if read size else return error code return size_or_error if size_or_error != 4 else 0 return read_register def _get_write_register_callback(self): """ Write register callback. Returns: function: Write register callback """ xcl_write = self._fpga_library.xclWrite xcl_write.restype = _c_size_t # written size or error code xcl_write.argtypes = ( _c_void_p, # handle _c_int, # space _c_uint64, # offset _c_char_p, # hostBuf _c_size_t # size ) self._fpga_write_register = xcl_write def write_register(register_offset, data_to_write, driver=self): """ Write register. Args: register_offset (int): Offset data_to_write (int): Data to write. driver (accelize_drm.fpga_drivers._aws_xrt.FpgaDriver): Keep a reference to driver. """ with driver._fpga_write_register_lock(): size_or_error = driver._fpga_write_register( driver._fpga_handle, 2, # XCL_ADDR_KERNEL_CTRL driver._drm_ctrl_base_addr + register_offset, data_to_write.to_bytes(4, byteorder="little"), 4 # 4 bytes ) # Return 0 return code if written size else return error code return size_or_error if size_or_error != 4 else 0 return write_register
def _get_depends1_dll_path(dllpath): d = _path.dirname(dllpath) dbg = _match(_REGEX_DBG_DLL_PATH, dllpath) base = d + "/" + DLL_DEPENDS1_NAME + "-" + SYS_ARCH_TYPE path = base + ("_d.dll" if dbg else ".dll") return path