• 0
Sign in to follow this  
Weevil

FFT

Question

Hi all,

i started to do a FFT from exact one sine wave with the XFFT(9.0). This works for the 32bit input signal, but for the 16bit input signal it seems not to work. By doing the FFT i would expect one peak in the frequency spectrum like i get in in the following picture:

FFT_32bit.thumb.PNG.8ee3d905534374bc1681b4b7f784f212.PNG

XFFT settings:

- Architecture Choice -> Pipelined, Streaming I/O

- Transform Lenght -> 256

- Scaling Options -> Scaled

- Input Data Width -> 16 -> input signal from DDS 32bit

- Input Data Width -> 8 -> input signal from DDS 16bit

For generating a sine wave i use the DDS compiler at a Superious Free Dynamic Range of 96 dB and Frequency Resolution 100 Hz. The Phase Increment is in Streaming mode and set with a constant block to 4096. One sine wave is generated by 256 samples now (number_0 x2).

If the settings are switched now for a 16bit sine input signal the FFT works not like i would expect. Maybe anyone has an idea?

FFT_16bit.thumb.PNG.85e243cb6240cc824a3b0f8b552f7f30.PNG

Thanky for any response!

Edited by Weevil

Share this post


Link to post
Share on other sites

9 answers to this question

Recommended Posts

  • 1

@Weevil,

As to the data input size: yes, a 16'bit FFT input will include both imaginary and real components.

Not sure if the LogiCore FFT offers a real FFT implementation.  Were it to do so, the input would only be 16'bits for a 16'bit FFT.  The output would then alternate between a 16-bit real and a 16-bit imaginary value.  I'd have to dig into the spec's more to know if this is even a possibility for the LogiCore FFT--it's certainly a possibility for an FFT in general though.

Dan

Share this post


Link to post
Share on other sites
  • 1

Looks plausible, given ...

image.png.fb919868778b361bccbc4189d4c4ae94.png

positive frequencies : exp(i x); negative frequencies: -exp(- i x)

I haven't read the FFT IP documentation but I suspect you need to split each e.g. 32-bit output bin into 16-bit real and imaginary part

Edited by xc6lx45

Share this post


Link to post
Share on other sites
  • 0

@Weevil,

I'm struggling to understand your picture.

Can you explain for me what it is you are plotting?  What is going into the FFT, and what is coming out?

Even better, can you create a more complete trace showing the input and output FFT signaling as well?

I'm hoping that would make your question easier to follow.  Thanks!

Dan

Share this post


Link to post
Share on other sites
  • 0

@D@n

- "ddsAnalog" is the output signal of the DDS core (displayed as signed decimal) and is the input for the FFT core.

- "FFT_RAW" shows the output of the FFT core (signed decimal).

-> the sourroundings of the ddsAnalog and FFT_RAW signals are on both pictures the same, only the bit size is different.

 

- "m_axis_data_last_0" shows the tlast of the FFT core.

- "number_0" is a counter only to control the DDS output lenght

I hope this helpts to easier follow my question.

 

.....actual i am most confused about the data input size. If i set the XFFT core input size to 16bit i need a 32bit signal input, is this right?

Edited by Weevil

Share this post


Link to post
Share on other sites
  • 0

@Weevil,

So then ... why would the output of the FFT look like a ramp?  That doesn't make sense.

I guess I'm struggling to understand why your diagram has this ramp in the first place.  What's its purpose?

Dan

Share this post


Link to post
Share on other sites
  • 0

@D@n

Thank you so much for your reply!

The reason for the ramp is a wrong figure in vivado. As you can see in the attached picture the values before the FFT-peak are 0. If i switch to the Architecture Choice -> Automatically Selected this doesn't happen, but the problem is the same.

FFT_32bit_2.thumb.PNG.e51b13ff6a3b78ec039866c0d9c8b668.PNG

So if it is the input i can try to connect a 16bit sine wave generated by the DDS to the 32bit input of the XFFT (XFFT Input Data Width = 16).

Would the following verilog code work for such small block or do i have to do something additional?

module bit_wandler(
    input [15:0] val_in,
    input clk_in,
    output reg [31:0] val_out
    );    

always @(posedge clk_in) 
begin
  
    val_out = val_in;
  
end
    
endmodule

 

Share this post


Link to post
Share on other sites
  • 0

It was signed number format, wasn't it? I think this

   val_out = val_in;

doesn't work because the 16-bit word needs to be sign-extended to 32 bits.

If I write it out without tricks (not use the "signed" Verilog keyword) and using combinational logic for simplicity it is

wire [31:0]     val_out = {{16{val_in[15]}}, val_in[15:0]};

In other words, the unused high bits are filled with the MSB (sign bit).

Example:

1'b1 is -1 in 1 bit

8'b11111111 is also -1 in 8 bits

32'b11111111111111111111111111111111 is still -1 but in 32 bits

Try adding 1 to either (-1 +1 =0) and see for yourself what happens... theory.

 

 

Edited by xc6lx45

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this