From de6f162499f3f889815c00632dfd770f4dca7524 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 5 Feb 2015 23:46:57 +0100 Subject: [PATCH] arp: add live time for cached IP/MAC couple --- liteeth/core/__init__.py | 8 ++++---- liteeth/core/arp.py | 28 ++++++++++++++++++---------- liteeth/test/arp_tb.py | 2 +- liteeth/test/ip_tb.py | 2 +- liteeth/test/udpip_tb.py | 2 +- targets/udpip.py | 2 +- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/liteeth/core/__init__.py b/liteeth/core/__init__.py index 14e01fdd4..545b7a0fe 100644 --- a/liteeth/core/__init__.py +++ b/liteeth/core/__init__.py @@ -5,14 +5,14 @@ from liteeth.core.ip import LiteEthIP from liteeth.core.udp import LiteEthUDP class LiteEthIPCore(Module, AutoCSR): - def __init__(self, phy, mac_address, ip_address): + def __init__(self, phy, mac_address, ip_address, clk_freq): self.submodules.mac = LiteEthMAC(phy, 8, interface="crossbar", with_hw_preamble_crc=True) - self.submodules.arp = LiteEthARP(self.mac, mac_address, ip_address) + self.submodules.arp = LiteEthARP(self.mac, mac_address, ip_address, clk_freq) self.submodules.ip = LiteEthIP(self.mac, mac_address, ip_address, self.arp.table) self.sink, self.source = self.ip.sink, self.ip.source class LiteEthUDPIPCore(LiteEthIPCore): - def __init__(self, phy, mac_address, ip_address): - LiteEthIPCore.__init__(self, phy, mac_address, ip_address) + 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) self.sink, self.source = self.udp.sink, self.udp.source diff --git a/liteeth/core/arp.py b/liteeth/core/arp.py index 85acd4077..10ff1ad85 100644 --- a/liteeth/core/arp.py +++ b/liteeth/core/arp.py @@ -134,17 +134,17 @@ class LiteEthARPRX(Module): ) class LiteEthARPTable(Module): - def __init__(self): - self.sink = sink = Sink(_arp_table_layout) # from arp_rx + def __init__(self, clk_freq): + self.sink = sink = Sink(_arp_table_layout) # from arp_rx self.source = source = Source(_arp_table_layout) # to arp_tx # Request/Response interface self.request = request = Sink(arp_table_request_layout) self.response = response = Source(arp_table_response_layout) ### - request_timeout = Timeout(166000000//10) # XXX use clk_freq + request_timeout = Timeout(clk_freq//10) request_pending = FlipFlop() - request_ip_address = FlipFlop(32, reset=0xffffffff) # XXX add cached_valid? + request_ip_address = FlipFlop(32, reset=0xffffffff) self.submodules += request_timeout, request_pending, request_ip_address self.comb += [ request_timeout.ce.eq(request_pending.q), @@ -152,12 +152,15 @@ class LiteEthARPTable(Module): request_ip_address.d.eq(request.ip_address) ] - # Note: Store only one ip/mac couple, replace this with - # a real ARP table + # Note: Only store 1 IP/MAC couple, can be improved with a real + # table in the future to improve performance when packet are + # targeting multiple destinations. update = Signal() cached_valid = Signal() cached_ip_address = Signal(32) cached_mac_address = Signal(48) + cached_timeout = Timeout(clk_freq*10) + self.submodules += cached_timeout self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", @@ -188,12 +191,17 @@ class LiteEthARPTable(Module): If(update, cached_valid.eq(1), cached_ip_address.eq(sink.ip_address), - cached_mac_address.eq(sink.mac_address) + cached_mac_address.eq(sink.mac_address), + cached_timeout.reset.eq(1) + ).Else( + cached_timeout.ce.eq(1), + If(cached_timeout.reached, + cached_valid.eq(0) + ) ) ] found = Signal() fsm.act("CHECK_TABLE", - # XXX: add a live time for cached_mac_address If(cached_valid, If(request_ip_address.q == cached_ip_address, request_ip_address.reset.eq(1), @@ -231,10 +239,10 @@ class LiteEthARPTable(Module): ) class LiteEthARP(Module): - def __init__(self, mac, mac_address, ip_address): + def __init__(self, mac, mac_address, ip_address, clk_freq): self.submodules.tx = LiteEthARPTX(mac_address, ip_address) self.submodules.rx = LiteEthARPRX(mac_address, ip_address) - self.submodules.table = LiteEthARPTable() + self.submodules.table = LiteEthARPTable(clk_freq) self.comb += [ Record.connect(self.rx.source, self.table.sink), Record.connect(self.table.source, self.tx.sink) diff --git a/liteeth/test/arp_tb.py b/liteeth/test/arp_tb.py index 1bfd7289b..373a48018 100644 --- a/liteeth/test/arp_tb.py +++ b/liteeth/test/arp_tb.py @@ -20,7 +20,7 @@ class TB(Module): self.submodules.arp_model = arp.ARP(self.mac_model, mac_address, ip_address, debug=False) self.submodules.mac = LiteEthMAC(self.phy_model, dw=8, with_hw_preamble_crc=True) - self.submodules.arp = LiteEthARP(self.mac, mac_address, ip_address) + self.submodules.arp = LiteEthARP(self.mac, mac_address, ip_address, 100000) # use sys_clk for each clock_domain self.clock_domains.cd_eth_rx = ClockDomain() diff --git a/liteeth/test/ip_tb.py b/liteeth/test/ip_tb.py index 267760e00..eb68916fb 100644 --- a/liteeth/test/ip_tb.py +++ b/liteeth/test/ip_tb.py @@ -19,7 +19,7 @@ class TB(Module): self.submodules.arp_model = arp.ARP(self.mac_model, mac_address, ip_address, debug=False) self.submodules.ip_model = ip.IP(self.mac_model, mac_address, ip_address, debug=False, loopback=True) - self.submodules.ip = LiteEthIPCore(self.phy_model, mac_address, ip_address) + self.submodules.ip = LiteEthIPCore(self.phy_model, mac_address, ip_address, 100000) # use sys_clk for each clock_domain self.clock_domains.cd_eth_rx = ClockDomain() diff --git a/liteeth/test/udpip_tb.py b/liteeth/test/udpip_tb.py index 4dc70a984..fada83fb9 100644 --- a/liteeth/test/udpip_tb.py +++ b/liteeth/test/udpip_tb.py @@ -20,7 +20,7 @@ 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_ip = LiteEthUDPIPCore(self.phy_model, mac_address, ip_address) + self.submodules.udp_ip = LiteEthUDPIPCore(self.phy_model, mac_address, ip_address, 100000) self.submodules.streamer = PacketStreamer(eth_udp_user_description(8)) self.submodules.logger = PacketLogger(eth_udp_user_description(8)) self.comb += [ diff --git a/targets/udpip.py b/targets/udpip.py index 8b3d5f7d3..98a92484c 100644 --- a/targets/udpip.py +++ b/targets/udpip.py @@ -176,7 +176,7 @@ class UDPIPSoC(GenSoC, AutoCSR): # Ethernet PHY and UDP/IP self.submodules.ethphy = LiteEthPHYGMII(platform.request("eth_clocks"), platform.request("eth")) - self.submodules.udpip_core = LiteEthUDPIPCore(self.ethphy, 0x10e2d5000000, convert_ip("192.168.1.40")) + self.submodules.udpip_core = LiteEthUDPIPCore(self.ethphy, 0x10e2d5000000, convert_ip("192.168.1.40"), clk_freq) # BIST self.submodules.bist_generator = UDPIPBISTGenerator()