diff --git a/examples/udp_raw_ecp5rgmii.yml b/examples/udp_raw_ecp5rgmii.yml index 81c81a0..9ec4dbc 100644 --- a/examples/udp_raw_ecp5rgmii.yml +++ b/examples/udp_raw_ecp5rgmii.yml @@ -9,11 +9,11 @@ device: LFE5U-25F-6BG256C vendor: lattice toolchain: trellis # Core ------------------------------------------------------------------------- -clk_freq: 125e6 +clk_freq: 50e6 core: udp mac_address: 0x10e2d5000000 -ip_address: 172.30.0.1 +dhcp: True tx_cdc_depth: 16 tx_cdc_buffered: True diff --git a/liteeth/core/__init__.py b/liteeth/core/__init__.py index 9e3b732..be2995f 100644 --- a/liteeth/core/__init__.py +++ b/liteeth/core/__init__.py @@ -81,6 +81,7 @@ class LiteEthIPCore(Module, AutoCSR): class LiteEthUDPIPCore(LiteEthIPCore): def __init__(self, phy, mac_address, ip_address, clk_freq, arp_entries=1, dw=8, with_icmp = True, + with_dhcp = False, with_ip_broadcast = True, with_sys_datapath = False, tx_cdc_depth = 32, @@ -90,9 +91,15 @@ class LiteEthUDPIPCore(LiteEthIPCore): interface = "crossbar", endianness = "big", ): + # Ensure either IP is external or DHCP is used + assert((ip_address is None) == with_dhcp) + # Parameters. # ----------- - ip_address = convert_ip(ip_address) + if ip_address is not None: + ip_address = convert_ip(ip_address) + else: + ip_address = Signal(32) # Core: MAC + ARP + IP + (ICMP). # ------------------------------ @@ -113,10 +120,13 @@ class LiteEthUDPIPCore(LiteEthIPCore): rx_cdc_depth = rx_cdc_depth, rx_cdc_buffered = rx_cdc_buffered, ) - # UDP. - # ---- + # UDP + (DHCP). + # ------------- self.submodules.udp = LiteEthUDP( - ip = self.ip, - ip_address = ip_address, - dw = dw, + ip = self.ip, + mac_address = mac_address, + ip_address = ip_address, + clk_freq = clk_freq, + with_dhcp = with_dhcp, + dw = dw, ) diff --git a/liteeth/core/udp.py b/liteeth/core/udp.py index 6bd7ea7..2d729fc 100644 --- a/liteeth/core/udp.py +++ b/liteeth/core/udp.py @@ -11,6 +11,7 @@ from litex.soc.interconnect import stream from liteeth.common import * from liteeth.crossbar import LiteEthCrossbar from liteeth.packet import Depacketizer, Packetizer +from liteeth.core.dhcp import DHCP_CLIENT_PORT, LiteEthDHCP # UDP Crossbar ------------------------------------------------------------------------------------- @@ -231,7 +232,7 @@ class LiteEthUDPRX(LiteXModule): # UDP ---------------------------------------------------------------------------------------------- class LiteEthUDP(LiteXModule): - def __init__(self, ip, ip_address, dw=8): + def __init__(self, ip, ip_address, mac_address, clk_freq, with_dhcp = False, dw=8): self.tx = tx = LiteEthUDPTX(ip_address, dw) self.rx = rx = LiteEthUDPRX(ip_address, dw) ip_port = ip.crossbar.get_port(udp_protocol, dw) @@ -244,3 +245,11 @@ class LiteEthUDP(LiteXModule): crossbar.master.source.connect(tx.sink), rx.source.connect(crossbar.master.sink) ] + + if with_dhcp: + dhcp_udp_port = self.crossbar.get_port(DHCP_CLIENT_PORT, dw=32, cd="sys") + self.dhcp = dhcp = LiteEthDHCP(dhcp_udp_port, clk_freq) + self.comb += [ + dhcp.mac_address.eq(mac_address), + ip_address.eq(dhcp.ip_address), + ] diff --git a/liteeth/gen.py b/liteeth/gen.py index 6498fff..7d46abe 100755 --- a/liteeth/gen.py +++ b/liteeth/gen.py @@ -67,14 +67,6 @@ _io = [ # Interrupt ("interrupt", 0, Pins(1)), - # DHCP. - ("dhcp", 0, - Subsignal("start", Pins(1)), - Subsignal("done", Pins(1)), - Subsignal("timeout", Pins(1)), - Subsignal("ip_address", Pins(32)), - ), - # MII PHY Pads ("mii_clocks", 0, Subsignal("tx", Pins(1)), @@ -520,11 +512,9 @@ class UDPCore(PHYCore): # IP Address. dhcp = core_config.get("dhcp", False) ip_address = core_config.get("ip_address", None) - # Get IP Address from IOs when not specified. - if ip_address is None: + # Get IP Address from IOs when not specified and DHCP is not used + if ip_address is None and not dhcp: ip_address = platform.request("ip_address") - else: - assert not dhcp # PHY -------------------------------------------------------------------------------------- PHYCore.__init__(self, platform, core_config) @@ -534,6 +524,7 @@ class UDPCore(PHYCore): self.core = LiteEthUDPIPCore(self.ethphy, mac_address = mac_address, ip_address = ip_address, + with_dhcp = dhcp, clk_freq = core_config["clk_freq"], dw = data_width, with_sys_datapath = (data_width == 32), @@ -543,23 +534,6 @@ class UDPCore(PHYCore): rx_cdc_buffered = rx_cdc_buffered, ) - # DHCP ------------------------------------------------------------------------------------- - - if dhcp: - dhcp_pads = platform.request("dhcp") - dhcp_port = self.core.udp.crossbar.get_port(68, dw=32, cd="sys") - if isinstance(mac_address, Signal): - dhcp_mac_address = mac_address - else: - dhcp_mac_address = Signal(48, reset=0x10e2d5000001) - self.dhcp = LiteEthDHCP(udp_port=dhcp_port, sys_clk_freq=self.sys_clk_freq) - self.comb += [ - self.dhcp.start.eq(dhcp_pads.start), - dhcp_pads.done.eq(self.dhcp.done), - dhcp_pads.timeout.eq(self.dhcp.timeout), - dhcp_pads.ip_address.eq(self.dhcp.ip_address), - ] - # Etherbone -------------------------------------------------------------------------------- etherbone = core_config.get("etherbone", False)