From 036c91539b0ff74988cb49c17616177463aea061 Mon Sep 17 00:00:00 2001 From: Donald Sebastian Leung Date: Fri, 16 Oct 2020 12:18:09 +0800 Subject: [PATCH] Start preparing assertions for sorting network --- rtio/sed/output_network.py | 30 +++++++++++++++++++++++++++++- rtio/test/__init__.py | 0 rtio/test/sed/__init__.py | 0 rtio/test/sed/output_network.py | 18 ++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 rtio/test/__init__.py create mode 100644 rtio/test/sed/__init__.py create mode 100644 rtio/test/sed/output_network.py diff --git a/rtio/sed/output_network.py b/rtio/sed/output_network.py index 9d5198c..9919815 100644 --- a/rtio/sed/output_network.py +++ b/rtio/sed/output_network.py @@ -1,5 +1,6 @@ from nmigen import * from nmigen.utils import * +from nmigen.asserts import * from rtio.sed import layouts @@ -44,13 +45,23 @@ def cmp_wrap(a, b): return Mux((a[-2] == a[-1]) & (b[-2] == b[-1]) & (a[-1] != b[-1]), a[-1], a < b) class OutputNetwork(Elaboratable): - def __init__(self, lane_count, seqn_width, layout_payload): + def __init__(self, lane_count, seqn_width, layout_payload, *, fv_mode=False): m = Module() self.m = m self.input = [Record(layouts.output_network_node(seqn_width, layout_payload)) for _ in range(lane_count)] self.output = None + if fv_mode: + # Model arbitrary inputs for network nodes + for i in range(lane_count): + m.d.comb += self.input[i].valid.eq(AnySeq(1)) + m.d.comb += self.input[i].seqn.eq(AnySeq(seqn_width)) + m.d.comb += self.input[i].replace_occured.eq(AnySeq(1)) + m.d.comb += self.input[i].nondata_replace_occured.eq(AnySeq(1)) + for field, width in layout_payload: + m.d.comb += getattr(self.input[i].payload, field).eq(AnySeq(width)) + step_input = self.input for step in boms_steps_pairs(lane_count): step_output = [] @@ -98,5 +109,22 @@ class OutputNetwork(Elaboratable): self.output = step_output step_input = step_output + if fv_mode: + # Sanity checks + assert self.output is not None + assert len(self.input) == lane_count + assert len(self.output) == lane_count + + # Indicator of when Past() is valid + f_past_valid = Signal() + m.d.sync += f_past_valid.eq(1) + + # TODO: assert outputs is a permutation of inputs + + # Channel numbers for outputs are sorted in increasing order + with m.If(f_past_valid): + # TODO: Get the below (bogus) assertion to fail + m.d.comb += Assert(self.output[7].payload.channel == 0) + def elaborate(self, platform): return self.m diff --git a/rtio/test/__init__.py b/rtio/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rtio/test/sed/__init__.py b/rtio/test/sed/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rtio/test/sed/output_network.py b/rtio/test/sed/output_network.py new file mode 100644 index 0000000..180d0fd --- /dev/null +++ b/rtio/test/sed/output_network.py @@ -0,0 +1,18 @@ +from nmigen import * +from nmigen.asserts import * +from nmigen.test.utils import * +from ...sed.output_network import * + +""" +Verification tasks for OutputNetwork +""" + +class OutputNetworkTestCase(FHDLTestCase): + def verify(self): + # Bounded model check + self.assertFormal( + OutputNetwork(16, 2, [("data", 32), ("channel", 3)], fv_mode=True), + mode="bmc", depth=10) + # TODO: unbounded proof + +OutputNetworkTestCase().verify()