change test_fpsin to use 32 bit floats
[ieee754fpu.git] / src / ieee754 / cordic / test / test_fpsin_cos.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay
3 from nmigen.test.utils import FHDLTestCase
4
5 from ieee754.cordic.fpsin_cos import CORDIC
6 from ieee754.fpcommon.fpbase import FPNumBaseRecord
7 from python_sin_cos import run_cordic
8 from sfpy import Float32, Float32
9 import unittest
10 import math
11 import random
12
13
14 class SinCosTestCase(FHDLTestCase):
15 def run_test(self, zin=0, fracbits=8, expected_sin=0, expected_cos=0):
16
17 m = Module()
18
19 m.submodules.dut = dut = CORDIC(32)
20 z = Signal(dut.z0.width)
21 start = Signal()
22
23 sin = Signal(dut.sin.shape())
24 cos = Signal(dut.cos.shape())
25 ready = Signal()
26
27 m.d.comb += [
28 dut.z0.eq(z),
29 dut.start.eq(start),
30 sin.eq(dut.sin),
31 cos.eq(dut.cos),
32 ready.eq(dut.ready)]
33
34 sim = Simulator(m)
35 sim.add_clock(1e-6)
36
37 def process():
38 asserted = False
39 yield z.eq(zin.get_bits())
40 yield start.eq(1)
41
42 yield
43 yield start.eq(0)
44 yield
45 for i in range(dut.fracbits+1):
46 rdy = yield ready
47 zo = yield dut.z_out
48 if rdy and not asserted:
49 frac = self.get_frac(zo, dut.z_out.width - 2)
50 print(f"{zo:x} {frac}")
51 self.assertEqual(str(frac), zin.__str__())
52 asserted = True
53
54 real_sin = yield dut.sin
55 real_sin = self.get_frac(real_sin, dut.sin.width - 2)
56 diff = abs(real_sin - expected_sin)
57 print(f"{real_sin} {expected_sin} {diff}")
58 self.assertTrue(diff < 0.001)
59 real_cos = yield dut.cos
60 real_cos = self.get_frac(real_cos, dut.cos.width - 2)
61 diff = abs(real_cos - expected_cos)
62 print(f"{real_cos} {expected_cos} {diff}")
63 self.assertTrue(diff < 0.001)
64
65 yield
66
67 sim.add_sync_process(process)
68 with sim.write_vcd("fpsin_cos.vcd", "fpsin_cos.gtkw", traces=[
69 cos, sin, ready, start]):
70 sim.run()
71
72 def run_test_assert(self, z, fracbits=8):
73 zpi = z * Float32(math.pi/2)
74 e_sin = math.sin(zpi)
75 e_cos = math.cos(zpi)
76 self.run_test(zin=z, fracbits=fracbits, expected_sin=e_sin,
77 expected_cos=e_cos)
78
79 def test_1(self):
80 x = Float32(1.0)
81 print(x)
82 self.run_test_assert(x)
83
84 def test_pi_4(self):
85 x = Float32(1/3)
86 print(x)
87 self.run_test_assert(x)
88
89 def test_rand(self):
90 for i in range(500):
91 z = random.uniform(-1, 1)
92 f = Float32(z)
93 self.run_test_assert(f)
94
95 def get_frac(self, value, bits):
96 return value/(1 << bits)
97
98 if __name__ == "__main__":
99 unittest.main()