Vivado HLS设计读取FIFO

发布于 2025-01-24 10:06:17 字数 871 浏览 1 评论 0原文

我正在尝试开发FPGA上的系统来读取外部世界的数据(即Geiger Pulse Integrator,但此时我正在使用Arduino对其进行模拟);数据流将存储在FIFO缓冲区中,我使用Vivado的FIFO Generator IP实现了该数据流。一个小的RTL模块从Arduino获取数据,并将其写入FIFO。为了读取来自FIFO输出的数据,我需要设置一个可读取到较高的读数,然后等待N时钟周期,同时将输出存储在数组中,最后再次设置可读取的低点。我需要在Vivado HLS中执行此操作(因为我想将AXI接口与微处理器具有)。到目前为止,我已经尝试了此(以及一些不合格的变化):

#include "ap_cint.h"

#define N 10

int readfifo(int fifo_dout, int1* fifo_rd_en, int data[N])
{
#pragma HLS INTERFACE s_axilite port=data
#pragma HLS INTERFACE ap_none register port=fifo_rd_en
#pragma HLS INTERFACE ap_none port=fifo_dout
#pragma HLS INTERFACE s_axilite port=return

    *fifo_rd_en=1;
    for(int i=0; i<10; i++)
    {
#pragma HLS PIPELINE off
        data[i] = fifo_dout;
    }
    *fifo_rd_en=0;
    return 1;
}

在不同的试验中,我发现了两种行为:FIFO_RD_EN要么变得很高,而且数据被成功地读取了,但它永远不会下降,或者FIFO_RD_EN永远不会变得很高。

这种方法错了吗?

非常感谢。

I am trying to develop a system on FPGA to read data from the outer world (namely a Geiger pulse integrator, but at this point I am emulating it using an Arduino); the data stream is to be stored in a FIFO buffer, which I have implemented using the FIFO generator IP in Vivado. A little RTL module gets the data from the Arduino and succesfully writes it to the FIFO. In order to read the data from the FIFO output I need to set a read_enable to high, then wait for N clock cycles while storing the output in an array, and finally set the read_enable low again. And I need to do this in Vivado HLS (because I want to have AXI interface to a microprocessor). So far I have tried this (and some unsuccesful variations):

#include "ap_cint.h"

#define N 10

int readfifo(int fifo_dout, int1* fifo_rd_en, int data[N])
{
#pragma HLS INTERFACE s_axilite port=data
#pragma HLS INTERFACE ap_none register port=fifo_rd_en
#pragma HLS INTERFACE ap_none port=fifo_dout
#pragma HLS INTERFACE s_axilite port=return

    *fifo_rd_en=1;
    for(int i=0; i<10; i++)
    {
#pragma HLS PIPELINE off
        data[i] = fifo_dout;
    }
    *fifo_rd_en=0;
    return 1;
}

On different trials I have found two behaviours: either fifo_rd_en gets high and data is succesfully read but it never goes down again, or fifo_rd_en never gets high at all.

Is this approach wrong?

Thank you very much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

胡渣熟男 2025-01-31 10:06:17

由于无论如何您都使用Xilinx IP来生成外部FIFO,因此您只需在ap_fifo fifo_dout上使用ap_fifo指令,然后摆脱fifo_rd_en

这是修改的代码:

int readfifo(int fifo_dout[N], int data[N])
{
#pragma HLS INTERFACE s_axilite port=data
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE ap_fifo port=fifo_dout
  for(int i = 0; i < N; i++)
  {
#pragma HLS PIPELINE II=1
    data[i] = fifo_dout[i];
  }
  return 1;
}

这样,将自动包含读取启用启用信号。因此,无需在代码中写下它。以下是合成的HLS模块的共拟合波形。

。对于n周期和一个新元素,每个周期都存储。

请注意,此实现添加了A 必要的检查FIFO是否为空。这意味着,如果FIFO为空,则将产生的硬件模块将等待端口上的第i-the元素。 (您的预期实现中缺少此功能,并且可能导致硬件模块存储毫无意义的数据)

PS如果您的实现应在n循环中完成,无论FIFO是否为空,切换到C ++,其中您拥有FIFO类及其方法read_nb()

Since you're anyway using a Xilinx IP for generating the external FIFO, you can simply use the ap_fifo directive on fifo_dout and get rid of fifo_rd_en.

Here is the modified code:

int readfifo(int fifo_dout[N], int data[N])
{
#pragma HLS INTERFACE s_axilite port=data
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE ap_fifo port=fifo_dout
  for(int i = 0; i < N; i++)
  {
#pragma HLS PIPELINE II=1
    data[i] = fifo_dout[i];
  }
  return 1;
}

In this way, the read enable output signal is automatically included. Hence, there's no need to write it in the code. The following are the cosimulation waveforms of the synthesized HLS module.

Waveforms of the FIFO read port. The read enable output signal is automatically included.

As you can see, assuming the FIFO is not empty and already contains the N elements, the read enable stays on for N cycles and a new element is stored at each cycle.

Note that this implementation adds a necessary check on whether the FIFO is empty. This means that, if the FIFO is empty, the resulting hardware module will wait for the i-th element to be available on the port. (This feature was missing in your intended implementation and could lead the hardware module to store meaningless data)

p.s. If your implementation shall complete in N cycles no matter whether the FIFO is empty or not, you may want to switch to C++, where you have a FIFO class and its method read_nb()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文