0

I’m writing a Radix-2 DIT FFT algorithm in VHDL, which requires some fractional multiplication of input data by Twiddle Factor (TF). I use Fixed Point arithmetic’s to achieve that, with every word being 16 bit long, where 1 bit is a sign bit and the rest is distributed between integer and fraction. Therefore my dilemma:

I have no idea, in what range my input data will be, so if I just decide that 4 bits go to integer and the rest 11 bits to fraction, in case I get integer numbers higher than 4 bits = 15 decimal, I’m screwed. The same applies if I do 50/50, like 7 bits to integer and the rest to fraction. If I get numbers, which are very small, I’m screwed because of truncation or rounding, i.e:

Let’s assume I have an integer "3"(0000 0011) on input and TF of "0.7071" ( 0.10110101 - 8 bit), and let’s assume, for simplicity, my data is 8 bit long, therefore:

3x0.7071 = 2.1213

3x0.7071 = 0000 0010 . 0001 1111 = 2.12109375 (for 16 bits).

Here comes the trick - I need to up/down round or truncate 16 bits to 8 bits, therefore, I get 0000 0010, i.e 2 - the error is way too high.

My questions are:

  • How would you solve this problem of range vs precision if you don’t know the range of your input data AND you would have numbers represented in fixed point?
  • Should I make a process, which decides after every multiplication where to put the comma? Wouldn’t it make the multiplication slower?
  • Xilinx IP Core has 3 different ways for Fixed Number Arithmetic’s – Unscaled (similar to what I want to do, just truncate in case overflow happens), Scaled fixed point (I would assume, that in that case it decides after each multiplication, where the comma should be and what should be rounded) and Block Floating Point(No idea what it is or how it works - would appreciate an explanation). So how does this IP Core decide where to put the comma? If the decision is made depending on the highest value in my dataset, then in case I have just 1 high peak and the rest of the data is low, the error will be very high.

I will appreciate any ideas or information on any known methods.

refDL
  • 89
  • 3
  • 11
  • To your second point: Dynamically rescaling fixed-point operands after every operation would be akin to using floating-point (which includes a dynamic scaling factor 2**N represented by the exponent). To your first point: Use of fixed-point computation when nothing is known about the input domain strikes me as very risky: I would suggest to either get a better handle on the input domain by working with people with a deep understanding of the use case(s), or considering the use of floating-point arithmetic (it doesn't have to be IEEE-754 compliant, you could use a simplified custom format). – njuffa Dec 18 '15 at 01:12
  • 1
    As for "block floating-point": This is a format in which operands are represented by a mantissa and a *common* exponent shared between all operands. The operations on the mantissas are then basically fixed-point operations, which makes this suitable for fixed-point platforms. Done right, you can basically reap most of the benefits of the dynamic range of floating-point, with the lower cost of fixed-point hardware. I can't say exactly how flexible this is as I have never used it (only pure fixed-point or pure floating-point). A quick internet search will find multiple relevant app notes. – njuffa Dec 18 '15 at 01:19
  • @njuffa, thank you for your answers! Regarding my first question, it's sadly the case and the team I am working with is not done with their work by far, and I have no time waiting for them either. So it's either do or fail. And the same with fixed vs float. In my opinion float would be better solution, but it was decided from "above", that we should use fixed, and you can die, but should use it. So yeah, basically, I'm constrained from all sides. – refDL Dec 18 '15 at 12:19

1 Answers1

0

You don't need to know the fixed-point format of your input. You can safely treat it as normalized -1 to 1 range or full integer-range.

The reason is that your output will have the same format as the input. Or, more likely for FFT, a known relationship like 3 bits increase, which would the output has 3 more integer bits than the input.

It is the core user's burden to know where the decimal point will end up, you have to document the change to dynamic range of course.

Jonathan Drolet
  • 3,318
  • 1
  • 12
  • 23
  • Thank you for your post, Jonathan. I probably was overthinking it. I will assume that the input is normalized and just put it into specs of my IP-Core. – refDL Dec 28 '15 at 22:42