From: Michael Nolan Date: Mon, 4 May 2020 17:40:10 +0000 (-0400) Subject: Have sin_cos pipeline use bigfloat calculated atan table X-Git-Tag: ls180-24jan2020~74 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=86c586660a4e90927c16bf166e4f1829760c985e;p=ieee754fpu.git Have sin_cos pipeline use bigfloat calculated atan table --- diff --git a/src/ieee754/cordic/sin_cos_pipe_stage.py b/src/ieee754/cordic/sin_cos_pipe_stage.py index 79ad6590..94916abf 100644 --- a/src/ieee754/cordic/sin_cos_pipe_stage.py +++ b/src/ieee754/cordic/sin_cos_pipe_stage.py @@ -2,6 +2,8 @@ from nmigen import Module, Signal from nmutil.pipemodbase import PipeModBase from ieee754.cordic.pipe_data import CordicData, CordicInitialData import math +import bigfloat as bf +from bigfloat import BigFloat class CordicInitialStage(PipeModBase): @@ -47,8 +49,11 @@ class CordicStage(PipeModBase): dx = Signal(self.i.x.shape()) dy = Signal(self.i.y.shape()) dz = Signal(self.i.z.shape()) - angle = int(round(self.pspec.M * - math.atan(2**(-self.stagenum)))) + with bf.quadruple_precision: + x = bf.atan(BigFloat(2) ** BigFloat(-self.stagenum)) + x = x/(bf.const_pi()/2) + x = x * self.pspec.M + angle = int(round(x)) comb += dx.eq(self.i.y >> self.stagenum) comb += dy.eq(self.i.x >> self.stagenum) diff --git a/src/ieee754/cordic/test/test_pipe.py b/src/ieee754/cordic/test/test_pipe.py deleted file mode 100644 index b7eaf8ad..00000000 --- a/src/ieee754/cordic/test/test_pipe.py +++ /dev/null @@ -1,89 +0,0 @@ -from nmigen import Module, Signal -from nmigen.back.pysim import Simulator, Passive -from nmigen.test.utils import FHDLTestCase -from nmigen.cli import rtlil - -from ieee754.cordic.sin_cos_pipeline import CordicBasePipe -from ieee754.cordic.pipe_data import CordicPipeSpec -from python_sin_cos import run_cordic -import unittest -import math -import random - - -class SinCosTestCase(FHDLTestCase): - def run_test(self, inputs, outputs, fracbits=8): - m = Module() - pspec = CordicPipeSpec(fracbits=fracbits, rounds_per_stage=4) - m.submodules.dut = dut = CordicBasePipe(pspec) - - for port in dut.ports(): - print ("port", port) - - vl = rtlil.convert(dut, ports=dut.ports()) - with open("test_cordic_pipe_sin_cos.il", "w") as f: - f.write(vl) - - z = Signal(dut.p.data_i.z0.shape()) - z_valid = Signal() - ready = Signal() - x = Signal(dut.n.data_o.x.shape()) - y = Signal(dut.n.data_o.y.shape()) - - m.d.comb += [ - dut.p.data_i.z0.eq(z), - dut.p.valid_i.eq(z_valid), - dut.n.ready_i.eq(ready), - x.eq(dut.n.data_o.x), - y.eq(dut.n.data_o.y)] - - sim = Simulator(m) - sim.add_clock(1e-6) - - def writer_process(): - yield Passive() - for val in inputs: - yield z.eq(val) - yield z_valid.eq(1) - yield ready.eq(1) - yield - - def reader_process(): - while True: - yield - vld = yield dut.n.valid_o - if vld: - try: - (sin, cos) = outputs.__next__() - result = yield x - msg = "cos: {}, expected {}".format(result, cos) - assert result == cos, msg - result = yield y - msg = "sin: {}, expected {}".format(result, sin) - assert result == sin, msg - - except StopIteration: - break - - sim.add_sync_process(writer_process) - sim.add_sync_process(reader_process) - with sim.write_vcd("pipeline.vcd", "pipeline.gtkw", traces=[ - z, x, y]): - sim.run() - - def test_rand(self): - fracbits = 16 - M = (1 << fracbits) - ZMAX = int(round(M * math.pi/2)) - inputs = [] - outputs = [] - for i in range(50): - z = random.randrange(-ZMAX, ZMAX-1) - (sin, cos) = run_cordic(z, fracbits=fracbits, log=False) - inputs.append(z) - outputs.append((sin, cos)) - self.run_test(iter(inputs), iter(outputs), fracbits=fracbits) - - -if __name__ == "__main__": - unittest.main()