Memory Copy — a free-running composite kernel
This is the worked example for the concurrent (free-running) flow,
the counterpart to the sequential register-map example. Where simp_fun is a single
host-launched function, mem_copy is a composite of free-running hls::tasks that copies a run of
words from one memory region to another — and it is verified not by Vitis co-simulation (which cannot
drive a free-running kernel) but by driving the real RTL cycle-by-cycle through an XSI BFM.
Beyond demonstrating composite free-running kernels, mem_copy reuses core infrastructure — the
reusable MemRStream / MemWStream adaptors and the m_axi bus — whose timing models Waveflow ships
pre-fit for supported platforms, so the loosely-timed pysim reproduces the RTL with no calibration of
its own. (Those shared models were in fact measured on mem_copy behind the scenes; that machinery
is the general calibration guide, not a step in this example — fitting a custom
component’s timing is taken up in the interleaver example.) The final page visualizes that timing.
Learning Objectives
In going through this example, you will learn to:
- Model hardware as free-running component classes (the
FreeRunModclass in Waveflow), and interconnect them into composite free-running components to describe a target hardware object - Develop a concurrent testbench as a composite graph that wires the DUT to stimulus and capture, using Waveflow’s built-in stream source/sink models (
StreamDriver,StreamSink) - Run a Python concurrent simulation of the composite target hardware in conjunction with the testbench components
- Generate a concurrent Vitis C++ kernel from the Python descriptions, where each sub-component becomes an HLS task
- Synthesize the concurrent Vitis C++ kernel into RTL with Vitis HLS C-synthesis (the generated
mem_copy.tcl) - Map each testbench component to an XSI BFM model (hand-written framework classes) and generate the XSI harness that wires those models to the RTL and drives the clock
- Run the XSI simulation to extract timing and functionally validate the generated RTL
- Visualize the concurrent timing of the components on an activity diagram — the pipeline overlap and where every cycle of the period goes
- See why the loosely-timed pysim reproduces the RTL to 0.0% —
mem_copyreuses the platform’s pre-fit infra timing models (them_axibus and the memory-stream adaptors), which ship with Waveflow, and calibrates nothing itself (fitting a custom component’s timing is the general calibration guide, worked end-to-end in the interleaver example)
In this example
The pages build the design up from Python, parallel to the register-map example — model it, test it in Python, generate the kernel, generate the testbench, then run the RTL:
- Module overview — the three-stage design, the in-band forwarding protocol, and how it is wired.
- Python model — the schemas and the three
FreeRunModleaves + the composite. - Testbench (Python) — the
MemCopyTBgraph, theMemCopySimprocedure, and running the pysim step. - DUT codegen — what an
hls::taskis, and how the design graph becomes theap_ctrl_nonetop. - Testbench codegen — what XSI and a harness are, and how the testbench graph becomes the BFM harness.
- RTL simulation — running the RTL through XSI, inspecting the results, and comparing the timing to pysim.
- Visualizing timing — tracing an RTL run and rendering it: the pipeline overlap, the bottleneck, where every cycle of the period goes, and why the loosely-timed pysim reproduces it using the platform’s shipped infra models (no per-example calibration).