Component Code Generation

WaveFlow generates Vitis-ready C++ for every HwComponent. You write the component once in Python — its ports, its parameters, its behavior — and the generator emits a top-level HLS kernel with the right AXI interfaces, the C++ type lowering, and the build-ready file set, all from that single source.

This chapter covers what the generator produces automatically: the structure of a generated component, how each endpoint becomes an HLS port, the execution model it lowers to, what the HwStmt extractor accepts, and how HwParam parameterizes the output.

A component’s compute body is not always auto-generated. When a datapath needs hand-tuned HLS C++, you write the kernel body yourself and attach it with @synthesizable(impl_file=…). That hand-written path — how to author a kernel body, the in-kernel port and loop patterns — is the next chapter, Custom Hooks. This chapter is the auto-generated structure those hooks plug into.

In this section

  • Component structure — how an HwComponent becomes a Vitis HLS top-level function: the kernel entry, the execution model (free-running vs. regmap-launched), and where hooks come from.
  • Endpoint interfaces — how each declared endpoint (stream / m_axi / regmap) is realized as a Vitis port (hls::stream / m_axi / s_axilite) and how a slave endpoint’s handler binds.
  • Extractor — how HwStmtExtractor parses the synthesizable Python subset into the HwStmt IR, failing fast on unsupported patterns.
  • Codegen — how kernel_files_to_str emits the deterministic kernel file set and resolves naming.
  • Templating — the C++ realization of parameterization: how HwParam lowers (concrete widths / .tpp template params), HwConst (deferred), and how param_supports emits variant kernels.
  • TestbenchHwTestbench and is_testbench=True codegen mode.

See also

  • Hardware Components — the Python HwComponent this section generates C++ for.
  • Custom Hooks — the hand-written synthesizable kernel bodies that plug into a generated component.
  • Cosim timing — extracting and validating cycle timing from the generated kernel’s cosim (now under Timing Analysis, where the timeline analysis lives).
  • Build System — the BuildDag that drives these codegen steps end to end.

Table of contents

  • Component structure - The Vitis HLS realization of an HwComponent: each component becomes one top-level kernel function whose arguments are its endpoints; the execution model is a free-running loop (run_proc) or a one-time regmap-launched call (on_start), selected by whether the component carries a VitisRegMapMMIFSlave; the kernel body comes from the @synthesizable methods (auto-extracted or, with impl_file=, hand-written).
  • Endpoint interfaces - How each declared endpoint on an HwComponent is realized as a Vitis HLS port: stream endpoints become hls::stream>& with #pragma HLS INTERFACE axis; m_axi masters become ap_uint* with m_axi offset=slave bundle=gmem; a VitisRegMapMMIFSlave becomes s_axilite register-field ports plus the ap_start/ap_done control protocol. Also how a slave endpoint's handler binds to the kernel body.
  • Extractor - How HwStmtExtractor parses the synthesizable subset of a component's Python (on_start / run_proc, or main for a testbench) into the HwStmt IR, failing fast with SynthesisError on unsupported patterns.
  • Codegen - How resolved HwStmt IR is emitted to deterministic kernel files — .hpp / .cpp plus sticky hook impl files — with C++ type lowering, top-level signatures, namespace-qualified hook calls, and variant naming.
  • Templating - The C++ realization of component parameterization: HwParam values lower to concrete literal widths in the top kernel signature and to template parameters in .tpp hooks (HwParamValue carries the param name so the emitter chooses name vs literal); HwConst lowers to static constexpr (currently deferred); and param_supports emits one concrete _ top per variant from a single class.
  • Testbench - The codegen-source testbench path: HwTestbench.main() lowered to a sequential C++ int main() (DUT build, file I/O, stream push/pop, dut.run()), emitted as _tb.cpp when is_testbench=True.

This site uses Just the Docs, a documentation theme for Jekyll.