Add actual tests to test_pipeline.py
authorMichael Nolan <mtnolan2640@gmail.com>
Wed, 1 Apr 2020 17:17:40 +0000 (13:17 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Wed, 1 Apr 2020 17:20:22 +0000 (13:20 -0400)
src/ieee754/cordic/test/test_pipe.py

index 8e8bbc9f8848e667aa56dfdd05ffab0d2637a26e..bcfd563f0d936d3abaabf883474cb55a51b055e7 100644 (file)
@@ -1,42 +1,83 @@
 from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay
+from nmigen.back.pysim import Simulator, Delay, Passive
 from nmigen.test.utils import FHDLTestCase
 
 from ieee754.cordic.sin_cos_pipeline import CordicBasePipe
 from ieee754.cordic.pipe_data import CordicPipeSpec
 from python_sin_cos import run_cordic
 import unittest
+import math
+import random
 
 
 class SinCosTestCase(FHDLTestCase):
-    def run_test(self, zin=0, fracbits=8, expected_sin=0, expected_cos=0):
+    def run_test(self, inputs, outputs, fracbits=8):
         m = Module()
         pspec = CordicPipeSpec(fracbits=fracbits)
         m.submodules.dut = dut = CordicBasePipe(pspec)
 
         z = Signal(dut.p.data_i.z0.shape())
+        z_valid = Signal()
+        ready = Signal()
         x = Signal(dut.n.data_o.x.shape())
         y = Signal(dut.n.data_o.y.shape())
 
+        m.d.comb += [
+            dut.p.data_i.z0.eq(z),
+            dut.p.valid_i.eq(z_valid),
+            dut.n.ready_i.eq(ready),
+            x.eq(dut.n.data_o.x),
+            y.eq(dut.n.data_o.y)]
+
         sim = Simulator(m)
         sim.add_clock(1e-6)
 
-        def process():
-            yield z.eq(zin)
-            for i in range(10):
+        def writer_process():
+            yield Passive()
+            for val in inputs:
+                yield z.eq(val)
+                yield z_valid.eq(1)
+                yield ready.eq(1)
+                yield
+
+        def reader_process():
+            while True:
                 yield
-        sim.add_sync_process(process)
+                vld = yield dut.n.valid_o
+                if vld:
+                    try:
+                        (sin, cos) = outputs.__next__()
+                        result = yield x
+                        msg = "cos: {}, expected {}".format(result, cos)
+                        assert result == cos, msg
+                        result = yield y
+                        msg = "sin: {}, expected {}".format(result, sin)
+                        assert result == sin, msg
+
+                    except StopIteration:
+                        break
+
+
+        sim.add_sync_process(writer_process)
+        sim.add_sync_process(reader_process)
         with sim.write_vcd("pipeline.vcd", "pipeline.gtkw", traces=[
                 z, x, y]):
             sim.run()
 
-    def run_test_assert(self, z, fracbits=8):
-        (sin, cos) = run_cordic(z, fracbits=fracbits, log=False)
-        self.run_test(zin=z, fracbits=fracbits,
-                      expected_sin=sin, expected_cos=cos)
 
-    def test_0(self):
-        self.run_test_assert(0)
+    def test_rand(self):
+        fracbits = 16
+        M = (1 << fracbits)
+        ZMAX = int(round(M * math.pi/2))
+        inputs = []
+        outputs = []
+        for i in range(50):
+            z = random.randrange(-ZMAX, ZMAX-1)
+            (sin, cos) = run_cordic(z, fracbits=fracbits, log=False)
+            inputs.append(z)
+            outputs.append((sin, cos))
+        self.run_test(iter(inputs), iter(outputs), fracbits=fracbits)
+
 
 
 if __name__ == "__main__":