lib.io: add i_clk and o_clk to pin layout with xdr>=1.
authorwhitequark <cz@m-labs.hk>
Mon, 3 Jun 2019 05:56:18 +0000 (05:56 +0000)
committerwhitequark <cz@m-labs.hk>
Mon, 3 Jun 2019 07:43:31 +0000 (07:43 +0000)
nmigen/lib/io.py
nmigen/test/test_lib_io.py

index 81f16c5f80f8cb532a4b9f176551e7e74085f832..42c2def67b2b42ec907fe5ba55455f6c3215af6c 100644 (file)
@@ -5,7 +5,7 @@ from ..hdl.rec import *
 __all__ = ["pin_layout", "Pin"]
 
 
-def pin_layout(width, dir, xdr=1):
+def pin_layout(width, dir, xdr=0):
     """
     Layout of the platform interface of a pin or several pins, which may be used inside
     user-defined records.
@@ -24,12 +24,16 @@ def pin_layout(width, dir, xdr=1):
 
     fields = []
     if dir in ("i", "io"):
+        if xdr > 0:
+            fields.append(("i_clk", 1))
         if xdr in (0, 1):
             fields.append(("i", width))
         else:
             for n in range(xdr):
                 fields.append(("i{}".format(n), width))
     if dir in ("o", "oe", "io"):
+        if xdr > 0:
+            fields.append(("o_clk", 1))
         if xdr in (0, 1):
             fields.append(("o", width))
         else:
@@ -72,12 +76,16 @@ class Pin(Record):
 
     Attributes
     ----------
+    i_clk:
+        I/O buffer input clock. Synchronizes `i*`. Present if ``xdr`` is nonzero.
     i : Signal, out
         I/O buffer input, without gearing. Present if ``dir="i"`` or ``dir="io"``, and ``xdr`` is
         equal to 0 or 1.
     i0, i1, ... : Signal, out
         I/O buffer inputs, with gearing. Present if ``dir="i"`` or ``dir="io"``, and ``xdr`` is
         greater than 1.
+    o_clk:
+        I/O buffer output clock. Synchronizes `o*`, including `oe`. Present if ``xdr`` is nonzero.
     o : Signal, in
         I/O buffer output, without gearing. Present if ``dir="o"`` or ``dir="io"``, and ``xdr`` is
         equal to 0 or 1.
index 0e05277b19bc2579be35e6038a354e6699b01df0..38f66cbcf2dd0c89937bce4fa65d26ecfaa9c566 100644 (file)
@@ -60,34 +60,40 @@ class PinLayoutSDRTestCase(FHDLTestCase):
     def test_pin_layout_i(self):
         layout_1 = pin_layout(1, dir="i", xdr=1)
         self.assertEqual(layout_1.fields, {
+            "i_clk": ((1, False), DIR_NONE),
             "i": ((1, False), DIR_NONE),
         })
 
         layout_2 = pin_layout(2, dir="i", xdr=1)
         self.assertEqual(layout_2.fields, {
+            "i_clk": ((1, False), DIR_NONE),
             "i": ((2, False), DIR_NONE),
         })
 
     def test_pin_layout_o(self):
         layout_1 = pin_layout(1, dir="o", xdr=1)
         self.assertEqual(layout_1.fields, {
+            "o_clk": ((1, False), DIR_NONE),
             "o": ((1, False), DIR_NONE),
         })
 
         layout_2 = pin_layout(2, dir="o", xdr=1)
         self.assertEqual(layout_2.fields, {
+            "o_clk": ((1, False), DIR_NONE),
             "o": ((2, False), DIR_NONE),
         })
 
     def test_pin_layout_oe(self):
         layout_1 = pin_layout(1, dir="oe", xdr=1)
         self.assertEqual(layout_1.fields, {
+            "o_clk": ((1, False), DIR_NONE),
             "o":  ((1, False), DIR_NONE),
             "oe": ((1, False), DIR_NONE),
         })
 
         layout_2 = pin_layout(2, dir="oe", xdr=1)
         self.assertEqual(layout_2.fields, {
+            "o_clk": ((1, False), DIR_NONE),
             "o":  ((2, False), DIR_NONE),
             "oe": ((1, False), DIR_NONE),
         })
@@ -95,14 +101,18 @@ class PinLayoutSDRTestCase(FHDLTestCase):
     def test_pin_layout_io(self):
         layout_1 = pin_layout(1, dir="io", xdr=1)
         self.assertEqual(layout_1.fields, {
+            "i_clk": ((1, False), DIR_NONE),
             "i":  ((1, False), DIR_NONE),
+            "o_clk": ((1, False), DIR_NONE),
             "o":  ((1, False), DIR_NONE),
             "oe": ((1, False), DIR_NONE),
         })
 
         layout_2 = pin_layout(2, dir="io", xdr=1)
         self.assertEqual(layout_2.fields, {
+            "i_clk": ((1, False), DIR_NONE),
             "i":  ((2, False), DIR_NONE),
+            "o_clk": ((1, False), DIR_NONE),
             "o":  ((2, False), DIR_NONE),
             "oe": ((1, False), DIR_NONE),
         })
@@ -112,12 +122,14 @@ class PinLayoutDDRTestCase(FHDLTestCase):
     def test_pin_layout_i(self):
         layout_1 = pin_layout(1, dir="i", xdr=2)
         self.assertEqual(layout_1.fields, {
+            "i_clk": ((1, False), DIR_NONE),
             "i0": ((1, False), DIR_NONE),
             "i1": ((1, False), DIR_NONE),
         })
 
         layout_2 = pin_layout(2, dir="i", xdr=2)
         self.assertEqual(layout_2.fields, {
+            "i_clk": ((1, False), DIR_NONE),
             "i0": ((2, False), DIR_NONE),
             "i1": ((2, False), DIR_NONE),
         })
@@ -125,12 +137,14 @@ class PinLayoutDDRTestCase(FHDLTestCase):
     def test_pin_layout_o(self):
         layout_1 = pin_layout(1, dir="o", xdr=2)
         self.assertEqual(layout_1.fields, {
+            "o_clk": ((1, False), DIR_NONE),
             "o0": ((1, False), DIR_NONE),
             "o1": ((1, False), DIR_NONE),
         })
 
         layout_2 = pin_layout(2, dir="o", xdr=2)
         self.assertEqual(layout_2.fields, {
+            "o_clk": ((1, False), DIR_NONE),
             "o0": ((2, False), DIR_NONE),
             "o1": ((2, False), DIR_NONE),
         })
@@ -138,6 +152,7 @@ class PinLayoutDDRTestCase(FHDLTestCase):
     def test_pin_layout_oe(self):
         layout_1 = pin_layout(1, dir="oe", xdr=2)
         self.assertEqual(layout_1.fields, {
+            "o_clk": ((1, False), DIR_NONE),
             "o0": ((1, False), DIR_NONE),
             "o1": ((1, False), DIR_NONE),
             "oe": ((1, False), DIR_NONE),
@@ -145,6 +160,7 @@ class PinLayoutDDRTestCase(FHDLTestCase):
 
         layout_2 = pin_layout(2, dir="oe", xdr=2)
         self.assertEqual(layout_2.fields, {
+            "o_clk": ((1, False), DIR_NONE),
             "o0": ((2, False), DIR_NONE),
             "o1": ((2, False), DIR_NONE),
             "oe": ((1, False), DIR_NONE),
@@ -153,8 +169,10 @@ class PinLayoutDDRTestCase(FHDLTestCase):
     def test_pin_layout_io(self):
         layout_1 = pin_layout(1, dir="io", xdr=2)
         self.assertEqual(layout_1.fields, {
+            "i_clk": ((1, False), DIR_NONE),
             "i0": ((1, False), DIR_NONE),
             "i1": ((1, False), DIR_NONE),
+            "o_clk": ((1, False), DIR_NONE),
             "o0": ((1, False), DIR_NONE),
             "o1": ((1, False), DIR_NONE),
             "oe": ((1, False), DIR_NONE),
@@ -162,8 +180,10 @@ class PinLayoutDDRTestCase(FHDLTestCase):
 
         layout_2 = pin_layout(2, dir="io", xdr=2)
         self.assertEqual(layout_2.fields, {
+            "i_clk": ((1, False), DIR_NONE),
             "i0": ((2, False), DIR_NONE),
             "i1": ((2, False), DIR_NONE),
+            "o_clk": ((1, False), DIR_NONE),
             "o0": ((2, False), DIR_NONE),
             "o1": ((2, False), DIR_NONE),
             "oe": ((1, False), DIR_NONE),