mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
cordic: round() constants if not power of two bitwidth, cleanup, simplify some logic
This commit is contained in:
parent
11f58862db
commit
3d84a7a9de
3 changed files with 32 additions and 33 deletions
|
@ -15,30 +15,30 @@ class TestBench(Module):
|
||||||
n = 1<<flen(self.cordic.xi)
|
n = 1<<flen(self.cordic.xi)
|
||||||
self.c = c = 2**(flen(self.cordic.xi) - 1)
|
self.c = c = 2**(flen(self.cordic.xi) - 1)
|
||||||
self.cz = cz = 2**(flen(self.cordic.zi) - 1)
|
self.cz = cz = 2**(flen(self.cordic.zi) - 1)
|
||||||
|
x = int(xmax*c/self.cordic.gain)
|
||||||
if i is None:
|
if i is None:
|
||||||
i = [(int(xmax*c/self.cordic.gain), 0, int(cz*(i/n - .5)))
|
i = [(x, 0, int(cz*(2.*ii/n - 1))) for ii in range(n)]
|
||||||
for i in range(n)]
|
|
||||||
self.i = i
|
self.i = i
|
||||||
random.shuffle(self.i)
|
random.shuffle(self.i)
|
||||||
self.ii = iter(self.i)
|
self.ii = iter(self.i)
|
||||||
self.o = []
|
self.o = []
|
||||||
|
|
||||||
def do_simulation(self, selfp):
|
def do_simulation(self, selfp):
|
||||||
|
if selfp.cordic.new_out:
|
||||||
|
self.o.append((selfp.cordic.xo, selfp.cordic.yo, selfp.cordic.zo))
|
||||||
if selfp.cordic.new_in:
|
if selfp.cordic.new_in:
|
||||||
try:
|
try:
|
||||||
selfp.cordic.xi, selfp.cordic.yi, selfp.cordic.zi = next(self.ii)
|
selfp.cordic.xi, selfp.cordic.yi, selfp.cordic.zi = next(self.ii)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise StopSimulation
|
raise StopSimulation
|
||||||
if selfp.cordic.new_out:
|
|
||||||
self.o.append((selfp.cordic.xo, selfp.cordic.yo, selfp.cordic.zo))
|
|
||||||
|
|
||||||
def run_io(self):
|
def run_io(self):
|
||||||
run_simulation(self)
|
run_simulation(self)
|
||||||
del self.i[-1], self.o[0]
|
del self.o[0]
|
||||||
if self.i[0] != (0, 0, 0):
|
if self.i[0] != (0, 0, 0):
|
||||||
assert self.o[0] != (0, 0, 0)
|
assert self.o[0] != (0, 0, 0)
|
||||||
if self.i[-1] != self.i[-2]:
|
#if self.i[-1] != self.i[-2]:
|
||||||
assert self.o[-1] != self.o[-2], self.o[-2:]
|
# assert self.o[-1] != self.o[-2], self.o[-2:]
|
||||||
|
|
||||||
def rms_err(width, guard=None, stages=None, n=None):
|
def rms_err(width, guard=None, stages=None, n=None):
|
||||||
tb = TestBench(width=width, guard=guard, stages=stages,
|
tb = TestBench(width=width, guard=guard, stages=stages,
|
||||||
|
@ -87,9 +87,10 @@ def plot_function(**kwargs):
|
||||||
xi, yi, zi = np.array(tb.i).T
|
xi, yi, zi = np.array(tb.i).T
|
||||||
xo, yo, zo = np.array(tb.o).T
|
xo, yo, zo = np.array(tb.o).T
|
||||||
fig, ax = plt.subplots()
|
fig, ax = plt.subplots()
|
||||||
|
#ax.plot(zi, xo-np.around(xi[0]*g*np.cos(zi/cz*np.pi)), "k-")
|
||||||
ax.plot(zi, xo, "r,")
|
ax.plot(zi, xo, "r,")
|
||||||
ax.plot(zi, yo, "g,")
|
ax.plot(zi, yo, "g,")
|
||||||
ax.plot(zi, zo, "g,")
|
ax.plot(zi, zo, "b,")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -101,6 +102,8 @@ if __name__ == "__main__":
|
||||||
#plot_function(func_mode="hyperbolic", xmax=.3, width=16, n=333)
|
#plot_function(func_mode="hyperbolic", xmax=.3, width=16, n=333)
|
||||||
#plot_function(func_mode="circular", width=16, n=333)
|
#plot_function(func_mode="circular", width=16, n=333)
|
||||||
#plot_function(func_mode="hyperbolic", cordic_mode="vector",
|
#plot_function(func_mode="hyperbolic", cordic_mode="vector",
|
||||||
# xmax=.3, width=16, n=333)
|
# xmax=.3, width=16, n=333)
|
||||||
#plot_function(func_mode="circular", width=16, n=333)
|
plot_function(func_mode="circular",
|
||||||
|
width=16, stages=15, guard=0,
|
||||||
|
n=1000, xmax=.98)
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from math import atan, atanh, log, sqrt, pi, ceil
|
from math import atan, atanh, log, sqrt, pi
|
||||||
|
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
|
|
||||||
|
@ -276,9 +276,12 @@ class TwoQuadrantCordic(Module):
|
||||||
a = [atanh(2**-i) for i in s]
|
a = [atanh(2**-i) for i in s]
|
||||||
g = [sqrt(1 - 2**(-2*i)) for i in s]
|
g = [sqrt(1 - 2**(-2*i)) for i in s]
|
||||||
zmax = sum(a)*2
|
zmax = sum(a)*2
|
||||||
a = [int(ai*2**(bits - 1)/zmax) for ai in a]
|
|
||||||
# round here helps the width=2**i - 1 case but hurts the
|
# round here helps the width=2**i - 1 case but hurts the
|
||||||
# important width=2**i case
|
# important width=2**i case
|
||||||
|
cast = int
|
||||||
|
if log(bits)/log(2) % 1:
|
||||||
|
cast = round
|
||||||
|
a = [cast(ai*2**(bits - 1)/zmax) for ai in a]
|
||||||
gain = 1.
|
gain = 1.
|
||||||
for gi in g:
|
for gi in g:
|
||||||
gain *= gi
|
gain *= gi
|
||||||
|
@ -316,30 +319,23 @@ class Cordic(TwoQuadrantCordic):
|
||||||
if self.func_mode != "circular":
|
if self.func_mode != "circular":
|
||||||
return # no need to remap quadrants
|
return # no need to remap quadrants
|
||||||
|
|
||||||
width = flen(self.xi)
|
|
||||||
widthz = flen(self.zi)
|
|
||||||
cxi, cyi, czi = self.xi, self.yi, self.zi
|
cxi, cyi, czi = self.xi, self.yi, self.zi
|
||||||
self.xi = Signal((width, True))
|
self.xi = xi = Signal.like(cxi)
|
||||||
self.yi = Signal((width, True))
|
self.yi = yi = Signal.like(cyi)
|
||||||
self.zi = Signal((widthz, True))
|
self.zi = zi = Signal.like(czi)
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
pi2 = 1<<(widthz - 2)
|
q = Signal()
|
||||||
if self.cordic_mode == "rotate":
|
if self.cordic_mode == "rotate":
|
||||||
#rot = self.zi + pi2 < 0
|
self.comb += q.eq(zi[-2] ^ zi[-1])
|
||||||
rot = self.zi[-1] ^ self.zi[-2]
|
|
||||||
else: # vector
|
else: # vector
|
||||||
rot = self.xi < 0
|
self.comb += q.eq(xi < 0)
|
||||||
#rot = self.xi[-1]
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
cxi.eq(self.xi),
|
If(q,
|
||||||
cyi.eq(self.yi),
|
Cat(cxi, cyi, czi).eq(Cat(-xi, -yi,
|
||||||
czi.eq(self.zi),
|
zi + (1 << flen(zi) - 1)))
|
||||||
If(rot,
|
).Else(
|
||||||
cxi.eq(-self.xi),
|
Cat(cxi, cyi, czi).eq(Cat(xi, yi, zi))
|
||||||
cyi.eq(-self.yi),
|
)
|
||||||
czi.eq(self.zi + 2*pi2),
|
]
|
||||||
#czi.eq(self.zi ^ (2*pi2)),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ class CordicCase(SimCase, unittest.TestCase):
|
||||||
return xi, yi, 0
|
return xi, yi, 0
|
||||||
def proc(xi, yi, zi):
|
def proc(xi, yi, zi):
|
||||||
return sqrt(xi**2 - yi**2), 0, atanh(yi/xi)
|
return sqrt(xi**2 - yi**2), 0, atanh(yi/xi)
|
||||||
self._run_io(50, gen, proc)
|
self._run_io(50, gen, proc, deltaz=2)
|
||||||
|
|
||||||
def test_vec_hyp(self):
|
def test_vec_hyp(self):
|
||||||
self.setUp(cordic_mode="vector", func_mode="hyperbolic")
|
self.setUp(cordic_mode="vector", func_mode="hyperbolic")
|
||||||
|
|
Loading…
Reference in a new issue