ip: able to request mac_address if not cached and send an empty ip frame

This commit is contained in:
Florent Kermarrec 2015-01-30 17:44:44 +01:00
parent 124a041fbd
commit d066497ab1
7 changed files with 24 additions and 14 deletions

View File

@ -8,7 +8,7 @@ from liteeth.ip import LiteEthIP
class LiteEthIPStack(Module, AutoCSR): class LiteEthIPStack(Module, AutoCSR):
def __init__(self, phy, mac_address, ip_address): def __init__(self, phy, mac_address, ip_address):
self.phy = phy 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.arp = arp = LiteEthARP(mac, mac_address, ip_address)
self.submodules.ip = ip = LiteEthIP(mac, ip_address, arp.table) self.submodules.ip = ip = LiteEthIP(mac, ip_address, arp.table)
self.sink, self.source = self.ip.sink, self.ip.source self.sink, self.source = self.ip.sink, self.ip.source

View File

@ -146,10 +146,12 @@ class LiteEthARPTable(Module):
### ###
request_timeout = Timeout(512) # XXX fix me 100ms? request_timeout = Timeout(512) # XXX fix me 100ms?
request_pending = FlipFlop() 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 += [ self.comb += [
request_timeout.ce.eq(request_pending.q), 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 # Note: Store only one ip/mac couple, replace this with
@ -166,7 +168,7 @@ class LiteEthARPTable(Module):
If(sink.stb & sink.request, If(sink.stb & sink.request,
NextState("SEND_REPLY") NextState("SEND_REPLY")
).Elif(sink.stb & sink.reply & request_pending.q, ).Elif(sink.stb & sink.reply & request_pending.q,
NextState("UPDATE_TABLE") NextState("UPDATE_TABLE"),
).Elif(request.stb | (request_pending.q & request_timeout.reached), ).Elif(request.stb | (request_pending.q & request_timeout.reached),
NextState("CHECK_TABLE") NextState("CHECK_TABLE")
) )
@ -193,10 +195,14 @@ class LiteEthARPTable(Module):
found = Signal() found = Signal()
fsm.act("CHECK_TABLE", fsm.act("CHECK_TABLE",
# XXX: add a live time for cached_mac_address # 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), request.ack.eq(request.stb),
NextState("PRESENT_RESPONSE") NextState("PRESENT_RESPONSE"),
).Else( ).Else(
request_ip_address.ce.eq(1),
NextState("SEND_REQUEST") NextState("SEND_REQUEST")
) )
) )

View File

@ -141,9 +141,9 @@ def eth_udp_description(dw):
@DecorateModule(InsertReset) @DecorateModule(InsertReset)
@DecorateModule(InsertCE) @DecorateModule(InsertCE)
class FlipFlop(Module): class FlipFlop(Module):
def __init__(self, **kwargs): def __init__(self, *args, **kwargs):
self.d = Signal(**kwargs) self.d = Signal(*args, **kwargs)
self.q = Signal(**kwargs) self.q = Signal(*args, **kwargs)
self.sync += self.q.eq(self.d) self.sync += self.q.eq(self.d)
@DecorateModule(InsertReset) @DecorateModule(InsertReset)

View File

@ -10,7 +10,7 @@ class Arbiter(Module):
self.grant = Signal() self.grant = Signal()
self.comb += Record.connect(sources[0], sink) self.comb += Record.connect(sources[0], sink)
else: else:
self.rr = RoundRobin(len(sources)) self.submodules.rr = RoundRobin(len(sources))
self.grant = self.rr.grant self.grant = self.rr.grant
cases = {} cases = {}
for i, source in enumerate(sources): for i, source in enumerate(sources):

View File

@ -20,12 +20,13 @@ class LiteEthIPV4Packetizer(LiteEthPacketizer):
class LiteEthIPTX(Module): class LiteEthIPTX(Module):
def __init__(self, ip_address, arp_table): 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)) self.source = Source(eth_mac_description(8))
### ###
packetizer = LiteEthIPV4Packetizer() packetizer = LiteEthIPV4Packetizer()
self.submodules += packetizer self.submodules += packetizer
source = packetizer.sink self.comb += Record.connect(self.sink, packetizer.sink)
sink = packetizer.source
fsm = FSM(reset_state="IDLE") fsm = FSM(reset_state="IDLE")
self.submodules += fsm self.submodules += fsm
@ -38,7 +39,7 @@ class LiteEthIPTX(Module):
) )
fsm.act("SEND_MAC_ADDRESS_REQUEST", fsm.act("SEND_MAC_ADDRESS_REQUEST",
arp_table.request.stb.eq(1), 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, If(arp_table.request.stb & arp_table.request.ack,
NextState("WAIT_MAC_ADDRESS_RESPONSE") NextState("WAIT_MAC_ADDRESS_RESPONSE")
) )
@ -46,6 +47,7 @@ class LiteEthIPTX(Module):
fsm.act("WAIT_MAC_ADDRESS_RESPONSE", fsm.act("WAIT_MAC_ADDRESS_RESPONSE",
# XXX add timeout # XXX add timeout
If(arp_table.response.stb, If(arp_table.response.stb,
arp_table.response.ack.eq(1),
# XXX manage failed # XXX manage failed
NextState("SEND") NextState("SEND")
) )

View File

@ -47,7 +47,7 @@ class LiteEthMAC(Module, AutoCSR):
elif interface == "dma": elif interface == "dma":
raise NotImplementedError raise NotImplementedError
else: else:
raise ValueError(inteface + " not supported by LiteEthMac!") raise ValueError(interface + " not supported by LiteEthMac!")
def get_csrs(self): def get_csrs(self):
return self.csrs return self.csrs

View File

@ -41,6 +41,8 @@ class TB(Module):
yield yield
selfp.ip.sink.stb = 1 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.destination_ip_address = 0x12345678
selfp.ip.sink.source_ip_address = ip_address selfp.ip.sink.source_ip_address = ip_address