Forum Discussion
Fixed-point multiplication with "altmult_complex" megafunction
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.15 Replies
- Altera_Forum
Honored Contributor
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? - Altera_Forum
Honored Contributor
And if you discard any bits like this, it should be the MSB, not the 2nd bit.
- Altera_Forum
Honored Contributor
you should never discard any bits, unless you can garantee you are not multiplying two max negative numbers.
- Altera_Forum
Honored Contributor
So the 11.15 would have the first two MSB bits as the sign bits?
If so, can the second sign bit be discarded while implementing something like addressing a RAM? - Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
--- 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. - Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
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.