-
Notifications
You must be signed in to change notification settings - Fork 821
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PL Server now uses global state file (based on PYNQ-Metadata) rather …
…than separate process. * Improves performance when accessing non-dereferenced IP from dictionaries, such as DMA. * Instead of a separate process that can be queried for information of dictionaries etc.. a PYNQ-Metadata json file is stored globally that is only referenced when an overlay is downloaded. This file can be parsed on overlay download to check for AXI Shutdown IP that needs to be triggered. * PL.py now uses the global state file to access the currently loaded dictionaries outside the process that configured the overlay. * Bugfix for buffers where they are now freed when deleted/go out of scope.
- Loading branch information
Showing
13 changed files
with
939 additions
and
1,597 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,23 @@ | ||
# Copyright (c) 2016, Xilinx, Inc. | ||
# All rights reserved. | ||
# | ||
# Redistribution and use in source and binary forms, with or without | ||
# modification, are permitted provided that the following conditions are met: | ||
# | ||
# 1. Redistributions of source code must retain the above copyright notice, | ||
# this list of conditions and the following disclaimer. | ||
# | ||
# 2. Redistributions in binary form must reproduce the above copyright | ||
# notice, this list of conditions and the following disclaimer in the | ||
# documentation and/or other materials provided with the distribution. | ||
# | ||
# 3. Neither the name of the copyright holder nor the names of its | ||
# contributors may be used to endorse or promote products derived from | ||
# this software without specific prior written permission. | ||
# | ||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
# OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
|
||
import os | ||
import struct | ||
import warnings | ||
from copy import deepcopy | ||
from datetime import datetime | ||
import struct | ||
from multiprocessing.connection import Client, Listener | ||
from pathlib import Path | ||
|
||
import numpy as np | ||
from multiprocessing.connection import Listener | ||
from multiprocessing.connection import Client | ||
from .mmio import MMIO | ||
from .ps import CPU_ARCH_IS_SUPPORTED, CPU_ARCH, ZYNQ_ARCH, ZU_ARCH | ||
from .devicetree import DeviceTreeSegment | ||
from .devicetree import get_dtbo_path | ||
from .devicetree import get_dtbo_base_name | ||
|
||
from .pl_server import HWH | ||
from .pl_server import get_hwh_name | ||
from .pl_server import Device | ||
from .devicetree import DeviceTreeSegment, get_dtbo_base_name, get_dtbo_path | ||
from .mmio import MMIO | ||
from .pl_server.device import Device | ||
from .pl_server.global_state import clear_global_state, load_global_state, global_state_file_exists | ||
from .pl_server.hwh_parser import HWH, get_hwh_name | ||
from .ps import CPU_ARCH, CPU_ARCH_IS_SUPPORTED, ZU_ARCH, ZYNQ_ARCH | ||
|
||
__author__ = "Yun Rock Qu" | ||
__copyright__ = "Copyright 2016, Xilinx" | ||
__email__ = "[email protected]" | ||
|
||
|
||
class PLMeta(type): | ||
|
@@ -77,7 +47,13 @@ def bitfile_name(cls): | |
The absolute path of the bitstream currently on PL. | ||
""" | ||
return Device.active_device.bitfile_name | ||
if hasattr(Device.active_device, "bitfile_name"): | ||
if not Device.active_device.bitfile_name is None: | ||
return Device.active_device.bitfile_name | ||
|
||
if global_state_file_exists(): | ||
gs = load_global_state() | ||
return gs.bitfile_name | ||
|
||
@property | ||
def timestamp(cls): | ||
|
@@ -91,6 +67,27 @@ def timestamp(cls): | |
""" | ||
return Device.active_device.timestamp | ||
|
||
@property | ||
def dict_views(cls): | ||
""" | ||
Getter attribute for the `systemgraph` | ||
First checks to see if the metadata file is where it is expected. | ||
If it is, parses it, and create a runtime_views object for it | ||
""" | ||
if hasattr(cls, "_dict_views_cached"): | ||
return cls._dict_view_cache | ||
else: | ||
import os | ||
from pynqmetadata.frontends import Metadata | ||
from .metadata.runtime_metadata_parser import RuntimeMetadataParser | ||
metadata_state_file = Path(f"{os.path.dirname(__file__)}/pl_server/_current_metadata.json") | ||
if os.path.isfile(metadata_state_file): | ||
cls._dict_views_cached = True | ||
cls._dict_view_cache = RuntimeMetadataParser(Metadata(input=metadata_state_file)) | ||
return cls._dict_view_cache | ||
else: | ||
return None | ||
|
||
@property | ||
def ip_dict(cls): | ||
"""The getter for the attribute `ip_dict`. | ||
|
@@ -101,7 +98,12 @@ def ip_dict(cls): | |
The dictionary storing addressable IP instances; can be empty. | ||
""" | ||
return Device.active_device.ip_dict | ||
if hasattr(Device.active_device, "ip_dict"): | ||
if not Device.active_device.ip_dict is None: | ||
return Device.active_device.ip_dict | ||
|
||
if not cls.dict_views is None: | ||
return cls.dict_views.ip_dict | ||
|
||
@property | ||
def gpio_dict(cls): | ||
|
@@ -113,7 +115,12 @@ def gpio_dict(cls): | |
The dictionary storing the PS GPIO pins. | ||
""" | ||
return Device.active_device.gpio_dict | ||
if hasattr(Device.active_device, "gpio_dict"): | ||
if not Device.active_device.gpio_dict is None: | ||
return Device.active_device.gpio_dict | ||
|
||
if not cls.dict_views is None: | ||
return cls.dict_views.gpio_dict | ||
|
||
@property | ||
def interrupt_controllers(cls): | ||
|
@@ -125,7 +132,12 @@ def interrupt_controllers(cls): | |
The dictionary storing interrupt controller information. | ||
""" | ||
return Device.active_device.interrupt_controllers | ||
if hasattr(Device.active_device, "interrupt_controllers"): | ||
if not Device.active_device.interrupt_controllers is None: | ||
return Device.active_device.interrupt_controllers | ||
|
||
if not cls.dict_views is None: | ||
return cls.dict_views.interrupt_controllers | ||
|
||
@property | ||
def interrupt_pins(cls): | ||
|
@@ -137,7 +149,12 @@ def interrupt_pins(cls): | |
The dictionary storing the interrupt endpoint information. | ||
""" | ||
return Device.active_device.interrupt_pins | ||
if hasattr(Device.active_device, "interrupt_pins"): | ||
if not Device.active_device.interrupt_pins is None: | ||
return Device.active_device.interrupt_pins | ||
|
||
if not cls.dict_views is None: | ||
return cls.dict_views.interrupt_pins | ||
|
||
@property | ||
def hierarchy_dict(cls): | ||
|
@@ -149,7 +166,12 @@ def hierarchy_dict(cls): | |
The dictionary containing the hierarchies in the design | ||
""" | ||
return Device.active_device.hierarchy_dict | ||
if hasattr(Device.active_device, "hierarchy_dict"): | ||
if not Device.active_device.hierarchy_dict is None: | ||
return Device.active_device.hierarchy_dict | ||
|
||
if not cls.dict_views.hierarchy_dict is None: | ||
return cls.dict_views.hierarchy_dict | ||
|
||
@property | ||
def devicetree_dict(cls): | ||
|
@@ -185,7 +207,12 @@ def mem_dict(self): | |
The dictionary containing the memories in the design. | ||
""" | ||
return Device.active_device.mem_dict | ||
if hasattr(Device.active_device, "mem_dict"): | ||
if not Device.active_device.mem_dict is None: | ||
return Device.active_device.mem_dict | ||
|
||
if not self.dict_views.mem_dict is None: | ||
return self.dict_views.mem_dict | ||
|
||
def shutdown(cls): | ||
"""Shutdown the AXI connections to the PL in preparation for | ||
|
@@ -213,7 +240,11 @@ def reset(cls, parser=None): | |
A parser object to speed up the reset process. | ||
""" | ||
Device.active_device.reset(parser) | ||
clear_global_state() | ||
for i in cls.mem_dict.values(): | ||
i['state'] = None | ||
for i in cls.ip_dict.values(): | ||
i['state'] = None | ||
|
||
def clear_dict(cls): | ||
"""Clear all the dictionaries stored in PL. | ||
|
@@ -350,6 +381,7 @@ class PL(metaclass=PLMeta): | |
'gpio': dict, 'fullpath': str}} | ||
""" | ||
|
||
def __init__(self): | ||
"""Return a new PL object. | ||
|
@@ -358,4 +390,6 @@ def __init__(self): | |
""" | ||
euid = os.geteuid() | ||
if euid != 0: | ||
raise EnvironmentError('Root permissions required.') | ||
raise EnvironmentError("Root permissions required.") | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,22 @@ | ||
# Copyright (c) 2016, Xilinx, Inc. | ||
# All rights reserved. | ||
# | ||
# Redistribution and use in source and binary forms, with or without | ||
# modification, are permitted provided that the following conditions are met: | ||
# | ||
# 1. Redistributions of source code must retain the above copyright notice, | ||
# this list of conditions and the following disclaimer. | ||
# | ||
# 2. Redistributions in binary form must reproduce the above copyright | ||
# notice, this list of conditions and the following disclaimer in the | ||
# documentation and/or other materials provided with the distribution. | ||
# | ||
# 3. Neither the name of the copyright holder nor the names of its | ||
# contributors may be used to endorse or promote products derived from | ||
# this software without specific prior written permission. | ||
# | ||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
# OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
|
||
__author__ = "Peter Ogden" | ||
__copyright__ = "Copyright 2019, Xilinx" | ||
__email__ = "[email protected]" | ||
|
||
|
||
from .hwh_parser import HWH, get_hwh_name | ||
from .server import DeviceClient | ||
import os | ||
|
||
from .device import Device | ||
from .global_state import ( | ||
GlobalState, | ||
global_state_file_exists, | ||
load_global_state, | ||
save_global_state, | ||
) | ||
from .hwh_parser import HWH, get_hwh_name | ||
|
||
import os | ||
if 'XILINX_XRT' in os.environ: | ||
if "XILINX_XRT" in os.environ: | ||
from .embedded_device import EmbeddedDevice | ||
from .xclbin_parser import XclBin | ||
from .xrt_device import XrtDevice | ||
from .embedded_device import EmbeddedDevice | ||
|
||
|
Oops, something went wrong.