I'm new to fixed point representation, which I use in a FPGA vi. I'm not sure I'm doing things correctly in manipulating FXP from the output of a vi to the input of another.
I have two FXP numbers a,b , both <+-,16,30>. I calculate c = sqrt(x^2+y^2), which is set automatically as a FXP<+,34,30>. Now, I'd like to send c (FXP<+,34,30>) to the input of a vi (PID), which takes in input a number d FXP<+,16,16>.
I care of the relative changes of c, not its absolute value. So I think I should "scale" the 34 bit c into the 16 bit d, losing resolution.
When c = 0, I'd like to have d = 0.
When c = max (=7.59...e8), I'd like to have d = max (=65535).
So I calculate
(c / 7.59...e8 * 65535) - (65535/2)
which becomes a FXP<+,64,50>, and trasform it (by the "To Fixed-Point" Vi) into the required <+-,16,16>.
Is this the right thing to do? if not, what is the good way?
First a correction: The max value of a <+, 34, 30> is 1.073...E9 and not as you mention 7.59...E8.
Assuming you then want to convert that max value to 65535 in an <+, 16, 16> FXP you have two different approaches.
The generic approach is to first re-interpret your <+, 34, 30> bit pattern to a number of type <+, 34, 16>. This keeps all your 34 bit resolution while moving the value in the range [0, 65535.99..]. You can then simply coerce that to your final <+, 16, 16>
In your particular case there is also another method that would work and that is to shift your value by 14 position. This reduces your integer bits from 30 to 16 but you'll loose corresponding resolution. It works for you because reducing 34 bit by 14 leaves you 20 bit resolution, still higher than your final 16 bit.
I am not sure which method is most efficient, so I'd suggest to use the first one that is generic.
I have attached an example VI (screenshot added in case your Lv version is incompatible)
Ah... I misunderstood what you meant with 'max' of your <+, 34, 30> it is the actual max value that your SQRT operation can return so SQRT(2)/2 of the FXP max value.
So you basically want to re-interpret your number and include a multiplication by SQRT(2).
Since you end with only 16 bit resolution there is really no need to keep 34 or even 50 bit floating around. I'd suggest to reduce the intermediate resolutions to more appropriate values (and save FPGA resources).
Here is an example where I start by re-interpretating your input value to <+, 34, 16> (this is free) then reduce your resolution to 20 bit and multiply by the SQRT(2) value with 18 bit resolution. This fits the FPGA multiplier well. I have also configured the output of the multiplier to directly return your requested <+, 16, 16>
Hope it's right this time 🙂