X-Git-Url: https://git.libre-soc.org/?p=ieee754fpu.git;a=blobdiff_plain;f=src%2Fieee754%2Fdiv_rem_sqrt_rsqrt%2Ftest_core.py;h=7df7be47a35c2af800706665bacb483fdeb98659;hp=95292f9afbf95e6198dc05e7a1864bcd420f8d54;hb=HEAD;hpb=0f6f64290345e962a5a18417aa19583dca00addd diff --git a/src/ieee754/div_rem_sqrt_rsqrt/test_core.py b/src/ieee754/div_rem_sqrt_rsqrt/test_core.py index 95292f9a..d7aeded6 100755 --- a/src/ieee754/div_rem_sqrt_rsqrt/test_core.py +++ b/src/ieee754/div_rem_sqrt_rsqrt/test_core.py @@ -2,11 +2,13 @@ # SPDX-License-Identifier: LGPL-2.1-or-later # See Notices.txt for copyright information -from .core import (DivPipeCoreConfig, DivPipeCoreSetupStage, - DivPipeCoreCalculateStage, DivPipeCoreFinalStage, - DivPipeCoreOperation, DivPipeCoreInputData, - DivPipeCoreInterstageData, DivPipeCoreOutputData) -from .algorithm import (FixedUDivRemSqrtRSqrt, Fixed, Operation, div_rem, +from ieee754.div_rem_sqrt_rsqrt.core import (DivPipeCoreConfig, + DivPipeCoreSetupStage, + DivPipeCoreCalculateStage, DivPipeCoreFinalStage, + DivPipeCoreOperation, DivPipeCoreInputData, + DivPipeCoreInterstageData, DivPipeCoreOutputData) +from ieee754.div_rem_sqrt_rsqrt.algorithm import (FixedUDivRemSqrtRSqrt, + Fixed, Operation, div_rem, fixed_sqrt, fixed_rsqrt) import unittest from nmigen import Module, Elaboratable, Signal @@ -14,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): @@ -160,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: @@ -210,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, @@ -223,36 +252,59 @@ 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]) with open(f"{base_name}.il", "w") as f: f.write(vl) dut = DivPipeCoreTestPipeline(core_config, sync) - with Simulator(dut, - vcd_file=open(f"{base_name}.vcd", "w"), - gtkw_file=open(f"{base_name}.gtkw", "w"), - traces=[*dut.traces()]) as sim: + sim = Simulator(dut) + with sim.write_vcd(vcd_file=open(f"{base_name}.vcd", "w"), + 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: - yield Tick() + if sync: + yield Tick() yield dut.i.dividend.eq(test_case.dividend) yield dut.i.divisor_radicand.eq(test_case.divisor_radicand) yield dut.i.operation.eq(int(test_case.core_op)) - yield Delay(0.9e-6) + if sync: + yield Delay(0.9e-6) + else: + 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: - yield Tick() - yield Delay(0.9e-6) + if sync: + yield Tick() + yield Delay(0.9e-6) + else: + yield Delay(1e-6) quotient_root = (yield dut.o.quotient_root) remainder = (yield dut.o.remainder) with self.subTest(test_case=str(test_case)): @@ -261,9 +313,11 @@ class TestDivPipeCore(unittest.TestCase): str(test_case)) self.assertEqual(remainder, test_case.remainder, str(test_case)) - sim.add_clock(2e-6) - sim.add_sync_process(generate_process) - sim.add_sync_process(check_process) + if sync: + sim.add_clock(2e-6) + 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): @@ -288,23 +342,53 @@ 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, fract_width=24, log2_radix=3), sync=False) + @unittest.skip("really slow") def test_bit_width_32_fract_width_24_radix_8(self): self.handle_config(DivPipeCoreConfig(bit_width=32, fract_width=24, log2_radix=3)) + @unittest.skip("really slow") def test_bit_width_32_fract_width_28_radix_8_comb(self): self.handle_config(DivPipeCoreConfig(bit_width=32, fract_width=28, log2_radix=3), sync=False) + @unittest.skip("really slow") def test_bit_width_32_fract_width_28_radix_8(self): self.handle_config(DivPipeCoreConfig(bit_width=32, fract_width=28,