import migen in litex/gen
[litex.git] / litex / soc / misoc / cores / liteeth_mini / phy / mii.py
1 from migen import *
2
3 from misoc.interconnect.csr import *
4 from misoc.interconnect.stream import *
5 from misoc.cores.liteeth_mini.common import *
6
7
8 def converter_description(dw):
9 payload_layout = [("data", dw)]
10 return EndpointDescription(payload_layout, packetized=True)
11
12
13 class LiteEthPHYMIITX(Module):
14 def __init__(self, pads, pads_register=True):
15 self.sink = sink = Sink(eth_phy_description(8))
16
17 # # #
18
19 if hasattr(pads, "tx_er"):
20 self.sync += pads.tx_er.eq(0)
21 converter = Converter(converter_description(8),
22 converter_description(4))
23 self.submodules += converter
24 self.comb += [
25 converter.sink.stb.eq(sink.stb),
26 converter.sink.data.eq(sink.data),
27 sink.ack.eq(converter.sink.ack),
28 converter.source.ack.eq(1)
29 ]
30 pads_eq = [
31 pads.tx_en.eq(converter.source.stb),
32 pads.tx_data.eq(converter.source.data)
33 ]
34 if pads_register:
35 self.sync += pads_eq
36 else:
37 self.comb += pads_eq
38
39
40 class LiteEthPHYMIIRX(Module):
41 def __init__(self, pads):
42 self.source = source = Source(eth_phy_description(8))
43
44 # # #
45
46 sop = Signal(reset=1)
47 sop_set = Signal()
48 sop_clr = Signal()
49 self.sync += If(sop_set, sop.eq(1)).Elif(sop_clr, sop.eq(0))
50
51 converter = Converter(converter_description(4),
52 converter_description(8))
53 converter = ResetInserter()(converter)
54 self.submodules += converter
55
56 self.sync += [
57 converter.reset.eq(~pads.dv),
58 converter.sink.stb.eq(1),
59 converter.sink.data.eq(pads.rx_data)
60 ]
61 self.sync += [
62 sop_set.eq(~pads.dv),
63 sop_clr.eq(pads.dv)
64 ]
65 self.comb += [
66 converter.sink.sop.eq(sop),
67 converter.sink.eop.eq(~pads.dv)
68 ]
69 self.comb += Record.connect(converter.source, source)
70
71
72 class LiteEthPHYMIICRG(Module, AutoCSR):
73 def __init__(self, clock_pads, pads, with_hw_init_reset):
74 self._reset = CSRStorage()
75
76 # # #
77
78 if hasattr(clock_pads, "phy"):
79 self.sync.base50 += clock_pads.phy.eq(~clock_pads.phy)
80
81 self.clock_domains.cd_eth_rx = ClockDomain()
82 self.clock_domains.cd_eth_tx = ClockDomain()
83 self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx)
84 self.comb += self.cd_eth_tx.clk.eq(clock_pads.tx)
85
86 if with_hw_init_reset:
87 reset = Signal()
88 counter_done = Signal()
89 self.submodules.counter = counter = Counter(max=512)
90 self.comb += [
91 counter_done.eq(counter.value == 256),
92 counter.ce.eq(~counter_done),
93 reset.eq(~counter_done | self._reset.storage)
94 ]
95 else:
96 reset = self._reset.storage
97 self.comb += pads.rst_n.eq(~reset)
98 self.specials += [
99 AsyncResetSynchronizer(self.cd_eth_tx, reset),
100 AsyncResetSynchronizer(self.cd_eth_rx, reset),
101 ]
102
103
104 class LiteEthPHYMII(Module, AutoCSR):
105 def __init__(self, clock_pads, pads, with_hw_init_reset=True):
106 self.dw = 8
107 self.submodules.crg = LiteEthPHYMIICRG(clock_pads, pads, with_hw_init_reset)
108 self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYMIITX(pads))
109 self.submodules.rx = ClockDomainsRenamer("eth_tx")(LiteEthPHYMIIRX(pads))
110 self.sink, self.source = self.tx.sink, self.rx.source