ip: add skeleton
[litex.git] / liteeth / ip / __init__.py
1 from liteeth.common import *
2 from liteeth.generic.depacketizer import LiteEthDepacketizer
3 from liteeth.generic.packetizer import LiteEthPacketizer
4
5 class LiteEthIPV4Depacketizer(LiteEthDepacketizer):
6 def __init__(self):
7 LiteEthDepacketizer.__init__(self,
8 eth_mac_description(8),
9 eth_ipv4_description(8),
10 ipv4_header,
11 ipv4_header_len)
12
13 class LiteEthIPV4Packetizer(LiteEthPacketizer):
14 def __init__(self):
15 LiteEthPacketizer.__init__(self,
16 eth_ipv4_description(8),
17 eth_mac_description(8),
18 ipv4_header,
19 ipv4_header_len)
20
21 class LiteEthIPTX(Module):
22 def __init__(self, ip_address, arp_table):
23 self.sink = sink = Sink(eth_ipv4_description(8))
24 self.source = Source(eth_mac_description(8))
25 ###
26 packetizer = LiteEthIPV4Packetizer()
27 self.submodules += packetizer
28 source = packetizer.sink
29
30 fsm = FSM(reset_state="IDLE")
31 self.submodules += fsm
32 fsm.act("IDLE",
33 sink.ack.eq(1),
34 If(sink.stb & sink.sop,
35 sink.ack.eq(0),
36 NextState("SEND_MAC_ADDRESS_REQUEST")
37 )
38 )
39 fsm.act("SEND_MAC_ADDRESS_REQUEST",
40 arp_table.request.stb.eq(1),
41 arp_table.request.ip_address.eq(sink.destination_ip_address),
42 If(arp_table.request.stb & arp_table.request.ack,
43 NextState("WAIT_MAC_ADDRESS_RESPONSE")
44 )
45 )
46 fsm.act("WAIT_MAC_ADDRESS_RESPONSE",
47 # XXX add timeout
48 If(arp_table.response.stb,
49 # XXX manage failed
50 NextState("SEND")
51 )
52 )
53 fsm.act("SEND",
54 Record.connect(packetizer.source, self.source),
55 # XXX compute check sum
56
57 # XXX add timeout
58 If(arp_table.response.stb,
59 # XXX manage failed
60 NextState("SEND")
61 )
62 )
63
64 class LiteEthIPRX(Module):
65 def __init__(self, ip_address):
66 self.sink = Sink(eth_mac_description(8))
67 self.source = source = Source(eth_ipv4_description(8))
68 ###
69 depacketizer = LiteEthIPV4Depacketizer()
70 self.submodules += depacketizer
71 self.comb += Record.connect(self.sink, depacketizer.sink)
72 sink = depacketizer.source
73
74 fsm = FSM(reset_state="IDLE")
75 self.submodules += fsm
76 fsm.act("IDLE",
77 sink.ack.eq(1),
78 If(sink.stb & sink.sop,
79 sink.ack.eq(0),
80 NextState("CHECK")
81 )
82 )
83 valid = Signal()
84 self.comb += valid.eq(1) # XXX FIXME
85 fsm.act("CHECK",
86 If(valid,
87 NextState("PRESENT")
88 ).Else(
89 NextState("DROP")
90 )
91 ),
92 fsm.act("PRESENT",
93 Record.connect(sink, source),
94 If(source.stb & source.eop & source.ack,
95 NextState("IDLE")
96 )
97 )
98 fsm.act("DROP",
99 sink.ack.eq(1),
100 If(source.stb & source.eop & source.ack,
101 NextState("IDLE")
102 )
103 )
104
105 class LiteEthIP(Module):
106 def __init__(self, ip_address, arp_table):
107 self.submodules.tx = LiteEthIPTX(ip_address, arp_table)
108 self.submodules.rx = LiteEthIPRX(ip_address)
109 self.sink, self.source = self.rx.sink, self.tx.source