From f0c1c2cfeb5c64b90f0b602ff17c374c788b630f Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 8 Jul 2019 10:32:41 +0000 Subject: [PATCH] build.dsl: allow assertions on subsignal widths. This is useful when building abstractions around resources where the pin names are user-specified. Fixes #129. --- nmigen/build/dsl.py | 12 ++++++++---- nmigen/test/test_build_dsl.py | 10 ++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/nmigen/build/dsl.py b/nmigen/build/dsl.py index 6f76d05..90e09f8 100644 --- a/nmigen/build/dsl.py +++ b/nmigen/build/dsl.py @@ -6,7 +6,7 @@ __all__ = ["Pins", "PinsN", "DiffPairs", "DiffPairsN", class Pins: - def __init__(self, names, *, dir="io", conn=None): + def __init__(self, names, *, dir="io", conn=None, assert_width=None): if not isinstance(names, str): raise TypeError("Names must be a whitespace-separated string, not {!r}" .format(names)) @@ -23,6 +23,10 @@ class Pins: raise TypeError("Direction must be one of \"i\", \"o\", \"oe\", or \"io\", not {!r}" .format(dir)) + if assert_width is not None and len(names) != assert_width: + raise AssertionError("{} names are specified ({}), but {} names are expected" + .format(len(names), " ".join(names), assert_width)) + self.names = names self.dir = dir self.invert = False @@ -56,9 +60,9 @@ def PinsN(*args, **kwargs): class DiffPairs: - def __init__(self, p, n, *, dir="io", conn=None): - self.p = Pins(p, dir=dir, conn=conn) - self.n = Pins(n, dir=dir, conn=conn) + def __init__(self, p, n, *, dir="io", conn=None, assert_width=None): + self.p = Pins(p, dir=dir, conn=conn, assert_width=assert_width) + self.n = Pins(n, dir=dir, conn=conn, assert_width=assert_width) if len(self.p.names) != len(self.n.names): raise TypeError("Positive and negative pins must have the same width, but {!r} " diff --git a/nmigen/test/test_build_dsl.py b/nmigen/test/test_build_dsl.py index 158ef35..d084340 100644 --- a/nmigen/test/test_build_dsl.py +++ b/nmigen/test/test_build_dsl.py @@ -59,6 +59,11 @@ class PinsTestCase(FHDLTestCase): "connector pin pmod_0:1"): p.map_names(mapping, p) + def test_wrong_assert_width(self): + with self.assertRaises(AssertionError, + msg="3 names are specified (0 1 2), but 4 names are expected"): + Pins("0 1 2", assert_width=4) + class DiffPairsTestCase(FHDLTestCase): def test_basic(self): @@ -96,6 +101,11 @@ class DiffPairsTestCase(FHDLTestCase): "and (pins io B0 B1) do not"): dp = DiffPairs("A0", "B0 B1") + def test_wrong_assert_width(self): + with self.assertRaises(AssertionError, + msg="3 names are specified (0 1 2), but 4 names are expected"): + DiffPairs("0 1 2", "3 4 5", assert_width=4) + class AttrsTestCase(FHDLTestCase): def test_basic(self): -- 2.30.2