1f312aceb549d256b2f8514916cb5601e99ed9d1
1 # RGMII PHY for Spartan-6
4 from migen
.genlib
.io
import DDROutput
5 from migen
.genlib
.misc
import WaitTimer
6 from migen
.genlib
.fsm
import FSM
, NextState
8 from misoc
.interconnect
.stream
import *
9 from misoc
.interconnect
.csr
import *
10 from misoc
.cores
.liteeth_mini
.common
import *
13 class LiteEthPHYRGMIITX(Module
):
14 def __init__(self
, pads
, pads_register
=True):
15 self
.sink
= sink
= Sink(eth_phy_description(8))
19 self
.specials
+= Instance("ODDR2",
20 p_DDR_ALIGNMENT
="C0", p_INIT
=0, p_SRTYPE
="ASYNC",
21 i_C0
=ClockSignal("eth_tx"), i_C1
=~
ClockSignal("eth_tx"),
23 i_D0
=sink
.stb
, i_D1
=sink
.stb
, o_Q
=pads
.tx_ctl
,
26 self
.specials
+= Instance("ODDR2",
27 p_DDR_ALIGNMENT
="C0", p_INIT
=0, p_SRTYPE
="ASYNC",
28 i_C0
=ClockSignal("eth_tx"), i_C1
=~
ClockSignal("eth_tx"),
30 i_D0
=sink
.data
[i
], i_D1
=sink
.data
[4+i
], o_Q
=pads
.tx_data
[i
],
32 self
.comb
+= sink
.ack
.eq(1)
35 class LiteEthPHYRGMIIRX(Module
):
36 def __init__(self
, pads
):
37 self
.source
= source
= Source(eth_phy_description(8))
44 self
.specials
+= Instance("IDDR2",
45 p_DDR_ALIGNMENT
="C0", p_INIT_Q0
=0, p_INIT_Q1
=0, p_SRTYPE
="ASYNC",
46 i_C0
=ClockSignal("eth_rx"), i_C1
=~
ClockSignal("eth_rx"),
48 i_D
=pads
.rx_ctl
, o_Q1
=rx_ctl
,
51 self
.specials
+= Instance("IDDR2",
52 p_DDR_ALIGNMENT
="C0", p_INIT_Q0
=0, p_INIT_Q1
=0, p_SRTYPE
="ASYNC",
53 i_C0
=ClockSignal("eth_rx"), i_C1
=~
ClockSignal("eth_rx"),
55 i_D
=pads
.rx_data
[i
], o_Q0
=rx_data
[4+i
], o_Q1
=rx_data
[i
],
60 self
.sync
+= rx_ctl_d
.eq(rx_ctl
)
65 sop
.eq(rx_ctl
& ~rx_ctl_d
),
66 eop
.eq(~rx_ctl
& rx_ctl_d
)
69 source
.stb
.eq(rx_ctl
),
71 source
.data
.eq(rx_data
)
73 self
.comb
+= source
.eop
.eq(eop
)
76 class LiteEthPHYRGMIICRG(Module
, AutoCSR
):
77 def __init__(self
, clock_pads
, pads
, with_hw_init_reset
):
78 self
._reset
= CSRStorage()
82 self
.clock_domains
.cd_eth_rx
= ClockDomain()
83 self
.clock_domains
.cd_eth_tx
= ClockDomain()
90 timer
= WaitTimer(1024)
91 fsm
= FSM(reset_state
="DCM_RESET")
92 self
.submodules
+= timer
, fsm
105 NextState("DCM_CHECK_LOCK")
108 fsm
.act("DCM_CHECK_LOCK",
110 NextState("DCM_RESET")
116 clk0_rx_bufg
= Signal()
117 self
.specials
+= Instance("DCM",
118 i_CLKIN
=clock_pads
.rx
,
119 i_CLKFB
=clk0_rx_bufg
,
129 self
.specials
+= Instance("BUFG", i_I
=clk0_rx
, o_O
=clk0_rx_bufg
)
130 self
.specials
+= Instance("BUFG", i_I
=clk90_rx
, o_O
=self
.cd_eth_rx
.clk
)
133 self
.specials
+= DDROutput(1, 0, clock_pads
.tx
, ClockSignal("eth_tx"))
134 self
.specials
+= Instance("BUFG", i_I
=self
.cd_eth_rx
.clk
, o_O
=self
.cd_eth_tx
.clk
)
137 if with_hw_init_reset
:
139 counter_done
= Signal()
140 self
.submodules
.counter
= counter
= Counter(max=512)
142 counter_done
.eq(counter
.value
== 256),
143 counter
.ce
.eq(~counter_done
),
144 reset
.eq(~counter_done | self
._reset
.storage
)
147 reset
= self
._reset
.storage
148 self
.comb
+= pads
.rst_n
.eq(~reset
)
150 AsyncResetSynchronizer(self
.cd_eth_tx
, reset
),
151 AsyncResetSynchronizer(self
.cd_eth_rx
, reset
),
155 class LiteEthPHYRGMII(Module
, AutoCSR
):
156 def __init__(self
, clock_pads
, pads
, with_hw_init_reset
=True):
158 self
.submodules
.crg
= LiteEthPHYRGMIICRG(clock_pads
, pads
, with_hw_init_reset
)
159 self
.submodules
.tx
= ClockDomainsRenamer("eth_tx")(LiteEthPHYRGMIITX(pads
))
160 self
.submodules
.rx
= ClockDomainsRenamer("eth_rx")(LiteEthPHYRGMIIRX(pads
))
161 self
.sink
, self
.source
= self
.tx
.sink
, self
.rx
.source