diff --git a/liteeth/common.py b/liteeth/common.py index 271940f29..682ab4fac 100644 --- a/liteeth/common.py +++ b/liteeth/common.py @@ -130,6 +130,16 @@ def eth_ipv4_description(dw): ] return EndpointDescription(layout, packetized=True) +def eth_ipv4_user_description(dw): + layout = [ + ("total_length", 16), + ("protocol", 8), + ("destination_ip_address", 32), + ("data", dw), + ("error", dw//8) + ] + return EndpointDescription(layout, packetized=True) + def eth_udp_description(dw): layout = _layout_from_header(udp_header) + [ ("data", dw), diff --git a/liteeth/generic/dispatcher.py b/liteeth/generic/dispatcher.py index 713dd6174..a9ecd5d11 100644 --- a/liteeth/generic/dispatcher.py +++ b/liteeth/generic/dispatcher.py @@ -16,8 +16,8 @@ class Dispatcher(Module): ### sop = Signal() self.comb += sop.eq(source.stb & source.sop) - sel = Signal(max=len(sinks)) - sel_r = Signal(max=len(sinks)) + sel = Signal(flen(self.sel)) + sel_r = Signal(flen(self.sel)) self.sync += \ If(sop, sel_r.eq(self.sel) diff --git a/liteeth/ip/__init__.py b/liteeth/ip/__init__.py index 1d807423a..7685f3cd3 100644 --- a/liteeth/ip/__init__.py +++ b/liteeth/ip/__init__.py @@ -20,12 +20,24 @@ class LiteEthIPV4Packetizer(LiteEthPacketizer): class LiteEthIPTX(Module): def __init__(self, mac_address, ip_address, arp_table): - self.sink = Sink(eth_ipv4_description(8)) + self.sink = Sink(eth_ipv4_user_description(8)) self.source = Source(eth_mac_description(8)) ### packetizer = LiteEthIPV4Packetizer() self.submodules += packetizer - self.comb += Record.connect(self.sink, packetizer.sink) + self.comb += [ + Record.connect(self.sink, packetizer.sink), + packetizer.sink.version.eq(0x5), + packetizer.sink.ihl.eq(0x4), + packetizer.sink.dscp.eq(0), + packetizer.sink.ecn.eq(0), + packetizer.sink.identification.eq(0), + packetizer.sink.flags.eq(0), + packetizer.sink.fragment_offset.eq(0), + packetizer.sink.time_to_live.eq(0x80), + packetizer.sink.source_ip_address.eq(ip_address), + packetizer.sink.options.eq(0) + ] sink = packetizer.source destination_mac_address = Signal(48) @@ -70,7 +82,7 @@ class LiteEthIPTX(Module): class LiteEthIPRX(Module): def __init__(self, mac_address, ip_address): self.sink = Sink(eth_mac_description(8)) - self.source = source = Source(eth_ipv4_description(8)) + self.source = source = Source(eth_ipv4_user_description(8)) ### depacketizer = LiteEthIPV4Depacketizer() self.submodules += depacketizer @@ -96,7 +108,15 @@ class LiteEthIPRX(Module): ) ), fsm.act("PRESENT", - Record.connect(sink, source), + source.stb.eq(sink.stb), + source.sop.eq(sink.sop), + source.eop.eq(sink.eop), + sink.ack.eq(source.ack), + source.total_length.eq(sink.total_length), + source.protocol.eq(sink.protocol), + source.destination_ip_address.eq(sink.destination_ip_address), + source.data.eq(sink.data), + source.error.eq(sink.error), If(source.stb & source.eop & source.ack, NextState("IDLE") ) diff --git a/liteeth/test/ip_tb.py b/liteeth/test/ip_tb.py index 54aee7bfc..8057371df 100644 --- a/liteeth/test/ip_tb.py +++ b/liteeth/test/ip_tb.py @@ -14,10 +14,10 @@ mac_address = 0x12345678abcd class TB(Module): def __init__(self): - self.submodules.phy_model = phy.PHY(8, debug=True) - self.submodules.mac_model = mac.MAC(self.phy_model, debug=True, loopback=False) - self.submodules.arp_model = arp.ARP(self.mac_model, mac_address, ip_address, debug=True) - self.submodules.ip_model = ip.IP(self.mac_model, mac_address, ip_address, debug=True) + self.submodules.phy_model = phy.PHY(8, debug=False) + self.submodules.mac_model = mac.MAC(self.phy_model, debug=False, loopback=False) + 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 = LiteEthIPStack(self.phy_model, mac_address, ip_address) @@ -41,11 +41,18 @@ class TB(Module): for i in range(100): 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 + while True: + 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.protocol = 0x11 + + selfp.ip.source.ack = 1 + if selfp.ip.source.stb == 1 and selfp.ip.source.sop == 1: + print("IP Packet / destination_ip_address %08x" %selfp.ip.sink.destination_ip_address) + + yield if __name__ == "__main__": run_simulation(TB(), ncycles=2048, vcd_name="my.vcd", keep_files=True) diff --git a/liteeth/test/model/ip.py b/liteeth/test/model/ip.py index c39a39be2..4a8c18750 100644 --- a/liteeth/test/model/ip.py +++ b/liteeth/test/model/ip.py @@ -41,11 +41,12 @@ class IPPacket(Packet): return r class IP(Module): - def __init__(self, mac, mac_address, ip_address, debug=False): + def __init__(self, mac, mac_address, ip_address, debug=False, loopback=False): self.mac = mac self.mac_address = mac_address self.ip_address = ip_address self.debug = debug + self.loopback = loopback self.tx_packets = [] self.tx_packet = IPPacket() self.rx_packet = IPPacket() @@ -60,8 +61,8 @@ class IP(Module): print_ip(">>>>>>>>") print_ip(packet) mac_packet = mac.MACPacket(packet) - mac_packet.destination_mac_address = packet.destination_mac_address - mac_packet.source_mac_address = packet.source_mac_address + mac_packet.destination_mac_address = 0x12345678abcd # XXX + mac_packet.source_mac_address = self.mac_address mac_packet.ethernet_type = ethernet_type_ip self.mac.send(mac_packet) @@ -71,7 +72,10 @@ class IP(Module): if self.debug: print_ip("<<<<<<<<") print_ip(packet) - self.process(packet) + if self.loopback: + self.send(packet) + else: + self.process(packet) def process(self, packet): pass @@ -87,7 +91,7 @@ if __name__ == "__main__": packet = IPPacket(packet) # check decoding packet.decode() - #print(packet) + print(packet) errors += verify_packet(packet, {}) # check encoding packet.encode()