Shop OBEX P1 Docs P2 Docs Learn Events
Signed 16x18 pasm multiply — Parallax Forums

Signed 16x18 pasm multiply

richaj45richaj45 Posts: 179
edited 2013-09-23 10:10 in Propeller 1
Hello:

Could some one help me.
I want a singed 16-bit x 18-bit integer multiply in PASM that is as fast as possible.

In use the format of the integers is:

16-bit: s.fff_ffff_ffff_ffff Range: +.99999, -1.0000
18-bit: si.ffff_ffff_ffff_ffff Range: +1.99999, -2.0000

The results format is:
34-bits ssi.fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff Range: +0.999999999, -2.00000000

Since there is no need for two sign bits the output can be cut to 33-bits.
The actual number of nine is just an aproximate to show it is close to 1 but not since it is one fractional LSB less. However the -2 is exactly -2.

Thanks for any PASM you can contribute to this. It is for digital filtering were the coefficients are realtime updated.

Regards,
rich

Comments

  • lanternfishlanternfish Posts: 366
    edited 2013-09-23 03:21
    From a 2010 thread here rayman suggests multiplying two integers and then applying the sign. So I'm thinking make multiplier and multiplicand 18-bit.
    Of course there are more knowledgeable heads around here than me who may have a more appropriate solution.
  • AribaAriba Posts: 2,690
    edited 2013-09-23 06:26
    Here is a possible solution.

    The input is in registers signal (16bit) and coeff (18bit).
    The output is a 32bit result for the absolute part and the sign bit in a sign-register. (=33 bits together)

    This is just a draft and not tested!
    {
           shl signal,#16          'sign extend to long if needed
           sar signal,#16
    }
           mov sign,#0
           abs signal,signal  wc   '16bit sssssssssssssssss.fffffffffffffff
           rcl sign,#1
           abs coeff,coeff    wc   '18bit sssssssssssssssi.ffffffffffffffff
     if_c  xor sign,#1
    
           shl coeff,#15
           mov res,signal
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
           shr res,#1     wc
     if_c  add res,coeff
    
    ' now we have abs 32bit result in res-register: i.fffffffffffffffffffffffffffffff
    ' and sign in sign-register bit0
    
    Andy

    Edit: If you can make the signal 15 bits signed, or the coefficients only 17bits then the result would fit in one long.
  • richaj45richaj45 Posts: 179
    edited 2013-09-23 07:43
    Ariba:

    Yes reducing the sizes make thinks fit into 32 bits but i am doing audio filtering and more this is a bare minimum of bits as it is. When i do it in FPGA land i use 24-bits X 24-bits.

    Thanks for the code.

    regards,
    rich
  • lonesocklonesock Posts: 917
    edited 2013-09-23 10:10
    Assuming the filter coefficients don't change, you can save time by shifting through the filter coefficient once, and then accumulating 2 or 4 audio samples at the same time.
    shr coef, #1 wc
    if_c add accum1, sample1
         shl sample1, #1
    if_c add accum2, sample2
         shl sample2, #1
    if_c add accum3, sample3
         shl sample3, #1
    if_c add accum4, sample4
         shl sample4, #1
         'etc.
    
    Jonathan
Sign In or Register to comment.