From b42043f7646b5f80912d97848117863c15d9de5e Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 3 Jun 2019 05:56:18 +0000 Subject: [PATCH] lib.io: add i_clk and o_clk to pin layout with xdr>=1. --- nmigen/lib/io.py | 10 +++++++++- nmigen/test/test_lib_io.py | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/nmigen/lib/io.py b/nmigen/lib/io.py index 81f16c5..42c2def 100644 --- a/nmigen/lib/io.py +++ b/nmigen/lib/io.py @@ -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. diff --git a/nmigen/test/test_lib_io.py b/nmigen/test/test_lib_io.py index 0e05277..38f66cb 100644 --- a/nmigen/test/test_lib_io.py +++ b/nmigen/test/test_lib_io.py @@ -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), -- 2.30.2