From: bugzilla-daemon@libre-soc.org
To: libre-riscv-dev@lists.libre-riscv.org
Subject: [libre-riscv-dev] [Bug 208] implement CORDIC in a general way sufficient to do transcendentals
Date: Tue, 05 May 2020 17:02:11 +0000
Message-ID: <bug-208-13-opKayy0Ev6@https.bugs.libre-soc.org/> (raw)
In-Reply-To: <bug-208-13@https.bugs.libre-soc.org/>
https://bugs.libre-soc.org/show_bug.cgi?id=208
--- Comment #53 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
(In reply to Michael Nolan from comment #52)
> (In reply to Luke Kenneth Casson Leighton from comment #50)
> > btw 12 stages is too many, because we need a minimum of one FunctionUnit
> > "managing" (matching up) source operands and results.
> >
> > each extra Function Unit added creates an Order N^2 increase in the overall
> > size of the Dependency Matrices.
> >
> > so - and i don't mean right now - if this can be either:
> >
> > * cut into two separate pipelines (partial data fed back as a micro-op)
> > * number of combinatorial blocks increased to 5 or 6
> >
> > we stand a chance of keeping the FU count down (8 is ok).
> >
> > have to think that through carefully, how to do micro-ops.
>
> Sure. I don't know about splitting it up into multiple uops,
neither do i at the moment! i think i might have got confused about
sharing the MUL unit with FPMUL.
> but reducing
> the number of stages is pretty easy. I added a parameter to the module
> called rounds_per_stage which governs how many cordic rounds go in each
> pipeline stage. Increasing that number will decrease the number of pipeline
> stages.
fantastic, that's exactly the kind of parameterisation _we_ need,
however as a general-purpose IEEE754 FP library, it's exactly
the kind of parameterisation that other _users_ need :)
>
> (In reply to Luke Kenneth Casson Leighton from comment #51)
> > the other option:
> >
> > keep the long pipeline lengths: we *know* that there's more stages than
> > there are FUs, and that's just "tough luck". we know that with only
> > 8 FUs and 12 pipeline stages, 4 of those at any one time will run
> > empty, and we just... live with that.
>
> I was going to ask if we could do something like this. Since I don't think
> the cordic will be used *that* often, this seems like a reasonable thing to
> do.
yehyeh.
ok what else can we throw in here? LOG1P is probably a good thing to try
this is a great explanation:
http://www.mclenegan.com/public/thesis.pdf
section 4.4.1 explains "rotation mode"
however we also need *vector* mode (4.4.2)
i know - somewhere - i've seen a python implementation of vector mode.
it also specified, as you can see, the three other modes: circular,
linear, hyperbolic.
ah! i know why we want to keep the two answers: see p39 of that
thesis: you can use them (with some post-processing) to do
tan.
also, see circular-vectoring mode, it ends up computing the
normal distance and... and the angle? ohh, that's for... darn
what was it... it's for arcs. there's a name for this... sorry
i forget what it's called right now.
https://www.ijert.org/vhdl-implementation-of-cordic-algorithm-for-wireless-lan
this version, p14, explains much clearer that "rotate" mode goes
by angle and computes x,y
"vector" mode the vector is rotated to be flat against the x-axis,
recording the angle (Z) needed to do so.
this one is a survey of CORDIC algorithms:
http://www.ee.ic.ac.uk/pcheung/teaching/ee3_DSD/crdcsrvy.pdf
it shows - *briefly* - how to use them to do different things, but
it also, by being a survey, has some really useful insights into
various optimisations.
so can i suggest, first adding the infrastructure back in to allow
cancellation and operations (ctx), then see if you can add one extra
"mode" (the m=-1, m=0, m=1 thing seems trivial which will give the
circular, linear and hyperbolic modes, respectively).
"circular" mode is covered with the output being SIN/COS.
ah ha! here's a useful suite of implementations (annoyingly being
in jupiter)
https://github.com/suyashmahar/cordic-algorithm-python/blob/master/cordic_implementation.ipynb
extractign the two modes:
circular = 1
linear = 0
hyperbolic = -1
def ROM_lookup(iteration, coordinate):
if (coordinate == circular):
return math.degrees(math.atan(2**(-1*iteration)))
elif (coordinate == linear):
return 2**(-1*iteration)
elif (coordinate == hyperbolic):
return (math.atanh(2**(-1*iteration)))
def rotation_mode(x, y, z, coordinate, iterations):
a = 0.607252935; # = 1/K
x_val_list = []
y_val_list = []
z_val_list = []
iterations_list = []
i = 0; # Keeps count on number of iterations
current_x = x # Value of X on ith iteration
current_y = y # Value of Y on ith iteration
current_z = z # Value of Z on ith iteration
di = 0
if (coordinate == hyperbolic):
i = 1
else:
i = 0
flag = 0
if (iterations > 0):
while (i < iterations):
if (current_z < 0):
di = -1
else:
di = +1
next_z = current_z - di * ROM_lookup(i, coordinate)
next_x = current_x - coordinate * di * current_y * (2**(-1*i))
next_y = current_y + di * current_x * 2**(-1*i)
current_x = next_x
current_y = next_y
current_z = next_z
x_val_list.append(current_x)
y_val_list.append(current_y)
z_val_list.append(current_z)
iterations_list.append(i)
if (coordinate == hyperbolic):
if ((i != 4) & (i != 13) & (i!=40)):
i = i+1
elif (flag == 0):
flag = 1
elif (flag == 1):
flag = 0
i = i+1
else:
i = i+1
return { 'x':x_val_list, 'y':y_val_list, 'z':z_val_list,
'iteration':iterations_list, }
ahhh, i recognise this code :) i've seen it before.
def vector_mode(x, y, z, coordinate, iterations):
a = 1.2075; # = 1/K
x_val_list = []
y_val_list = []
z_val_list = []
iterations_list = []
i = 0; # Keeps count on number of iterations
current_x = x # Value of X on ith iteration
current_y = y # Value of Y on ith iteration
current_z = z # Value of Z on ith iteration
di = 0
# This is neccesary since result for i=0 doesn't exists for hyperbolic
# co-ordinate system.
if (coordinate == hyperbolic):
i = 1
else:
i = 0
flag = 0
if (iterations > 0):
while (i < iterations):
di = -1*math.copysign(1, current_y);#*current_x);
next_x = current_x - coordinate * di * current_y * (2**(-1*i))
next_y = current_y + di * current_x * 2**(-1*i)
next_z = current_z - di * ROM_lookup(i, coordinate)
current_x = next_x
current_y = next_y
current_z = next_z
x_val_list.append(current_x)
y_val_list.append(current_y)
z_val_list.append(current_z)
iterations_list.append(i)
if (coordinate == hyperbolic):
if ((i != 4) & (i != 13) & (i!=40)):
i = i+1
elif (flag == 0):
flag = 1
elif (flag == 1):
flag = 0
i = i+1
else:
i = i+1
return { 'x':x_val_list, 'y':y_val_list, 'z':z_val_list,
'iteration':iterations_list }
if you can drop that into a repository, get it working, write a
few simple experiments and see how it operates in each of the 6
modes, we're on a roll :)
--
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev
next prev parent reply index
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <bug-208-13@https.bugs.libre-soc.org/>
2020-04-13 14:35 ` bugzilla-daemon
2020-04-13 17:23 ` bugzilla-daemon
2020-04-13 17:34 ` bugzilla-daemon
2020-04-15 17:54 ` bugzilla-daemon
2020-04-15 18:04 ` Cole Poirier
2020-04-15 19:14 ` bugzilla-daemon
2020-04-15 19:16 ` bugzilla-daemon
2020-04-15 19:17 ` bugzilla-daemon
2020-04-15 19:19 ` bugzilla-daemon
2020-04-15 19:21 ` Cole Poirier
2020-04-15 19:25 ` Luke Kenneth Casson Leighton
2020-04-15 19:29 ` Cole Poirier
2020-04-15 19:34 ` bugzilla-daemon
2020-04-15 19:54 ` bugzilla-daemon
2020-04-15 21:30 ` bugzilla-daemon
2020-04-16 7:53 ` bugzilla-daemon
2020-04-16 8:53 ` bugzilla-daemon
2020-04-16 9:48 ` bugzilla-daemon
2020-04-16 15:36 ` bugzilla-daemon
2020-04-16 16:22 ` bugzilla-daemon
2020-04-16 16:46 ` bugzilla-daemon
2020-04-16 16:59 ` bugzilla-daemon
2020-04-16 17:16 ` bugzilla-daemon
2020-04-17 12:29 ` bugzilla-daemon
2020-04-17 17:19 ` bugzilla-daemon
2020-04-17 17:28 ` bugzilla-daemon
2020-04-17 17:31 ` bugzilla-daemon
2020-04-17 18:02 ` bugzilla-daemon
2020-04-17 18:37 ` bugzilla-daemon
2020-04-17 18:38 ` bugzilla-daemon
2020-04-17 18:42 ` bugzilla-daemon
2020-04-17 19:36 ` bugzilla-daemon
2020-04-17 19:56 ` bugzilla-daemon
2020-04-17 19:59 ` bugzilla-daemon
2020-04-18 21:52 ` bugzilla-daemon
2020-04-20 21:51 ` bugzilla-daemon
2020-04-20 22:43 ` Jacob Lifshay
2020-05-05 13:17 ` bugzilla-daemon
2020-05-05 14:04 ` bugzilla-daemon
2020-05-05 14:06 ` bugzilla-daemon
2020-05-05 14:29 ` bugzilla-daemon
2020-05-05 14:42 ` bugzilla-daemon
2020-05-05 14:52 ` bugzilla-daemon
2020-05-05 14:53 ` bugzilla-daemon
2020-05-05 14:55 ` bugzilla-daemon
2020-05-05 14:58 ` bugzilla-daemon
2020-05-05 15:00 ` bugzilla-daemon
2020-05-05 15:00 ` bugzilla-daemon
2020-05-05 15:10 ` bugzilla-daemon
2020-05-05 15:10 ` bugzilla-daemon
2020-05-05 15:13 ` bugzilla-daemon
2020-05-05 16:03 ` bugzilla-daemon
2020-05-05 16:12 ` bugzilla-daemon
2020-05-05 16:16 ` bugzilla-daemon
2020-05-05 16:28 ` bugzilla-daemon
2020-05-05 17:02 ` bugzilla-daemon [this message]
2020-05-05 17:30 ` bugzilla-daemon
2020-05-06 9:53 ` bugzilla-daemon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bug-208-13-opKayy0Ev6@https.bugs.libre-soc.org/ \
--to=bugzilla-daemon@libre-soc.org \
--cc=libre-riscv-dev@lists.libre-riscv.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Libre RISC-V Mailing list Archives (accessible via public-inbox)
Archives are clonable: git clone --mirror https://inbox.libre-soc.org/libre-riscv-dev
Example config snippet for mirrors
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git