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):
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:
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,
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)):
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):
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,