Skip to content

Commit d2b60e1

Browse files
committed
bench/arty_ptp: add sys_eth clock domain for PTP isolation
Use a dedicated sys_eth PLL output (same frequency as sys) for the PTP core and UDP ports. This avoids crossing from sys to eth_rx through the async FIFO on every packet, reducing Delay_Req/Resp latency to match the original digilent_arty design.
1 parent 95f9526 commit d2b60e1

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

bench/arty_ptp.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
from litex.gen import *
4747

4848
from litex_boards.platforms import digilent_arty
49-
from litex_boards.targets.digilent_arty import _CRG
5049

5150
from litex.soc.cores.clock import *
5251
from litex.soc.integration.soc_core import *
@@ -56,6 +55,31 @@
5655
from liteeth.phy.mii import LiteEthPHYMII
5756
from liteeth.core.ptp import LiteEthPTP
5857

58+
# CRG ----------------------------------------------------------------------------------------------
59+
60+
class _CRG(LiteXModule):
61+
def __init__(self, platform, sys_clk_freq):
62+
self.rst = Signal()
63+
self.cd_sys = ClockDomain()
64+
self.cd_sys_eth = ClockDomain()
65+
self.cd_eth = ClockDomain()
66+
67+
# # #
68+
69+
# Clk/Rst.
70+
clk100 = platform.request("clk100")
71+
rst_n = platform.request("cpu_reset_n")
72+
73+
# PLL.
74+
self.pll = pll = S7PLL(speedgrade=-1)
75+
self.comb += pll.reset.eq(~rst_n | self.rst)
76+
pll.register_clkin(clk100, 100e6)
77+
pll.create_clkout(self.cd_sys, sys_clk_freq)
78+
pll.create_clkout(self.cd_sys_eth, sys_clk_freq)
79+
pll.create_clkout(self.cd_eth, 25e6)
80+
self.comb += platform.request("eth_ref_clk").eq(self.cd_eth.clk)
81+
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin)
82+
5983
# PTP Bench SoC ------------------------------------------------------------------------------------
6084

6185
class PTPBenchSoC(SoCCore):
@@ -77,6 +101,12 @@ def __init__(self, sys_clk_freq=int(100e6), p2p=False, ptp_debug=False):
77101
pads = self.platform.request("eth"),
78102
with_hw_init_reset = False,
79103
)
104+
# CDC between sys_eth and Ethernet PHY clocks.
105+
self.platform.add_false_path_constraints(
106+
self.crg.cd_sys_eth.clk,
107+
self.ethphy.crg.cd_eth_rx.clk,
108+
self.ethphy.crg.cd_eth_tx.clk,
109+
)
80110
ptp_igmp_groups = [0xE0000181, 0xE0000182] # 224.0.1.129, 224.0.1.130.
81111
if p2p:
82112
ptp_igmp_groups.append(0xE000006B) # 224.0.0.107.
@@ -88,17 +118,17 @@ def __init__(self, sys_clk_freq=int(100e6), p2p=False, ptp_debug=False):
88118
# PTP --------------------------------------------------------------------------------------
89119
udp = self.ethcore_etherbone.udp
90120

91-
# PTP event / general ports.
92-
self.ptp_event_port = udp.crossbar.get_port(319, dw=8, cd="sys")
93-
self.ptp_general_port = udp.crossbar.get_port(320, dw=8, cd="sys")
121+
# PTP event / general ports (CDC from sys_eth to ethcore clock domain).
122+
self.ptp_event_port = udp.crossbar.get_port(319, dw=8, cd="sys_eth")
123+
self.ptp_general_port = udp.crossbar.get_port(320, dw=8, cd="sys_eth")
94124

95-
# PTP core.
96-
self.ptp = LiteEthPTP(
125+
# PTP core (runs in sys_eth domain).
126+
self.ptp = ClockDomainsRenamer("sys_eth")(LiteEthPTP(
97127
self.ptp_event_port,
98128
self.ptp_general_port,
99129
sys_clk_freq,
100130
monitor_debug = ptp_debug,
101-
)
131+
))
102132

103133
# PTP configuration.
104134
self.comb += [

0 commit comments

Comments
 (0)