From 8c70e6d22aa33923e73a32290f2932f601637961 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 9 Feb 2015 11:19:26 +0100 Subject: [PATCH] udp: add crossbar --- liteeth/core/__init__.py | 6 +- liteeth/core/udp/__init__.py | 16 ++--- liteeth/core/udp/common.py | 27 ++++++++ liteeth/core/udp/crossbar.py | 33 +++++++++ liteeth/test/udp_tb.py | 15 ++-- targets/udp.py | 129 +++++++++++++++++++---------------- 6 files changed, 146 insertions(+), 80 deletions(-) create mode 100644 liteeth/core/udp/common.py create mode 100644 liteeth/core/udp/crossbar.py diff --git a/liteeth/core/__init__.py b/liteeth/core/__init__.py index 7783a15f..6a143c9c 100644 --- a/liteeth/core/__init__.py +++ b/liteeth/core/__init__.py @@ -13,8 +13,6 @@ class LiteEthIPCore(Module, AutoCSR): self.submodules.icmp = LiteEthICMP(self.ip, ip_address) class LiteEthUDPIPCore(LiteEthIPCore): - def __init__(self, phy, mac_address, ip_address, clk_freq, with_loopback=False): + def __init__(self, phy, mac_address, ip_address, clk_freq): LiteEthIPCore.__init__(self, phy, mac_address, ip_address, clk_freq) - self.submodules.udp = LiteEthUDP(self.ip, ip_address, with_loopback) - if not with_loopback: - self.sink, self.source = self.udp.sink, self.udp.source + self.submodules.udp = LiteEthUDP(self.ip, ip_address) diff --git a/liteeth/core/udp/__init__.py b/liteeth/core/udp/__init__.py index 9e6bd874..f4df2e5e 100644 --- a/liteeth/core/udp/__init__.py +++ b/liteeth/core/udp/__init__.py @@ -1,6 +1,7 @@ from liteeth.common import * from liteeth.generic.depacketizer import LiteEthDepacketizer from liteeth.generic.packetizer import LiteEthPacketizer +from liteeth.core.udp.crossbar import LiteEthUDPCrossbar class LiteEthUDPDepacketizer(LiteEthDepacketizer): def __init__(self): @@ -108,7 +109,7 @@ class LiteEthUDPRX(Module): ) class LiteEthUDP(Module): - def __init__(self, ip, ip_address, with_loopback): + def __init__(self, ip, ip_address): self.submodules.tx = tx = LiteEthUDPTX(ip_address) self.submodules.rx = rx = LiteEthUDPRX(ip_address) ip_port = ip.crossbar.get_port(udp_protocol) @@ -116,11 +117,8 @@ class LiteEthUDP(Module): Record.connect(tx.source, ip_port.sink), Record.connect(ip_port.source, rx.sink) ] - if with_loopback: - self.submodules.fifo = fifo = SyncFIFO(eth_udp_user_description(8), 2048, buffered=True) - self.comb += [ - Record.connect(rx.source, fifo.sink), - Record.connect(fifo.source, tx.sink) - ] - else: - self.sink, self.source = self.tx.sink, self.rx.source + self.submodules.crossbar = crossbar = LiteEthUDPCrossbar() + self.comb += [ + Record.connect(crossbar.master.source, tx.sink), + Record.connect(rx.source, crossbar.master.sink) + ] diff --git a/liteeth/core/udp/common.py b/liteeth/core/udp/common.py new file mode 100644 index 00000000..feb55bf8 --- /dev/null +++ b/liteeth/core/udp/common.py @@ -0,0 +1,27 @@ +from liteeth.common import * + +class LiteEthUDPMasterPort: + def __init__(self, dw): + self.source = Source(eth_udp_user_description(dw)) + self.sink = Sink(eth_udp_user_description(dw)) + + def connect(self, slave): + return [ + Record.connect(self.source, slave.sink), + Record.connect(slave.source, self.sink) + ] + +class LiteEthUDPSlavePort: + def __init__(self, dw): + self.sink = Sink(eth_udp_user_description(dw)) + self.source = Source(eth_udp_user_description(dw)) + + def connect(self, master): + return [ + Record.connect(self.sink, master.source), + Record.connect(master.sink, self.source) + ] + +class LiteEthUDPUserPort(LiteEthUDPSlavePort): + def __init__(self, dw): + LiteEthUDPSlavePort.__init__(self, dw) diff --git a/liteeth/core/udp/crossbar.py b/liteeth/core/udp/crossbar.py new file mode 100644 index 00000000..f533a677 --- /dev/null +++ b/liteeth/core/udp/crossbar.py @@ -0,0 +1,33 @@ +from collections import OrderedDict + +from liteeth.common import * +from liteeth.generic.arbiter import Arbiter +from liteeth.generic.dispatcher import Dispatcher +from liteeth.core.udp.common import * + +class LiteEthUDPCrossbar(Module): + def __init__(self): + self.users = OrderedDict() + self.master = LiteEthUDPMasterPort(8) + + def get_port(self, udp_port): + port = LiteEthUDPUserPort(8) + if udp_port in self.users.keys(): + raise ValueError("Port {0:#x} already assigned".format(udp_port)) + self.users[udp_port] = port + return port + + def do_finalize(self): + # TX arbitrate + sinks = [port.sink for port in self.users.values()] + self.submodules.udp_arbiter = Arbiter(sinks, self.master.source) + + # RX dispatch + sources = [port.source for port in self.users.values()] + self.submodules.udp_dispatcher = Dispatcher(self.master.sink, sources, one_hot=True) + cases = {} + cases["default"] = self.udp_dispatcher.sel.eq(0) + for i, (k, v) in enumerate(self.users.items()): + cases[k] = self.udp_dispatcher.sel.eq(2**i) + self.comb += \ + Case(self.master.sink.dst_port, cases) diff --git a/liteeth/test/udp_tb.py b/liteeth/test/udp_tb.py index 4718cb94..b0274773 100644 --- a/liteeth/test/udp_tb.py +++ b/liteeth/test/udp_tb.py @@ -20,16 +20,17 @@ class TB(Module): self.submodules.ip_model = ip.IP(self.mac_model, mac_address, ip_address, debug=False, loopback=False) self.submodules.udp_model = udp.UDP(self.ip_model, ip_address, debug=False, loopback=True) - self.submodules.udp = LiteEthUDPIPCore(self.phy_model, mac_address, ip_address, 100000) + self.submodules.core = LiteEthUDPIPCore(self.phy_model, mac_address, ip_address, 100000) + udp_port = self.core.udp.crossbar.get_port(0x5678) self.submodules.streamer = PacketStreamer(eth_udp_user_description(8)) self.submodules.logger = PacketLogger(eth_udp_user_description(8)) self.comb += [ - Record.connect(self.streamer.source, self.udp.sink), - self.udp.sink.ip_address.eq(0x12345678), - self.udp.sink.src_port.eq(0x1234), - self.udp.sink.dst_port.eq(0x5678), - self.udp.sink.length.eq(64), - Record.connect(self.udp.source, self.logger.sink) + Record.connect(self.streamer.source, udp_port.sink), + udp_port.sink.ip_address.eq(0x12345678), + udp_port.sink.src_port.eq(0x1234), + udp_port.sink.dst_port.eq(0x5678), + udp_port.sink.length.eq(64), + Record.connect(udp_port.source, self.logger.sink) ] # use sys_clk for each clock_domain diff --git a/targets/udp.py b/targets/udp.py index 37bf9909..6491e6c0 100644 --- a/targets/udp.py +++ b/targets/udp.py @@ -102,7 +102,7 @@ class UDPSoC(GenSoC, AutoCSR): default_platform = "kc705" csr_map = { "phy": 11, - "udp": 12 + "core": 12 } csr_map.update(GenSoC.csr_map) def __init__(self, platform): @@ -112,7 +112,16 @@ class UDPSoC(GenSoC, AutoCSR): # Ethernet PHY and UDP/IP self.submodules.phy = LiteEthPHYGMII(platform.request("eth_clocks"), platform.request("eth")) - self.submodules.udp = LiteEthUDPIPCore(self.phy, 0x10e2d5000000, convert_ip("192.168.1.40"), clk_freq, with_loopback=True) + self.submodules.core = LiteEthUDPIPCore(self.phy, 0x10e2d5000000, convert_ip("192.168.1.40"), clk_freq) + + # Create loopback on UDP port 6000 + loopback_port = self.core.udp.crossbar.get_port(6000) + loopback_fifo = SyncFIFO(eth_udp_user_description(8), 2048, buffered=True) + self.submodules += loopback_fifo + self.comb += [ + Record.connect(loopback_port.source, loopback_fifo.sink), + Record.connect(loopback_fifo.source, loopback_port.sink) + ] class UDPSoCDevel(UDPSoC, AutoCSR): csr_map = { @@ -122,48 +131,48 @@ class UDPSoCDevel(UDPSoC, AutoCSR): def __init__(self, platform): UDPSoC.__init__(self, platform) - self.udp_icmp_rx_fsm_state = Signal(4) - self.udp_icmp_tx_fsm_state = Signal(4) - self.udp_udp_rx_fsm_state = Signal(4) - self.udp_udp_tx_fsm_state = Signal(4) - self.udp_ip_rx_fsm_state = Signal(4) - self.udp_ip_tx_fsm_state = Signal(4) - self.udp_arp_rx_fsm_state = Signal(4) - self.udp_arp_tx_fsm_state = Signal(4) - self.udp_arp_table_fsm_state = Signal(4) + self.core_icmp_rx_fsm_state = Signal(4) + self.core_icmp_tx_fsm_state = Signal(4) + self.core_udp_rx_fsm_state = Signal(4) + self.core_udp_tx_fsm_state = Signal(4) + self.core_ip_rx_fsm_state = Signal(4) + self.core_ip_tx_fsm_state = Signal(4) + self.core_arp_rx_fsm_state = Signal(4) + self.core_arp_tx_fsm_state = Signal(4) + self.core_arp_table_fsm_state = Signal(4) debug = ( - self.udp.mac.core.sink.stb, - self.udp.mac.core.sink.sop, - self.udp.mac.core.sink.eop, - self.udp.mac.core.sink.ack, - self.udp.mac.core.sink.data, - - self.udp.mac.core.source.stb, - self.udp.mac.core.source.sop, - self.udp.mac.core.source.eop, - self.udp.mac.core.source.ack, - self.udp.mac.core.source.data, - - self.udp.icmp.echo.sink.stb, - self.udp.icmp.echo.sink.sop, - self.udp.icmp.echo.sink.eop, - self.udp.icmp.echo.sink.ack, - self.udp.icmp.echo.sink.data, - - self.udp.icmp.echo.source.stb, - self.udp.icmp.echo.source.sop, - self.udp.icmp.echo.source.eop, - self.udp.icmp.echo.source.ack, - self.udp.icmp.echo.source.data, - - self.udp.ip.crossbar.master.sink.stb, - self.udp.ip.crossbar.master.sink.sop, - self.udp.ip.crossbar.master.sink.eop, - self.udp.ip.crossbar.master.sink.ack, - self.udp.ip.crossbar.master.sink.data, - self.udp.ip.crossbar.master.sink.ip_address, - self.udp.ip.crossbar.master.sink.protocol, + self.core.mac.core.sink.stb, + self.core.mac.core.sink.sop, + self.core.mac.core.sink.eop, + self.core.mac.core.sink.ack, + self.core.mac.core.sink.data, + + self.core.mac.core.source.stb, + self.core.mac.core.source.sop, + self.core.mac.core.source.eop, + self.core.mac.core.source.ack, + self.core.mac.core.source.data, + + self.core.icmp.echo.sink.stb, + self.core.icmp.echo.sink.sop, + self.core.icmp.echo.sink.eop, + self.core.icmp.echo.sink.ack, + self.core.icmp.echo.sink.data, + + self.core.icmp.echo.source.stb, + self.core.icmp.echo.source.sop, + self.core.icmp.echo.source.eop, + self.core.icmp.echo.source.ack, + self.core.icmp.echo.source.data, + + self.core.ip.crossbar.master.sink.stb, + self.core.ip.crossbar.master.sink.sop, + self.core.ip.crossbar.master.sink.eop, + self.core.ip.crossbar.master.sink.ack, + self.core.ip.crossbar.master.sink.data, + self.core.ip.crossbar.master.sink.ip_address, + self.core.ip.crossbar.master.sink.protocol, self.phy.sink.stb, self.phy.sink.sop, @@ -177,15 +186,15 @@ class UDPSoCDevel(UDPSoC, AutoCSR): self.phy.source.ack, self.phy.source.data, - self.udp_icmp_rx_fsm_state, - self.udp_icmp_tx_fsm_state, - self.udp_udp_rx_fsm_state, - self.udp_udp_tx_fsm_state, - self.udp_ip_rx_fsm_state, - self.udp_ip_tx_fsm_state, - self.udp_arp_rx_fsm_state, - self.udp_arp_tx_fsm_state, - self.udp_arp_table_fsm_state, + self.core_icmp_rx_fsm_state, + self.core_icmp_tx_fsm_state, + self.core_udp_rx_fsm_state, + self.core_udp_tx_fsm_state, + self.core_ip_rx_fsm_state, + self.core_ip_tx_fsm_state, + self.core_arp_rx_fsm_state, + self.core_arp_tx_fsm_state, + self.core_arp_table_fsm_state, ) self.submodules.la = LiteScopeLA(debug, 2048) @@ -195,15 +204,15 @@ class UDPSoCDevel(UDPSoC, AutoCSR): def do_finalize(self): UDPSoC.do_finalize(self) self.comb += [ - self.udp_icmp_rx_fsm_state.eq(self.udp.icmp.rx.fsm.state), - self.udp_icmp_tx_fsm_state.eq(self.udp.icmp.tx.fsm.state), - self.udp_udp_rx_fsm_state.eq(self.udp.udp.rx.fsm.state), - self.udp_udp_tx_fsm_state.eq(self.udp.udp.tx.fsm.state), - self.udp_ip_rx_fsm_state.eq(self.udp.ip.rx.fsm.state), - self.udp_ip_tx_fsm_state.eq(self.udp.ip.tx.fsm.state), - self.udp_arp_rx_fsm_state.eq(self.udp.arp.rx.fsm.state), - self.udp_arp_tx_fsm_state.eq(self.udp.arp.tx.fsm.state), - self.udp_arp_table_fsm_state.eq(self.udp.arp.table.fsm.state) + self.core_icmp_rx_fsm_state.eq(self.core.icmp.rx.fsm.state), + self.core_icmp_tx_fsm_state.eq(self.core.icmp.tx.fsm.state), + self.core_udp_rx_fsm_state.eq(self.core.udp.rx.fsm.state), + self.core_udp_tx_fsm_state.eq(self.core.udp.tx.fsm.state), + self.core_ip_rx_fsm_state.eq(self.core.ip.rx.fsm.state), + self.core_ip_tx_fsm_state.eq(self.core.ip.tx.fsm.state), + self.core_arp_rx_fsm_state.eq(self.core.arp.rx.fsm.state), + self.core_arp_tx_fsm_state.eq(self.core.arp.tx.fsm.state), + self.core_arp_table_fsm_state.eq(self.core.arp.table.fsm.state) ] def exit(self, platform): -- 2.30.2