Zynq Book Tutorials Lab 4-C部分添加指令问题

The Zynq Book Tutorials Lab 4-C part adding directive problem

我正在尝试运行 zynq book tutorials lab 4 and c part in vivado hls (hls included vitis in new version) 但是当我在书中描述的添加指令的步骤中右键单击时,添加指令 window 未打开。我分别在 2015.1、2018.3 和 2021.2 版本的 vivado 中尝试了这个,结果在我遇到问题的所有 them.The 步骤中都是相同的,如下所示。Tutorial Book Link is here. Although I researched the problem a lot on the internet, there was not much result, but someone who encountered this problem in xilinx's forum explained in this link 他提到这是一个错误并且可以使用 #pragma 命令将相同的操作添加到 c 文件 line.Since 我是这些问题的新手,如果您能帮助我如何使用中提到的 #pragma 命令添加指令,我将不胜感激教程中的步骤 (m)。

提到的c代码如下

    void nco (ap_fixed<16,2> *sine_sample, ap_ufixed<16,12> step_size){
    ap_ufixed<12,12> address;

    temp+=step_size; // Accumulator. Values will wrap around on overflow.

    address = ap_ufixed<12,12>(temp); // Cast address to a 12-bit integer value.

    *sine_sample = sine_lut[(int)address]; // Assign sign sample from LUT based on current address
    }

我会尽量给你一个更具教学意义的答案,而不是针对你的问题的具体答案。

Xilinx HLS-specific pragma 的想法是指导 HLS“编译器”生成接近设计者意图的硬件组件。 因此,存在很多这样的 HLS pragma,Xilinx Vitis-HLS 用户指南充满了可供查阅的参考资料。

在实践中,根据您要使用的 pragma,您需要将其相应地放置在您的代码中(毕竟,pragma 与任何其他代码行一样)。 例如,在您的代码片段中:

void nco (ap_fixed<16,2> *sine_sample, ap_ufixed<16,12> step_size){
#pragma HLS INTERFACE port=sine_sample ...
#pragma HLS INTERFACE port=step_size ...
    ap_ufixed<12,12> address;
    static ap_ufixed<12,12> temp = 0;
#pragma HLS RESOURCE variable=temp ...
    temp += step_size; // Accumulator. Values will wrap around on overflow.
    address = ap_ufixed<12,12>(temp); // Cast address to a 12-bit integer value.
    *sine_sample = sine_lut[(int)address]; // Assign sign sample from LUT based on current
}

pragma INTERFACE 可以放在函数中的任何位置,因为它指的是函数参数,并且它们在函数范围内随处可用。另一方面,pragma RESOURCE 必须放在 之后 定义变量的范围, temp

编译指示顺序更重要的另一个例子是循环和嵌套循环。例如,假设将 pragma PIPELINE 放在这三个不同的位置:

#pragma HLS PIPELINE II=1 // It will appy the pipeline to the whole function, fully unrolls both N-loop and M-loop
for (int i = 0; i < N; ++i) {
#pragma HLS PIPELINE II=1 // It will appy the pipeline to the N-loop and fully unroll the M loop
    for (int j = 0; j < M; ++j) {
#pragma HLS PIPELINE II=1 // It will appy the pipeline to M-loop only, keeping both the N-loop and M-loop rolled, but pipelined
        // ...
    }
}

注意,在这个例子中,假设当时只有一个编译指示被注释掉了。我将它们放在一起只是为了示例(以这种方式所有活动都没有多大意义,我相信 function-level 编译指示将简单地接管其他编译指示)。

一般来说,我建议您仔细阅读您打算使用的每个 pragma 的文档,以及如何以及在代码中放置它的位置。

祝你好运!

是的,有时 Vivado(现在是 Vitis)HLS GUI 不显示该指令。但是,这是一个因祸得福,因为它迫使您在代码中手动添加编译指示,因此您实际上可能理解 编译指示和它们对生成的 RTL 的影响。从上面的示例看来,您将使用 INTERFACERESOURCE pragmas.

作为HLS爱好者,我想先简单介绍一下这两个pragma的基本理解和语法,最后你可以查看我对你问题的解答。


杂注 HLS 接口 :


INTERFACE 编译指示指定在接口综合期间如何从函数定义创建 RTL 端口。 RTL 实现中的端口来自:

  • 任何指定的 function-level 协议。
  • 函数参数。
  • 全局变量由 top-level 函数访问并在其作用域外定义。

下面是 INTERFACE pragma 的语法:

语法:

#pragma HLS interface <mode> port=<name> bundle=<string> \
register register_mode=<mode> depth=<int> offset=<string> \
clock=<string> name=<string> \
num_read_outstanding=<int> num_write_outstanding=<int> \
max_read_burst_length=<int> max_write_burst_length=<int>

为了明确理解语法中的每个参数,请执行阅读以下参考资料中的详细信息:


pragma HLS 资源:


指定特定的库资源(核心)用于在RTL中实现变量(数组、算术运算或函数参数)。如果未指定 RESOURCE pragma,Vivado HLS 将确定要使用的资源。

#pragma HLS resource variable=<variable> core=<core>\
latency=<int>

为了明确理解语法中的每个参数,请执行阅读以下参考资料中的详细信息:


您的解决方案


更新:现在我再次 post 这个解决方案 运行 我自己在 Vivado HLS 上的代码,因此更清楚:

void nco (ap_fixed<16,2> *sine_sample, ap_ufixed<16,12> step_size) {


#pragma HLS RESOURCE variable=sine_sample core=AXI4LiteS
#pragma HLS RESOURCE variable=step_size core=AXI4LiteS
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS RESOURCE variable=return core=AXI4LiteS

    // Define the pcore interface and group into AXI4 slave "slv0"

    /* Value to hold the current address value of the sine LUT
     * 12-bit unsigned fixed-point, all integer bits.
     * Overflow is set to "wrap around" by default. */
    ap_ufixed<12,12> address;

    temp+=step_size; // Accumulator. Values will wrap around on overflow.

    address = ap_ufixed<12,12>(temp); // Cast address to a 12-bit integer value.

    *sine_sample = sine_lut[(int)address]; // Assign sign sample from LUT based on current address
}

在某些 Vivado HLS 版本上,上述解决方案可能会发出如下警告:

WARNING: [HLS 200-41] Resource core 'AXI4LiteS' on port '&sine_sample' is deprecated. Please use the interface directive to specify the AXI interface.

因此,我们对所有变量使用 INTERFACE 指令,如下所示不会发出警告:

void nco (ap_fixed<16,2> *sine_sample, ap_ufixed<16,12> step_size) {

#pragma HLS INTERFACE s_axilite port=sine_sample
#pragma HLS INTERFACE s_axilite port=step_size
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE ap_ctrl_none port=return

    // Define the pcore interface and group into AXI4 slave "slv0"

    /* Value to hold the current address value of the sine LUT
     * 12-bit unsigned fixed-point, all integer bits.
     * Overflow is set to "wrap around" by default. */
    ap_ufixed<12,12> address;

    temp+=step_size; // Accumulator. Values will wrap around on overflow.

    address = ap_ufixed<12,12>(temp); // Cast address to a 12-bit integer value.

    *sine_sample = sine_lut[(int)address]; // Assign sign sample from LUT based on current address
}