Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2cdfd86
Add virtual HLS FIFO
fpjentzsch Feb 14, 2025
7c04eb6
Integrate instrumentation into ZynqBuild
fpjentzsch Feb 14, 2025
419e18f
Nest AXI interconnects if required
fpjentzsch Feb 19, 2025
5628ab2
Fix AXI interconnect connection
fpjentzsch Feb 19, 2025
0c57d1b
Make floorplan partitioning of AXI-lite interfaces more consistent
fpjentzsch Feb 19, 2025
684459c
Add GPIO IP for reset
fpjentzsch Feb 19, 2025
8d45488
Remove unneeded connect_bd_net
fpjentzsch Feb 20, 2025
960a7f4
Fix redundant bd_automation
fpjentzsch Feb 20, 2025
76ef35d
Remove tcl.collectionResultDisplayLimit
fpjentzsch Feb 21, 2025
9c6c3cd
Add driver for iterative live FIFO-sizing
fpjentzsch Feb 22, 2025
01d5551
Generate FIFO size report as part of step_set_fifo_depths
fpjentzsch Feb 27, 2025
3598501
Add PYNQ driver for ZYNQ platforms
fpjentzsch Feb 27, 2025
bd0517f
Merge branch 'feature/instrumentation' into feature/live_fifosizing
fpjentzsch Feb 27, 2025
f32e884
Add non-interactive driver
fpjentzsch Feb 27, 2025
0c812bc
Nested interconnects for Zynq-7000, fixes
fpjentzsch Mar 6, 2025
0bcb99c
Merge branch 'feature/instrumentation' into feature/live_fifosizing
fpjentzsch Mar 6, 2025
4bf21a2
Force disable additional AXI-lite interfaces for live FIFO sizing
fpjentzsch Mar 6, 2025
230ac92
Fix clkname variable expansion
fpjentzsch Mar 7, 2025
bb19afc
Merge branch 'feature/instrumentation' into feature/live_fifosizing
fpjentzsch Mar 7, 2025
ef7b8cf
Fix FIFO width export for driver
fpjentzsch Mar 8, 2025
b0fb5f2
[Driver] Reset PYNQ cache before loading Overlay
fpjentzsch Mar 9, 2025
a5c37c9
Merge branch 'feature/instrumentation' into feature/live_fifosizing
fpjentzsch Mar 9, 2025
a08e2c4
[Driver] Reset PYNQ cache, fix json int keys
fpjentzsch Mar 9, 2025
2c9925d
Start search for start depths from 1
fpjentzsch Mar 24, 2025
9f3e7c7
Let driver fill live FIFO sizes into complete folding config
fpjentzsch Mar 24, 2025
15fef09
Increase virtual FIFO depth offset to 8
fpjentzsch Mar 28, 2025
b5aee28
Update gitignore
fpjentzsch Apr 28, 2025
4f9dc7e
[Driver] Increase recursion limit
fpjentzsch Apr 28, 2025
e4df7dc
Merge branch 'dev' into feature/instrumentation
fpjentzsch May 20, 2025
7a3f928
Adapt to FINN_ROOT refactoring
fpjentzsch May 20, 2025
028bc5f
Merge branch 'feature/instrumentation' into feature/live_fifosizing
fpjentzsch May 20, 2025
ccebbdc
Fix use of deprecated FINN_ROOT
fpjentzsch May 20, 2025
6c4c3eb
Merge branch 'feature/instrumentation' into feature/live_fifosizing
fpjentzsch May 20, 2025
cc0be94
[CI] Adapt to recent runner version change
fpjentzsch May 21, 2025
9106fbf
Merge branch 'feature/instrumentation' into feature/live_fifosizing
fpjentzsch May 21, 2025
a942390
Refactor remaining MakePYNQDriver calls
fpjentzsch May 21, 2025
f1ce17d
Merge branch 'dev' into feature/instrumentation
fpjentzsch May 22, 2025
41d441b
Merge branch 'feature/instrumentation' into feature/live_fifosizing
fpjentzsch May 22, 2025
f0bb38d
Merge branch 'dev' into feature/live_fifosizing
fpjentzsch May 22, 2025
109f31f
Remove old Jupyter notebook driver
fpjentzsch May 22, 2025
2b86e81
Fix linting
fpjentzsch May 22, 2025
5ce444b
Remove old AXI-Lite restriction
fpjentzsch May 22, 2025
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
81 changes: 81 additions & 0 deletions custom_hls/virtual_fifo.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef VIRTUAL_FIFO_HPP
#define VIRTUAL_FIFO_HPP

#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

// Utility Functions, taken from instrumentation wrapper
template<typename T>
static void move(
hls::stream<T> &src,
hls::stream<T> &dst
) {
#pragma HLS pipeline II=1 style=flp
dst.write(src.read());
}

template<typename T>
static void move(
hls::stream<hls::axis<T, 0, 0, 0>> &src,
hls::stream<T> &dst
) {
#pragma HLS pipeline II=1 style=flp
dst.write(src.read().data);
}

template<typename T>
class Payload {
public:
using type = T;
};
template<typename T>
class Payload<hls::axis<T, 0, 0, 0>> {
public:
using type = T;
};

template<unsigned int Width>
void VirtualFIFO(hls::stream<ap_uint<Width> > &in, hls::stream<ap_uint<Width> > &out,
ap_uint<32> mode,
ap_uint<32> depth,
ap_uint<32> &occupancy,
ap_uint<32> &max_occupancy)
{
#pragma HLS pipeline II=1 style=flp

static ap_uint<32> c_occupancy = 0;
static ap_uint<32> c_max_occupancy = 0;
#pragma HLS reset variable=c_occupancy
#pragma HLS reset variable=c_max_occupancy

ap_uint<Width> inElem;

bool read = mode == 0 || c_occupancy != depth;
bool write = c_occupancy != 0;

// INPUT
if(read)
{
if(in.read_nb(inElem)) //disregard input data
{
c_occupancy++;
c_max_occupancy = (c_occupancy > c_max_occupancy) ? c_occupancy : c_max_occupancy;
}
}

// OUTPUT
if(write)
{
if(out.write_nb(0)) //write dummy output data
{
c_occupancy--;
}
}

// Update output status registers
occupancy = c_occupancy;
max_occupancy = c_max_occupancy;
}

#endif
3 changes: 3 additions & 0 deletions src/finn/builder/build_dataflow_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ class DataflowBuildConfig(DataClassJSONMixin, DataClassYAMLMixin):
#: for each FIFO.
auto_fifo_depths: Optional[bool] = True

# Enables experimental live FIFO sizing
live_fifo_sizing: Optional[bool] = False

#: Whether FIFO nodes with depth larger than 32768 will be split.
#: Allow to configure very large FIFOs in the folding_config_file.
split_large_fifos: Optional[bool] = False
Expand Down
110 changes: 94 additions & 16 deletions src/finn/builder/build_dataflow_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
GiveUniqueNodeNames,
RemoveStaticGraphInputs,
RemoveUnusedTensors,
SortGraph,
)
from qonnx.transformation.infer_data_layouts import InferDataLayouts
from qonnx.transformation.infer_datatypes import InferDataTypes
Expand Down Expand Up @@ -529,6 +530,81 @@ def step_set_fifo_depths(model: ModelWrapper, cfg: DataflowBuildConfig):
`GiveUniqueNodeNames`.
"""

hw_attrs = [
"PE",
"SIMD",
"parallel_window",
"ram_style",
"depth",
"impl_style",
"resType",
"mem_mode",
"runtime_writeable_weights",
"inFIFODepths",
"outFIFODepths",
"depth_trigger_uram",
"depth_trigger_bram",
]

# Experimental live FIFO-sizing, overwrites all other FIFO-related behavior
if cfg.live_fifo_sizing:
# Create all DWCs and FIFOs normally
model = model.transform(InsertDWC())
model = model.transform(
InsertFIFO(vivado_ram_style=cfg.large_fifo_mem_style, create_shallow_fifos=True)
)

# Clean up model
model = model.transform(SortGraph())
model = model.transform(GiveUniqueNodeNames())
model = model.transform(GiveReadableTensorNames())

# save original folding config before potentially modifying it
cfg_path = cfg.output_dir + "/report/folding_config_before_lfs.json"
extract_model_config_to_json(model, cfg_path, hw_attrs)
model.set_metadata_prop("folding_config_before_lfs", cfg_path)

# Disable runtime-writable weights, external weights, and dynamic mode,
# as we don't support additional AXI-lite interfaces next to the FIFOs
for node in model.graph.node:
if node.domain.startswith("finn.custom_op.fpgadataflow"):
node_inst = getCustomOp(node)
try:
if node_inst.get_nodeattr("runtime_writeable_weights") == 1:
node_inst.set_nodeattr("runtime_writeable_weights", 0)
if node_inst.get_nodeattr("ram_style") == "ultra":
node_inst.set_nodeattr("ram_style", "block")
except AttributeError:
pass
try:
if node_inst.get_nodeattr("mem_mode") == "external":
node_inst.set_nodeattr("mem_mode", "internal_decoupled")
except AttributeError:
pass
try:
if node_inst.get_nodeattr("dynamic_mode") == 1:
node_inst.set_nodeattr("dynamic_mode", 0)
except AttributeError:
pass

# Specialize FIFOs to HLS back-end instead of default RTL back-end
for node in model.get_nodes_by_op_type("StreamingFIFO"):
node_inst = getCustomOp(node)
node_inst.set_nodeattr("preferred_impl_style", "hls")
model = model.transform(SpecializeLayers(cfg._resolve_fpga_part()))

# Fix impl_style attribute
for node in model.get_nodes_by_op_type("StreamingFIFO_hls"):
node_inst = getCustomOp(node)
node_inst.set_nodeattr("impl_style", "virtual")

# Clean up model
model = model.transform(SortGraph())
model = model.transform(GiveUniqueNodeNames())
model = model.transform(GiveReadableTensorNames())

return model

if cfg.auto_fifo_depths:
if cfg.auto_fifo_strategy == "characterize":
model = model.transform(InsertDWC())
Expand Down Expand Up @@ -587,21 +663,6 @@ def step_set_fifo_depths(model: ModelWrapper, cfg: DataflowBuildConfig):
model = model.transform(ApplyConfig(cfg.folding_config_file))

# extract the final configuration and save it as json
hw_attrs = [
"PE",
"SIMD",
"parallel_window",
"ram_style",
"depth",
"impl_style",
"resType",
"mem_mode",
"runtime_writeable_weights",
"inFIFODepths",
"outFIFODepths",
"depth_trigger_uram",
"depth_trigger_bram",
]
extract_model_config_to_json(model, cfg.output_dir + "/final_hw_config.json", hw_attrs)

# perform FIFO splitting and shallow FIFO removal only after the final config
Expand All @@ -611,6 +672,23 @@ def step_set_fifo_depths(model: ModelWrapper, cfg: DataflowBuildConfig):
model = model.transform(SplitLargeFIFOs())
model = model.transform(RemoveShallowFIFOs())

# generate a dedicated report about final FIFO sizes
fifo_info = {}
fifo_info["fifo_depths"] = {}
fifo_info["fifo_sizes"] = {}
total_fifo_size = 0
for node in model.get_nodes_by_op_type("StreamingFIFO_rtl"):
node_inst = getCustomOp(node)
fifo_info["fifo_depths"][node.name] = node_inst.get_nodeattr("depth")
fifo_info["fifo_sizes"][
node.name
] = node_inst.get_instream_width() * node_inst.get_nodeattr("depth")
total_fifo_size += fifo_info["fifo_sizes"][node.name]
fifo_info["total_fifo_size_kB"] = int(total_fifo_size / 8.0 / 1000.0)

with open(cfg.output_dir + "/report/fifo_sizing.json", "w") as f:
json.dump(fifo_info, f, indent=2)

# after FIFOs are ready to go, call PrepareIP and HLSSynthIP again
# this will only run for the new nodes (e.g. FIFOs and DWCs)
model = model.transform(PrepareIP(cfg._resolve_fpga_part(), cfg._resolve_hls_clk_period()))
Expand Down Expand Up @@ -745,7 +823,7 @@ def step_make_driver(model: ModelWrapper, cfg: DataflowBuildConfig):
if cfg.enable_instrumentation:
model = model.transform(
MakePYNQDriverInstrumentation(
cfg._resolve_driver_platform(), cfg.synth_clk_period_ns
cfg._resolve_driver_platform(), cfg.synth_clk_period_ns, cfg.live_fifo_sizing
)
)
else:
Expand Down
2 changes: 2 additions & 0 deletions src/finn/custom_op/fpgadataflow/hls/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def register_custom_op(cls):
StreamingDataWidthConverter_hls,
)
from finn.custom_op.fpgadataflow.hls.streamingeltwise_hls import StreamingEltwise_hls
from finn.custom_op.fpgadataflow.hls.streamingfifo_hls import StreamingFIFO_hls
from finn.custom_op.fpgadataflow.hls.streamingmaxpool_hls import StreamingMaxPool_hls
from finn.custom_op.fpgadataflow.hls.thresholding_hls import Thresholding_hls
from finn.custom_op.fpgadataflow.hls.tlastmarker_hls import TLastMarker_hls
Expand All @@ -119,6 +120,7 @@ def register_custom_op(cls):
custom_op["StreamingEltwise_hls"] = StreamingEltwise_hls
custom_op["StreamingDataWidthConverter_hls"] = StreamingDataWidthConverter_hls
custom_op["StreamingMaxPool_hls"] = StreamingMaxPool_hls
custom_op["StreamingFIFO_hls"] = StreamingFIFO_hls
custom_op["Thresholding_hls"] = Thresholding_hls
custom_op["TLastMarker_hls"] = TLastMarker_hls
custom_op["UpsampleNearestNeighbour_hls"] = UpsampleNearestNeighbour_hls
Expand Down
Loading