ip: able to request mac_address if not cached and send an empty ip frame
This commit is contained in:
parent
124a041fbd
commit
d066497ab1
|
@ -8,7 +8,7 @@ from liteeth.ip import LiteEthIP
|
|||
class LiteEthIPStack(Module, AutoCSR):
|
||||
def __init__(self, phy, mac_address, ip_address):
|
||||
self.phy = phy
|
||||
self.submodules.mac = mac = LiteEthMAC(phy, 8, interface="mac", with_hw_preamble_crc=True)
|
||||
self.submodules.mac = mac = LiteEthMAC(phy, 8, interface="crossbar", with_hw_preamble_crc=True)
|
||||
self.submodules.arp = arp = LiteEthARP(mac, mac_address, ip_address)
|
||||
self.submodules.ip = ip = LiteEthIP(mac, ip_address, arp.table)
|
||||
self.sink, self.source = self.ip.sink, self.ip.source
|
||||
|
|
|
@ -146,10 +146,12 @@ class LiteEthARPTable(Module):
|
|||
###
|
||||
request_timeout = Timeout(512) # XXX fix me 100ms?
|
||||
request_pending = FlipFlop()
|
||||
self.submodules += request_timeout, request_pending
|
||||
request_ip_address = FlipFlop(32, reset=0xffffffff) # XXX add cached_valid?
|
||||
self.submodules += request_timeout, request_pending, request_ip_address
|
||||
self.comb += [
|
||||
request_timeout.ce.eq(request_pending.q),
|
||||
request_pending.d.eq(1)
|
||||
request_pending.d.eq(1),
|
||||
request_ip_address.d.eq(request.ip_address)
|
||||
]
|
||||
|
||||
# Note: Store only one ip/mac couple, replace this with
|
||||
|
@ -166,7 +168,7 @@ class LiteEthARPTable(Module):
|
|||
If(sink.stb & sink.request,
|
||||
NextState("SEND_REPLY")
|
||||
).Elif(sink.stb & sink.reply & request_pending.q,
|
||||
NextState("UPDATE_TABLE")
|
||||
NextState("UPDATE_TABLE"),
|
||||
).Elif(request.stb | (request_pending.q & request_timeout.reached),
|
||||
NextState("CHECK_TABLE")
|
||||
)
|
||||
|
@ -193,10 +195,14 @@ class LiteEthARPTable(Module):
|
|||
found = Signal()
|
||||
fsm.act("CHECK_TABLE",
|
||||
# XXX: add a live time for cached_mac_address
|
||||
If(request.ip_address == cached_ip_address,
|
||||
If(request_ip_address.q == cached_ip_address,
|
||||
request_ip_address.reset.eq(1),
|
||||
NextState("PRESENT_RESPONSE"),
|
||||
).Elif(request.ip_address == cached_ip_address,
|
||||
request.ack.eq(request.stb),
|
||||
NextState("PRESENT_RESPONSE")
|
||||
NextState("PRESENT_RESPONSE"),
|
||||
).Else(
|
||||
request_ip_address.ce.eq(1),
|
||||
NextState("SEND_REQUEST")
|
||||
)
|
||||
)
|
||||
|
|
|
@ -141,9 +141,9 @@ def eth_udp_description(dw):
|
|||
@DecorateModule(InsertReset)
|
||||
@DecorateModule(InsertCE)
|
||||
class FlipFlop(Module):
|
||||
def __init__(self, **kwargs):
|
||||
self.d = Signal(**kwargs)
|
||||
self.q = Signal(**kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.d = Signal(*args, **kwargs)
|
||||
self.q = Signal(*args, **kwargs)
|
||||
self.sync += self.q.eq(self.d)
|
||||
|
||||
@DecorateModule(InsertReset)
|
||||
|
|
|
@ -10,7 +10,7 @@ class Arbiter(Module):
|
|||
self.grant = Signal()
|
||||
self.comb += Record.connect(sources[0], sink)
|
||||
else:
|
||||
self.rr = RoundRobin(len(sources))
|
||||
self.submodules.rr = RoundRobin(len(sources))
|
||||
self.grant = self.rr.grant
|
||||
cases = {}
|
||||
for i, source in enumerate(sources):
|
||||
|
|
|
@ -20,12 +20,13 @@ class LiteEthIPV4Packetizer(LiteEthPacketizer):
|
|||
|
||||
class LiteEthIPTX(Module):
|
||||
def __init__(self, ip_address, arp_table):
|
||||
self.sink = sink = Sink(eth_ipv4_description(8))
|
||||
self.sink = Sink(eth_ipv4_description(8))
|
||||
self.source = Source(eth_mac_description(8))
|
||||
###
|
||||
packetizer = LiteEthIPV4Packetizer()
|
||||
self.submodules += packetizer
|
||||
source = packetizer.sink
|
||||
self.comb += Record.connect(self.sink, packetizer.sink)
|
||||
sink = packetizer.source
|
||||
|
||||
fsm = FSM(reset_state="IDLE")
|
||||
self.submodules += fsm
|
||||
|
@ -38,7 +39,7 @@ class LiteEthIPTX(Module):
|
|||
)
|
||||
fsm.act("SEND_MAC_ADDRESS_REQUEST",
|
||||
arp_table.request.stb.eq(1),
|
||||
arp_table.request.ip_address.eq(sink.destination_ip_address),
|
||||
arp_table.request.ip_address.eq(self.sink.destination_ip_address),
|
||||
If(arp_table.request.stb & arp_table.request.ack,
|
||||
NextState("WAIT_MAC_ADDRESS_RESPONSE")
|
||||
)
|
||||
|
@ -46,6 +47,7 @@ class LiteEthIPTX(Module):
|
|||
fsm.act("WAIT_MAC_ADDRESS_RESPONSE",
|
||||
# XXX add timeout
|
||||
If(arp_table.response.stb,
|
||||
arp_table.response.ack.eq(1),
|
||||
# XXX manage failed
|
||||
NextState("SEND")
|
||||
)
|
||||
|
|
|
@ -47,7 +47,7 @@ class LiteEthMAC(Module, AutoCSR):
|
|||
elif interface == "dma":
|
||||
raise NotImplementedError
|
||||
else:
|
||||
raise ValueError(inteface + " not supported by LiteEthMac!")
|
||||
raise ValueError(interface + " not supported by LiteEthMac!")
|
||||
|
||||
def get_csrs(self):
|
||||
return self.csrs
|
||||
|
|
|
@ -41,6 +41,8 @@ class TB(Module):
|
|||
yield
|
||||
|
||||
selfp.ip.sink.stb = 1
|
||||
selfp.ip.sink.sop = 1
|
||||
selfp.ip.sink.eop = 1
|
||||
selfp.ip.sink.destination_ip_address = 0x12345678
|
||||
selfp.ip.sink.source_ip_address = ip_address
|
||||
|
||||
|
|
Loading…
Reference in New Issue