Vivado HLS 设计读取 FIFO

Vivado HLS design to read FIFO

我正在尝试在 FPGA 上开发一个系统以从外部世界读取数据(即 Geiger 脉冲积分器,但此时我正在使用 Arduino 对其进行仿真);数据流将存储在 FIFO 缓冲区中,这是我在 Vivado 中使用 FIFO 生成器 IP 实现的。一个小的 RTL 模块从 Arduino 获取数据并成功将其写入 FIFO。为了从 FIFO 输出读取数据,我需要将 read_enable 设置为高电平,然后等待 N 个时钟周期,同时将输出存储在数组中,最后再次将 read_enable 设置为低电平。我需要在 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 根本不会变高。

这种做法有错吗?

非常感谢。

由于您无论如何都在使用 Xilinx IP 来生成外部 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模块的协同仿真波形

如您所见,假设 FIFO 不为空并且已经包含 N 个元素,读取使能保持 N 个周期,并且在每个周期存储一个新元素。

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

p.s。如果无论 FIFO 是否为空,您的实现都应在 N 个周期内完成,您可能需要切换到 C++,其中有一个 FIFO class 及其方法 read_nb()