Skip to content
Draft
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ my-hls-test
*.tar.gz
docs/_build
docs/autodoc/*
hls4mlprj_*
test/pytest/*_test_*
*~
*.ipynb
*.ipynb_checkpoints/
Expand Down
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@
[submodule "hls4ml/templates/catapult/ac_math"]
path = hls4ml/templates/catapult/ac_math
url = https://github.com/hlslibs/ac_math.git
[submodule "hls4ml/templates/bambu/nnet_utils/gcem"]
path = hls4ml/templates/bambu/nnet_utils/gcem
url = https://github.com/kthohr/gcem
[submodule "hls4ml/templates/bambu/ac_types"]
path = hls4ml/templates/bambu/ac_types
url = https://github.com/ferrandi/ac_types.git
64 changes: 64 additions & 0 deletions docs/backend/bambu.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
=====
Bambu
=====

The ``Bambu`` backend targets `Bambu/PandA <https://panda.dei.polimi.it/>`_, an
open-source high-level synthesis compiler. It converts ``hls4ml`` models to HLS
C++ and drives Bambu to synthesizable Verilog, so no proprietary HLS tool is
required on the critical path. Both ``io_parallel`` and ``io_stream`` are
supported.

Quick start
===========

.. code-block:: python

import hls4ml

config = hls4ml.utils.config_from_keras_model(model, granularity='name', backend='Bambu')

hls_model = hls4ml.converters.convert_from_keras_model(
model,
hls_config=config,
backend='Bambu',
part='xc7a100tcsg324-1',
io_type='io_parallel',
output_dir='my_bambu_prj',
)

# Compile the bridge and check numerical accuracy against Keras
hls_model.compile()
y = hls_model.predict(X)

# Run Bambu: C-simulation, HLS synthesis, RTL co-simulation and (optionally)
# a Vivado logic-synthesis pass for post-route resource/timing/power numbers.
hls_model.build(csim=True, synth=True, cosim=True, vsynth=True)

report = hls4ml.report.parse_bambu_report('my_bambu_prj')

``part`` must be a device Bambu knows about; the supported names are the keys of
``partname_to_bambu`` in ``hls4ml/backends/bambu/bambu_backend.py``. Requiring
``vsynth=True`` (and therefore the resource/timing/power numbers) needs Vivado on
the ``PATH``; the rest of the flow only needs the ``bambu`` executable.

Post-route utilization, timing and power numbers are parsed from the reports
Bambu's Vivado flow produces, reusing the shared report helpers in
``hls4ml/report/vivado_report.py``.

Known limitations
=================

* Large completely-partitioned arrays crash Bambu's frontend, so dense layers
must be kept small.
* The softmax inverse lookup table is emitted as a ``constexpr`` array. When
``fix_softmax_table_size`` shrinks the table (i.e. when
``2 ** min(input_bitwidth, table_bitwidth)`` is below the default table size),
Bambu's clang rejects the initializer at compile time. Other softmax
configurations work; if you hit this, widen the input/table precision or take
the argmax on the host.
* ``-m64`` combined with ``ac_channel`` crashes ``InterfaceInfer``. The default
path avoids this by using the headers Bambu ships.

These were reported to the PandA developers and are addressed by
`PandA-bambu#396 <https://github.com/ferrandi/PandA-bambu/pull/396>`_; the
limitations above apply to current Bambu versions until that release lands.
64 changes: 64 additions & 0 deletions docs/backend/nanoxplore.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
=====================
NanoXploreAccelerator
=====================

The **NanoXploreAccelerator** backend builds on the :doc:`Bambu <bambu>` backend
and turns a Bambu-generated HLS core into a complete accelerator: a float I/O
wrapper, an AXI4 slave, a PLL configuration, and a versioned ``manifest.json``
describing the result. It targets NanoXplore's `NG-ULTRA
<https://www.nanoxplore.com/>`_, a radiation-hardened FPGA with no HLS tool of
its own.

.. code-block:: python

hls_model = hls4ml.converters.convert_from_keras_model(
model,
hls_config=config,
backend='NanoXploreAccelerator',
)
hls_model.build(synth=True, bitstream=True)

Defaults are the NG-ULTRA DevKit's: part ``nx2h540tsc`` and a 20 ns clock
period, matching the board's 50 MHz oscillator.

A deliberate seam
=================

``hls4ml`` never imports a vendor tool. The backend writes everything a
place-and-route flow needs into the project directory -- the complete RTL file
list, clock, port map and data widths, all in ``manifest.json`` and versioned so
a mismatch fails loudly -- then shells out to a single command and reads back
``report.json``:

.. code-block:: text

hls4ml-nanoxplore-bitstream <project_dir>

The command is configurable through the ``BitStreamCommand`` config value. The
vendor-specific driver lives out of tree, which means the abstract layer can be
built and tested with no vendor licence: ``build(synth=True, bitstream=False)``
produces the wrapper, the RTL and the manifest, and stops before place and
route.

Structure
=========

``BambuAcceleratorBackend`` is abstract and unregistered. It provides the
wrapper generation, the RTL templates, the manifest and the PLL patching, and
leaves one abstract method, ``_generate_bitstream``. Other FPGA families can
reuse the layer by subclassing it.

``NanoXploreAcceleratorBackend`` is the registered concrete backend: NG-ULTRA
defaults plus the CLI call.

Clocking
========

Any requested ``ClockPeriod`` is turned into a solved ``NX_PLL_U``
configuration, spliced into the generated top level, so the hardware clock and
the timing constraint agree by construction rather than by convention. This
needs OR-Tools:

.. code-block:: bash

pip install hls4ml[nanoxplore]
2 changes: 2 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
backend/oneapi
backend/catapult
backend/quartus
backend/bambu
backend/nanoxplore
backend/sr

.. toctree::
Expand Down
8 changes: 8 additions & 0 deletions hls4ml/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

from hls4ml.backends.vitis.vitis_backend import VitisBackend # isort: skip

from hls4ml.backends.bambu.bambu_backend import BambuBackend # isort: skip

from hls4ml.backends.bambu_accelerator.bambu_accelerator_backend import BambuAcceleratorBackend # isort: skip # noqa: F401

from hls4ml.backends.nanoxplore_accelerator.nanoxplore_accelerator_backend import NanoXploreAcceleratorBackend # isort: skip # noqa: E501,F401


def _register_builtin_backends():
register_backend('Vivado', VivadoBackend)
Expand All @@ -23,6 +29,8 @@ def _register_builtin_backends():
register_backend('SymbolicExpression', SymbolicExpressionBackend)
register_backend('oneAPI', OneAPIBackend)
register_backend('Libero', LiberoBackend)
register_backend('Bambu', BambuBackend)
register_backend('NanoXploreAccelerator', NanoXploreAcceleratorBackend)


_register_builtin_backends()
Expand Down
Empty file.
Loading
Loading