From c2f5fd37f954a213ef176ba247addb8d6c966f9d Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Sun, 6 Mar 2022 01:20:21 -0500
Subject: [PATCH] resources.interface: Added support for clock-specific
 attributes to the ULPIResource, including setting up a clock speed constraint

---
 amaranth_boards/resources/interface.py | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/amaranth_boards/resources/interface.py b/amaranth_boards/resources/interface.py
index 8941be1d..0c028cb7 100644
--- a/amaranth_boards/resources/interface.py
+++ b/amaranth_boards/resources/interface.py
@@ -114,13 +114,20 @@ def DirectUSBResource(*args, d_p, d_n, pullup=None, vbus_valid=None, conn=None,
     return Resource.family(*args, default_name="usb", ios=io)
 
 
-def ULPIResource(*args, data, clk, dir, nxt, stp, rst=None,
-            clk_dir='i', rst_invert=False, attrs=None, conn=None):
+def ULPIResource(*args, data, clk, dir, nxt, stp, rst=None, clk_dir='i',
+            rst_invert=False, conn=None, attrs=None, clk_attrs=None):
     assert clk_dir in ('i', 'o',)
 
+    clk_subsig = Subsignal("clk", Pins(clk, dir=clk_dir, conn=conn, assert_width=1))
+    # If the clock is an input, we must constrain it to be 60MHz.
+    if clk_dir == 'i':
+        clk_subsig.clock = Clock(60e6)
+    if clk_attrs is not None:
+        clk_subsig.attrs.update(clk_attrs)
+
     io = []
     io.append(Subsignal("data", Pins(data, dir="io", conn=conn, assert_width=8)))
-    io.append(Subsignal("clk", Pins(clk, dir=clk_dir, conn=conn, assert_width=1)))
+    io.append(clk_subsig)
     io.append(Subsignal("dir", Pins(dir, dir="i", conn=conn, assert_width=1)))
     io.append(Subsignal("nxt", Pins(nxt, dir="i", conn=conn, assert_width=1)))
     io.append(Subsignal("stp", Pins(stp, dir="o", conn=conn, assert_width=1)))