11-21-2020 02:48 PM
Hi,
I am experiencing a problem with FFTs of higher size. So far I have been testing my project with lower FFT size and I didn't notice this.
When I use 512 long FFT with 48kHz data rate all computation happens in one input data period and there is no problem. I see burst of output data that is 512 long and fft_out_last is set..
However, with higher length (1024), data rate is the same, I see the following:
Once the fft_last signal is asserted (signaling to the input of the FFT module) there is a burst of data at the output (with about ~1000 cycles delay). However, when fft_vaild is asserted again, meaning that a new input sample is available, the fft_out_valid is brought low. FFT module brings fft_out_valid signal high anytime the fft_valid is high until the last FFT output sample and then it sets the fft_out_last; thus, informing that all output FFT samples were provided. See the picture below (the initial output burst was 944 long and then there were 80 fft_out_valid high pulses (fft_data_counter=80), giving 1024 in total):
With the same FFT size of 1024 and half the input data rate I do not see that. It looks like for 512 long FFT, burst at the output of the FFT module and m_axis_data_tlast (fft_out_last) assertion. See below:
It means that whenever FFT can be computed within one period of input data the output burst provides all data and fft_out_last is set. When computation takes longer than one sampling period I see this behavior.
I am using the Pipelined Streaming I/O architecture with 100MHz clock and 100MHz throughput. For now I took all of the other modules out and just test the FFT part.
Any thoughts? Thanks.
always_ff @(posedge clk_100mhz)begin
if (sample_counter == SAMPLE_COUNT)begin
sample_counter <= 16'b0;
end else begin
sample_counter <= sample_counter + 16'b1;
end
if (sample_trigger) begin
scaled_adc_data <= 16*adc_data;
if (fft_ready && fft_out_valid==0)begin
fft_data_counter <= fft_data_counter+1;
fft_last <= fft_data_counter==(FFT_SIZE);//<-1024-1
fft_valid <= 1'b1;
fft_data <= {~scaled_adc_data[15],scaled_adc_data[14:0]};
led[0]<=1'b1;
end
end else begin
fft_data <= 0;
fft_last <= 0;
fft_valid <= 0;
led[0]<=1'b0;
end
end
xadc_mod adc_1 (
.clk_in(clk_100mhz),
.den_in(eoc_out),
.vauxn3(vauxn3),
.vauxp3(vauxp3),
.adc_ready(adc_ready),
.adc_data(adc_data),
.eoc_out(eoc_out)
);
xfft_0 my_fft (.aclk(clk_100mhz), .s_axis_data_tdata(fft_data),
.s_axis_data_tvalid(fft_valid),
.s_axis_data_tlast(fft_last), .s_axis_data_tready(fft_ready),
.s_axis_config_tdata(0),
.s_axis_config_tvalid(0),
.s_axis_config_tready(),
.m_axis_data_tdata(fft_out_data), .m_axis_data_tvalid(fft_out_valid),
.m_axis_data_tlast(fft_out_last), .m_axis_data_tready(1'b1));
ila_0 myila (.clk(clk_100mhz), .probe0(fft_data_counter), .probe1(adc_data), .probe2(sqrt_data), .probe3(fft_out_data), .probe4(fft_ready), .probe5(fft_out_valid),
11-21-2020 07:38 PM
The pipelined / streaming I/O architecture is meant to handle data that is constantly coming into the FFT. You are presenting one block of data at a time. Why not use the burst FFT architecture instead? That would be more suited to your use case.
My guess of what's going on, having written my own pipelined FFT, is that the FFT logic is waiting for new samples at some point and therefore it is stalled. Building the FFT instead so that the pipeline can handle inconsistent/non-lockstep states (as you are expecting) takes more work to do. Why do it if your requirement is for a pipelined FFT where data will keep streaming into the core?
Dan