From: Michael Nolan Date: Tue, 28 Apr 2020 17:44:53 +0000 (-0400) Subject: Add stage to convert input float to fixed point number X-Git-Tag: ls180-24jan2020~76 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d55a0ef358cc72d4f0a6a845c1dc765f2be5f526;p=ieee754fpu.git Add stage to convert input float to fixed point number --- diff --git a/src/ieee754/cordic/fp_pipe_init_stages.py b/src/ieee754/cordic/fp_pipe_init_stages.py index ab740064..2d538713 100644 --- a/src/ieee754/cordic/fp_pipe_init_stages.py +++ b/src/ieee754/cordic/fp_pipe_init_stages.py @@ -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 + diff --git a/src/ieee754/cordic/fp_pipeline.py b/src/ieee754/cordic/fp_pipeline.py index d6bf90a9..9ceaaea4 100644 --- a/src/ieee754/cordic/fp_pipeline.py +++ b/src/ieee754/cordic/fp_pipeline.py @@ -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]) diff --git a/src/ieee754/cordic/test/test_fp_pipe.py b/src/ieee754/cordic/test/test_fp_pipe.py index c75ef741..1b2ead12 100644 --- a/src/ieee754/cordic/test/test_fp_pipe.py +++ b/src/ieee754/cordic/test/test_fp_pipe.py @@ -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))