From 641c5dbdc77b47e5f31e5627946d27b7607d4150 Mon Sep 17 00:00:00 2001 From: rowanG077 Date: Thu, 16 Feb 2023 22:05:07 +0100 Subject: [PATCH 1/2] Add core CDC depth and buffered parameters. --- liteeth/core/__init__.py | 21 +++++++++++++++++++-- liteeth/gen.py | 39 +++++++++++++++++++++++++++++---------- liteeth/mac/__init__.py | 13 +++++++++++-- liteeth/mac/core.py | 16 +++++++++++++--- 4 files changed, 72 insertions(+), 17 deletions(-) diff --git a/liteeth/core/__init__.py b/liteeth/core/__init__.py index 772c76a..9a6f593 100644 --- a/liteeth/core/__init__.py +++ b/liteeth/core/__init__.py @@ -2,6 +2,7 @@ # This file is part of LiteEth. # # Copyright (c) 2015-2020 Florent Kermarrec +# Copyright (c) 2023 LumiGuide Fietsdetectie B.V. # SPDX-License-Identifier: BSD-2-Clause from liteeth.common import * @@ -17,7 +18,11 @@ class LiteEthIPCore(Module, AutoCSR): def __init__(self, phy, mac_address, ip_address, clk_freq, dw=8, with_icmp = True, with_ip_broadcast = True, - with_sys_datapath = False): + with_sys_datapath = False, + tx_cdc_depth = 32, + tx_cdc_buffered = False, + rx_cdc_depth = 32, + rx_cdc_buffered = False): # Parameters. # ----------- ip_address = convert_ip(ip_address) @@ -30,6 +35,10 @@ class LiteEthIPCore(Module, AutoCSR): interface = "crossbar", with_preamble_crc = True, with_sys_datapath = with_sys_datapath, + tx_cdc_depth = tx_cdc_depth, + tx_cdc_buffered = tx_cdc_buffered, + rx_cdc_depth = rx_cdc_depth, + rx_cdc_buffered = rx_cdc_buffered ) # ARP. @@ -67,7 +76,11 @@ class LiteEthUDPIPCore(LiteEthIPCore): def __init__(self, phy, mac_address, ip_address, clk_freq, dw=8, with_icmp = True, with_ip_broadcast = True, - with_sys_datapath = False): + with_sys_datapath = False, + tx_cdc_depth = 32, + tx_cdc_buffered = False, + rx_cdc_depth = 32, + rx_cdc_buffered = False): # Parameters. # ----------- ip_address = convert_ip(ip_address) @@ -83,6 +96,10 @@ class LiteEthUDPIPCore(LiteEthIPCore): dw = dw, with_ip_broadcast = with_ip_broadcast, with_sys_datapath = with_sys_datapath, + tx_cdc_depth = tx_cdc_depth, + tx_cdc_buffered = tx_cdc_buffered, + rx_cdc_depth = rx_cdc_depth, + rx_cdc_buffered = rx_cdc_buffered ) # UDP. # ---- diff --git a/liteeth/gen.py b/liteeth/gen.py index a85011c..e713f47 100755 --- a/liteeth/gen.py +++ b/liteeth/gen.py @@ -7,6 +7,7 @@ # Copyright (c) 2020 Xiretza # Copyright (c) 2020 Stefan Schrijvers # Copyright (c) 2022 Victor Suarez Rovere +# Copyright (c) 2023 LumiGuide Fietsdetectie B.V. # SPDX-License-Identifier: BSD-2-Clause """ @@ -233,9 +234,13 @@ class PHYCore(SoCMini): class MACCore(PHYCore): def __init__(self, platform, core_config): # Parameters ------------------------------------------------------------------------------- - nrxslots = core_config.get("nrxslots", 2) - ntxslots = core_config.get("ntxslots", 2) - bus_standard = core_config["core"] + nrxslots = core_config.get("nrxslots", 2) + ntxslots = core_config.get("ntxslots", 2) + bus_standard = core_config["core"] + tx_cdc_depth = core_config.get("tx_cdc_depth", 32) + tx_cdc_buffered = core_config.get("tx_cdc_buffered", False) + rx_cdc_depth = core_config.get("rx_cdc_depth", 32) + rx_cdc_buffered = core_config.get("rx_cdc_buffered", False) assert bus_standard in ["wishbone", "axi-lite"] # PHY -------------------------------------------------------------------------------------- @@ -243,13 +248,18 @@ class MACCore(PHYCore): # MAC -------------------------------------------------------------------------------------- self.submodules.ethmac = ethmac = LiteEthMAC( - phy = self.ethphy, - dw = 32, - interface = "wishbone", - endianness = core_config["endianness"], - nrxslots = nrxslots, - ntxslots = ntxslots, - full_memory_we = core_config.get("full_memory_we", False)) + phy = self.ethphy, + dw = 32, + interface = "wishbone", + endianness = core_config["endianness"], + nrxslots = nrxslots, + ntxslots = ntxslots, + full_memory_we = core_config.get("full_memory_we", False), + tx_cdc_depth = tx_cdc_depth + tx_cdc_buffered = tx_cdc_buffered + rx_cdc_depth = rx_cdc_depth + rx_cdc_buffered = rx_cdc_buffered + ) if bus_standard == "wishbone": # Wishbone Interface ----------------------------------------------------------------------- @@ -280,6 +290,10 @@ class UDPCore(PHYCore): from liteeth.frontend.stream import LiteEthUDPStreamer # Config ----------------------------------------------------------------------------------- + tx_cdc_depth = core_config.get("tx_cdc_depth", 32) + tx_cdc_buffered = core_config.get("tx_cdc_buffered", False) + rx_cdc_depth = core_config.get("rx_cdc_depth", 32) + rx_cdc_buffered = core_config.get("rx_cdc_buffered", False) # MAC Address. mac_address = core_config.get("mac_address", None) @@ -304,6 +318,11 @@ class UDPCore(PHYCore): clk_freq = core_config["clk_freq"], dw = data_width, with_sys_datapath = (data_width == 32), + tx_cdc_depth = tx_cdc_depth + tx_cdc_buffered = tx_cdc_buffered + rx_cdc_depth = rx_cdc_depth + rx_cdc_buffered = rx_cdc_buffered + ) # UDP Ports -------------------------------------------------------------------------------- diff --git a/liteeth/mac/__init__.py b/liteeth/mac/__init__.py index b660e79..a357308 100644 --- a/liteeth/mac/__init__.py +++ b/liteeth/mac/__init__.py @@ -2,6 +2,7 @@ # This file is part of LiteEth. # # Copyright (c) 2015-2020 Florent Kermarrec +# Copyright (c) 2023 LumiGuide Fietsdetectie B.V. # SPDX-License-Identifier: BSD-2-Clause from liteeth.common import * @@ -21,7 +22,11 @@ class LiteEthMAC(Module, AutoCSR): hw_mac = None, timestamp = None, full_memory_we = False, - with_sys_datapath = False): + with_sys_datapath = False, + tx_cdc_depth = 32, + tx_cdc_buffered = False, + rx_cdc_depth = 32, + rx_cdc_buffered = False): assert dw%8 == 0 assert interface in ["crossbar", "wishbone", "hybrid"] @@ -31,7 +36,11 @@ class LiteEthMAC(Module, AutoCSR): phy = phy, dw = dw, with_sys_datapath = with_sys_datapath, - with_preamble_crc = with_preamble_crc + with_preamble_crc = with_preamble_crc, + tx_cdc_depth = tx_cdc_depth, + tx_cdc_buffered = tx_cdc_buffered, + rx_cdc_depth = rx_cdc_depth, + rx_cdc_buffered = rx_cdc_buffered ) self.csrs = [] if interface == "crossbar": diff --git a/liteeth/mac/core.py b/liteeth/mac/core.py index 21d5858..203c79f 100644 --- a/liteeth/mac/core.py +++ b/liteeth/mac/core.py @@ -5,6 +5,7 @@ # Copyright (c) 2015-2017 Sebastien Bourdeauducq # Copyright (c) 2021 David Sawatzke # Copyright (c) 2017-2018 whitequark +# Copyright (c) 2023 LumiGuide Fietsdetectie B.V. # SPDX-License-Identifier: BSD-2-Clause from liteeth.common import * @@ -21,7 +22,12 @@ class LiteEthMACCore(Module, AutoCSR): def __init__(self, phy, dw, with_sys_datapath = False, with_preamble_crc = True, - with_padding = True): + with_padding = True, + tx_cdc_depth = 32, + tx_cdc_buffered = False, + rx_cdc_depth = 32, + rx_cdc_buffered = False, + ): # Endpoints. self.sink = stream.Endpoint(eth_phy_description(dw)) @@ -57,7 +63,9 @@ class LiteEthMACCore(Module, AutoCSR): tx_cdc = stream.ClockDomainCrossing(eth_phy_description(core_dw), cd_from = "sys", cd_to = "eth_tx", - depth = 32) + depth = tx_cdc_depth, + buffered = tx_cdc_buffered + ) self.submodules += tx_cdc self.pipeline.append(tx_cdc) @@ -186,7 +194,9 @@ class LiteEthMACCore(Module, AutoCSR): rx_cdc = stream.ClockDomainCrossing(eth_phy_description(core_dw), cd_from = "eth_rx", cd_to = "sys", - depth = 32) + depth = rx_cdc_depth, + buffered = rx_cdc_buffered + ) self.submodules += rx_cdc self.pipeline.append(rx_cdc) From c30a6f8cd3456724f3361098ca435334d667b307 Mon Sep 17 00:00:00 2001 From: rowanG077 Date: Mon, 13 Mar 2023 10:37:11 +0100 Subject: [PATCH 2/2] ecp5rgmii: Add way to set external TX clock to avoid loop clock --- liteeth/phy/ecp5rgmii.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/liteeth/phy/ecp5rgmii.py b/liteeth/phy/ecp5rgmii.py index d5b0eb3..8a88415 100644 --- a/liteeth/phy/ecp5rgmii.py +++ b/liteeth/phy/ecp5rgmii.py @@ -139,7 +139,7 @@ class LiteEthPHYRGMIIRX(Module, AutoCSR): class LiteEthPHYRGMIICRG(Module, AutoCSR): - def __init__(self, clock_pads, pads, with_hw_init_reset, tx_delay=2e-9): + def __init__(self, clock_pads, pads, with_hw_init_reset, tx_delay=2e-9, with_phy_tx_clock = None): self._reset = CSRStorage() # # # @@ -150,7 +150,14 @@ class LiteEthPHYRGMIICRG(Module, AutoCSR): # TX Clock self.clock_domains.cd_eth_tx = ClockDomain() - self.comb += self.cd_eth_tx.clk.eq(self.cd_eth_rx.clk) + + if isinstance(with_phy_tx_clock, Signal): + phy_tx_clock = with_phy_tx_clock + else: + phy_tx_clock = self.cd_eth_rx.clk + + self.comb += self.cd_eth_tx.clk.eq(phy_tx_clock) + tx_delay_taps = int(tx_delay/25e-12) # 25ps per tap assert tx_delay_taps < 128 @@ -190,8 +197,10 @@ class LiteEthPHYRGMII(Module, AutoCSR): def __init__(self, clock_pads, pads, with_hw_init_reset=True, tx_delay = 2e-9, rx_delay = 2e-9, - with_inband_status = True): - self.submodules.crg = LiteEthPHYRGMIICRG(clock_pads, pads, with_hw_init_reset, tx_delay) + with_inband_status = True, + with_phy_tx_clock = None + ): + self.submodules.crg = LiteEthPHYRGMIICRG(clock_pads, pads, with_hw_init_reset, tx_delay, with_phy_tx_clock) self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYRGMIITX(pads)) self.submodules.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYRGMIIRX(pads, rx_delay, with_inband_status)) self.sink, self.source = self.tx.sink, self.rx.source