Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions docker/finn_entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ recho () {
mv ${FINN_ROOT}/deps/qonnx/pyproject.toml ${FINN_ROOT}/deps/qonnx/pyproject.tmp
pip install --user -e ${FINN_ROOT}/deps/qonnx
mv ${FINN_ROOT}/deps/qonnx/pyproject.tmp ${FINN_ROOT}/deps/qonnx/pyproject.toml

# finn-experimental
pip install --user -e ${FINN_ROOT}/deps/finn-experimental
# brevitas
Expand Down Expand Up @@ -106,15 +107,18 @@ fi
if [ -z "${XILINX_VIVADO}" ]; then
yecho "finnxsi will be unavailable since Vivado was not found"
else
# Build finn_xsi using the new Python-based setup
if [ -f "${FINN_ROOT}/finn_xsi/xsi.so" ]; then
gecho "Found finnxsi at ${FINN_ROOT}/finn_xsi/xsi.so"
gecho "Found existing finn_xsi at ${FINN_ROOT}/finn_xsi/xsi.so"
else
OLDPWD=$(pwd)
cd ${FINN_ROOT}/finn_xsi
make
cd $OLDPWD
gecho "Building finn_xsi using finn.xsi.setup..."
python -m finn.xsi.setup --quiet
if [ $? -eq 0 ]; then
gecho "finn_xsi built successfully"
else
recho "Failed to build finn_xsi"
fi
fi
export PYTHONPATH=$PYTHONPATH:${FINN_ROOT}/finn_xsi
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib/x86_64-linux-gnu/:${XILINX_VIVADO}/lib/lnx64.o
fi

Expand Down Expand Up @@ -152,5 +156,6 @@ else
fi

export PATH=$PATH:$HOME/.local/bin

# execute the provided command(s) as root
exec "$@"
29 changes: 0 additions & 29 deletions finn_xsi/Makefile

This file was deleted.

1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ onnxruntime==1.18.1
pre-commit==3.3.2
protobuf==3.20.3
psutil==5.9.4
pybind11==2.10.0
pyscaffold==4.6
pytest-forked==1.6.0
scipy==1.10.1
Expand Down
8 changes: 3 additions & 5 deletions src/finn/core/rtlsim_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,11 @@
# 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.

try:
import finn_xsi.adapter as finnxsi
except ModuleNotFoundError:
finnxsi = None

import numpy as np
import os
from qonnx.custom_op.registry import getCustomOp

from finn import xsi
from finn.util.basic import (
get_finn_root,
get_liveness_threshold_cycles,
Expand All @@ -44,6 +40,8 @@
)
from finn.util.data_packing import npy_to_rtlsim_input, rtlsim_output_to_npy

finnxsi = xsi if xsi.is_available() else None


def prep_rtlsim_io_dict(model, execution_context):
# extract i/o info to prepare io_dict
Expand Down
8 changes: 3 additions & 5 deletions src/finn/custom_op/fpgadataflow/hlsbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,21 @@
# 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.

try:
import finn_xsi.adapter as finnxsi
except ModuleNotFoundError:
finnxsi = None

import numpy as np
import os
import subprocess
import warnings
from abc import ABC, abstractmethod
from qonnx.core.datatype import DataType

from finn import xsi
from finn.custom_op.fpgadataflow import templates
from finn.util.basic import CppBuilder, make_build_dir
from finn.util.data_packing import npy_to_rtlsim_input, rtlsim_output_to_npy
from finn.util.hls import CallHLS

finnxsi = xsi if xsi.is_available() else None


class HLSBackend(ABC):
"""HLSBackend class all custom ops that correspond to a finn-hlslib
Expand Down
8 changes: 3 additions & 5 deletions src/finn/custom_op/fpgadataflow/hwcustomop.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,18 @@
# 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.

try:
import finn_xsi.adapter as finnxsi
except ModuleNotFoundError:
finnxsi = None

import numpy as np
import os
import warnings
from abc import abstractmethod
from qonnx.custom_op.base import CustomOp
from qonnx.util.basic import roundup_to_integer_multiple

from finn import xsi
from finn.util.basic import get_liveness_threshold_cycles, is_versal

finnxsi = xsi if xsi.is_available() else None


class HWCustomOp(CustomOp):
"""HWCustomOp class all custom ops that can be implemented with either
Expand Down
8 changes: 3 additions & 5 deletions src/finn/custom_op/fpgadataflow/rtlbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,16 @@
# 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.

try:
import finn_xsi.adapter as finnxsi
except ModuleNotFoundError:
finnxsi = None

import numpy as np
import os
from abc import ABC, abstractmethod

from finn import xsi
from finn.util.basic import make_build_dir
from finn.util.data_packing import npy_to_rtlsim_input, rtlsim_output_to_npy

finnxsi = xsi if xsi.is_available() else None


class RTLBackend(ABC):
"""RTLBackend class all custom ops that correspond to a module in finn-rtllib
Expand Down
135 changes: 135 additions & 0 deletions src/finn/xsi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
############################################################################
# Copyright (C) 2025, Advanced Micro Devices, Inc.
# All rights reserved.
# Portions of this content consist of AI generated content.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# ##########################################################################
"""FINN XSI (Xilinx Simulation Interface) support module

This module provides utilities for RTL simulation support via finn_xsi.
The finn_xsi extension must be built separately using the setup command.

Usage:
# Check if XSI support is available
from finn import xsi
if xsi.is_available():
import finn_xsi.adapter
"""

import os
import sys
from pathlib import Path
from typing import Any, Optional


def is_available() -> bool:
"""Check if XSI (RTL simulation) support is available.

Returns:
bool: True if finn_xsi can be imported, False otherwise
"""
# Check if xsi.so exists
xsi_path = Path(os.environ["FINN_ROOT"]) / "finn_xsi"
xsi_so = xsi_path / "xsi.so"
if not xsi_so.exists():
return False

# Try loading the modules (this will cache them if successful)
return _load_modules()


# Cache for loaded modules
_adapter_module: Optional[Any] = None
_sim_engine_module: Optional[Any] = None
_xsi_module: Optional[Any] = None


def _load_modules() -> bool:
"""Load finn_xsi modules if available."""
global _adapter_module, _sim_engine_module, _xsi_module

if _adapter_module is not None:
return True

xsi_path = Path(os.environ["FINN_ROOT"]) / "finn_xsi"
xsi_so = xsi_path / "xsi.so"

if not xsi_so.exists():
return False

# Temporarily add to path for import
path_added = str(xsi_path) not in sys.path
if path_added:
sys.path.insert(0, str(xsi_path))

try:
import finn_xsi.adapter
import finn_xsi.sim_engine
import xsi

_xsi_module = xsi
_adapter_module = finn_xsi.adapter
_sim_engine_module = finn_xsi.sim_engine

return True
except ImportError as e:
# Log the specific import error for debugging
import logging

logging.debug(f"Failed to import finn_xsi modules: {e}")
return False
except Exception as e:
# Catch any unexpected errors during module loading
import logging

logging.warning(f"Unexpected error loading finn_xsi: {type(e).__name__}: {e}")
return False
finally:
# Remove from path if we added it
if path_added and str(xsi_path) in sys.path:
try:
sys.path.remove(str(xsi_path))
except ValueError:
pass # Path was already removed somehow


# List of functions to wrap from finn_xsi.adapter
_ADAPTER_FUNCTIONS = [
"locate_glbl",
"compile_sim_obj",
"get_simkernel_so",
"load_sim_obj",
"reset_rtlsim",
"close_rtlsim",
"rtlsim_multi_io",
]


def __getattr__(name: str) -> Any:
"""Dynamically wrap finn_xsi.adapter functions."""
if name in _ADAPTER_FUNCTIONS:

def wrapper(*args, **kwargs):
if not _load_modules():
raise ImportError("finn_xsi not available. Run: python -m finn.xsi.setup")
return getattr(_adapter_module, name)(*args, **kwargs)

wrapper.__name__ = name
wrapper.__doc__ = f"Wrapper for finn_xsi.adapter.{name}"
return wrapper
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")


# SimEngine class wrapper
class SimEngine:
"""Wrapper for finn_xsi.sim_engine.SimEngine."""

def __init__(self, *args, **kwargs):
if not _load_modules():
raise ImportError("finn_xsi not available. Run: python -m finn.xsi.setup")
self._engine = _sim_engine_module.SimEngine(*args, **kwargs)

def __getattr__(self, name):
return getattr(self._engine, name)
Loading