一、概述
AVED (Alveo Versal Example Design) 是 AMD 为 Alveo V80 数据中心加速器卡提供的示例设计,采用 Vivado 设计流程,包含:
- 硬件基础设计(PCIe 连接、系统管理)
- 固件库(运行在 RPU 处理器上)
- 主机驱动和工具程序
Alveo V80 卡特性
| 组件 | 规格 |
|---|---|
| FPGA | Versal HBM |
| 内部 HBM | 32GB |
| DDR4 (板上) | 4GB |
| DDR4 DIMM | 32GB |
| 接口 | PCIe Gen5x8、QSFP、MCIO |
二、开发环境准备
1. 系统要求
| 操作系统 | 内核版本 |
|---|---|
| Ubuntu 24.04 | 6.8.0 |
| RHEL 9.4 | 5.14.0 |
2. 工具依赖
- Vivado 2025.1(与 AVED 发布版本匹配)
- Python 3.6.8+
- CMake 3.5.0+
- 系统内存: 64GB(用于构建)
3. 重要提示
# AVED 不使用 XRT,需先卸载
# Ubuntu
sudo apt remove xrt
# RHEL
sudo yum remove xrt
三、快速入门:安装预构建设计
步骤 1: 下载部署包
从 AVED 发布页面 下载最新部署包。
步骤 2: 安装到主机
# 解压并运行安装脚本
sudo ./aved_install.sh
步骤 3: 通过 JTAG 烧录 Flash
首次安装需通过 JTAG 更新 FPT(Flash Partition Table):
- 打开 Vivado Hardware Manager
- 连接 JTAG
- 烧录 FPT 镜像
- 冷启动服务器
步骤 4: 验证安装
# 查看设备概览
ami_tool overview
# 查看传感器状态
ami_tool sensors -d <BDF>
# 运行验证测试
xbtest -d <BDF> -c verify
# 运行内存测试
xbtest -d <BDF> -c memory
四、从源码构建设计
1. 下载源码
# 克隆 AVED 仓库(指定版本标签)
git clone --branch <tag> https://github.com/Xilinx/AVED.git
2. 获取 SMBus IP
从 https://www.xilinx.com/member/v80.html 下载 SMBus IP,放入:
AVED/hw/amd_v80_gen5x8_25.1/src/iprepo/smbus_v1_1/
3. 目录结构
AVED/
├── deploy/scripts/ # 部署脚本
├── fw/AMC/ # 固件源码
├── hw/amd_v80_gen5x8_25.1/ # 硬件设计
└── sw/AMI/ # 主机软件
4. 构建硬件
# 设置 Vivado 环境
source settings64.sh
# 进入硬件目录
cd AVED/hw/amd_v80_gen5x8_25.1
# 执行构建脚本
./build_all.sh
5. 构建输出文件
build/
├── amd_v80_gen5x8_25.1_nofpt.pdi # 设计 PDI(用于 PCIe 更新)
├── amc.elf # 固件 ELF
├── fpt.bin # Flash 分区表
└── prj.xpr # Vivado 工程
6. 构建软件
cd AVED/sw/AMI
python3 scripts/gen_package.py
# 在部署服务器上安装
sudo apt install <path/to/ami_xxx.deb>
五、硬件架构
设计层次
┌─────────────────────────────────────────┐
│ CIPS (控制接口处理系统) │
│ ┌─────────┐ ┌─────────┐ ┌───────────┐ │
│ │ CPM │ │ RPU │ │ PMC │ │
│ │(PCIe) │ │(R5固件) │ │(平台管理) │ │
│ └─────────┘ └─────────┘ └───────────┘ │
├─────────────────────────────────────────┤
│ NoC (片上网络) │
│ 连接 PCIe、HBM、DDR、PL │
├─────────────────────────────────────────┤
│ PL (可编程逻辑) │
│ ┌───────────┐ ┌───────────────────────┐│
│ │ Base Logic│ │ Clocks & Resets ││
│ │ (管理逻辑) │ │ (时钟复位模块) ││
│ └───────────┘ └───────────────────────┘│
└─────────────────────────────────────────┘
Base Logic 组件
| 组件 | 功能 |
|---|---|
| UUID ROM | 存储 128 位唯一设计标识 |
| Hardware Discovery | PCIe 扩展能力,发现硬件端点 |
| GCQ (gcq_m2r) | 主机与 RPU 通信邮箱 |
| SMBus IP | 带外管理接口(与 BMC 通信) |
内存资源分配
| 内存类型 | 容量 | 用途 |
|---|---|---|
| DDR4 (板上) | 4GB | RPU 处理器 + DMA |
| HBM | 32GB | 用户应用 |
| DDR4 DIMM | 32GB | 用户应用 |
六、软件架构
AMC 固件分层
┌─────────────────────────────────────┐
│ Applications │
│ (AMC主程序、In-Band/Out-Band遥测) │
├─────────────────────────────────────┤
│ Proxy Drivers │
│ (AMI、APC、ASC、AXC、BMC) │
├─────────────────────────────────────┤
│ Profiles │
│ (板级配置) │
├─────────────────────────────────────┤
│ Device Drivers │
│ (I2C、EEPROM、SMBus、GCQ等) │
├──────────────┬──────────────────────┤
│ OSAL │ FAL │
│ (操作系统抽象) │ (固件接口抽象) │
└──────────────┴──────────────────────┘
Proxy Driver 功能
| Driver | 功能 |
|---|---|
| AMI | 主机通信管理 |
| APC | Flash 编程控制 |
| ASC | 传感器控制 |
| AXC | 外部设备控制(QSFP) |
| BMC | 板级管理控制器通信 |
七、主机与卡通信
PCIe 物理功能
| PF | 用途 |
|---|---|
| PF0 | 管理(UUID ROM、GCQ 邮箱) |
| PF1 | 用户数据(DMA 访问 DDR/HBM) |
通信机制
Host (AMI) ←→ GCQ邮箱 ←→ RPU (AMC固件) ←→ 传感器/Flash
↓
共享内存
八、设计编程与更新
更新设计 PDI(通过 PCIe)
# 使用 ami_tool 更新 Flash
sudo ami_tool cfgmem_program -d <BDF> -t primary \
-i /path/to/design.pdi -p 0
更新 FPT(通过 JTAG)
仅当 FPT 修改时需要,使用 Vivado Hardware Manager。
九、开发流程总结
1. 准备环境 (Vivado + SMBus IP)
↓
2. 克隆源码
↓
3. 构建硬件
↓
4. 构建固件 (fw step)
↓
5. 生成 FPT (fpt step)
↓
6. 打包 PDI (pdi step)
↓
7. 部署到主机
↓
8. 编程到卡
↓
9. 测试验证
十、关键命令速查
| 操作 | 命令 |
|---|---|
| 查看设备状态 | ami_tool overview |
| 查看传感器 | ami_tool sensors -d <BDF> |
| 查看制造信息 | ami_tool mfg_info -d <BDF> |
| 更新 Flash | ami_tool cfgmem_program -d <BDF> -t primary -i <pdi> -p 0 |
| 验证测试 | xbtest -d <BDF> -c verify |
| 内存测试 | xbtest -d <BDF> -c memory |
| 压力测试 | xbtest -d <BDF> -c stress |
你的困惑非常正常!FPGA 加速器开发确实与传统软件开发完全不同。让我帮你理清思路:
核心问题:AVED 不是让你"写代码",而是让你"搭积木"
传统软件开发:
写代码 → 编译 → 运行
FPGA 加速器开发:
选择基础框架 → 添加加速模块 → 综合/实现 → 部署
你需要先回答一个问题
你要加速什么?
| 场景 | 开发方式 | 工具 |
|---|---|---|
| 已有 C/C++ 算法 | HLS 高层综合 | Vitis HLS |
| 已有 RTL 设计 | 直接集成 | Vivado |
| 数据包处理/网络 | RTL 开发 | Vivado |
| 从零开始的新算法 | HLS 或 RTL | 两者皆可 |
三条开发路径
路径 A:使用 Vitis HLS(推荐入门)
适合:有 C/C++ 算法经验的人
步骤:
1. 用 C++ 写加速函数(kernel)
2. 用 Vitis HLS 综合 → 生成 IP
3. 在 AVED Block Design 中集成这个 IP
4. 生成 PDI → 部署
你的第一个 HLS kernel:
// vector_add.cpp - 简单向量加法
#include <hls_stream.h>
extern "C" {
void vector_add(
hls::stream<int>& in1,
hls::stream<int>& in2,
hls::stream<int>& out,
int size
) {
for (int i = 0; i < size; i++) {
#pragma HLS PIPELINE II=1
out.write(in1.read() + in2.read());
}
}
}
路径 B:修改 AVED Block Design(系统集成)
适合:想在 AVED 框架上添加自己的 IP
步骤:
1. 打开 Vivado 工程
vivado AVED/hw/amd_v80_gen5x8_25.1/build/prj.xpr
2. 打开 Block Design(IP Integrator)
3. 添加你的 IP(自己写的或 Xilinx IP 库)
4. 连接到 NoC 或 AXI 总线
5. 修改地址映射
6. 重新构建
路径 C:RTL 开发
适合:有 Verilog/VHDL 经验的人
// my_accelerator.v
module my_accelerator (
input wire clk,
input wire rst,
input wire [31:0] data_in,
output reg [31:0] data_out
);
always @(posedge clk) begin
if (rst)
data_out <= 0;
else
data_out <= data_in * 2; // 简单示例
end
endmodule
具体上手步骤(从零到第一个加速器)
第 1 步:先跑通 AVED 预构建版本
# 安装预构建版本,确认环境正常
sudo ./aved_install.sh
ami_tool overview
xbtest -d <BDF> -c verify
目的:确保硬件、驱动、工具链都正常
第 2 步:打开 Vivado 工程,理解现有设计
vivado AVED/hw/amd_v80_gen5x8_25.1/build/prj.xpr
在 Vivado 中:
- 点击 Open Block Design
- 观察现有 IP 连接方式
- 找到 User Application 区域(如果有的话)
第 3 步:创建你的第一个 HLS IP
# 启动 Vitis HLS
vitis_hls
# 或在 Vivado 中:Tools → Create and Package New IP
示例项目:向量加法
源文件:
├── vector_add.cpp # 内核代码
├── vector_add.h # 头文件
└── vector_add_test.cpp # 测试平台
// vector_add.cpp
#include <hls_vector.h>
#include "hls_stream.h"
typedef hls::vector<int, 16> vec16; // 一次处理16个int
extern "C" {
void vector_add(
vec16* a, // 输入A
vec16* b, // 输入B
vec16* out, // 输出
int count // 元素数量
) {
#pragma HLS INTERFACE m_axi port=a bundle=gmem0
#pragma HLS INTERFACE m_axi port=b bundle=gmem1
#pragma HLS INTERFACE m_axi port=out bundle=gmem2
#pragma HLS INTERFACE s_axilite port=count bundle=control
#pragma HLS INTERFACE s_axilite port=return bundle=control
for (int i = 0; i < count; i++) {
#pragma HLS PIPELINE II=1
out[i] = a[i] + b[i];
}
}
}
HLS 流程:
- C Simulation(验证功能)
- C Synthesis(生成 RTL)
- Export RTL(导出为 IP)
第 4 步:将 IP 集成到 AVED
在 Vivado Block Design 中:
-
添加你的 IP
- Window → IP Catalog
- 搜索你的 IP 名称
- 双击添加
-
连接到 NoC
- 你的 IP 的 AXI Master → NoC Slave
- NoC Master → 你的 IP 的 AXI Slave(控制接口)
-
分配地址
- Address Editor → 为你的 IP 分配地址范围
-
连接时钟和复位
- 连接到 Clock Reset Module
第 5 步:修改主机程序
AVED 使用 AMI 而非 XRT,你需要:
// my_host_app.cpp
#include "ami.h"
int main() {
// 1. 初始化设备
ami_device_t device;
ami_device_open(0, &device); // 打开第一个设备
// 2. 分配缓冲区
void* buf_a = ami_alloc(device, SIZE);
void* buf_b = ami_alloc(device, SIZE);
void* buf_out = ami_alloc(device, SIZE);
// 3. 写入数据
ami_write(device, buf_a, host_data_a, SIZE);
ami_write(device, buf_b, host_data_b, SIZE);
// 4. 启动内核(通过 MMIO)
ami_mmio_write(device, CONTROL_REG, 1);
ami_mmio_write(device, COUNT_REG, SIZE);
// 5. 等待完成
while (ami_mmio_read(device, STATUS_REG) != DONE);
// 6. 读回结果
ami_read(device, buf_out, host_result, SIZE);
return 0;
}
开发范式对比
| 传统软件 | FPGA 加速器 |
|---|---|
写 .c/.cpp 文件 |
写 HLS kernel 或 RTL |
gcc 编译 |
HLS 综合 + Vivado 实现 |
运行 .exe |
生成 .pdi 烧录到卡 |
printf 调试 |
ILA/ChipScope 波形调试 |
| 内存自动管理 | 手动管理 AXI 总线/NoC |
我的建议
如果你是 FPGA 新手:
- 先不要改 AVED,从独立的 HLS 项目开始
- 学习 HLS 教程:Vitis HLS 入门
- 理解
#pragma HLS指令的作用 - 学会生成 IP 后,再集成到 AVED
推荐的入门项目:
- 向量加法(理解数据流)
- 矩阵乘法(理解并行化)
- FIR 滤波器(理解流水线)