continue code refactoring
[litex.git] / liteeth / phy / mii.py
1 from liteeth.common import *
2
3 class LiteEthPHYMIITX(Module):
4 def __init__(self, pads):
5 self.sink = sink = Sink(eth_description(8))
6 ###
7 tx_en_r = Signal()
8 tx_data_r = Signal(4)
9 self.sync += [
10 pads.tx_er.eq(0),
11 pads.tx_en.eq(tx_en_r),
12 pads.tx_data.eq(tx_data_r),
13 ]
14
15 fsm = FSM(reset_state="IDLE")
16 self.submodules += fsm
17 fsm.act("IDLE",
18 sink.ack.eq(1),
19 If(sink.stb & sink.sop,
20 sink.ack.eq(0),
21 NextState("SEND_LO")
22 )
23 )
24 fsm.act("SEND_LO",
25 tx_data_r.eq(sink.d[0:4]),
26 tx_en_r.eq(1),
27 NextState("SEND_HI")
28 )
29 fsm.act("SEND_HI",
30 tx_data_r.eq(sink.d[4:8]),
31 tx_en_r.eq(1),
32 sink.ack.eq(1),
33 If(sink.stb & sink.eop,
34 NextState("IDLE")
35 ).Else(
36 NextState("SEND_LO")
37 )
38 )
39
40 class LiteEthPHYMIIRX(Module):
41 def __init__(self, pads):
42 self.source = source = Source(eth_description(8))
43 ###
44 sop = source.sop
45 set_sop = Signal()
46 clr_sop = Signal()
47 self.sync += \
48 If(clr_sop,
49 sop.eq(0)
50 ).Elif(set_sop,
51 sop.eq(1)
52 )
53
54 lo = Signal(4)
55 hi = Signal(4)
56 load_nibble = Signal(2)
57 self.sync += \
58 If(load_nibble[0],
59 lo.eq(pads.rx_data)
60 ).Elif(load_nibble[1],
61 hi.eq(pads.rx_data)
62 )
63 self.comb += [
64 source.d.eq(Cat(lo, hi))
65 ]
66
67 fsm = FSM(reset_state="IDLE")
68 self.submodules += fsm
69 fsm.act("IDLE",
70 set_sop.eq(1),
71 If(pads.dv,
72 load_nibble.eq(0b01),
73 NextState("LOAD_HI")
74 )
75 )
76 fsm.act("LOAD_LO",
77 source.stb.eq(1),
78 If(pads.dv,
79 clr_sop.eq(1),
80 load_nibble.eq(0b01),
81 NextState("LOAD_HI")
82 ).Else(
83 source.eop.eq(1),
84 NextState("IDLE")
85 )
86 )
87 fsm.act("LOAD_HI",
88 load_nibble.eq(0b10),
89 NextState("LOAD_LO")
90 )
91
92 class LiteEthPHYMIICRG(Module, AutoCSR):
93 def __init__(self, clock_pads, pads):
94 self._reset = CSRStorage()
95 ###
96 self.sync.base50 += clock_pads.phy.eq(~clock_pads.phy)
97
98 self.clock_domains.cd_eth_rx = ClockDomain()
99 self.clock_domains.cd_eth_tx = ClockDomain()
100 self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx)
101 self.comb += self.cd_eth_tx.clk.eq(clock_pads.tx)
102
103 reset = self._reset.storage
104 self.comb += pads.rst_n.eq(~reset)
105 self.specials += [
106 AsyncResetSynchronizer(self.cd_eth_tx, reset),
107 AsyncResetSynchronizer(self.cd_eth_rx, reset),
108 ]
109
110 class LiteEthPHYMII(Module, AutoCSR):
111 def __init__(self, clock_pads, pads):
112 self.dw = 8
113 self.submodules.crg = LiteEthPHYMIICRG(clock_pads, pads)
114 self.submodules.tx = RenameClockDomains(LiteEthPHYMIITX(pads), "eth_tx")
115 self.submodules.rx = RenameClockDomains(LiteEthPHYMIIRX(pads), "eth_rx")
116 self.sink, self.source = self.tx.sink, self.rx.source