Sorta working FP renormalization in cordic
authorMichael Nolan <mtnolan2640@gmail.com>
Mon, 4 May 2020 20:52:41 +0000 (16:52 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Mon, 4 May 2020 20:52:41 +0000 (16:52 -0400)
src/ieee754/cordic/fp_pipeline.py
src/ieee754/cordic/pipe_data.py
src/ieee754/cordic/test/test_fp_pipe.py
src/ieee754/cordic/test/test_fpsin_cos.py

index 2b0b8287dccf7540ff6753cc38803b1eb3a1c727..43fb3dc905ad1acbbe8a624a41a4c2e313e21838 100644 (file)
@@ -6,6 +6,7 @@ from ieee754.cordic.fp_pipe_init_stages import (FPCordicInitStage,
                                                 FPCordicConvertFixed)
 from ieee754.cordic.sin_cos_pipe_stage import (CordicStage,
                                                CordicInitialStage)
+from ieee754.cordic.renormalize import CordicRenormalize
 
 
 class CordicPipeChain(PipeModBaseChain):
@@ -30,10 +31,12 @@ class FPCordicBasePipe(ControlBase):
         self.cordicstages = []
 
         initstage = CordicInitialStage(pspec)
+        finalstage = CordicRenormalize(pspec)
         stages = []
         for i in range(pspec.iterations):
             stages.append(CordicStage(pspec, i))
         chunks = self.chunkify(initstage, stages)
+        chunks[-1].append(finalstage)
         for chunk in chunks:
             chain = CordicPipeChain(pspec, chunk)
             self.cordicstages.append(chain)
index 493331b0977977f856a692561e2296c868edecf8..83690e8d7656f480a36188211ca3cb40e6979078 100644 (file)
@@ -1,5 +1,7 @@
 from nmigen import Signal, Const
 from nmutil.dynamicpipe import SimpleHandshakeRedir
+from ieee754.fpcommon.fpbase import Overflow, FPNumBaseRecord
+from ieee754.fpcommon.getop import FPPipeContext
 import math
 
 
@@ -16,6 +18,25 @@ class CordicInitialData:
         return [self.z0.eq(i.z0)]
 
 
+class CordicOutputData:
+
+    def __init__(self, pspec, e_extra=False):
+        width = pspec.width
+        self.x = FPNumBaseRecord(width, False, e_extra, name="x")
+        self.y = FPNumBaseRecord(width, False, e_extra, name="y")
+        self.ctx = FPPipeContext(pspec)
+        self.muxid = self.ctx.muxid
+
+    def __iter__(self):
+        yield from self.x
+        yield from self.y
+        yield from self.ctx
+
+    def eq(self, i):
+        return [self.x.eq(i.x), self.y.eq(i.y),
+                self.ctx.eq(i.ctx)]
+
+
 class CordicData:
 
     def __init__(self, pspec):
index 295c3c4f3c42c3596a441750c6eefc467a652768..9edfd58b348addd2f67255802b4766c0291f582b 100644 (file)
@@ -44,6 +44,8 @@ class SinCosTestCase(FHDLTestCase):
                 yield z_valid.eq(1)
                 yield ready.eq(1)
                 yield
+            for i in range(40):
+                yield
 
         sim.add_sync_process(writer_process)
         with sim.write_vcd("fp_pipeline.vcd", "fp_pipeline.gtkw", traces=[
@@ -62,6 +64,11 @@ class SinCosTestCase(FHDLTestCase):
                 inputs.append(Float32(2.0**(-abs(i))))
         self.run_test(iter(inputs))
 
+    def test_pi_2(self):
+        inputs = [Float32(0.5), Float32(1/3), Float32(2/3),
+                  Float32(-.5), Float32(0.001)]
+        self.run_test(iter(inputs))
+
 
 if __name__ == "__main__":
     unittest.main()
index 7e3c214b8cbc6fc4cba73aad27cc27d780f58e87..a98db72d3011e53ec4ea23dd9f6d437889c6a618 100644 (file)
@@ -10,13 +10,17 @@ import unittest
 import math
 import random
 
+float_class_for_bits = {64: Float64,
+                        32: Float32,
+                        16: Float16}
+
 
 class SinCosTestCase(FHDLTestCase):
-    def run_test(self, zin=0, fracbits=8, expected_sin=0, expected_cos=0):
+    def run_test(self, zin=0, bits=64, expected_sin=0, expected_cos=0):
 
         m = Module()
 
-        m.submodules.dut = dut = CORDIC(64)
+        m.submodules.dut = dut = CORDIC(32)
         z = Signal(dut.z0.width)
         start = Signal()
 
@@ -69,11 +73,12 @@ class SinCosTestCase(FHDLTestCase):
                  cos, sin, ready, start]):
             sim.run()
 
-    def run_test_assert(self, z, fracbits=8):
-        zpi = z * Float64(math.pi/2)
+    def run_test_assert(self, z, bits=64):
+        kls = float_class_for_bits[bits]
+        zpi = z * kls(math.pi/2)
         e_sin = math.sin(zpi)
         e_cos = math.cos(zpi)
-        self.run_test(zin=z, fracbits=fracbits, expected_sin=e_sin,
+        self.run_test(zin=z, expected_sin=e_sin,
                       expected_cos=e_cos)
 
     def test_1(self):
@@ -81,8 +86,8 @@ class SinCosTestCase(FHDLTestCase):
         self.run_test_assert(x)
 
     def test_pi_4(self):
-        x = Float64(1/3)
-        self.run_test_assert(x)
+        x = Float32(1/2)
+        self.run_test_assert(x, bits=32)
 
     def test_rand(self):
         for i in range(10000):