Add stage to convert input float to fixed point number
authorMichael Nolan <mtnolan2640@gmail.com>
Tue, 28 Apr 2020 17:44:53 +0000 (13:44 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Mon, 4 May 2020 18:55:10 +0000 (14:55 -0400)
src/ieee754/cordic/fp_pipe_init_stages.py
src/ieee754/cordic/fp_pipeline.py
src/ieee754/cordic/test/test_fp_pipe.py

index ab7400640877aa2e723eba8041a684b7c8d46220..2d5387131de5455f4813712ab1270216e880eaf5 100644 (file)
@@ -1,4 +1,5 @@
-from nmigen import Module, Signal, Cat, Const, Mux
+from nmigen import (Module, Signal, Cat, Const, Mux, Repl, signed,
+                    unsigned)
 from nmigen.cli import main, verilog
 
 from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord
@@ -6,6 +7,7 @@ from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord
 from nmutil.pipemodbase import PipeModBase
 from ieee754.fpcommon.basedata import FPBaseData
 from ieee754.fpcommon.denorm import FPSCData
+from ieee754.cordic.fp_pipe_data import CordicInitialData
 
 
 class FPCordicInitStage(PipeModBase):
@@ -34,3 +36,34 @@ class FPCordicInitStage(PipeModBase):
         comb += self.o.ctx.eq(self.i.ctx)
 
         return m
+
+
+class FPCordicConvertFixed(PipeModBase):
+    def __init__(self, pspec):
+        super().__init__(pspec, "tofixed")
+
+    def ispec(self):
+        return FPSCData(self.pspec, False)
+
+    def ospec(self):
+        return CordicInitialData(self.pspec)
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+
+        shifter = Signal(self.i.a.e.width)
+        comb += shifter.eq(-self.i.a.e)
+
+        z_intermed = Signal(unsigned(self.o.z0.width))
+        z_shifted = Signal(signed(self.o.z0.width))
+        comb += z_intermed.eq(Cat(Repl(0, self.pspec.fracbits -
+                                       self.i.a.rmw),
+                                  self.i.a.m))
+        comb += z_shifted.eq(z_intermed >> shifter)
+        comb += self.o.z0.eq(Mux(self.i.a.s,
+                                 ~z_shifted + 1,
+                                 z_shifted))
+
+        return m
+
index d6bf90a9d3b441214fcf33d395a3033ac2e817fd..9ceaaea46d77c5f0b4bf6fc997ddc4474cf197fa 100644 (file)
@@ -2,7 +2,8 @@ from nmutil.singlepipe import ControlBase
 from nmutil.pipemodbase import PipeModBaseChain
 
 from ieee754.fpcommon.denorm import FPAddDeNormMod
-from ieee754.cordic.fp_pipe_init_stages import (FPCordicInitStage)
+from ieee754.cordic.fp_pipe_init_stages import (FPCordicInitStage,
+                                                FPCordicConvertFixed)
 
 
 class CordicPipeChain(PipeModBaseChain):
@@ -21,7 +22,8 @@ class FPCordicBasePipe(ControlBase):
 
         self.denorm = CordicPipeChain(pspec,
                                       [FPCordicInitStage(self.pspec),
-                                       FPAddDeNormMod(self.pspec, False)])
+                                       FPAddDeNormMod(self.pspec, False),
+                                       FPCordicConvertFixed(self.pspec)])
 
         self._eqs = self.connect([self.denorm])
 
index c75ef74116d650df4354f8fc509b47c799594a18..1b2ead125381d366065fd0c943f85e9c3dd51c96 100644 (file)
@@ -47,7 +47,7 @@ class SinCosTestCase(FHDLTestCase):
 
         sim.add_sync_process(writer_process)
         with sim.write_vcd("fp_pipeline.vcd", "fp_pipeline.gtkw", traces=[
-                z]):
+                z, dut.n.data_o.z0]):
             sim.run()
 
     def test_rand(self):
@@ -55,8 +55,11 @@ class SinCosTestCase(FHDLTestCase):
         M = (1 << fracbits)
         ZMAX = int(round(M * math.pi/2))
         inputs = []
-        for i in range(10):
-            inputs.append(Float32(1.0*i))
+        for i in range(-5, 10, 1):
+            if i < 0:
+                inputs.append(Float32(-2.0**(-abs(i))))
+            else:
+                inputs.append(Float32(2.0**(-abs(i))))
         self.run_test(iter(inputs))