2 from migen
.genlib
.io
import DDROutput
3 from migen
.genlib
.resetsync
import AsyncResetSynchronizer
5 from misoc
.cores
.liteeth_mini
.common
import *
8 class LiteEthPHYGMIITX(Module
):
9 def __init__(self
, pads
, pads_register
=True):
10 self
.sink
= sink
= Sink(eth_phy_description(8))
14 if hasattr(pads
, "tx_er"):
15 self
.sync
+= pads
.tx_er
.eq(0)
17 pads
.tx_en
.eq(sink
.stb
),
18 pads
.tx_data
.eq(sink
.data
)
24 self
.comb
+= sink
.ack
.eq(1)
27 class LiteEthPHYGMIIRX(Module
):
28 def __init__(self
, pads
):
29 self
.source
= source
= Source(eth_phy_description(8))
34 self
.sync
+= dv_d
.eq(pads
.dv
)
39 sop
.eq(pads
.dv
& ~dv_d
),
40 eop
.eq(~pads
.dv
& dv_d
)
43 source
.stb
.eq(pads
.dv
),
45 source
.data
.eq(pads
.rx_data
)
47 self
.comb
+= source
.eop
.eq(eop
)
50 class LiteEthPHYGMIICRG(Module
, AutoCSR
):
51 def __init__(self
, clock_pads
, pads
, with_hw_init_reset
, mii_mode
=0):
52 self
._reset
= CSRStorage()
56 self
.clock_domains
.cd_eth_rx
= ClockDomain()
57 self
.clock_domains
.cd_eth_tx
= ClockDomain()
59 # RX : Let the synthesis tool insert the appropriate clock buffer
60 self
.comb
+= self
.cd_eth_rx
.clk
.eq(clock_pads
.rx
)
62 # TX : GMII: Drive clock_pads.gtx, clock_pads.tx unused
63 # MII: Use PHY clock_pads.tx as eth_tx_clk, do not drive clock_pads.gtx
64 self
.specials
+= DDROutput(1, mii_mode
, clock_pads
.gtx
, ClockSignal("eth_tx"))
65 # XXX Xilinx specific, replace BUFGMUX with a generic clock buffer?
66 self
.specials
+= Instance("BUFGMUX",
67 i_I0
=self
.cd_eth_rx
.clk
,
70 o_O
=self
.cd_eth_tx
.clk
)
72 if with_hw_init_reset
:
74 counter
= Signal(max=512)
75 counter_done
= Signal()
77 self
.sync
+= If(counter_ce
, counter
.eq(counter
+ 1))
79 counter_done
.eq(counter
== 256),
80 counter_ce
.eq(~counter_done
),
81 reset
.eq(~counter_done | self
._reset
.storage
)
84 reset
= self
._reset
.storage
85 self
.comb
+= pads
.rst_n
.eq(~reset
)
87 AsyncResetSynchronizer(self
.cd_eth_tx
, reset
),
88 AsyncResetSynchronizer(self
.cd_eth_rx
, reset
),
92 class LiteEthPHYGMII(Module
, AutoCSR
):
93 def __init__(self
, clock_pads
, pads
, with_hw_init_reset
=True):
95 self
.submodules
.crg
= LiteEthPHYGMIICRG(clock_pads
, pads
, with_hw_init_reset
)
96 self
.submodules
.tx
= ClockDomainsRenamer("eth_tx")(LiteEthPHYGMIITX(pads
))
97 self
.submodules
.rx
= ClockDomainsRenamer("eth_rx")(LiteEthPHYGMIIRX(pads
))
98 self
.sink
, self
.source
= self
.tx
.sink
, self
.rx
.source