Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21608 Discussions

Fixed-point multiplication with "altmult_complex" megafunction

Altera_Forum
Honored Contributor II
2,299 Views

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.
0 Kudos
15 Replies
Altera_Forum
Honored Contributor II
1,515 Views

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?
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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?
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

thanks for this this is what i need exactly!

0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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?
0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

you should never discard any bits, unless you can garantee you are not multiplying two max negative numbers.

0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

And if you discard any bits like this, it should be the MSB, not the 2nd bit.

0 Kudos
Altera_Forum
Honored Contributor II
1,515 Views

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?
0 Kudos
Reply