R
rickman
isn't it "fubar" ?
Jamie
This is the French spelling. Make sure you put the accent on the second
syLAble.
isn't it "fubar" ?
Jamie
http://www.andraka.com/files/crdcsrvy.pdf should be a good start. Do you
remember Ray Andraka?
Seems what they instead do is implement
sin(M)cos(L)+cos(M)sin(L) where M and L are the more and less
significant bits of theta. Also, cos(L) tends to be almost 1,
so they just say it is 1.
Seems like that is one of the suggestions, but not done in the ROMs
they were selling. Then the interpolation has to add or subtract,
which is slightly (in TTL) harder.
The interpolated sine was done in 1970 with 128x8 ROMs. With larger
ROMs, like usual today, you shouldn't need it unless you want really
high resolution.
isn't it "fubar" ?rickman said:It is a lot of document for just two pages. Try this link to see the
short version...
arius.com/foobar/1972_National_MOS_Integrated_Circuits_Pages_273-274.pdf
In comp.dsp rickman said:On 3/18/2013 2:10 PM, Jerry Avins wrote:
Yes, of course. I should have thought of that. I don't go to his site
often, but his stuff is always excellent. I may have even downloaded
this paper before. I took a look at the CORDIC once a few years ago and
didn't get too far. I'm happy with my current approach for the moment,
but I will dig into this more another time.
I appreciate the link. Thanks Jerry.
I did a little work with this tonight and guess what, this is nearly the
same as the linear interpolation. cos(M) is as you say, nearly one. So
close in fact, that using the 10 msbs for M and an 18 bit output word,
there value calculated for the 1023rd entry is 0x40000.
That leaves sin(L). Surprise! This turns out to be a straight line! So
the formula is FAPP the same as the linear interpolation with the added
fudge factor of multiplying sin(L) by cos(M) rather than just
multiplying L directly with the difference sin(M+1)-sin(M). The sin*cos
method does require a second table to be stored. In fact, the paper you
reference uses a bit of slight of hand to include both the cos(M) *
sin(L) at a lesser precision both in the input and output of this table.
I'm not sure how well this would work with higher precision needs, but
I suppose it is worth a bit further look. It would be nice to eliminate
the multiplier which is used in the linear interpolation.
So I think this is just different strokes for different folks in the
end. The sin*cos method might work out a little better with the RMS
noise depending on how the second table is handled. But I think it may
end up... well, in the noise anyway.
I think the real problem is that as the resolution of the input
increases, the second table gets harder to keep small. But their trick
of essentially tossing the middle bits seems to work fairly well.
Yes, I see this note. This seems to be exactly what I was thinking. But
I don't think the data has to be subtracted. The unadjusted error is
zero at the end points of each interpolated line and consistently
increases in toward the middle from each end point. Adjusting the data
in the table results in an error that instead goes positive and
negative, but the table data is still always added, although they don't
deal with the issues of implementing more than 90 degrees. If you go
around the clock you then need to consider sign bits (as opposed to sine
bits) on the inputs to the tables.
I am working in a small FPGA with rather limited block RAM capabilities.
It is already on the board, so I can't swap it out. I also need two
generator circuits which pushes the limits a bit more. At least I don't
have any shortage of adder/subtractors or all the other logic this will
need.
Thanks for the pointer and the advice.
this *should* be a relatively simple issue, but i am confused
On 3/16/13 6:30 PM, rickman wrote:
I've been studying an approach to implementing a lookup table (LUT) to
implement a sine function. The two msbs of the phase define the
quadrant. I have decided that an 8 bit address for a single quadrant is
sufficient with an 18 bit output.
10 bits or 1024 points. since you're doing linear interpolation, add one
more, copy the zeroth point x[0] to the last x[1024] so you don't have
to do any modulo (by ANDing with (1023-1) on the address of the second
point. (probably not necessary for hardware implementation.)
x[n] = sin( (pi/512)*n ) for 0 <= n <= 1024
So you are suggesting a table with 2^n+1 entries? Not such a great idea
in some apps, like hardware.
i think about hardware as a technology, not so much an app. i think that
apps can have either hardware or software realizations.
What is the advantage?
in *software* when using a LUT *and* linear interpolation for sinusoid
generation, you are interpolating between x[n] and x[n+1] where n is
from the upper bits of the word that comes outa the phase accumulator:
#define PHASE_BITS 10
#define PHASE_MASK 0x001FFFFF // 2^21 - 1
#define FRAC_BITS 11
#define FRAC_MASK 0x000007FF // 2^11 - 1
#define ROUNDING_OFFSET 0x000400
long phase, phase_increment, int_part, frac_part;
long y, x[1025];
...
phase = phase + phase_increment;
phase = phase & PHASE_MASK;
int_part = phase >> FRAC_BITS;
frac_part = phase & FRAC_MASK;
y = x[int_part];
y = y + (((x[int_part+1]-y)*frac_part + ROUNDING_OFFSET)>>FRAC_BITS);
now if the lookup table is 1025 long with the last point a copy of the
first (that is x[1024] = x[0]), then you need not mask int_part+1.
x[int_part+1] always exists.
Also, why 10 bit
address for a 1024 element table?
uh, because 2^10 = 1024?
that came from your numbers: 8-bit address for a single quadrant and
there are 4 quadrants, 2 bits for the quadrant.
why wouldn't you use those extra bits in the linear interpolation if
they are part of the phase word? not doing so makes no sense to me at
all. if you have more bits of precision in the fractional part of the phase
not in software. i realize that in hardware and you're worried about
real estate, you might want only one quadrant in ROM, but in software
you would have an entire cycle of the waveform (plus one repeated point
at the end for the linear interpolation).
and if you *don't* have the size constraint in your hardware target and
you can implement a 1024 point LUT as easily as a 256 point LUT, then
why not? so you don't have to fiddle with reflecting the single quadrant
around a couple of different ways.
i read this over a couple times and cannot grok it quite. need to be
more explicit (mathematically, or with C or pseudocode) with what your
operations are.
not with defining the points of the table. you do that in MATLAB or in C
or something. your hardware gets its LUT spec from something you create
with a math program.
i'm just thinking that if you were using LUT to generate a sinusoid that
is a *signal* (not some parameter that you use to calculate other
stuff), then i think you want to minimize the mean square error (which
is the power of the noise relative to the power of the sinusoid). so the
LUT values might not be exactly the same as the sine function evaluated
at those points.
what are "lines"? not quite following you.
if you want to define your LUT to minimize the mean square error,
assuming linear interpolation between LUT entries, that can be a little
complicated, but i don't think harder than what i remember doing in grad
school. want me to show you? you get a big system of linear equations to
get the points. if you want to minimize the maximum error (again
assuming linear interpolation), then it's that fitting a straight line
to that little snippet of quadratic curve bit that i mentioned.
sin(t) = t + ... small terms when t is small
cos(t) = 1 - (t^2)/2 + ... small terms when t is small
but they beat you by a few hundred years.
I had used my "standard" 4.0 Acrobat; fails in that manner very reliably.glen said:(snip, I wrote)
I just tried it, copy and paste from the above link, and it worked.
You might be sure to use Adobe reader if that matters.
Also, it is page 273 in the document, page 282 in the PDF.
(snip)
One of many reasons i hate Adobe Reader 7.0: along near the top is aglen said:(snip, I wrote)
I just tried it, copy and paste from the above link, and it worked.
You might be sure to use Adobe reader if that matters.
Also, it is page 273 in the document, page 282 in the PDF.
(snip)
The basic approach given there is very good; use of puny 4 or 5 digitglen said:(snip, I wrote)
I just tried it, copy and paste from the above link, and it worked.
You might be sure to use Adobe reader if that matters.
Also, it is page 273 in the document, page 282 in the PDF.
(snip)
Robert said:The basic approach given there is very good; use of puny 4 or 5 digit
tables is a major weakness: sqrt(2)/2 as 0.7071 is junk; CRC in the
squares, cubes and roots section gives sqrt(2) as 1.414214 (6 digits)
and sqrt(50) as 7.07168 (also 6 digits).
And if one needs more, use the Taylor series (for reasonably small
angles) as it converges fast (Nth odd power and Nth odd factorial).
--or, use the FPU in the computer to get SIN and COS at the same time!
Reduction from 360 degrees helps:
"Split" 180 degrees: sin(-x)=-sin(x)
"Split" 90 degrees: sin(180-x)=sin(x)
"Split" 45 degrees: sin(90-x)=cos(x)
"Split" 22.5 degrees: (sqrt(0.5)*(cos(x)-sin(x))
Small angles requires less iterations for a given accuracy.
Yes, of course. I should have thought of that. I don't go to his site
often, but his stuff is always excellent. I may have even downloaded
this paper before. I took a look at the CORDIC once a few years ago and
didn't get too far. I'm happy with my current approach for the moment,
but I will dig into this more another time.
I appreciate the link. Thanks Jerry.
I had used my "standard" 4.0 Acrobat; fails in that manner very
reliably. ver 7.0 works 100 percent; thanks.
The basic approach given there is very good; use of puny 4 or 5 digit
tables is a major weakness: sqrt(2)/2 as 0.7071 is junk; CRC in the
squares, cubes and roots section gives sqrt(2) as 1.414214 (6 digits)
and sqrt(50) as 7.07168 (also 6 digits).
And if one needs more, use the Taylor series (for reasonably small
angles) as it converges fast (Nth odd power and Nth odd factorial).
--or, use the FPU in the computer to get SIN and COS at the same time!
Reduction from 360 degrees helps:
"Split" 180 degrees: sin(-x)=-sin(x)
"Split" 90 degrees: sin(180-x)=sin(x)
"Split" 45 degrees: sin(90-x)=cos(x)
"Split" 22.5 degrees: (sqrt(0.5)*(cos(x)-sin(x))
Small angles requires less iterations for a given accuracy.
It requires a 12V
power supply, though the outputs are still TTL compatible, using
both -12V and +5V power supplies.
On 3/19/13 12:05 AM, glen herrmannsfeldt wrote:
...
my goodness we're old, glen.
I'm glad it's just you guys.![]()
He indicated that his target is an FPGA that has no multiplies. This
is the exact environment where the CORDIC excels. LUTs can be
expensive in FPGAs depending on the vendor and the device.
what was that EPROM? a 2716 or 2708 or something like that?
One of many reasons i hate Adobe Reader 7.0: along near the top is a
number of cons, one is the so-called hand tool and it defaults as
"selected" - BUT you see the "hand" only while moving the cursor and
when you stop that changes to the "select tool" so that it is IMPOSSIBLE
to move the page around.
When moving the hand, the mouse will highlight text if push left button;
CANNOT grab!!!!!!!!!!!!!!!
That always works in 4.0 ..
Newer versions are worse.