Reply by Jitendra Rayala August 24, 20052005-08-24
philfuxx wrote:
> Hi all, > > I'm new to DSP programming. So far my asm program works fine on TI's > TMS320LF2407 DSP. However, I have to extend my program and need to > divide two 10 bit integer numbers (a, b) which are not related to each > other and change over time (they're obtained through 2 ch AD > conversion). > In most cases b > a. Does anyone know a simple algorithm to compute the > result x = a/b? The DSP provides only add, sub and multiplication > (signed/unsigned). > > Moreover I want to compute the Taylor series for > > ln(1-x) = x - x^2/2 + x^3/3 - ... > > Here, I encounter the same difficulties: how to perform the division of > each summand? I need it to simplify to multiplication and > addition/subtraction that the fixed point dsp can handle. > BTW: I know that a look-up table is the easiest way to compute the ln > of some numbers. But the range is relatively wide and memory > consumption is an issue. > > I appreciate any help! > > Regards, > > Arno
Yoy may want to check the following brief application note which describes a fast algorithm for computing fixed point reciprocal through multiply-accumulate operations. It also has matlab code. http://www.zsp.com/support/downloads/docs/pdf/fixedpointrecipalgo.pdf Jitendra
Reply by robert bristow-johnson August 24, 20052005-08-24
in article 1124916575.869608.115010@z14g2000cwz.googlegroups.com, philfuxx
at ArnoKromke@gmx.de wrote on 08/24/2005 16:49:

> ... In addition there is another command 'norm' that normalizes a > number to its mantissa and exponent (for both 16bit and 32bit). I think > that's all I need.
not knowing diddley about any modern TI (other than i think i still dislike TI DSP architecture and instruction set), this sounds about right. do your 'norm' (i presume it tells you how many bits it was shifted) and perform the log2() on the mantissa. -- r b-j rbj@audioimagination.com "Imagination is more important than knowledge."
Reply by philfuxx August 24, 20052005-08-24
Hi all,

thanks again for helping me. I found what I was looking for. On the
TMS320LF24x there is a command called subc which can be used for
division. In addition there is another command 'norm' that normalizes a
number to its mantissa and exponent (for both 16bit and 32bit). I think
that's all I need.

-Arno

Reply by robert bristow-johnson August 23, 20052005-08-23
in article 1124838598.688415.89610@g44g2000cwa.googlegroups.com, philfuxx at
ArnoKromke@gmx.de wrote on 08/23/2005 20:01:

> Thank you Robert, > > this is very interesting. However, I still don't know how to implement > that because it is not clear to me how the factional coefficients are > supposed to use. > > E.g. the first coefficient is: > > 1.4425449290 > > The number consists of an integer part "1" and the remainder or > fractional part "4425449290".
since that is the only coefficient bigger than 1, what you can do is split it up as: &#4294967295; &#4294967295; &#4294967295; &#4294967295; log2(1+x) ~= x &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; + &#4294967295; &#4294967295; &#4294967295; &#4294967295;0.4425449290 * x &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; + &#4294967295; &#4294967295; &#4294967295; -0.7181451002 * x^2 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; + &#4294967295; &#4294967295; &#4294967295; &#4294967295;0.4575485901 * x^3 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; + &#4294967295; &#4294967295; &#4294967295; -0.2779042655 * x^4 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; + &#4294967295; &#4294967295; &#4294967295; &#4294967295;0.1217970128 * x^5 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; + &#4294967295; &#4294967295; &#4294967295; -0.0258411662 * x^6 for 0 <= x <= 1 it might be one additional addition.
> The DSP performs only 16 bit by 16 bit multiplication. Therefore, > the coeficient needs to be truncated anyway, right.
when i earlier used the word "truncated", i meant a finite order power series taken from the (infinite order) Taylor series. but, yes, ALL of those coefficients will be represented with less precision than is shown above.
> usually a multiplication looks like this:
"usually" with some particular chip. i dunno how you do things with whatever chip you're using. is this an integer machine only? isn't there a mode or means to do fixed-point fractional arithmetic? if no, you represent all of the coefficients that are less than 1 as integer coef = 32768*coef do all of the multiply accumulate operations and then shift the result left by one bit and take the result out of the most significant word.
> LAR AR0, #200h ; AR0 points to data memory address 200h > LAR AR1, #210h ; AR1 points to data memory address 210h > MAR *, AR0 ; make AR0 current aux-reg > > SPLK #7FFFh, *+ ; 200h = 7FFFh > SPLK #7FFFh, *- ; 201h = 7FFFh > > LT *+ ; Load T-reg with content of memory address 200h > MPY *, AR1 ; Multiply the T reg by the content of the > memory address 201h > SPL *+ ; Store the low word of the product register at > memory address 210h > SPH * ; Store high word of the product register at > memory address 211h > > The multiplication is signed, regardless of the state of SXM because > MPY was used. If I were to use MPYU, an unsigned multiplication would > have been carried out. > Assuming that the content of data memory address 200h = 201h = 7FFFh (= > + 32767 decimal) the product will be 3FFF0001h. > > Alrighty, now can anyone tell me how a multiplication of 1.4425449290 x > whatever would look like? I saw somewhere that you can regard a > register also as remainder, like nominator/denominator (that is for 16 > bit nominator/65536). Is this the right way? > > The more I think about it the more confused I get. Maybe someone can > enlighten me ;-)
i don't know the particulars of the chip or assembly language that you are using. -- r b-j rbj@audioimagination.com "Imagination is more important than knowledge."
Reply by Jon Harris August 23, 20052005-08-23
I think Dan outlined it earlier in the thread:
"Another approach that is efficient is the method used by the Sharc
processors.  What you want to do is compute 1/b and then multiply by a.
 To compute 1/b, use b to go into a short lookup table, and then
iterate on it a couple of times.  You can look at the Sharc RECIPS
instruction."

"philfuxx" <ArnoKromke@gmx.de> wrote in message 
news:1124832842.295664.315210@g14g2000cwa.googlegroups.com...
> Hi Jerry, > > I'm interested in that floating-point algorithm for division on > multiply only DSPs. If you don't mind, then post it here. > > Thanks, > > Arno >
Reply by Jerry Avins August 23, 20052005-08-23
philfuxx wrote:
> Hi Jerry, > > I'm interested in that floating-point algorithm for division on > multiply only DSPs. If you don't mind, then post it here.
To evaluate n/d, evaluate 1/d and mulltiply by n. Here's how: Let x[0] approximate 1/d. Choosing x[0] wisely -- a LUT helps -- minimizes the number of necessary iterations. let x[i] = x[i-1]*(2 - d*x[i-1]) For a wild guess of x[0], continue until the change is trivial. For a well chosen x[0], a fixed number of iterations suffices. IIRC Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;
Reply by philfuxx August 23, 20052005-08-23
Thank you Robert,

this is very interesting. However, I still don't know how to implement
that because it is not clear to me how the factional coefficients are
supposed to use.

E.g. the first coefficient is:

1.4425449290

The number consists of an integer part "1" and the remainder or
fractional part "4425449290". The DSP performs only 16 bit by 16 bit
multiplication. Therefore, the coeficient needs to be truncated anyway,
right.

usually a multiplication looks like this:

LAR    AR0, #200h      ; AR0 points to data memory address 200h
LAR    AR1, #210h      ; AR1 points to data memory address 210h
MAR      *, AR0        ; make AR0 current aux-reg

SPLK  #7FFFh, *+       ; 200h = 7FFFh
SPLK  #7FFFh, *-       ; 201h = 7FFFh

LT      *+             ; Load T-reg with content of memory address 200h
MPY      *, AR1        ; Multiply the T reg by the content of the
memory address 201h
SPL     *+             ; Store the low word of the product register at
memory address 210h
SPH     *              ; Store high word of the product register at
memory address 211h

The multiplication is signed, regardless of the state of SXM because
MPY was used. If I were to use MPYU, an unsigned multiplication would
have been carried out.
Assuming that the content of data memory address 200h = 201h = 7FFFh (=
+ 32767 decimal) the product will be 3FFF0001h.

Alrighty, now can anyone tell me how a multiplication of 1.4425449290 x
whatever would look like? I saw somewhere that you can regard a
register also as remainder, like nominator/denominator (that is for 16
bit nominator/65536). Is this the right way?

The more I think about it the more confused I get. Maybe someone can
enlighten me ;-)

-Arno

Reply by robert bristow-johnson August 23, 20052005-08-23
in article 1124839702.013260.192190@g44g2000cwa.googlegroups.com, philfuxx
at ArnoKromke@gmx.de wrote on 08/23/2005 19:28:

> I just don't see the solution ... > > Yeah okay: x / (a/b) = x * (b/a) now I plug some numbers in: > > and obviouly: 4 / (3/5) = 4 * (5/3). > > Does this really change anything?
you compute (5/3) in advance. but, again, don't use a truncated Taylor series. for exactly the same price (it's the same operation but with slightly different coefficients), you can use an optimally designed power series.
> Guten Nacht ...
ya wohl. -- r b-j rbj@audioimagination.com "Imagination is more important than knowledge."
Reply by philfuxx August 23, 20052005-08-23
Hi Frank-Christian,

I just don't see the solution ...

Yeah okay: x / (a/b) = x * (b/a) now I plug some numbers in:

and obviouly: 4 / (3/5) = 4 * (5/3).

Does this really change anything? It's getting too late, I just can't
think. I'm gonna hit the hay.

Guten Nacht ...

Arno

Reply by philfuxx August 23, 20052005-08-23
Hey Dan,

this is definitely a good idea to see what the compiler does. I'm gonna
code the division part in C ...

-Arno