4f7705469e9612d99817f02dd214d18a6701f02b
[litex.git] / liteeth / mac / core / preamble.py
1 from liteeth.common import *
2 from liteeth.mac.common import *
3
4 class LiteEthMACPreambleInserter(Module):
5 def __init__(self, dw):
6 self.sink = Sink(eth_phy_description(dw))
7 self.source = Source(eth_phy_description(dw))
8
9 ###
10
11 preamble = Signal(64, reset=eth_preamble)
12 cnt_max = (64//dw)-1
13 cnt = Signal(max=cnt_max+1)
14 clr_cnt = Signal()
15 inc_cnt = Signal()
16
17 self.sync += \
18 If(clr_cnt,
19 cnt.eq(0)
20 ).Elif(inc_cnt,
21 cnt.eq(cnt+1)
22 )
23
24 fsm = FSM(reset_state="IDLE")
25 self.submodules += fsm
26 fsm.act("IDLE",
27 self.sink.ack.eq(1),
28 clr_cnt.eq(1),
29 If(self.sink.stb & self.sink.sop,
30 self.sink.ack.eq(0),
31 NextState("INSERT"),
32 )
33 )
34 fsm.act("INSERT",
35 self.source.stb.eq(1),
36 self.source.sop.eq(cnt==0),
37 chooser(preamble, cnt, self.source.data),
38 If(cnt == cnt_max,
39 If(self.source.ack, NextState("COPY"))
40 ).Else(
41 inc_cnt.eq(self.source.ack)
42 )
43 )
44 fsm.act("COPY",
45 Record.connect(self.sink, self.source),
46 self.source.sop.eq(0),
47
48 If(self.sink.stb & self.sink.eop & self.source.ack,
49 NextState("IDLE"),
50 )
51 )
52
53 class LiteEthMACPreambleChecker(Module):
54 def __init__(self, dw):
55 self.sink = Sink(eth_phy_description(dw))
56 self.source = Source(eth_phy_description(dw))
57
58 ###
59
60 preamble = Signal(64, reset=eth_preamble)
61 cnt_max = (64//dw) - 1
62 cnt = Signal(max=cnt_max+1)
63 clr_cnt = Signal()
64 inc_cnt = Signal()
65
66 self.sync += \
67 If(clr_cnt,
68 cnt.eq(0)
69 ).Elif(inc_cnt,
70 cnt.eq(cnt+1)
71 )
72
73 discard = Signal()
74 clr_discard = Signal()
75 set_discard = Signal()
76
77 self.sync += \
78 If(clr_discard,
79 discard.eq(0)
80 ).Elif(set_discard,
81 discard.eq(1)
82 )
83
84 sop = Signal()
85 clr_sop = Signal()
86 set_sop = Signal()
87 self.sync += \
88 If(clr_sop,
89 sop.eq(0)
90 ).Elif(set_sop,
91 sop.eq(1)
92 )
93
94 ref = Signal(dw)
95 match = Signal()
96 self.comb += [
97 chooser(preamble, cnt, ref),
98 match.eq(self.sink.data == ref)
99 ]
100
101 fsm = FSM(reset_state="IDLE")
102 self.submodules += fsm
103
104 fsm.act("IDLE",
105 self.sink.ack.eq(1),
106 clr_cnt.eq(1),
107 clr_discard.eq(1),
108 If(self.sink.stb & self.sink.sop,
109 clr_cnt.eq(0),
110 inc_cnt.eq(1),
111 clr_discard.eq(0),
112 set_discard.eq(~match),
113 NextState("CHECK"),
114 )
115 )
116 fsm.act("CHECK",
117 self.sink.ack.eq(1),
118 If(self.sink.stb,
119 set_discard.eq(~match),
120 If(cnt == cnt_max,
121 If(discard | (~match),
122 NextState("IDLE")
123 ).Else(
124 set_sop.eq(1),
125 NextState("COPY")
126 )
127 ).Else(
128 inc_cnt.eq(1)
129 )
130 )
131 )
132 fsm.act("COPY",
133 Record.connect(self.sink, self.source),
134 self.source.sop.eq(sop),
135 clr_sop.eq(self.source.stb & self.source.ack),
136
137 If(self.source.stb & self.source.eop & self.source.ack,
138 NextState("IDLE"),
139 )
140 )