I asked this while back in Xilinx Forum but I got no help, still need the help that's why am asking here.
I am working on FFT IP Core to match its result with Matlab. I created an RTL Kernel(XO) using Vivado contains just FFT IP Core, and below u see all the configuration(I tried different config as I tried with pipeline streaming arch and the same problem).
I am using Vitis to connect this RTL kernel with another C++ Kernel responsible for reading data from memory and stream it to the IP Core.
The input data is fixed point scaled between -1 and 1. The data is a sine wave samples.
The config packet is 24 bits, has N = 8, and FWD_INV = 1 ( config packet : 000000000000000100000011) // still not sure about SCALE_SCH parameter I will be thankful if someone make it more clear to me.
My problem is I can't get correct output, I check through the emulator the input data and it is streaming correctly, the config packet was sent correctly as well but the output I get is totally different if I compare it with fft Matlab results for the same sine wave.
Can you help me figure out what I am doing wrong and could anyone explain me how the scale_sch working in my case?
- C++ Kernel:
typedef ap_int<64> data64_t;
typedef ap_int<128> data128_t;
typedef ap_int<32> data32_t;
typedef ap_axis<IN_DWIDTH , 0, 0, 0> axis_in;
typedef ap_axis<OUT_DWIDTH , 0, 0, 0> axis_out;
void hls_dma(int num_words,
data64_t *din,
data64_t *dout,
hls::stream<axis_in> &strm_in,
hls::stream<axis_out> &strm_out)
{
#pragma HLS DATAFLOW
data64_t temp_in;
axis_in val_0, val_1;
data32_t tmp_val;
rd_loop: for (int i = 0; i < 2 * num_words; i++)
{
temp_in = din[i];
val_0.data = 0x0;
val_1.data = 0x0;
tmp_val = temp_in.range(31, 0);
val_0.data |= tmp_val;
strm_in.write(val_0);
tmp_val = temp_in.range(63, 32);
val_1.data |= tmp_val;
if(!(val_1.data == 0)) val_1.data = 0;
strm_in.write(val_1);
}
axis_out v0, v1;
data64_t temp_out;
wr_loop:
for (int i = 0; i < 2 * num_words; i++)
{
v0 = strm_out.read();
v1 = strm_out.read();
temp_out.range(31, 0) = v0.data;
temp_out.range(63, 32) = v1.data;
*dout++ = temp_out;
}
}
extern "C" {
void fft_infc(int fft_select,
int num_fft,
int fft_dir,
data64_t *din,
data64_t *dout,
volatile ap_uint<24> *config,
hls::stream<axis_in> &strm_in,
hls::stream<axis_out> &strm_out)
{
#pragma HLS INTERFACE axis port=config
#pragma HLS INTERFACE axis_in port=strm_in
#pragma HLS INTERFACE axis_out port=strm_out
#pragma HLS INTERFACE m_axi port=din offset=slave bundle=gmem1
#pragma HLS INTERFACE m_axi port=dout offset=slave bundle=gmem2
ap_uint<24> tmp_config = 0;
tmp_config[8] = (fft_dir == 1) ? 1 : 0;
tmp_config.range(4, 0) = fft_select;
*config = tmp_config;
hls_dma(SAMPLE_NUM, din, dout, strm_in, strm_out);
}
}
Xilinx Forum : https://support.xilinx.com/s/question/0D54U00006ap3gpSAA/fft-ip-core-the-results-of-matlab-and-fft-ip-core-didnt-match-?language=en_US
Thank you in advance.
- The input data:
- The Matlab output:
- My fft ip core implementation output:
Note: I am ploting the abs of outputs.