08-10-2009 12:14 PM
I'm attempting to use the bit accurate C model to simulate the FFT core which I will use in my FPGA design. My problem lies with the syntax for inputting two's complement, fixed-point numbers as doubles into the model.
To my understanding, the fixed-point numbers should be represented in floating-point as s.ffff ... ffff, where there are C_INPUT_WIDTH - 1 fractional bits. On page 15 of UG459 v3.0, under the heading "FFTs with Fixed-Point Inferface", #1 states that all xn_re and xn_im must be in the range -1.0 <= data < 1.0. When I try setting xn_re = 1.5, I get an error stating that xn_re is not in the range [-1.0,1.0). Does the floating-point value of 1.5 not represent -0.5 in this model? That is, floating-point 1.5 doesn't translate to -1 + 2^-1 = -0.5?
Finally, my conversion algorithm to take 16-bit fixed-point numbers (s.ffff ffff ffff fff) to their floating-point representation for input is
for (i = 0; i<samples; i++)
xn_re[i] = (double)xn_re_int[i] / pow(2.0, 15);
xn_im[i] = (double)xn_im_int[i] / pow(2.0, 15);
where xn_re_int and xn_im_int contain 16-bit two's complement integers that will be inputted in vector waveform simulations. Also, this algorithm gives outputs that are not in the range for my test vector.
Can anyone please provide any comments on this?
08-11-2009 03:58 AM
Inputs are usually normalized to [-1.0, 1.0) first and then quantized (use quantize function) to the input width of the FFT.
Not sure what you're asking by "this algorithm gives outputs that are not in the range for my test vector.". If you run FFT in unscaled mode, the output grows left (getting bigger).
08-12-2009 10:04 AM
Thanks for the prompt reply Jim.
I adjusted my input conversion algorithms which convert the numbers between the 16-bit, 2's complement, fixed-point numbers and normalized doubles:
// real int-to-double conversion
if ((xn_re_int[i] >> 15) == 0) // xn_re_int > 0
xn_re_dbl[i] = ((double)xn_re_int[i]) / pow(2.0, 15);
else // xn_re_int < 0
xn_re_dbl[i] = -((double)((~xn_re_int[i] & 0x7FFF) + 1)) / pow(2.0, 15);
with the double output being converted back to integers as
// real double-to-int conversion
if (xk_re[i] > 0) // xk_re is positive
xk_re_int[i] = ((unsigned int)(xk_re[i] * pow(2.0, 15)));
else // xk_re is negative
xk_re_int[i] = (~(((unsigned int)(-xk_re[i] * pow(2.0, 15))) & 0x7FFFFF) + 1) & 0x7FFFFF;
Using these conversions and scaling the intermediate, I was able to cascade IFFT and FFT in the C model to achive near unity gain with my test pattern.
However, the output of the IFFT operation (intermediate) from the C model, does not match the simulated waveform.
My question is: do these conversions seem logical for my application?