title: Xilinx FFT v8.0 core example testbench
body: <p>I am trying to compute the DFT transform of a series of 16-bit input values using the Xilinx FFTv8.0 core on a Virtex 7 but I have some troubles understanding the datasheet.</p>
  
  <p>More specifically, I am using a standard auto-generated testbench (see below) but the output is always zero. Even after being through the datasheet and the "Jim Wu's FPGA Blog" (<a href="http://myfpgablog.blogspot.de/2010/07/fft-results-from-matlab-fft-bit.html" rel="nofollow noreferrer">http://myfpgablog.blogspot.de/2010/07/fft-results-from-matlab-fft-bit.html</a>) many times, I still don't understand how to use it. I think I am confused by the multiple input/output of the core..</p>
  
  <pre><code>`timescale 1ns / 1ps
  
  ////////////////////////////////////////////////////////////////////////////////
  // Company: 
  // Engineer:
  //
  // Create Date:   14:25:20 05/14/2015
  // Design Name:   fft_core
  // Module Name:   C:/Users/Alberto/Documents/MEGA/Master II/Master Thesis/test_fft/fft_tb.v
  // Project Name:  test_fft
  // Target Device:  
  // Tool versions:  
  // Description: 
  //
  // Verilog Test Fixture created by ISE for module: fft_core
  //
  // Dependencies:
  // 
  // Revision:
  // Revision 0.01 - File Created
  // Additional Comments:
  // 
  ////////////////////////////////////////////////////////////////////////////////
  
  module fft_tb;
  
      // Inputs
      reg aclk;
      reg s_axis_config_tvalid;
      reg s_axis_data_tvalid;
      reg s_axis_data_tlast;
      reg m_axis_data_tready;
      reg [7:0] s_axis_config_tdata;
      reg [31:0] s_axis_data_tdata;
  
      // Outputs
      wire s_axis_config_tready;
      wire s_axis_data_tready;
      wire m_axis_data_tvalid;
      wire m_axis_data_tlast;
      wire event_frame_started;
      wire event_tlast_unexpected;
      wire event_tlast_missing;
      wire event_status_channel_halt;
      wire event_data_in_channel_halt;
      wire event_data_out_channel_halt;
      wire [31:0] m_axis_data_tdata;
  
      // generate clk
      always #5 aclk =! aclk;
  
      // Instantiate the Unit Under Test (UUT)
      fft_core uut (
          .aclk(aclk), 
          .s_axis_config_tvalid(s_axis_config_tvalid), 
          .s_axis_data_tvalid(s_axis_data_tvalid), 
          .s_axis_data_tlast(s_axis_data_tlast), 
          .m_axis_data_tready(m_axis_data_tready), 
          .s_axis_config_tready(s_axis_config_tready), 
          .s_axis_data_tready(s_axis_data_tready), 
          .m_axis_data_tvalid(m_axis_data_tvalid), 
          .m_axis_data_tlast(m_axis_data_tlast), 
          .event_frame_started(event_frame_started), 
          .event_tlast_unexpected(event_tlast_unexpected), 
          .event_tlast_missing(event_tlast_missing), 
          .event_status_channel_halt(event_status_channel_halt), 
          .event_data_in_channel_halt(event_data_in_channel_halt), 
          .event_data_out_channel_halt(event_data_out_channel_halt), 
          .s_axis_config_tdata(s_axis_config_tdata), 
          .s_axis_data_tdata(s_axis_data_tdata), 
          .m_axis_data_tdata(m_axis_data_tdata)
      );
  
      initial begin
          // Initialize Inputs
          aclk = 0;
          s_axis_config_tvalid = 0;
          s_axis_data_tvalid = 0;
          s_axis_data_tlast = 0;
          m_axis_data_tready = 0;
          s_axis_config_tdata = 0;
          s_axis_data_tdata = 0;
  
          // Wait 100 ns for global reset to finish
          #150;
  
          s_axis_config_tvalid = 1;
          s_axis_data_tvalid = 1;
          //s_axis_data_tlast = 1;
          m_axis_data_tready = 1;
          s_axis_config_tdata = 1;
          s_axis_data_tdata = 1;
  
          // Add stimulus here
  
          // Some random inputs (just to understand how it works):
          s_axis_config_tdata = 8'b00000001; // FFT desired (and not IFFT)
          s_axis_data_tdata = 32'h00005678; // I have a real input signal, so the upper half (corresponding to the immaginary part) is zero
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001121;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001516;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001920;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001121;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001516;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001920;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001121;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001516;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001920;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001121;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001516;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001920;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001121;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001516;
          #10;
          s_axis_config_tdata = 8'b00000001;
          s_axis_data_tdata = 32'h00001920;
          #10;
  
  
      end
  
  endmodule
  </code></pre>
  
  <p>Here are some screenshots of the waveform and of the core configuration I used (I don't have yet the authority to post it directly):
  <a href="https://www.dropbox.com/s/0ejccc4dm6zdw7h/FFT.zip?dl=0" rel="nofollow noreferrer">https://www.dropbox.com/s/0ejccc4dm6zdw7h/FFT.zip?dl=0</a></p>
  
  <p>Does anybody have an explanation or a working testbench (possibly written in Verilog) processing data with this ip core ?</p>
  
  <p>I thank you in advance</p>
  
  <h2>Edit:</h2>
  
  <p>For posteriority, the full code is available <a href="https://github.com/asonnino/fourier-transmitter" rel="nofollow noreferrer">here</a>; details and explanations can be found in the <a href="https://sonnino.com/papers/figuli2016variable.pdf" rel="nofollow noreferrer">paper</a>.</p>