HLS中的MAXI位宽扩展

Vitis HLS版本 2022.2

在hls中常使用maxi接口用于从内存中加载数据至片上RAM,默认情况下axi的总线数据位宽为32位,当需要并行加载数据或一次加载多个数据时则可通过多个maxi接口或扩展maxi数据位宽

example

有一个[4][768][64]的权重数据进行加载,可在存储数据时调换维度,将第一维度通道调换至最后一维度,使得多个通道的数据相邻,扩展位宽可一次并行读取多个通道的数据,方便后续计算。

1.在工程设置中,修改以下参数

2. 在设置Interface pragama时要求ddr接口绑定(命名)bundle,

3. m_axi_max_widen_bitwidth为总线的最大位宽,alignment_byte_size 为字节对其数,我们设置最大位宽为128,则对齐字节字节数为128/8=16,意味着每次传输数据会对齐。

4. 并声明max_widen_bitwidth(总线位宽)的大小,必须为2的n次幂,其次要将用语缓存数据的RAM进行分块,分块数量与总线位宽相关联,

5. 最后在用for循环读取数据时,相邻数据必须连续,for循环的最内层利用pragama unroll factor展开

方法1

代码如下:

// 方法1

void load_w(float *wqkv_ddr, float wqkv_buff[768*64*4]){

#pragma HLS INTERFACE mode=m_axi bundle=gmem_0 max_widen_bitwidth=128 port=wqkv_ddr
#pragma HLS ARRAY_PARTITION dim=1 factor=4 type=cyclic variable=wqkv_buff


	for(int i=0;i<768*64*4;i++){
#pragma HLS UNROLL factor=4
		wqkv_buff[i] = wqkv_ddr[i];
	}

}

综合结果如下:可以看到不论是时钟周期(768*64)还是数据位宽128都可以证明已经提高了数据读取的并行度

方法2

以上为方法1的代码与结果,方法1存在一定的局限性,例如在当只需加载768*64*3的权重数据时,则必须在片上定义768*64*4的片上缓存空间,浪费掉了宝贵的片上BRAM,于是可以采用方法2,保持接口位宽不变,即访问地址的数据量不变,但仅读取部分的数据位宽,代码如下

void load_w(float*wqkv_ddr, floatwqkv_buff[768][64][3]){

#pragma HLS INTERFACE mode=m_axi bundle=gmem_0 max_widen_bitwidth=128 port=wqkv_ddr
#pragma HLS ARRAY_PARTITION dim=3 factor=3 type=cyclic variable=wqkv_buff


	for(int i=0;i<768;i++)
		for(int j=0;j<64;j++)
			for(int k=0;k<3;k++){	//chin*win*hin
#pragma HLS UNROLL factor=3

				wqkv_buff[i][j][k] = wqkv_ddr[i*64*4+j*4+k]; 	
                //此处数据偏移量为4*float,因此内存中数据要扩展一个维度[768][64][4]
	}

}

此方法需保证在ddr中存储的数据是整个位宽扩展对应的数据,例如:定义接口是4*32=128 bit,则内存中应对应单次访问4个数据,当所需数据仅有3个时,补充最后一个数据为0。此方法可避免因提高并行度扩展位宽所带来的额外存储资源开销

综合结果如图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值