diff --git a/liteeth/core/udp.py b/liteeth/core/udp.py index 71c45d6..b39b639 100644 --- a/liteeth/core/udp.py +++ b/liteeth/core/udp.py @@ -30,26 +30,43 @@ class LiteEthUDPCrossbar(LiteEthCrossbar): def __init__(self): LiteEthCrossbar.__init__(self, LiteEthUDPMasterPort, "dst_port") - def get_port(self, udp_port, dw=8): + def get_port(self, udp_port, dw=8, cd=None): if udp_port in self.users.keys(): raise ValueError("Port {0:#x} already assigned".format(udp_port)) user_port = LiteEthUDPUserPort(dw) internal_port = LiteEthUDPUserPort(8) if dw != 8: - converter = stream.StrideConverter(eth_udp_user_description(user_port.dw), - eth_udp_user_description(8)) - self.submodules += converter - self.comb += [ - user_port.sink.connect(converter.sink), - converter.source.connect(internal_port.sink) - ] - converter = stream.StrideConverter(eth_udp_user_description(8), - eth_udp_user_description(user_port.dw)) - self.submodules += converter - self.comb += [ - internal_port.source.connect(converter.sink), - converter.source.connect(user_port.source) - ] + # tx + tx_converter = stream.StrideConverter(eth_udp_user_description(user_port.dw), + eth_udp_user_description(8)) + self.submodules += tx_converter + if cd is not None: + tx_cdc = stream.AsyncFIFO(eth_udp_user_description(user_port.dw), 4) + tx_cdc = ClockDomainsRenamer({"write": cd, "read": "sys"})(tx_cdc) + self.submodules += tx_cdc + self.comb += [ + user_port.sink.connect(tx_cdc.sink), + tx_cdc.source.connect(tx_converter.sink) + ] + else: + self.comb += user_port.sink.connect(tx_converter.sink) + self.comb += tx_converter.source.connect(internal_port.sink) + + # rx + rx_converter = stream.StrideConverter(eth_udp_user_description(8), + eth_udp_user_description(user_port.dw)) + self.submodules += rx_converter + self.comb += internal_port.source.connect(rx_converter.sink) + if cd is not None: + rx_cdc = stream.AsyncFIFO(eth_udp_user_description(user_port.dw), 4) + rx_cdc = ClockDomainsRenamer({"write": "sys", "read": cd})(rx_cdc) + self.submodules += rx_cdc + self.comb += [ + rx_converter.source.connect(rx_cdc.sink), + rx_cdc.source.connect(user_port.source) + ] + else: + self.comb += rx_converter.source.connect(user_port.source) self.users[udp_port] = internal_port else: self.users[udp_port] = user_port diff --git a/liteeth/frontend/etherbone.py b/liteeth/frontend/etherbone.py index f1240b8..970596a 100644 --- a/liteeth/frontend/etherbone.py +++ b/liteeth/frontend/etherbone.py @@ -137,10 +137,10 @@ class LiteEthEtherbonePacketRX(Module): class LiteEthEtherbonePacket(Module): - def __init__(self, udp, udp_port): + def __init__(self, udp, udp_port, cd=None): self.submodules.tx = tx = LiteEthEtherbonePacketTX(udp_port) self.submodules.rx = rx = LiteEthEtherbonePacketRX() - udp_port = udp.crossbar.get_port(udp_port, dw=32) + udp_port = udp.crossbar.get_port(udp_port, dw=32, cd=cd) self.comb += [ tx.source.connect(udp_port.sink), udp_port.source.connect(rx.sink) @@ -497,9 +497,9 @@ class LiteEthEtherboneWishboneSlave(Module): # etherbone class LiteEthEtherbone(Module): - def __init__(self, udp, udp_port, mode="master"): + def __init__(self, udp, udp_port, mode="master", cd=None): # decode/encode etherbone packets - self.submodules.packet = packet = LiteEthEtherbonePacket(udp, udp_port) + self.submodules.packet = packet = LiteEthEtherbonePacket(udp, udp_port, cd) # packets can be probe (etherbone discovering) or records with # writes and reads