mohamed shffat

XADC and the FFT

Recommended Posts

Hello 

I'm trying to take an FFT on the FPGA after getting sampled data comes from XADC , but i couldn't get any results ! 

Here i figured out that the problem might be from the XADC's data , i tried to fix it but so far still no results . 

In my design i'm inserting an analog input signal to VP/VN pins on XADC header , then i'm trying to get some data comes out from the 1MSPS XADC . 

When i plot the output data it looks as it sampled correctly , but when i try to take its FFT whether on FPGA FFT CORE or on MATLAB , i get no results . The sampled signal and its FFT are shown below in the pics . 

Also i tried many frequencies for the input signal starts from 10KHz up to 480KHz , but they are all giving the same result , empty window in the Freq-domain . 

If someones know what's the problem i would really appreciate the help . 

Regards 

sampled sin with 50khz.jpg

Spectrum of the sampled sin.jpg

Arvind likes this

Share this post


Link to post
Share on other sites

@mohamed shffat,

Congratulations, you've made a *lot* of progress since your last post!  From what you've shown above, I can't say that I know what the problem is, but I do know where to look.

May I assume that you are using pipeline mode?  If not, my comments below might need to be changed/adjusted.

Xilinx builds a pipeline mode for their FFT.  In this mode, the FFT can accept one sample on every clock cycle, and it can produce one sample on every output clock cycle.  There's a couple of gotcha's to using this technique, however--even though it's the one I would encourage you to use.  I'm also referencing the Xilinx's FFT IP Core, version 7.1.  If you are using another version of the core, you might notice some differences--probably mosty in signal names.

  1. It takes a couple of FFT's through the whole process before your first valid FFT will come out.  It's sort of a delay within the FFT.  I think the delay is about two and a half FFT samples, but ever after that delay it works.  Failing to wait for the full delay might be the cause of getting no data out.
  2. You need to set the START signal high for one clock on your first sample into the FFT.  Then afterwards, you'll want to check for DONE going high.  Failing to set the START signal might be a cause of getting nothing out.
  3. The core is designed to work with asynchronous designs in this fashion: samples from an A/D converter will rarely ever be at the same rate as the clock rate of the FFT.  To make certain you've got this right, set the CE line high *only* when you have a valid sample going into the FFT.  For example, if you are sampling your audio at 48kHz, but running the FFT at 80MHz, then you need to set the CE line so that it only goes high for only one clock roughly every 1666 clocks.  This signal also needs to gate your reading of the core's outputs.  Only read the outputs on those clock cycles where CE was high.  (Or is it on those cycles when DV is high?  The charts in the Xilinx doc's aren't clear ...)  Failure to properly account for the CE signal could explain some of the other problems you've been having in your other post.
  4. Many FFT's have a "RESET" line as well.  I don't see it in the instructions for this one, but failing to set it or worse failing to clear it might also result in the problems you are struggling with.

Many of these things *could* be your problem, but they aren't necessarily your problem.  You are going to need to dig a bit to be certain and know.

Let me know if this helps.  (or if you aren't using pipeline mode, and I therefore need to adjust my comments ...)  If not, we can dig deeper.  If it does help, I'd like to join you in a little victory dance.  :D

Dan

mohamed shffat likes this

Share this post


Link to post
Share on other sites
12 hours ago, D@n said:

@mohamed shffat,

Congratulations, you've made a *lot* of progress since your last post!  From what you've shown above, I can't say that I know what the problem is, but I do know where to look.

May I assume that you are using pipeline mode?  If not, my comments below might need to be changed/adjusted.

Xilinx builds a pipeline mode for their FFT.  In this mode, the FFT can accept one sample on every clock cycle, and it can produce one sample on every output clock cycle.  There's a couple of gotcha's to using this technique, however--even though it's the one I would encourage you to use.  I'm also referencing the Xilinx's FFT IP Core, version 7.1.  If you are using another version of the core, you might notice some differences--probably mosty in signal names.

  1. It takes a couple of FFT's through the whole process before your first valid FFT will come out.  It's sort of a delay within the FFT.  I think the delay is about two and a half FFT samples, but ever after that delay it works.  Failing to wait for the full delay might be the cause of getting no data out.
  2. You need to set the START signal high for one clock on your first sample into the FFT.  Then afterwards, you'll want to check for DONE going high.  Failing to set the START signal might be a cause of getting nothing out.
  3. The core is designed to work with asynchronous designs in this fashion: samples from an A/D converter will rarely ever be at the same rate as the clock rate of the FFT.  To make certain you've got this right, set the CE line high *only* when you have a valid sample going into the FFT.  For example, if you are sampling your audio at 48kHz, but running the FFT at 80MHz, then you need to set the CE line so that it only goes high for only one clock roughly every 1666 clocks.  This signal also needs to gate your reading of the core's outputs.  Only read the outputs on those clock cycles where CE was high.  (Or is it on those cycles when DV is high?  The charts in the Xilinx doc's aren't clear ...)  Failure to properly account for the CE signal could explain some of the other problems you've been having in your other post.
  4. Many FFT's have a "RESET" line as well.  I don't see it in the instructions for this one, but failing to set it or worse failing to clear it might also result in the problems you are struggling with.

Many of these things *could* be your problem, but they aren't necessarily your problem.  You are going to need to dig a bit to be certain and know.

Let me know if this helps.  (or if you aren't using pipeline mode, and I therefore need to adjust my comments ...)  If not, we can dig deeper.  If it does help, I'd like to join you in a little victory dance.  :D

Dan

Thanks too much for everything MR. Dan , i really appreciate your helps .

My only problem that i wanted to explain on the post is that the output signals from the ADC can't be transformed to F-Domain using FFT , even on the MATLAB software ! Here i debugged the XADC individually and i took it's output , then i simulated the ADC's output signal and tried to take its FFT on MATLAB just to make sure that the signal is correct or not . But even the MATLAB gave me these results (Empty spectrum window with just to peaks in 0 point and the last point 1023 ) , so i'm wondering now why the sampled signal that i got from the XADC can't be taken by the FFT even on MATLAB ? Although it looks correct when i display it in T-Domain ? 

Greetings Sir :lol:

Share this post


Link to post
Share on other sites

@mohamed shffat,

MATLAB won't do an FFT of it?  If that's the case, it's because either 1) You aren't giving MATLAB the right values, or 2) You aren't giving it the right plotting command.  An easy way to test is to "plot" the values before doing the FFT.  If you get a good looking plot output, the result isn't the values you are giving MATLAB, but rather the plot command you are giving the FFT--and perhaps the X or Y axis limits.

Want to share your MATLAB script, together with a text file with your values that MATLAB is failing on?  That alone should be fairly easy to get working.  The Xilinx FFT ... that'll take more work.

Dan

Edited by D@n

Share this post


Link to post
Share on other sites

@D@n 

Yep sir , even the MATLAB couldn't do the FFT of the sampled data that i got from the XADC . On MATLAB all what i'm doing is just giving the samples or values that i extracted from the XADC , and trying to take it's simple FFT without any limits in X or Y axis . 

Here my MATLAB script , and the .csv file which contains the 32768 extracted samples from the XADC by the ILA debugging core . 

x = input('ADC data = ') ;

X = transpose(x) ;

y = abs(fft(x)) ;

subplot(2,1,1)

 plot(X) ; 

subplot(2,1,2)

plot(y); 

My .csv file is submitted below , it's contains the samples of a 10 KHz sampled sin from XADC .

Regards sir 

sin10khz.csv

Share this post


Link to post
Share on other sites

Yeah, so ... I'm not having a problem with your data at all.  Here's what I did:

% First, I removed the top-line from your CSV file, then ...
a = load('sin10khz.csv');
X = transpose(a);
plot(10*log(fftshift(abs(fft(X(4,:)))))/log(10)); grid on;

and you can see the result I got (attached--if all goes well).

Dan

Screenshot from 2016-12-05 11:53:06.png

Share this post


Link to post
Share on other sites

But ... you've got another problem here as well.  You have too many samples.  Your sampler sampled at a rate of about 1000x faster than your ADC.  If you want this FFT to work, you are going to need to gate the recorder, so that it only records valid samples--one each from one comes out of the recorder.

Dan

Share this post


Link to post
Share on other sites
On 12/5/2016 at 6:57 PM, D@n said:

But ... you've got another problem here as well.  You have too many samples.  Your sampler sampled at a rate of about 1000x faster than your ADC.  If you want this FFT to work, you are going to need to gate the recorder, so that it only records valid samples--one each from one comes out of the recorder.

Dan

Ok sir thanks too much , i'm gonna try to handle it . 

My last question now is that i'm using the 9.0th version of the FFT on the Vivado tool , and i'm not taking the data directly from the XADC . I'm storing a 1024 samples inside a FIFO memory first , then i'm reading and inserting these samples to the FFT core , and the clock speed of the memory is 100MHZ . So should i here control the S_axis_data_valid line with the writing speed from the FIFO memory or i should just control according to the sampling rate out of the XADC . 

Regards sir . 

Share this post


Link to post
Share on other sites

@mohamed shffat,

Ah, yes, v9 ... that's right, they moved to an AXI protocol and got rid of the CE line, didn't they?

The answer to your "or" question is to some extent "it depends", but I think I'm going to give you the answer "yes".  Here's why:

  1. Testing the FFT with a new sample every clock period will give you some confidence that the FFT works.  Do this first--it's easier.
  2. However, once you have that confidence, you'll want to apply it to the XADC, where a new sample will not be ready every clock period.

So ... try both.  Get comfortable with your tools (i.e. the FFT, your test harness, etc).  Then, when/if they don't work, you'll have a better understanding as to why or why not.

Dan

mohamed shffat and JColvin like this

Share this post


Link to post
Share on other sites

Dear sir,

 I am new to this feild. I wanted to a small help from your side. I have implemented XADC  16 bit. I want to verify my output is in sync with the input signal. Is there any process so that I can check my implementation correct or not.

thanx

Share this post


Link to post
Share on other sites

@Arvind,

Is there a "process" ... you mean like an engineering process to do this task?  Absolutely!

Here's a blog post I wrote about this sort of topic that should give you an idea of what's required.

In very short sum, you'll want to:

  1. Place a known input signal into your FPGA,
  2. Match it to a known output.

Don't make it any harder than that, your task will be hard enough without making it any harder.

You'll want to skip the whole xADC portion, though, until you've gotten this one step working.  If you don't, you'll never know what your problem is.

For your test bench, there are two basic FFT inputs that should tell you everything you need: The first is the vector with one value set, but the rest are all zeros.  This should return a sine/cosine wave at  the appropriate frequency--depending on where the one nonzero value is within your FFT window.  The second input is a sine or cosine wave at a frequency that is an exact multiple of your FFT length.  You should be able to suddenly switch between these two, and still get the right answer (there will be some delay between input and output, and should also be a synchronization pulse to help you get the right delay path.)

That's part one.

Part two is for the xADC: You'll want to read from the xADC a known value, dump it into a buffer (WITHOUT GOING THROUGH THE FFT), and make sure you can read a signal properly there.  At the right rate, too--if the xADC is only sampling at 102kHz, make sure you are only getting inputs at a rate of 102kHz.  Before you go into your FFT, you'll want to make sure that you can send inputs to it at 102kHz (or whatever your sample rate is) ONLY--no duplicated or dropped samples.  But ... for now, just make sure you have the sampling right coming out of the XADC.

Part 3 is putting the two together.  Don't skip part 1 or part 2 to get here.  To do part 3, you'll want an internal scope looking at the inputs to the FFT and the outputs in a synchronized fashion.  (You may have chosen to use such a scope before you go to this point as well, to do parts 1 and 2)  Otherwise, you'll never know what's going wrong when (if) anything goes wrong.

 

That's the "process" you are looking for.

You should find example code on my blog for several of the required pieces of this process.  (Sadly, I don't have all of the pieces described on the blog yet.  The biggest missing pieces are 1) the UART to wishbone interface, 2) the software side of that interface, and 3) how to write a VCD file)

Once you get that far, you'll still have the challenge of FFT windows to deal with.  You can see a challenge I gave regarding achieving good frequency resolution here, and the beginnings of a response (with references) here--that will start to show you how to do better than the traditional frequency resolution.

Dan

 

Share this post


Link to post
Share on other sites

hii mohamed shffat,

 i am also trying to implement FFT  in vivado .My ADC giving correct  output   but i don't know how to connect these output to the input of FFT IP core.

please give any suggestion..

thanks 

regards

Arvind 

Share this post


Link to post
Share on other sites

@Arvind,

Not sure I understand your question ... you connect the output data from the ADC to the input of the FFT, and the data valid wire on the input of the FFT to the data valid indicator from your ADC.

Can you be clearer about what part of the design you are struggling with?

Dan

Arvind likes this

Share this post


Link to post
Share on other sites

@Arvind,

Sorry, that's still not enough information to help you out.

Can you share any code you are using and data it is producing that convinces you that you are having problems?  Or are you still trying to build your code?  I can't tell which (yet)

Dan

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