Vitis Kernel implementation
Overview
On the Vitis HLS side, the kernel runs a persistent while (true) loop driven by an ap_ctrl_hs AXI-Lite control register. The host configures coefficients in the AXI-Lite register map, writes ap_start, and the kernel processes streamed commands until it sees an END header (clean exit) or hits an error (halt).
Generated schema headers make the protocol code much simpler. The kernel reads and writes typed protocol objects directly:
PolyCmdHdr— command header withcmd_type(DATA/END),tx_id,nsampPolyRespHdr— per-transaction response header echoingtx_idCoeffArray— polynomial coefficient array (read from the AXI-Lite regmap)
The accelerator’s control/status block is described in Python on PolyAccelComponent using VitisRegMap:
halted(R, 1 bit) —1if the kernel halted on errorerror(R, 8 bits) — last error code (PolyErrorenum)tx_id(R, 16 bits) —tx_idof the offending transactioncoeffs(RW, 4 × Float32) — polynomial coefficients
The matching C++ kernel signature exposes the same fields as s_axilite arguments.
Implementation code
The HLS kernel is implemented in examples/poly/poly.cpp. It declares one AXI-Lite control bundle covering coefficients, status registers, and the ap_ctrl_hs return port. The function signature:
void poly(hls::stream<axis_word_t>& in_stream,
hls::stream<axis_word_t>& out_stream,
const float coeffs[4],
ap_uint<1>& halted,
ap_uint<8>& error_code,
ap_uint<16>& tx_id_status);
The interface pragmas wire the scalars and the return port to the same AXI-Lite bundle as the coefficient array:
#pragma HLS INTERFACE axis port=in_stream
#pragma HLS INTERFACE axis port=out_stream
#pragma HLS INTERFACE s_axilite port=coeffs bundle=control
#pragma HLS INTERFACE s_axilite port=halted bundle=control
#pragma HLS INTERFACE s_axilite port=error_code bundle=control
#pragma HLS INTERFACE s_axilite port=tx_id_status bundle=control
#pragma HLS INTERFACE s_axilite port=return bundle=control
The loop body:
- reads a
PolyCmdHdrfrom the input stream; - if
cmd_type == END, breaks out of the loop and returns cleanly; - on TLAST framing errors latches
halted/error_code/tx_id_statusand breaks (no stream flush — the host re-launches via platform reset); - otherwise emits a
PolyRespHdr, processesnsamplane-packed samples through Horner evaluation using thes_axilitecoeffsargument, emits the result stream, and validates the sample-burst framing the same way.
When the function returns, Vitis asserts ap_done, the host reads the regmap status (halted / error_code / tx_id_status), and — if anything other than NO_ERROR is reported — re-launches the kernel by asserting ap_rst_n via the platform reset controller and then writing a fresh ap_start.