From: Michael Nolan Date: Mon, 4 May 2020 20:52:41 +0000 (-0400) Subject: Sorta working FP renormalization in cordic X-Git-Tag: ls180-24jan2020~69 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6b56e96ee37e8e31a9b1b942f1c8587fe28e0040;p=ieee754fpu.git Sorta working FP renormalization in cordic --- diff --git a/src/ieee754/cordic/fp_pipeline.py b/src/ieee754/cordic/fp_pipeline.py index 2b0b8287..43fb3dc9 100644 --- a/src/ieee754/cordic/fp_pipeline.py +++ b/src/ieee754/cordic/fp_pipeline.py @@ -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) diff --git a/src/ieee754/cordic/pipe_data.py b/src/ieee754/cordic/pipe_data.py index 493331b0..83690e8d 100644 --- a/src/ieee754/cordic/pipe_data.py +++ b/src/ieee754/cordic/pipe_data.py @@ -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): diff --git a/src/ieee754/cordic/test/test_fp_pipe.py b/src/ieee754/cordic/test/test_fp_pipe.py index 295c3c4f..9edfd58b 100644 --- a/src/ieee754/cordic/test/test_fp_pipe.py +++ b/src/ieee754/cordic/test/test_fp_pipe.py @@ -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() diff --git a/src/ieee754/cordic/test/test_fpsin_cos.py b/src/ieee754/cordic/test/test_fpsin_cos.py index 7e3c214b..a98db72d 100644 --- a/src/ieee754/cordic/test/test_fpsin_cos.py +++ b/src/ieee754/cordic/test/test_fpsin_cos.py @@ -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):