aws-fpga-f2-vitis-to-afi-poc

Tutorial

1) Introduction

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:


2) Step-by-step tutorial (copy/paste workflow)

Step 0 — Prerequisites

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.


Step 1 — Clone the repository

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 as HLS_RTL_DIR.

Check the supported CLI arguments for your version:

python3 ./aws-fpga-f2-vitis-to-afi-poc/hls_to_cl.py --help

Step 3 — Generate an AWS CL project from a Vitis HLS RTL export

This repository includes example inputs and reference outputs to validate the flow quickly:

Set the following variables:

export 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}

Step 4 — Optional: Compare against the reference output

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:

4A) Compare the synthesis TCL and top-level wrapper

# 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

4B) Confirm RTL files exist in the generated 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)

Step 5 — Run the AWS HDK build flow (CL → DCP → AFI)

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.

5A) CL → DCP

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

5B) Locate the generated DCP tarball

cd ../checkpoints
# This is your generated DCP file
ls -l *.Developer_CL.tar

Step 6 — DCP → AFI (AWS CLI ingestion)

The commands below are adapted from AWS documentation. Replace placeholder values before running.

6A) Upload the DCP tarball to S3

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}/

6B) Create a log location (S3)

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}/

6C) Create the AFI

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

6D) Check AFI build status

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.

Step 7 — Verify the AFI using the Python runtime

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

7A) Clear any previously loaded AFI from slot 0

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

7B) Describe the current slot state

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 FpgaImageId shows None/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.

7C) Load your AFI (AGFI) into slot 0

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

7D) Run the Python runtime tests

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.

7E) Clear the AFI before terminating the instance

sudo fpga-clear-local-image -S 0 -H

Complete

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.