Hi,
I am using the altmult_complex (complex multiplier) with inputs dataa (both real and imaginary) having 16 fractional bits, and inputs datab (both real and imaginary) having 2 decimal bits and 14 fractional bits. Dataa inputs are signed while datab inputs are unsigned. I know that the output of the megafunction block would be singed results: -> real = [(dataa_real * datab_real) - (dataa_imag * datab_imag)] -> imag = [(dataa_real * datab_imag) + (dataa_imag * datab_real)] Since the multiplication has both decimal and fractional bits, I'd like to know how many bits the outputs would have if I restrict the output to 16-bits in total. Since 0.16 * 2.14 = 2.30 (32 bits), would restricting output to 16-bits give 2.14? [x.y -> x=decimal bits and y=fractional bits] Also, would it be better if I use the fixed-point vhdl package? Appreciate your help and guidance.链接已复制
If I understand well you have:
dataa on 16 bit in 2's complement fractional bit. Your maximum dataa value is: .0111_1111_1111_1111 = 0.25 - 2^(-16) = MaxA Your minimum dataa value is: .1000_0000_0000_0000 = -0.5 = MinA datab on 16 bit unsigned with 14 fractional bit. Your maximum dataa value is: 11.11_1111_1111_1111 = 4 - 2^(-14) = MaxB Your minimum dataa value is: 00.00_0000_0000_0000 = 0 = MinB Now you need to calculate the range of your output. The maximum value is: 2*MaxA*MaxB = 2 - something small The minimum value is: -2 + something small I guess that your output mustb be 2's complement with 2 integer bit and 14 fractional bit whose range is: 10.00_0000_0000_0000 = -2 01.11_1111_1111_1111 = 2 - 2^(-14) Please check if my calculations are correct. I made them very fast. Was this your question?Thank you very much for numerically detailing out my post/question.
My main concern is that if I use the previously mentioned inputs into the altmult_complex megafunction block and keep the output bits restricted to 16-bits, would the outputs be 16 MSB, which would include the 2 integer bits (exactly from input datab) and 14 fractional bits by discarding the remaining 16 fractional bits?The product of two 0.16 signed numbers is normally 1.31 in fixed point, I would expect the same shift to take place with altmult_complex, as long as no saturation logic is applied to the result. You may want to keep 17 bits and perform the saturation logic - a result with the MSB set has to be replaced by the most negative value, otherwise, the MSB can be cut.
--- Quote Start --- Since 0.16 * 2.14 = 2.30 (32 bits), would restricting output to 16-bits give 2.14? [x.y -> x=decimal bits and y=fractional bits] --- Quote End --- altmult_complex knows nothing about fixed point, as you may have noticed. Restricting it's output it will give you the 16 less significant bits, which is not what you want. Instead, you can either a) use altmult_complex with a 32 bit output and then just select the 16 MSBs. b) use VHDL's complex package c) do it by hand in VHDL Any way is a good way.
Somewhat strange in my opinion, that altmult_complex is cutting on the MSB side while lpm_mult cuts LSB.
In neither case, the behaviour is specified in the documentation, so you effectively have to try it. P.S.: lpm_mult has a short hint in the online help under "Truth Table/Functionality" that clarifies: --- Quote Start --- LPM_WIDTHP most significant bits of a * b + s --- Quote End --- Unfortunately altmult_complex documentation misses a similar hint. The decision to cut MSB here seems arbitrary anyway.I tried the megafunctions and observed exactly what you both, rbugalho and FvM, stated.
I will try outputting the entire output range (depending on my input ranges) using altmult_complex and then just select the MSB by discarding the LSB. Thank you all for your diligent guidance and help.If precision is an issue, you can try using "rounding" instead of simply discarding the LSBs.
With rounding (that is adding the first bit that you discard to the result) you get a rounding error with average zero value. Discarding the LSBs you get an error that is always positive.--- Quote Start --- If precision is an issue, you can try using "rounding" instead of simply discarding the LSBs. With rounding (that is adding the first bit that you discard to the result) you get a rounding error with average zero value. Discarding the LSBs you get an error that is always positive. --- Quote End --- True, but as with any rounding or truncation, if you have multiple multipliers this adds a half error for each multiplier. So even though the average is the same, the error can end up being quite a bit.
I read somewhere that multiplying two signed n-bits would result in 2n-bits with the first to msb being sign bits. For example, 16-bit signed times 16-bit signed gives 32-bit signed with bits 31 and 30 sign bits.
- Is this true? (i got the above question after looking at --> http://www.edaboard.com/thread140547.html) Next, would multiplying a 16-bit signed with a 18-bit signed give a 34-bit signed with first two msb as sign bits? Appreciate your reply.The answer is yes to both of your questions, unless you multiply the two maximum negative numbers.
Even more useful is the fixed point rules. If you have a 16 bit number with 8 bit integer and 8 bits fraction, you multiply it by a 10 bit number with 3 bits integer and 7 bits fractional, you get an 11.15 bit result. You simply add together the integer and fraactional bits.My implementation requires me to multiply a 14-bit number with a 18-bit number, and take 10 MSB bits as my output. So I simply let all the 32-bits be outputted and then discarded the 22 LSBs.
So after reading that link I posted earlier, I thought why should I keep two sign bits in my 10-bit output and thought of discarding the the second MSB. Leaving all the 10 MSB as my output should be fine I suppose?