Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

Multiplication Rounding

Hey guys,

I am multiplying two 32 bit numbers using LPM_MULT. Each number is in Q16.16 fixed point format. The product is a 64 bit Q32.32 number. I then shift the product to the right by 16 bits to get a Q32.16 bit number. Now, I would like to round the number to get a Q16.16 bit number. Large inputs are possible, so the product needs to be rounded.

Does anyone know a simple and effective algorithm that could be implemented in Verilog? In my old rounding system I would simply divide by 65536. Since I am using Q16.16 format, I don't think it will work anymore.

17 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This thread interestingly raised a sensible issue regarding meaning of words we use.

    Indeed rounding implies immediately the rounding of fraction to integer.

    But with fractional notation of data buses it is quite misleading. One has to use integer view here and only use fractional view in tools like ip generators, dsp builder. It is really invasion by software mindset and very unfair...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    My question probably did involve some confusing use of terminology. I'm just a novice, so I should be more careful from now on.

    Anyways, lets say you have two Q2.2 numbers. One is 11.11( and the other 11.11. These are the largest values that can be represented in Q2.2. Now, if we multiply them, we get:

    11100001 = 14.0625.

    Now, this is Q4.4. I need Q2.2. You can't represent 14 with two bits. So there will be some wrap around. That is why I need rounding. Essentially, the desired product would be some smaller wrap around number, and a fractional portion of two bits.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I'm afraid you can't have your cake and eat it too.

    If you need to represent numbers into the range of 14, you need to either

    a) use Q4.2, 6 bits total

    b) use Q4.0, 4 bits total but no fractional part
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Now, this is Q4.4. I need Q2.2. You can't represent 14 with two bits. So there will be some wrap around. That is why I need rounding. Essentially, the desired product would be some smaller wrap around number, and a fractional portion of two bits.

    --- Quote End ---

    It's unclear, what you want to achieve.

    As a first point, the term rounding isn't commonly used for the handling of overflow problems. Basically there are two options:

    - omit/cut the high bits, which causes wrap around, in case of signed numbers often resulting in a wrong sign

    - apply saturation logic, limiting the output to the highest respectively lowest value that can be represented in the number system. This technique is mostly applied in digital signal processing
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Some engineers use the following notation for bit growth issues:

    
                 
             ==1==>
             |
       ==32======16==>
             |
             ==15==>
    
    i.e. of 32 bits data bus: I discard 15 LSBs, discard 1 MSB, pass 16 bits

    the top part needs saturation as FvM indicated (a must unless you don't expect values to get there). it is symmetric or not.

    The bottom part means divide by 2^15 and may be truncated directly or rounded. Rounding can be to nearest integer, or basic or unbiased or towards positive inf. or towards negative inf. or towards roof ...etc plenty of methods here but differences are trivial.

    The rule applies to any data signal irrespective whether you view it as integer(decimal point at start!!) or fractional(decimal point anywhere you imagine)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This is what I did, and it works great:

    Drop the MSB (sign bit) of the product, and grab the next lower N bits.

    Add the (N-2)th bit to these N bits. The result is the rounded number in the proper Q notation.

    For example, lets say you have 011.01(3.25) * 011.11(3.75). Using a calculator you get 001100.0011. This can be thought of as 13x15=195.

    If you do the rounding you get:

    01100 + 00000 = 01100.

    Now if you consider it as decimal Q2, it is 011.00= 3.00

    3.25x3.75=12.1875

    Divide this by 4 and you get 3.04, which is pretty close to the rounded result of 3.00.

    Integers and fixed point are the same except being multiples of each other. 3.75 is the same as 15, except for a division by 4.

    If you multiply integers together, you get a result which can then be rounded via the algorithm above, which is basically a division by 16.

    Then, if you consider both the inputs and product as fixed point Q2, then all of them are divided by 4. If you divide both sides of the same equation by the same number, nothing changes.

    The result of the integer multiplication is 195. The rounding divides it by 16 to yield 12.1875. The division by 4 yields 3.04.

    Essentially, as some people pointed out, the rounding works regardless of the number of fractional points.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    but be careful with 2's complement. MSB is sign bit and the one next to it may differ. Moreover apply saturation after you add the 1 of rounding in case rounding leads to overflow.