HLS:如何分离 AXI4 信号
HLS: How to separate AXI4 signals
我正在尝试编写一个使用 AXI4 流协议与上一个和下一个模块进行通信的模块。这些模块使用以下通信信号:
- TDATA,即16位,
- TKEEP,即2位,
- TUSER,即1位,
- TVALID,即1位,
- TREADY,这是 1 位,指向前一个模块,
- TLAST,即1位。
这些都需要是单独的信号。我尝试使用以下代码实现它:
#include "core.h"
void core_module(hls::stream<ap_axis_str> &input_stream, hls::stream<ap_axis_str> &output_stream){
#pragma HLS INTERFACE axis port=input_stream
#pragma HLS INTERFACE axis port=output_stream
#pragma HLS INTERFACE s_axilite port=return bundle=CTRL
ap_axis_str strm_val_in;
ap_axis_str strm_val_out;
for (int i = 0; i<NDATA; i++){
strm_val_in = input_stream.read();
strm_val_out.data = strm_val_in.data * 2;
strm_val_out.keep = 3;
strm_val_out.valid = 1;
strm_val_in.ready = 1;
strm_val_out.user = ((i%2)==0);
strm_val_out.last = (i == NDATA-1) ? 1:0;
output_stream.write(strm_val_out);
}
}
头文件在哪里
#ifndef core_h
#define core_h
#include <ap_int.h>
#include <ap_axi_sdata.h>
#include <hls_stream.h>
typedef ap_uint<16> word;
#define NDATA 10
struct ap_axis_str {
word data;
ap_uint<2> keep;
bool user;
bool last;
bool ready;
bool valid;
};
void core_module(hls::stream<ap_axis_str> &input_stream, hls::stream<ap_axis_str> &output_stream);
#endif
问题是这不会分离信号。当我在协同仿真中合成它并运行它(给它0到9的值)时,即使结果是我期望的,产生的波形看起来像这样:
我们可以看到有 TREADY、TVALID 和 TDATA,但没有其他 3 个。此外,查看 TDATA 的内容(由于某种原因是 64 位),我们注意到它们包含所有信号。它们是:
0001000001030000,
0001000000030002,
0001000001030004,
0001000000030006,
...
000100000003000c, (they are in base 16)
0001000001030010,
0001000100030012.
从中我们可以看出12位的3应该是TKEEP,8位的1只出现在最后一种情况下应该是TUSER,最后4位应该是 TDATA 等等。此外,程序在没有准备好接收数据时会丢弃 TREADY,这正是 TREADY 的本意,但我没有将其编程为以这种方式工作,这意味着它是自动生成,可能与我告诉它的 TREADY 无关。
所以我的问题是:如何制作一个模块,为我们正在使用的 AXI4 协议版本发出正确的 6 个独立信号?
嗯,根据Xilinx Documentation,
If you specify an hls::stream
object with a data type other than ap_axis
or ap_axiu
, the tool will infer an AXI4-Stream interface without the TLAST signal, or any of the side-channel signals. This implementation of the AXI4-Stream interface consumes fewer device resources, but offers no visibility into when the stream is ending.
现在我已经用 #include <ap_axi_sdata.h>
导入了所需的模块,我需要做的就是通过删除
来实际使用它
struct ap_axis_str {
word data;
ap_uint<2> keep;
bool user;
bool last;
bool ready;
bool valid;
};
并将其替换为
typedef ap_axiu<16, 1, 0, 0> ap_axis_str;
此外,我需要删除手动尝试控制 TREADY 和 TVALID,因为这些是自动完成的。
我正在尝试编写一个使用 AXI4 流协议与上一个和下一个模块进行通信的模块。这些模块使用以下通信信号:
- TDATA,即16位,
- TKEEP,即2位,
- TUSER,即1位,
- TVALID,即1位,
- TREADY,这是 1 位,指向前一个模块,
- TLAST,即1位。
这些都需要是单独的信号。我尝试使用以下代码实现它:
#include "core.h"
void core_module(hls::stream<ap_axis_str> &input_stream, hls::stream<ap_axis_str> &output_stream){
#pragma HLS INTERFACE axis port=input_stream
#pragma HLS INTERFACE axis port=output_stream
#pragma HLS INTERFACE s_axilite port=return bundle=CTRL
ap_axis_str strm_val_in;
ap_axis_str strm_val_out;
for (int i = 0; i<NDATA; i++){
strm_val_in = input_stream.read();
strm_val_out.data = strm_val_in.data * 2;
strm_val_out.keep = 3;
strm_val_out.valid = 1;
strm_val_in.ready = 1;
strm_val_out.user = ((i%2)==0);
strm_val_out.last = (i == NDATA-1) ? 1:0;
output_stream.write(strm_val_out);
}
}
头文件在哪里
#ifndef core_h
#define core_h
#include <ap_int.h>
#include <ap_axi_sdata.h>
#include <hls_stream.h>
typedef ap_uint<16> word;
#define NDATA 10
struct ap_axis_str {
word data;
ap_uint<2> keep;
bool user;
bool last;
bool ready;
bool valid;
};
void core_module(hls::stream<ap_axis_str> &input_stream, hls::stream<ap_axis_str> &output_stream);
#endif
问题是这不会分离信号。当我在协同仿真中合成它并运行它(给它0到9的值)时,即使结果是我期望的,产生的波形看起来像这样:
我们可以看到有 TREADY、TVALID 和 TDATA,但没有其他 3 个。此外,查看 TDATA 的内容(由于某种原因是 64 位),我们注意到它们包含所有信号。它们是:
0001000001030000,
0001000000030002,
0001000001030004,
0001000000030006,
...
000100000003000c, (they are in base 16)
0001000001030010,
0001000100030012.
从中我们可以看出12位的3应该是TKEEP,8位的1只出现在最后一种情况下应该是TUSER,最后4位应该是 TDATA 等等。此外,程序在没有准备好接收数据时会丢弃 TREADY,这正是 TREADY 的本意,但我没有将其编程为以这种方式工作,这意味着它是自动生成,可能与我告诉它的 TREADY 无关。
所以我的问题是:如何制作一个模块,为我们正在使用的 AXI4 协议版本发出正确的 6 个独立信号?
嗯,根据Xilinx Documentation,
If you specify an
hls::stream
object with a data type other thanap_axis
orap_axiu
, the tool will infer an AXI4-Stream interface without the TLAST signal, or any of the side-channel signals. This implementation of the AXI4-Stream interface consumes fewer device resources, but offers no visibility into when the stream is ending.
现在我已经用 #include <ap_axi_sdata.h>
导入了所需的模块,我需要做的就是通过删除
struct ap_axis_str {
word data;
ap_uint<2> keep;
bool user;
bool last;
bool ready;
bool valid;
};
并将其替换为
typedef ap_axiu<16, 1, 0, 0> ap_axis_str;
此外,我需要删除手动尝试控制 TREADY 和 TVALID,因为这些是自动完成的。