mac: add packetizer/depacketizer (untested)
[litex.git] / liteeth / mac / core / depacketizer.py
1 import math
2
3 from liteeth.common import *
4
5 def _decode_header(h_dict, h_signal, obj):
6 r = []
7 for k, v in sorted(h_dict.items()):
8 start = v.byte*8+v.offset
9 end = start+v.width
10 r.append(getattr(obj, k).eq(h_signal[start:end]))
11 return r
12
13 class LiteEthMACDepacketizer(Module):
14 def __init__(self):
15 self.sink = sink = Sink(eth_mac_description(8))
16 self.source = source = Source(eth_phy_description(8))
17 ###
18 shift = Signal()
19 header = Signal(mac_header_length*8)
20 counter = Counter(max=mac_header_length)
21 self.submodules += counter
22
23 fsm = FSM(reset_state="IDLE")
24 self.submodules += fsm
25
26 fsm.act("IDLE",
27 sink.ack.eq(1),
28 counter.reset.eq(1),
29 If(sink.stb,
30 shift.eq(1),
31 NextState("RECEIVE_HEADER")
32 )
33 )
34 fsm.act("RECEIVE_HEADER",
35 sink.ack.eq(1),
36 If(sink.stb,
37 counter.ce.eq(1),
38 shift.eq(1),
39 If(counter.value == mac_header_length-2,
40 NextState("COPY")
41 )
42 )
43 )
44 self.sync += \
45 If(fsm.before_entering("COPY"),
46 source.sop.eq(1)
47 ).Elif(source.stb & source.ack,
48 source.sop.eq(0)
49 )
50 self.comb += [
51 source.sop.eq(sop),
52 source.eop.eq(sink.eop),
53 source.data.eq(sink.data),
54 source.error.eq(sink.error),
55 _decode_header(mac_header, header, source)
56 ]
57 fsm.act("COPY",
58 sink.ack.eq(source.ack),
59 source.stb.eq(sink.stb),
60 If(source.stb & source.ack & source.eop,
61 NextState("IDLE")
62 )
63 )