build.dsl: add Resource.family abstraction.
authorwhitequark <whitequark@whitequark.org>
Tue, 9 Jul 2019 02:44:03 +0000 (02:44 +0000)
committerwhitequark <whitequark@whitequark.org>
Tue, 9 Jul 2019 02:44:03 +0000 (02:44 +0000)
nmigen/build/dsl.py
nmigen/test/test_build_dsl.py

index a3e4a580bc789deb996f57fa78aff511193a6c51..d5d181ec632e3e6c7f8e0b5eaf3817ebce11b2fd 100644 (file)
@@ -181,6 +181,20 @@ class Subsignal:
 
 
 class Resource(Subsignal):
+    @classmethod
+    def family(cls, name_or_number, number=None, *, ios, default_name):
+        # This constructor accepts two different forms:
+        #  1. Number-only form:
+        #       Resource.family(0, default_name="name", ios=[Pins("A0 A1")])
+        #  2. Name-and-number (name override) form:
+        #       Resource.family("override", 0, default_name="name", ios=...)
+        # This makes it easier to build abstractions for resources, e.g. an SPIResource abstraction
+        # could simply delegate to `Resource.family(*args, default_name="spi", ios=ios)`.
+        if number is None: # name_or_number is number
+            return cls(default_name, name_or_number, *ios)
+        else: # name_or_number is name
+            return cls(name_or_number, number, *ios)
+
     def __init__(self, name, number, *args):
         super().__init__(name, *args)
 
index c8f95ab1e4623637859c25709bd1685b528eb521..d7c73b9325393ff33ed7d1856044531c1afdd00d 100644 (file)
@@ -225,6 +225,15 @@ class ResourceTestCase(FHDLTestCase):
                                   " (subsignal rx (pins i A1))"
                                   " (attrs IOSTANDARD=LVCMOS33))")
 
+    def test_family(self):
+        ios = [Subsignal("clk", Pins("A0", dir="o"))]
+        r1  = Resource.family(0, default_name="spi", ios=ios)
+        r2  = Resource.family("spi_flash", 0, default_name="spi", ios=ios)
+        self.assertEqual(r1.name, "spi")
+        self.assertEqual(r1.ios, ios)
+        self.assertEqual(r2.name, "spi_flash")
+        self.assertEqual(r2.ios, ios)
+
 
 class ConnectorTestCase(FHDLTestCase):
     def test_string(self):