XILINX暑期学校记录(LAB1):GPT代码注释

#include "./fir.h"

// 定义一个全局变量数组c,用于存储滤波器的系数
//coef_t 是一个数据类型,用于表示滤波器的系数。它是用户自定义的数据类型,
//在这段代码中用于定义滤波器的系数数组 c 的元素类型。
coef_t c[N];

// FIR滤波器函数,输入一个样本x,输出滤波后的结果y

void fir(data_t *y, data_t x)
{
    // 使用HLS指令将数组c完全分区,以提高并行度
#pragma HLS ARRAY_PARTITION variable=c complete dim=0
/*
#pragma HLS ARRAY_PARTITION variable=c complete dim=0 是一个HLS指令,用于控制Vivado HLS工具对数组 c 进行分区优化。

解析该指令的含义如下:

#pragma HLS: 是用于向HLS工具提供指令的预处理器指令。
ARRAY_PARTITION: 指定对数组进行分区优化。
variable=c: 指定需要分区的数组是 c。
complete: 指定对数组进行完全分区,即将数组的所有元素均分到不同的存储区域。
dim=0: 指定分区的维度为维度0,即按照第一个维度对数组进行分区。
该指令的作用是将数组 c 进行完全分区,以提高并行度和性能。通过将数组的不同部分分配到不同的存储区域,
可以并行地处理数组的不同元素,从而加快计算速度。

需要注意的是,#pragma HLS 指令是用于告诉HLS工具如何对代码进行优化,
具体的优化效果和结果取决于HLS工具的实现和设置,以及代码的结构和特性。
在使用HLS指令时,建议参考相关的HLS工具文档和指南,以了解更详细的指令说明和使用方法。
*/
    // 定义一个静态数组shift_reg,用于存储滤波器的状态(延迟线)
    static data_t shift_reg[N];

    // 使用HLS指令将数组shift_reg完全分区,以提高并行度
#pragma HLS ARRAY_PARTITION variable=shift_reg complete dim=0

    // 定义一个累加器acc,用于计算滤波结果
    acc_t acc;

    // 定义一个循环变量i
    int i;

    // 初始化累加器为0
    acc = 0;

    // 使用流水线指令设置流水线间隔为1
#pragma HLS PIPELINE II=1
    /*
    #pragma HLS: 是用于向HLS工具提供指令的预处理器指令。
    PIPELINE: 指定对循环进行流水线优化。
    II=1: 指定流水线的间隔(II)为1,表示每个周期可以处理一个迭代。
    */
    // 循环计算滤波结果
    for (i = N - 1; i >= 0; i--)
    {
        // 判断是否是最后一个系数,如果是,直接将输入样本乘以系数,并更新延迟线的第一个元素
        if (i == 0)
        {
            acc += x * c[0];
            shift_reg[0] = x;
        }
        else
        {
            // 更新延迟线中的元素,将当前位置的元素设置为上一个位置的元素
            shift_reg[i] = shift_reg[i - 1];

            // 累加器加上当前位置的延迟线元素乘以对应的系数
            acc += shift_reg[i] * c[i];
        }
    }

    // 将累加器的值赋给输出结果
    *y = acc;
}
void fir_wrap(data_t *y, data_t *x, int len, coef_t *coef)
{
    // 使用HLS指令设置coef、x、y为M_AXI接口,并指定相应的内存深度
#pragma HLS INTERFACE m_axi port=coef offset=slave depth=99
#pragma HLS INTERFACE m_axi port=x offset=slave depth=100
#pragma HLS INTERFACE m_axi port=y offset=slave depth=100

    // 使用HLS指令设置len为S_AXILITE接口,表示len是一个轻量级的控制接口
#pragma HLS INTERFACE s_axilite port=len bundle=CTRL

    // 使用HLS指令设置return为S_AXILITE接口,表示函数的返回值是一个轻量级的控制接口
#pragma HLS INTERFACE s_axilite port=return bundle=CTRL

    // 定义一个中间变量res,用于存储每次调用fir函数的结果
    data_t res;

    // 使用循环将coef数组中的系数值赋给全局变量数组c
    for (int i = 0; i < N; i++)
    {
        // 使用HLS指令设置循环体为流水线,流水线间隔为1
#pragma HLS PIPELINE II=1
        c[i] = *coef++;
    }

    // 使用循环对输入样本数组x进行滤波,并将结果存储到输出数组y中
    for (int i = 0; i < len; i++)
    {
        // 使用HLS指令设置循环体为流水线,流水线间隔为1
#pragma HLS PIPELINE II=1
        fir(&res, *x++);
        *y = res;
        y++;
    }
}

HLS指令使用:

对于N阶FIR滤波器,需要N个乘法和N-1个加法器。

#pragma是用以引导RTL生成趋势的 注释,例如并行度。

#pragma HLS PIPELINE II=1

写在for循环之外,会将内侧展开为一个N份实体,由于使用数据的实体增多,并行性大大增加,故而我们在定义数组的时候需要使用:

#pragma HLS ARRAY_PARTITION variable=c complete dim=0

ARRAY_PARTITION: 指定对数组进行分区优化。

variable=c: 指定需要分区的数组是 c。

complete: 指定对数组进行完全分区,即将数组的所有元素均分到不同的存储区域。

dim=0: 指定分区的维度为维度0,即按照第一个维度对数组进行分区。

(个人理解类似于列表,每个元素生成一个独立的存储器)

该指令的作用是将数组 c 进行完全分区,以提高并行度和性能。通过将数组的不同部分分配到不同的存储区域,使得可以同时访问每个元素。

 #pragma HLS INTERFACE m_axi port=coef offset=slave depth=99

       #pragma HLS: 是用于向HLS工具提供指令的预处理器指令。

        INTERFACE: 指定定义接口类型和属性。

        m_axi: 指定接口类型为 m_axi,表示使用AXI总线接口。

        port=coef: 指定接口名称为 coef,表示接口与变量 coef 关联。

        offset=slave: 指定接口属性为 slave,表示接口是作为从设备使用。

        depth=99: 指定接口属性为 depth,表示指定接口的缓冲区深度为99。

        该指令的作用是定义变量 coef 的接口属性,以便与外部设备进行数据交换。

        m_axi 是一种常见的接口类型,用于连接FPGA与外部存储器或其他外设。

        offset=slave 表示 coef 是作为从设备接收数据。

        depth=99 表示定义接口的缓冲区深度为99,用于存储接收的数据。(TB处理的最大采样数)

因为一次处理一个数据/输出一个数据并不划算,事实上我们输入输出都会是一个很长的数组(或者其他形式)。

        // 使用循环将coef数组中的系数值赋给全局变量数组c
    for (int i = 0; i < N; i++)
    {
        // 使用HLS指令设置循环体为流水线,流水线间隔为1
#pragma HLS PIPELINE II=1
        c[i] = *coef++;
    }
        //读入所有滤波器系数,实现本地化,减少通讯时间。



    for (int i = 0; i < len; i++)

    {

        // 使用HLS指令设置循环体为流水线,流水线间隔为1

#pragma HLS PIPELINE II=1

        fir(&res, *x++);

        *y = res;

        y++;

    }

bundle:绑定两个s_axilite在一起,由于这两接口用的少,绑在一起轻量化设计(现在软件的自优化可以自动自行)

s_axilite 轻量化axi,减少资源占用;

#pragma HLS INTERFACE s_axilite port=return bundle=CTRL设置的目的是留一个接口便于控制。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值