UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
421 Views
Registered: ‎10-09-2019

FFT IP core not recognizing input data

Jump to solution

I'm trying to simulate FFT IP core V9.1. I have the IP block connected to various interfaces like shown below.

fft block.PNG

Clkin is set to generate a clock at 200 MHz. Following images show the IP customization options I've selected.

fft_ip_settings1.PNGfft_ip_settings2.PNG
fft_ip_settings3.PNG

 

 

I then went on to generate output Products then I created HDL wrapper. I made a verilog testbench and I made a custom input adc data file for the testbench to take the data from. The testbench is as follows

`timescale 1 ns / 1 ps

module fft_tb;
    reg clkin;
    wire event_data_in_channel_halt;
    wire event_data_out_channel_halt;
    wire event_frame_started;
    wire event_status_channel_halt;
    wire event_tlast_missing;
    wire event_tlast_unexpected;
    wire [31:0]m_data_tdata;
    wire m_data_tlast;
    reg m_data_tready;
    wire m_data_tvalid;
    reg [15:0]s_config_tdata;
    wire s_config_tready;
    reg s_config_tvalid;
    reg [31:0]s_data_tdata;
    reg s_data_tlast;
    wire s_data_tready;
    reg s_data_tvalid;
    
    reg signed [15:0]re_in;
    reg signed [15:0]im_in;
    reg signed [15:0]re_out;
    reg signed [15:0]im_out;                 ///shouldn't they be wire?
      

    FFT_test_wrapper wraptest(
        .clkin (clkin),
        .event_data_in_channel_halt (event_data_in_channel_halt),
        .event_data_out_channel_halt(event_data_out_channel_halt),
        .event_frame_started(event_frame_started),
        .event_status_channel_halt(event_status_channel_halt),
        .event_tlast_missing(event_tlast_missing),
        .event_tlast_unexpected(event_tlast_unexpected),
        .m_data_tdata(m_data_tdata),
        .m_data_tlast(m_data_tlast),
        .m_data_tready(m_data_tready),
        .m_data_tvalid(m_data_tvalid),
        .s_config_tdata(s_config_tdata),
        .s_config_tready(s_config_tready),
        .s_config_tvalid(s_config_tvalid),
        .s_data_tdata(s_data_tdata),
        .s_data_tlast(s_data_tlast),
        .s_data_tready(s_data_tready),
        .s_data_tvalid(s_data_tvalid));
  
  
  
integer file;
integer readerr = 1;
integer errorno;

reg[63:0] str;
  
  
initial begin
    clkin = 0;
    re_in = 0;
    im_in = 0;
    re_out = 0;
    im_out = 0;
    m_data_tready = 0;
    s_config_tdata = 0;
    s_config_tvalid = 0;
    s_data_tdata = 0;
    s_data_tlast = 0;
    s_data_tvalid = 0;
    m_data_tready = 1;
    
   #5
    if(s_config_tready) begin
        s_config_tvalid = 1;
        s_config_tdata = 16'b1;
    end
    else begin 
        s_config_tvalid = 0;
    end
    file = $fopen("C:/Users/aahmadfarooqui/Downloads/DataCollection-20191016T001538Z-001/DataCollection/ADC/ADC12_Rx0.txt", "r");
    errorno = $ferror(file,str);
    if(!file) begin
        $display("file# %d\n", file);
        $finish;
    end

    while(!$feof(file)) begin
        if(s_data_tready) begin
            readerr = $fscanf(file, "%d %d", re_in, im_in);

            s_data_tvalid = 1;
            s_data_tlast = 1;
            @(posedge clkin);
            s_data_tdata = {im_in, re_in};           

        end
    end
    s_data_tvalid = 0;
end

always @(m_data_tdata) begin
    re_out = m_data_tdata[15:0];
    im_out = m_data_tdata[31:16];
    $display("\nreal output %b\nimag output %d\n",re_out, im_out);
end
always
#2.5 clkin = !clkin;

endmodule

and the custom adc file data is as follows:

-6152 -4259 -2769 -7435 1941 -7561 5246 -4658 5525 -1693 6042 524 4575 3320 2745 4343 446 4807 -1141 4251 -2584 3226 -3288 2928 -5742 1008 -5691 -2532 -3815 -6001 369 -6649 3194 -6495 7261 -3605 7284 433 6083 4011 3513 5759 -16 7246 -3517 4922 -4988 2732 -4985 -854 -3345 -2143 -2141 -3195 -1083 -3454 227 -4673 2922 -4141 4434 -2830 5885 -923 6578 2043 4798 6080 1186 7302 -2940 7892 -7104 4375 -7441 -44 -6162 -3505 -3297 -6034 824 -6707 3734 -4186 4222 -1638 3529 -381 4079 351 3729 2455 2484 3785 1126 5022 -1806 5531 -4322 4185 -6604 1901 -7320 -2404 -4864 -6311 -719 -7905 3501 -7378 7073 -3863 7035 532 5255 2820 3258 4166 1467 4630 -516 4812 -2156 3895 -3489 2878 -4327 798 -4002 -698 -3898 -2209 -3809 -4600 -174 -8092 5535 -6527 7819 -2124 7567 2126 5248 5569 1585 7245 -2187 6493 -4976 4293 -6082 645 -4740 -1916 -3383 -3555 -1093 -4368 33 -3812 1343 -4129 3137 -4179 6184 -2306 6585 1511 4848 4574 2424 5937 -713 7383 -5105 5680 -7030 2189 -7480 -2093 -4488 -6172 -32 -6726 2506 -5268 4356 -3862 5807 -1617 5780 995 4652 3359 2771 4521 834 5392 -1193 5139 -3539 4318 -5207 2505 -6285 -680 -4999 -3564 -3466 -6677 2114 -8016 5625 -4631 7022 -1519 6717 1677 5753 5231 1125 7257 -1682 6123 -4361 4334 -4839 1759 -5075 -534 -3718 -1600 -3897 -3242 -1746 -5131 476 -5367 2942 -5477 6359 -3655 7630 355 6915 4149 3798 7735 -991 8613 -5402 6262 -7086 2739 -7941 -1440 -4987 -5621 -1034 -6751 2083 -4599 2001 -4419 5066 -3144 4918 -763 5639 1080 5082 3304 2929 6446 -334 6088 -3143 6719 -6745 3553 -8065 344 -7437 -5550 -2344 -8412 3271 -8182 6100 -3949 6613 -1082 5804 1895 5005 3789 2036 5933 -155 4972 -1935 5100 -3861 3096 -3646 1719 -5284 1236 -6779 -2525 -3913 -6702 20 -7555 4097 -7316 7839 -3412 7949 709 6730 4462 1 116 -5802 -308 -4559 -3576 -1152 -6540 4544 -4936 7380 -1059 7282 5739 2502 9520 -5169 8945 -7871 2598 -5032 -1690 -2715 -3197 -217 -2417 2334 -2986 3916 -764 5250 2541 4507 5541 891 9391 -5853 8615 -9050 2706 -7592 -3192 -2969 -5021 515 -5699 4207 -3076 4943 -332 4239 2913 2402 3724 1922 4322 825 5922 -1869 6287 -4631 5839 -6962 2811 -7693 174 -6699 -4204 -3922 -6035 -589 -7322 2831 -6770 6755 -4371 7660 286 6413 4040 3340 6670 -266 6489 -1957 5807 -4359 4776 -5625 2619 -5789 -23 -5085 -1282 -4499 -3318 -2595 -4319 -1428 -5142 1111 -5740 3847 -5352 6723 -2648 7196 899 6843 4739 2895 7517 391 8143 -4553 8661 -7869 4106 -8520 566 -6903 -3510 -4824 -5171 -1459 -7084 1538 -5216 3147 -5148 5529 -1702 4206 -450 5730 1865 3812 4285 2340 6460 -1286 7199 -4726 6920 -8775 2948 -8709 -1454 -6818 -6771 -1329 -7651 1633 -7597 6094 -5152 7690 -908 6550 3713 3164 6539 -1581 6000 -2048 3615 -3054 3606 -4436 2653 -6355 844 -6507 -2972 -3625 -5934 -923 -6916 3581 -7068 6749 -3886 8896 734 6348 6128 1960 8572 -2988 7600

When I simulate the core with these parameters, It recognizes the first input data after 6 clock cycles i.e., it asserts event_frame_started, even when S_DATA_TREADY and S_DATA_TVALID are asserted after the first clock cycle. It asserts event_data_in_channel_halt after 200 or so clock cycleseven when it is getting data at the input. It also asserts a tlast missing in the middle of data input. 

fft_ip_simulation window.PNG
Please guide me if I'm doing something wrong or if I have missed something. It'll be greately appreciated

 

1 Solution

Accepted Solutions
212 Views
Registered: ‎10-09-2019

Re: FFT IP core not recognizing input data

Jump to solution

UPDATE: So I found out I was not giving proper delays to the program. I ensured the packets go to the testbench on every positive edge of a clock cycle. I took the output values on a file and plotted the results and found out that the results were correct. The way I did it was just a crude hack I would say, but I still am pasting it for future reference. Thank you all for your help.

`timescale 1 ns / 1 ps

module fft_tb;
    reg clkin;
    wire event_data_in_channel_halt;
    wire event_data_out_channel_halt;
    wire event_frame_started;
    wire event_status_channel_halt;
    wire event_tlast_missing;
    wire event_tlast_unexpected;
    wire [31:0]m_data_tdata;
    wire m_data_tlast;
    reg m_data_tready;
    wire m_data_tvalid;
    reg [15:0]s_config_tdata;
    wire s_config_tready;
    reg s_config_tvalid;
    reg [31:0]s_data_tdata;
    reg s_data_tlast;
    wire s_data_tready;
    reg s_data_tvalid;
    
    reg signed [15:0]re_in;
    reg signed [15:0]im_in;
    reg signed [15:0]re_out;
    reg signed [15:0]im_out;                 ///shouldn't they be wire?
      

    FFT_test_wrapper wraptest(
        .clkin (clkin),
        .event_data_in_channel_halt (event_data_in_channel_halt),
        .event_data_out_channel_halt(event_data_out_channel_halt),
        .event_frame_started(event_frame_started),
        .event_status_channel_halt(event_status_channel_halt),
        .event_tlast_missing(event_tlast_missing),
        .event_tlast_unexpected(event_tlast_unexpected),
        .m_data_tdata(m_data_tdata),
        .m_data_tlast(m_data_tlast),
        .m_data_tready(m_data_tready),
        .m_data_tvalid(m_data_tvalid),
        .s_config_tdata(s_config_tdata),
        .s_config_tready(s_config_tready),
        .s_config_tvalid(s_config_tvalid),
        .s_data_tdata(s_data_tdata),
        .s_data_tlast(s_data_tlast),
        .s_data_tready(s_data_tready),
        .s_data_tvalid(s_data_tvalid));
  
  
  
integer data;
integer res;
integer readerr = 1;
integer errorno;
integer frame;

reg[63:0] str;
  
  
initial begin
    clkin = 0;
    re_in = 0;
    im_in = 0;
    re_out = 0;
    im_out = 0;
    m_data_tready = 0;
    s_config_tdata = 0;
    s_config_tvalid = 0;
    s_data_tdata = 0;
    s_data_tlast = 0;
    s_data_tvalid = 0;
    m_data_tready = 0;
    frame = 1;    
    #5
    if(s_config_tready ==1 ) begin
        s_config_tvalid = 1;
        s_config_tdata = { 7'b0,1'b1,3'b0,5'b10000};
    
  #7.5;

    end
    //else begin 
     //   s_config_tvalid = 0;
    //end
    data = $fopen("C:/Users/aahmadfarooqui/Downloads/DataCollection-20191016T001538Z-001/DataCollection/ADC/ADC12_Rx0.txt", "r");
    res = $fopen("C:/Users/aahmadfarooqui/Downloads/DataCollection-20191016T001538Z-001/DataCollection/ADC/ADC12_Rx0_res_1.txt", "w");
    errorno = $ferror(data,str);
    if(!data) begin
        $display("file# %d\n", data);
        $finish;
    end
    errorno = $ferror(res,str);
    if(!res) begin
        $display("file# %d\n", res);
        $finish;
    end
//end
//always @(s_data_tready) begin
//    s_data_tlast = 1;
    while(!$feof(data)) begin
        if(s_data_tready == 1) begin
            frame = frame + 1;
            readerr = $fscanf(data, "%d %d", re_in, im_in);
            s_data_tvalid = 1;
//            if(frame == 128) begin
//                s_data_tlast = 1;
//            end
            @(posedge clkin);
            #5 s_data_tdata = {im_in, re_in};           

        end
//        else begin
//        s_data_tdata = {im_in, re_in};
// 

    end
//    end
    s_data_tlast = 1;
//    s_data_tdata = 0;
    m_data_tready = 1;
    s_data_tvalid = 0;
    
    
    
end

always @(posedge clkin) begin
    if(m_data_tvalid == 1) begin
//        m_data_tready = 1;
        if(m_data_tdata[15] == 1) begin
            re_out = -(~(m_data_tdata[15:0])+1);
        end
        else begin
            re_out = m_data_tdata[15:0];
        end
        
        if(m_data_tdata[31] == 1) begin
            im_out = -(~(m_data_tdata[31:16]));
        end
        else begin
            im_out = m_data_tdata[31:16];
        end
        $display("\nreal output %b\nimag output %d\n",re_out, im_out);

    end
    else begin
    m_data_tready =1;
    end
    $fwrite(res, "%d %d\n", re_out, im_out);
end
always
#2.5 clkin = !clkin;

endmodule

View solution in original post

8 Replies
Moderator
Moderator
351 Views
Registered: ‎08-16-2018

Re: FFT IP core not recognizing input data

Jump to solution

HI asher@metawave.co 

The signal "event_frame_started" is asserted High when core starts to process the frame (not immediately after the start of frame). Therefore, this signal is going high after few clock cycle. 

It is described in section "Transform Timing" of PG109. Below is the screenshot of the section, 

Screenshot_1.jpgScreenshot_2.jpg


/ 7\7     Meher Krishna Patel, PhD
\ \        Senior Product Application Engineer, Xilinx
/ /        
\_\/\7   It is not so much that you are within the cosmos as that the cosmos is within you...
Visitor eddy2
Visitor
313 Views
Registered: ‎11-05-2019

Re: FFT IP core not recognizing input data

Jump to solution
hy,

is it possible to get a detailed description of the whole timing to handle the signals of the fft core correctly?
0 Kudos
282 Views
Registered: ‎10-09-2019

Re: FFT IP core not recognizing input data

Jump to solution

The outputs (real and imaginary) are just 40 points instead of 128. Also, it randomly asserts and de-asserts 'event_tlast_missing' (I'm only doing one frame i.e 128 points) and if I assert s_data_tlast to 1 in the initial block, it asserts 'event_tlast_unexpected'.

I went through the Transform timing section and figured out I have to wait before asking the core to output data, so I switched from Radix -2 to pipeline streaming for simultaneous operation but I'm getting only around 40 points instead of 128 and the results don't match either. 

I believe it is something I'm missing while implementing my TB. I'm going through all the documentation at this point. I would really appreciate it though if I'm pointed out the mistake I'm making. 

Moderator
Moderator
258 Views
Registered: ‎08-16-2018

Re: FFT IP core not recognizing input data

Jump to solution

As described in PG109, the event signals are intended for interrupt handling, not sample-wise control. The event_frame_started signal, for instance, will occur once processing begins internally, but this cannot be reliably timed relative to tvalid because there is a FIFO on the input in some configurations which means that some samples can be accepted into the FIFO until it fills, even if the FIFO is not being read by the internal processes because of a previous frame still being processed.

As such, the delay between tvalid on the data and event_frame_started is unpredictable. For example, for configurations which do not use the pipelined streaming architecture, a frame will take far longer to process than the time it takes to input a frame. The next frame can start to be input immediately after the first frame up to the capacity of the input FIFOs (at which point TREADY will deassert to indicate that the FIFO is full), but those samples will simply wait in the input FIFO until such time as processing of the first frame has ended. Only then will the FIFO be read and TREADY again be seen to assert to allow more data in.

 

The concept of latency is not particularly useful in the context of AXI4-streaming interfaces, as FIFOs are used to manage streams, but FIFOs have latency which varies according to their depth. The best policy is to follow the AXI4 streaming protocol and allow traffic to manage itself. The tlast signal on frames is a useful way to delineate one frame from another.

 

We can provide further suggestions if you can share the exact application of event_frame_started signal in your design. 


/ 7\7     Meher Krishna Patel, PhD
\ \        Senior Product Application Engineer, Xilinx
/ /        
\_\/\7   It is not so much that you are within the cosmos as that the cosmos is within you...
234 Views
Registered: ‎10-09-2019

Re: FFT IP core not recognizing input data

Jump to solution

Thank you for the reply meherp,

We want to implement FFT as part of a project that receives constant ADC data which needs 2D FFT on it. What I'm trying to do here is a sanity check of the core with the data which is generated from our sensors to compare it with the results we have. I don't care much about the event signal at this point but since I'm not getting meaningful data out of the core, I'm turning to these interrupt signals for clues. 
The AXIs protocol dictates that Tvlaid and Tready has to be asserted before the data goes into the core, that is being followed. The core is set to streaming for simultaneous loading and unloading of frames(to my understanding, I'm using only 1 frame i.e., 128 points). Tready from the master side is asserted so whenever the core asserts Tvalid from the master, it can start pumping the data out. The data that's coming out is not 128 points but 30 or maybe 40 points. The core asserts the event_data_in_channel_halt when I'm done loading the frame. I assert Tlast to let the core know that it's the only frame but when I do it, the core asserts event_unexpected_tlast. I'm not really sure what I'm doing wrong or what I'm missing that's making the core behave the way it is and that's what I'm hoping to get some suggestions on. 

0 Kudos
213 Views
Registered: ‎10-09-2019

Re: FFT IP core not recognizing input data

Jump to solution

UPDATE: So I found out I was not giving proper delays to the program. I ensured the packets go to the testbench on every positive edge of a clock cycle. I took the output values on a file and plotted the results and found out that the results were correct. The way I did it was just a crude hack I would say, but I still am pasting it for future reference. Thank you all for your help.

`timescale 1 ns / 1 ps

module fft_tb;
    reg clkin;
    wire event_data_in_channel_halt;
    wire event_data_out_channel_halt;
    wire event_frame_started;
    wire event_status_channel_halt;
    wire event_tlast_missing;
    wire event_tlast_unexpected;
    wire [31:0]m_data_tdata;
    wire m_data_tlast;
    reg m_data_tready;
    wire m_data_tvalid;
    reg [15:0]s_config_tdata;
    wire s_config_tready;
    reg s_config_tvalid;
    reg [31:0]s_data_tdata;
    reg s_data_tlast;
    wire s_data_tready;
    reg s_data_tvalid;
    
    reg signed [15:0]re_in;
    reg signed [15:0]im_in;
    reg signed [15:0]re_out;
    reg signed [15:0]im_out;                 ///shouldn't they be wire?
      

    FFT_test_wrapper wraptest(
        .clkin (clkin),
        .event_data_in_channel_halt (event_data_in_channel_halt),
        .event_data_out_channel_halt(event_data_out_channel_halt),
        .event_frame_started(event_frame_started),
        .event_status_channel_halt(event_status_channel_halt),
        .event_tlast_missing(event_tlast_missing),
        .event_tlast_unexpected(event_tlast_unexpected),
        .m_data_tdata(m_data_tdata),
        .m_data_tlast(m_data_tlast),
        .m_data_tready(m_data_tready),
        .m_data_tvalid(m_data_tvalid),
        .s_config_tdata(s_config_tdata),
        .s_config_tready(s_config_tready),
        .s_config_tvalid(s_config_tvalid),
        .s_data_tdata(s_data_tdata),
        .s_data_tlast(s_data_tlast),
        .s_data_tready(s_data_tready),
        .s_data_tvalid(s_data_tvalid));
  
  
  
integer data;
integer res;
integer readerr = 1;
integer errorno;
integer frame;

reg[63:0] str;
  
  
initial begin
    clkin = 0;
    re_in = 0;
    im_in = 0;
    re_out = 0;
    im_out = 0;
    m_data_tready = 0;
    s_config_tdata = 0;
    s_config_tvalid = 0;
    s_data_tdata = 0;
    s_data_tlast = 0;
    s_data_tvalid = 0;
    m_data_tready = 0;
    frame = 1;    
    #5
    if(s_config_tready ==1 ) begin
        s_config_tvalid = 1;
        s_config_tdata = { 7'b0,1'b1,3'b0,5'b10000};
    
  #7.5;

    end
    //else begin 
     //   s_config_tvalid = 0;
    //end
    data = $fopen("C:/Users/aahmadfarooqui/Downloads/DataCollection-20191016T001538Z-001/DataCollection/ADC/ADC12_Rx0.txt", "r");
    res = $fopen("C:/Users/aahmadfarooqui/Downloads/DataCollection-20191016T001538Z-001/DataCollection/ADC/ADC12_Rx0_res_1.txt", "w");
    errorno = $ferror(data,str);
    if(!data) begin
        $display("file# %d\n", data);
        $finish;
    end
    errorno = $ferror(res,str);
    if(!res) begin
        $display("file# %d\n", res);
        $finish;
    end
//end
//always @(s_data_tready) begin
//    s_data_tlast = 1;
    while(!$feof(data)) begin
        if(s_data_tready == 1) begin
            frame = frame + 1;
            readerr = $fscanf(data, "%d %d", re_in, im_in);
            s_data_tvalid = 1;
//            if(frame == 128) begin
//                s_data_tlast = 1;
//            end
            @(posedge clkin);
            #5 s_data_tdata = {im_in, re_in};           

        end
//        else begin
//        s_data_tdata = {im_in, re_in};
// 

    end
//    end
    s_data_tlast = 1;
//    s_data_tdata = 0;
    m_data_tready = 1;
    s_data_tvalid = 0;
    
    
    
end

always @(posedge clkin) begin
    if(m_data_tvalid == 1) begin
//        m_data_tready = 1;
        if(m_data_tdata[15] == 1) begin
            re_out = -(~(m_data_tdata[15:0])+1);
        end
        else begin
            re_out = m_data_tdata[15:0];
        end
        
        if(m_data_tdata[31] == 1) begin
            im_out = -(~(m_data_tdata[31:16]));
        end
        else begin
            im_out = m_data_tdata[31:16];
        end
        $display("\nreal output %b\nimag output %d\n",re_out, im_out);

    end
    else begin
    m_data_tready =1;
    end
    $fwrite(res, "%d %d\n", re_out, im_out);
end
always
#2.5 clkin = !clkin;

endmodule

View solution in original post

Moderator
Moderator
202 Views
Registered: ‎08-16-2018

Re: FFT IP core not recognizing input data

Jump to solution

So I found out I was not giving proper delays to the program. I ensured the packets go to the testbench on every positive edge of a clock cycle.

What I understood is, previously the data and clock egde were not aligned correctly (i.e. previously data was changing at the -ve edge of the clock). Later, you modify the testbench only (not the input data in text file) to  send the data at the positive edge of the clock and results are correct.


/ 7\7     Meher Krishna Patel, PhD
\ \        Senior Product Application Engineer, Xilinx
/ /        
\_\/\7   It is not so much that you are within the cosmos as that the cosmos is within you...
0 Kudos
171 Views
Registered: ‎10-09-2019

Re: FFT IP core not recognizing input data

Jump to solution

The data(except the first frame) was being loaded into the core on the positive edge. I ensured that even the first frame gets loaded on the positive edge, which (I think) fixed the timings internally. Thank you for all your help @meherp .

0 Kudos