【HLS】pragma HLS bundle的用法 AXI接口
0.代码段
#include "ap_int.h"#define N 100 // 定义向量的长度// C++ 函数原型
// a, b 是输入向量(数组)
// c 是输出向量(数组)
// length 是向量的实际处理长度
void vec_add(int* a, int* b, int* c, int length) {// #pragma 指令区域// 1. 将所有函数参数(包括函数返回本身)都映射到 AXI-Lite 从设备接口上// 'bundle=control' 将它们组织在一起#pragma HLS INTERFACE s_axilite port=return bundle=control#pragma HLS INTERFACE s_axilite port=a bundle=control#pragma HLS INTERFACE s_axilite port=b bundle=control#pragma HLS INTERFACE s_axilite port=c bundle=control#pragma HLS INTERFACE s_axilite port=length bundle=control// 2. 核心算法:一个简单的 for 循环// 这个循环是实现硬件逻辑的关键VADD_LOOP: for (int i = 0; i < length; i++) {#pragma HLS PIPELINE II=1 // 指令:告诉HLS将循环体进行流水线优化,目标是每个时钟周期启动一次新的循环迭代(Initiation Interval = 1)c[i] = a[i] + b[i];}
}
解释所选择的 bundle=control
这段代码的含义。这是一个非常核心的 HLS 概念,用于组织和管理硬件接口。
1. bundle=...
是什么意思?
bundle
的字面意思是“捆绑”或“打包”。在 HLS 的 pragma 指令中,bundle
是一个关键字,它的作用是将多个独立的端口(port)分组,并将它们映射到同一个物理总线接口上。
如果没有 bundle
,默认情况下,HLS 可能会为每个 s_axilite
接口创建一个独立的、物理的 AXI-Lite 端口,这将导致硬件上有大量的冗余引脚和接口逻辑。
2. bundle=control
代表什么?
control
在这里是一个你自定义的名称。它代表这个特定捆绑组的名字。
所以,bundle=control
的完整含义是:
“请将这个端口(例如 port=b
)加入到一个名为 control
的捆绑包中。所有同样声明为 bundle=control
的端口,都将被合并到同一个 AXI-Lite 从设备接口上。”
在你当前的 Canvas 代码中,return
, a
, b
, c
, 和 length
这五个端口都被捆绑到了名为 control
的组里。这意味着 HLS 将会:
- 只生成一个 AXI-Lite 从设备物理接口。
- 在这个接口的统一地址空间内,为
a
,b
,c
,length
这些数据端口,以及ap_start
,ap_done
等控制信号(由port=return
引入)分配不同的地址。
这正是我们之前讨论的,处理器可以通过一个接口、访问不同地址来配置所有参数和控制任务的启动/停止。
3. 如果 bundle
的是不同名字,哪里不一样?
这是一个非常棒的延伸问题,能帮助你理解其灵活性。
假设你把代码改成这样:
// ...
#pragma HLS INTERFACE s_axilite port=return bundle=control
#pragma HLS INTERFACE s_axilite port=a bundle=config
#pragma HLS INTERFACE s_axilite port=b bundle=config
#pragma HLS INTERFACE s_axilite port=c bundle=config
#pragma HLS INTERFACE s_axilite port=length bundle=control
// ...
这里我们创建了两个不同的捆绑包:control
和 config
。
HLS 在综合后,生成的 Verilog 顶层模块将会拥有两个独立的 AXI-Lite 从设备物理接口!
-
第一个接口(名为
s_axi_control
):- 这个接口会包含
ap_start
/ap_done
等控制信号和length
变量的寄存器。 - 它会有一套完整的 AXI 信号,如
s_axi_control_AWADDR
,s_axi_control_WDATA
等。
- 这个接口会包含
-
第二个接口(名为
s_axi_config
):- 这个接口会包含
a
,b
,c
三个指针变量的地址寄存器。 - 它会有另一套完全独立的 AXI 信号,如
s_axi_config_AWADDR
,s_axi_config_WDATA
等。
- 这个接口会包含
这样做的好处是什么?
在复杂的设计中,这可以用来:
- 逻辑分组:将频繁变化的控制信号(如
ap_start
)和相对静态的配置参数(如数据地址)分离开,使软件驱动更清晰。 - 物理布局优化:在 FPGA 布局布线时,如果两个接口连接到系统中不同的主设备上,这样做可以提供更大的灵活性。
- 满足不同总线标准: 虽然这里都是 AXI-Lite, 但理论上可以将不同端口捆绑到不同类型的总线上。
总结:
bundle
是一个强大的分组工具。bundle
后面的名字(如 control
)就是这个组的标签。所有具有相同标签的端口共享一个物理接口;具有不同标签的端口则会生成各自独立的物理接口。