07-23-2011 07:31 AM
Hey All,
Currently working on some mathematics in FPGA. Specifically interpolation of FFT bins using Grandke's method. I've reached a somewhat confusing stage of development. The first stage of Grandke's is obviously to Hanning window the data, then send it through the FFT, then we compute the magnitude of the FFT. I've done all of this to my satisfaction and validated the outputs. It all looks wonderful. Now I come to the interpolation stage and questions start popping up that I can't answer by looking at the help files (I've tried). You can find my project attached if you want to look at exactly what I'm talking about.
So, question:
1) The information coming out of the magnitude computation is FXP,+,22,21. I've decided to trust that this is what LV requires to not lose my info. But when I wire two values into the high throughput divide and choose adapt to source, the output is FXP,+,22,22. Just looking at this looks wrong. How does it handle any case where x < y (for x/y)? In other words, there is no decimal precision. So if we want decimal precision, do we just over-ride what LV does and manually choose our word and integer word lengths? Or is LV doing something funky to translate that precision into an integer scale? How exactly does LV perform the translation from the two FXP,+,22,21 inputs to say FXP,+,22,3 if we do over-ride "adapt to source"?
07-24-2011 06:27 AM
A further question on hand-shaking. If there are a chain of handshaking VI's as in my code included in the OP, will the first one only set ready for input true when all the following ones have reported ready? Or in other words, Is the "ready for output" input going true one of the criteria for a VI reporting ready for input?
07-25-2011 10:11 AM
The problem with the divide is that there is no output type that LabVIEW can choose to avoid data loss, and no default behavior that satisfies all use cases. The choice of default output type behavior is somewhat arbitrary, but consistent. I believe the choice is driven by overflow prevention, such that dividing by 1 LSB will not overflow (in your case, that means dividing by .5, so the output IWL grows by one). The total word length is generally just kept as the max of the input word lengths and output integer word length. You should definitely feel free to override that choice to meet your precision needs, and the results will be correct for your chosen type (no funky rescaling involved). The divide uses an iterative algorithm, so it's basically a loop that computes 1 bit at a time. More output precision requires more computation cycles.
In general, you will almost always need to override some output types, even for the more predictable add/subt/multiply functions. LabVIEW chooses the output to prevent data loss, which is a fine choice locally but eventually results in bitwidth explosion. You then need to choose a few strategic points in the datapath to reduce the width with appropriate rounding and overflow handling.
07-25-2011 10:33 AM
You can experiment with the handshaking behaviors by running the VI under My Computer. Use CTRL+Run (recompiling the VI) to simulate a fresh download with shift registers cleared. Different nodes have different behaviors, depending on their underlying implementation, so it's best to hook up the handshaking lines to control the data flow (ie, such that your "input valid" is AND'd with the "ready for input" from the previous iteration of the same node). The FFT with Handshaking example shows this process.
The Divide looks like it actually is ready to accept valid data on the first iteration, but there are other nodes that require at least one cycle before accepting inputs.