switch to exact version of cython
[ieee754fpu.git] / src / ieee754 / div_rem_sqrt_rsqrt / test_core.py
index 5a6724a53ad94fb7b0b86b172ae22bbc49cf58d9..d7aeded694f783ccb2b2982fe25172918af5a427 100755 (executable)
@@ -16,6 +16,7 @@ from nmigen.hdl.ir import Fragment
 from nmigen.back import rtlil
 from nmigen.back.pysim import Simulator, Delay, Tick
 from itertools import chain
+import inspect
 
 
 def show_fixed(bits, fract_width, bit_width):
@@ -162,6 +163,8 @@ def get_test_cases(core_config,
         assert isinstance(radicands, list)
 
     for alg_op in reversed(Operation):  # put UDivRem at end
+        if get_core_op(alg_op) not in core_config.supported:
+            continue
         if alg_op is Operation.UDivRem:
             for dividend in dividends:
                 for divisor in divisors:
@@ -212,6 +215,30 @@ class DivPipeCoreTestPipeline(Elaboratable):
         yield from self.o
 
 
+def trace_process(process, prefix="trace:", silent=False):
+    def generator():
+        if inspect.isgeneratorfunction(process):
+            proc = process()
+        else:
+            proc = process
+        response = None
+        while True:
+            try:
+                command = proc.send(response)
+                if not silent:
+                    print(prefix, command)
+            except StopIteration:
+                return
+            except Exception as e:
+                if not silent:
+                    print(prefix, "raised:", e)
+                raise e
+            response = (yield command)
+            if not silent:
+                print(prefix, "->", response)
+    return generator
+
+
 class TestDivPipeCore(unittest.TestCase):
     def handle_config(self,
                       core_config,
@@ -225,6 +252,18 @@ class TestDivPipeCore(unittest.TestCase):
         base_name += f"_radix_{1 << core_config.log2_radix}"
         if not sync:
             base_name += "_comb"
+        if core_config.supported != frozenset(DivPipeCoreOperation):
+            name_map = {
+                DivPipeCoreOperation.UDivRem: "div",
+                DivPipeCoreOperation.SqrtRem: "sqrt",
+                DivPipeCoreOperation.RSqrtRem: "rsqrt",
+            }
+            # loop using iter(DivPipeCoreOperation) to maintain order
+            for op in DivPipeCoreOperation:
+                if op in core_config.supported:
+                    base_name += f"_{name_map[op]}"
+            base_name+="_only"
+
         with self.subTest(part="synthesize"):
             dut = DivPipeCoreTestPipeline(core_config, sync)
             vl = rtlil.convert(dut, ports=[*dut.i, *dut.o])
@@ -236,6 +275,8 @@ class TestDivPipeCore(unittest.TestCase):
                            gtkw_file=open(f"{base_name}.gtkw", "w"),
                            traces=[*dut.traces()]):
             def generate_process():
+                if not sync:
+                    yield Delay(1e-6)
                 for test_case in test_cases:
                     if sync:
                         yield Tick()
@@ -245,15 +286,17 @@ class TestDivPipeCore(unittest.TestCase):
                     if sync:
                         yield Delay(0.9e-6)
                     else:
-                        yield
+                        yield Delay(1e-6)
 
             def check_process():
                 # sync with generator
                 if sync:
-                    yield
+                    yield Tick()
                     for _ in range(core_config.n_stages):
-                        yield
-                    yield
+                        yield Tick()
+                    yield Tick()
+                else:
+                    yield Delay(0.5e-6)
 
                 # now synched with generator
                 for test_case in test_cases:
@@ -261,7 +304,7 @@ class TestDivPipeCore(unittest.TestCase):
                         yield Tick()
                         yield Delay(0.9e-6)
                     else:
-                        yield
+                        yield Delay(1e-6)
                     quotient_root = (yield dut.o.quotient_root)
                     remainder = (yield dut.o.remainder)
                     with self.subTest(test_case=str(test_case)):
@@ -272,8 +315,9 @@ class TestDivPipeCore(unittest.TestCase):
                                          str(test_case))
             if sync:
                 sim.add_clock(2e-6)
-            sim.add_sync_process(generate_process)
-            sim.add_sync_process(check_process)
+            silent = True
+            sim.add_process(trace_process(generate_process, "generate:", silent=silent))
+            sim.add_process(trace_process(check_process, "check:", silent=silent))
             sim.run()
 
     def test_bit_width_2_fract_width_1_radix_2_comb(self):
@@ -298,6 +342,32 @@ class TestDivPipeCore(unittest.TestCase):
                                              fract_width=4,
                                              log2_radix=1))
 
+    def test_bit_width_8_fract_width_4_radix_4_comb(self):
+        self.handle_config(DivPipeCoreConfig(bit_width=8,
+                                             fract_width=4,
+                                             log2_radix=2),
+                           sync=False)
+
+    def test_bit_width_8_fract_width_4_radix_4(self):
+        self.handle_config(DivPipeCoreConfig(bit_width=8,
+                                             fract_width=4,
+                                             log2_radix=2))
+
+    def test_bit_width_8_fract_width_4_radix_4_div_only(self):
+        supported = (DivPipeCoreOperation.UDivRem,)
+        self.handle_config(DivPipeCoreConfig(bit_width=8,
+                                             fract_width=4,
+                                             log2_radix=2,
+                                             supported=supported))
+
+    def test_bit_width_8_fract_width_4_radix_4_comb_div_only(self):
+        supported = (DivPipeCoreOperation.UDivRem,)
+        self.handle_config(DivPipeCoreConfig(bit_width=8,
+                                             fract_width=4,
+                                             log2_radix=2,
+                                             supported=supported),
+                           sync=False)
+
     @unittest.skip("really slow")
     def test_bit_width_32_fract_width_24_radix_8_comb(self):
         self.handle_config(DivPipeCoreConfig(bit_width=32,