This repository provides a proof-of-concept flow that converts a Vitis HLS RTL export into an AWS EC2 F2 HDK Customer Logic (CL) project layout. The generated CL is intended to work with the standard AWS HDK build pipeline (CL → DCP → AFI). This repository focuses on CL generation; AFI creation is performed using AWS tooling and is therefore not automated by this repo.
At a high level, you will:
Before you start, ensure you have:
Note: This tutorial assumes you are using the AWS FPGA Developer AMI, which includes Vivado, AWS FPGA HDK tooling, and a compatible environment for the AWS build flow.
git clone https://github.com/aws/aws-fpga.git
git clone https://github.com/BoonHong317/aws-fpga-f2-vitis-to-afi-poc.git
If you are not using the included examples: copy your own Vitis HLS RTL export output (Verilog/SystemVerilog + metadata) to this instance first (e.g., via
scp, S3 download, or your preferred transfer method). You will reference this path later asHLS_RTL_DIR.
Check the supported CLI arguments for your version:
python3 ./aws-fpga-f2-vitis-to-afi-poc/hls_to_cl.py --help
This repository includes example inputs and reference outputs to validate the flow quickly:
examples_hls/ — example Vitis HLS projects (and reference RTL exports)examples_cl/ — reference generated CL outputsSet the following variables:
HLS_RTL_DIR: path to your Vitis HLS RTL export directoryHLS_NAME: kernel top/module name (as used by the script)CL_NAME: CL project name to generateexport HLS_RTL_DIR="aws-fpga-f2-vitis-to-afi-poc/examples_hls/cl_poc_ocl_ddr/verilog"
export HLS_NAME="vadd"
export CL_NAME="cl_poc_ocl_ddr"
# Template invocation (adjust flags to match: python3 scripts/hls_to_cl.py --help)
python3 ./aws-fpga-f2-vitis-to-afi-poc/hls_to_cl.py \
--hls_rtl_dir ${HLS_RTL_DIR} \
--hls_name ${HLS_NAME} \
--cl_name ${CL_NAME}
After completion, a generated CL project should exist under the AWS HDK tree, typically at:
aws-fpga/hdk/cl/examples/${CL_NAME}
If you are using the included example HLS inputs, you can diff your generated CL output against the corresponding reference under examples_cl/.
This repo’s verification intent focuses on a minimal set of “integration-critical” artifacts:
build/scripts/synth_${CL_NAME}.tcldesign/${CL_NAME}.svdesign/# Example: compare generated vs reference
diff -u aws-fpga-f2-vitis-to-afi-poc/examples_cl/${CL_NAME}/build/scripts/synth_${CL_NAME}.tcl \
aws-fpga/hdk/cl/examples/${CL_NAME}/build/scripts/synth_${CL_NAME}.tcl
diff -u aws-fpga-f2-vitis-to-afi-poc/examples_cl/${CL_NAME}/design/${CL_NAME}.sv \
aws-fpga/hdk/cl/examples/${CL_NAME}/design/${CL_NAME}.sv
design/ folder# Show what RTL files exist in the generated design folder
find aws-fpga/hdk/cl/examples/${CL_NAME}/design -maxdepth 1 -type f \( -name "*.v" -o -name "*.sv" \) | sort
If you want a quick “set comparison” of filenames against the reference:
comm -3 \
<(find aws-fpga-f2-vitis-to-afi-poc/examples_cl/${CL_NAME}/design -maxdepth 1 -type f \( -name "*.v" -o -name "*.sv" \) -printf "%f\n" | sort) \
<(find aws-fpga/hdk/cl/examples/${CL_NAME}/design -maxdepth 1 -type f \( -name "*.v" -o -name "*.sv" \) -printf "%f\n" | sort)
This step requires AWS CLI access and appropriate permissions (S3 + EC2 FPGA). Ensure your instance profile / IAM role is configured accordingly.
This repository generates the CL project layout, but DCP and AFI generation are performed by AWS HDK tooling.
cd aws-fpga/
source hdk_setup.sh
cd hdk/cl/examples/$CL_NAME
export CL_DIR=$(pwd)
cd build/scripts
python3 ./aws_build_dcp_from_cl.py --cl $CL_NAME
If you want to run long builds in a way that survives disconnects, refer to the AWS HDK documentation on recommended build practices. AWS Doc: Build Accelerator AFI using HDK Design Flow
cd ../checkpoints
# This is your generated DCP file
ls -l *.Developer_CL.tar
The commands below are adapted from AWS documentation. Replace placeholder values before running.
export DCP_BUCKET_NAME='<DCP bucket name>'
export DCP_FOLDER_NAME='<DCP folder name>'
export REGION='us-east-1'
# Replace with your DCP filename
export DCP_TARBALL_TO_INGEST='<$CL_DIR/build/checkpoints/YYYY_MM_DD-HHMMSS.Developer_CL.tar>'
# Create an S3 bucket (choose a unique bucket name)
aws s3 mb s3://${DCP_BUCKET_NAME} --region ${REGION}
# Create folder for your tarball files
aws s3 mb s3://${DCP_BUCKET_NAME}/${DCP_FOLDER_NAME}/
# Upload the file to S3
aws s3 cp ${DCP_TARBALL_TO_INGEST} s3://${DCP_BUCKET_NAME}/${DCP_FOLDER_NAME}/
export LOGS_BUCKET_NAME='<logs bucket name>'
export LOGS_FOLDER_NAME='<logs folder name>'
# Create a folder to keep your logs
aws s3 mb s3://${LOGS_BUCKET_NAME}/${LOGS_FOLDER_NAME}/ --region ${REGION}
# Create a temp file
touch LOGS_FILES_GO_HERE.txt
# Create the folder on S3
aws s3 cp LOGS_FILES_GO_HERE.txt s3://${LOGS_BUCKET_NAME}/${LOGS_FOLDER_NAME}/
export DCP_TARBALL_NAME=$(basename ${DCP_TARBALL_TO_INGEST})
export CL_DESIGN_NAME='<cl_design_name>'
export CL_DESIGN_DESCRIPTION="Description of ${CL_DESIGN_NAME}"
# Call AWS CLI ingestion command
aws ec2 create-fpga-image --name ${CL_DESIGN_NAME} --description "${CL_DESIGN_DESCRIPTION}" --input-storage-location Bucket=${DCP_BUCKET_NAME},Key=${DCP_FOLDER_NAME}/${DCP_TARBALL_NAME} --logs-storage-location Bucket=${LOGS_BUCKET_NAME},Key=${LOGS_FOLDER_NAME}/ --region ${REGION}
Expected response format:
{
"FpgaImageId": "afi-09953582f46c45b17",
"FpgaImageGlobalId": "agfi-0925b211f5a81b071"
}
After you successfully get the AFI/AGFI ID, you not longer required to the this EC2 instance
Check the AFI build progress
aws ec2 describe-fpga-images --fpga-image-ids afi-09953582f46c45b17 --region us-east-1
Example output (truncated):
{
"FpgaImages": [
{
"FpgaImageId": "afi-09953582f46c45b17",
"FpgaImageGlobalId": "agfi-0925b211f5a81b071",
"Name": "cl_sde_0x10212415",
"Description": "Latest devkit build of cl_sde with 0x10212415 small shell release",
"State": {
"Code": "available"
},
}
]
}
The Status will change from pending to available. This process may take approximately 30 minutes to 1 hour for the example provided.
This tutorial uses the provided Python runtime. You can also validate using the AWS C runtime if preferred.
1. Launch an F2 instance. 2. On the instance, clone the repositories:
git clone https://github.com/aws/aws-fpga.git
git clone https://github.com/BoonHong317/aws-fpga-f2-vitis-to-afi-poc.git
3. Set up the AWS FPGA SDK tooling:
cd aws-fpga
source sdk_setup.sh
sudo fpga-clear-local-image -S 0 -H
Example output:
AFI 0 No AFI cleared 1 ok 0 0x10212415
AFIDEVICE 0 0x1d0f 0x9048 0000:00:1e.0
sudo fpga-describe-local-image -S 0 -H
Example output:
Type FpgaImageSlot FpgaImageId StatusName StatusCode ErrorName ErrorCode ShVersion
AFI 0 No AFI cleared 1 ok 0 0x10212415
Type FpgaImageSlot VendorId DeviceId DBDF
AFIDEVICE 0 0x1d0f 0x9048 0000:00:1e.0
If
FpgaImageIdshowsNone/empty unexpectedly, stop and start the instance (do not “reboot”) so AWS can reallocate the FPGA device. If the issue persists, consider raising a support case with AWS.
sudo fpga-load-local-image -S 0 -H -I agfi-xxxxxxxxxxxxxxxxx
Example output:
AFI 0 agfi-xxxxxxxxxxxxxxxxx loaded 0 ok 0 0x10212415
AFIDEVICE 0 0x1d0f 0x9048 0000:00:1e.0
cd ~
# copy the testbench
cp ./aws-fpga-f2-vitis-to-afi-poc/cl_python_runtime/*.py ./aws-fpga/sdk/userspace/cython_bindings/
cd ~/aws-fpga/sdk/userspace/cython_bindings/
For the AXI-Lite-only example (cl_poc_ocl)
sudo python3 cl_poc_ocl.py
Output:
[INFO] Test PASSED: All output data matches expected results.
For the AXI-Lite + DDR (m_axi) example (cl_poc_ocl)
sudo python3 cl_poc_ocl_ddr.py
Output:
[INFO] Test PASSED: All output data matches expected results.
sudo fpga-clear-local-image -S 0 -H
You have now:
1. Exported RTL from Vitis HLS (or used the provided example export)
2. Generated an AWS F2 CL project using hls_to_cl.py
3. Built a DCP and created an AFI using AWS HDK and AWS CLI tooling
4. Validated the AFI on an F2 instance using the provided Python runtime
If you run into issues, please open a GitHub issue with:
If this repo is helpful, please consider starring it on GitHub.
For hiring or collaboration opportunities, feel free to contact the maintainer. Thank you.