11ccd3a82ce3d9b1ce5f8fe4b347ceb9db565952
3 from migen
.fhdl
.std
import *
4 from migen
.genlib
.resetsync
import AsyncResetSynchronizer
5 from migen
.genlib
.fsm
import FSM
, NextState
6 from migen
.flow
.actor
import Sink
, Source
8 from lib
.sata
.common
import *
11 clk_period_us
= 1000000/clk_freq
12 return ceil(t
/clk_period_us
)
14 class K7SATAPHYHostCtrl(Module
):
15 def __init__(self
, gtx
, crg
, clk_freq
):
18 self
.sink
= Sink(phy_description(32))
19 self
.source
= Source(phy_description(32))
21 self
.align_detect
= align_detect
= Signal()
22 align_timeout_cnt
= Signal(32)
23 align_timeout
= Signal()
25 retry_timeout_cnt
= Signal(32)
26 retry_timeout
= Signal()
28 non_align_cnt
= Signal(4)
34 self
.source
.stb
.eq(1),
38 fsm
= FSM(reset_state
="RESET")
39 self
.submodules
+= fsm
50 If(gtx
.txcomfinish
& ~gtx
.rxcominitdet
,
51 NextState("AWAIT_COMINIT")
54 fsm
.act("AWAIT_COMINIT",
57 NextState("AWAIT_NO_COMINIT")
64 fsm
.act("AWAIT_NO_COMINIT",
67 NextState("CALIBRATE")
78 NextState("AWAIT_COMWAKE")
81 fsm
.act("AWAIT_COMWAKE",
84 NextState("AWAIT_NO_COMWAKE")
91 fsm
.act("AWAIT_NO_COMWAKE",
94 NextState("AWAIT_NO_RXELECIDLE")
97 fsm
.act("AWAIT_NO_RXELECIDLE",
99 self
.source
.data
.eq(0x4A4A4A4A), #D10.2
100 self
.source
.charisk
.eq(0b0000),
102 NextState("AWAIT_ALIGN"),
107 fsm
.act("AWAIT_ALIGN",
108 gtx
.txelecidle
.eq(0),
109 self
.source
.data
.eq(0x4A4A4A4A), #D10.2
110 self
.source
.charisk
.eq(0b0000),
112 If((align_detect
& ~gtx
.rxelecidle
) & ~align_timeout
,
113 NextState("SEND_ALIGN")
114 ).Elif(~align_detect
& align_timeout
,
118 fsm
.act("SEND_ALIGN",
119 gtx
.txelecidle
.eq(0),
121 self
.source
.data
.eq(primitives
["ALIGN"]),
122 self
.source
.charisk
.eq(0b0001),
123 If(non_align_cnt
== 3,
128 gtx
.txelecidle
.eq(0),
130 self
.source
.data
.eq(primitives
["SYNC"]),
131 self
.source
.charisk
.eq(0b0001),
138 txcominit_d
= Signal()
139 txcomwake_d
= Signal()
141 txcominit_d
.eq(txcominit
),
142 txcomwake_d
.eq(txcomwake
),
143 gtx
.txcominit
.eq(txcominit
& ~txcominit_d
),
144 gtx
.txcomwake
.eq(txcomwake
& ~txcomwake_d
),
147 self
.comb
+= align_detect
.eq(self
.sink
.stb
& (self
.sink
.data
== primitives
["ALIGN"]));
149 If(fsm
.ongoing("RESET"),
150 align_timeout_cnt
.eq(us(873, clk_freq
))
151 ).Elif(fsm
.ongoing("AWAIT_ALIGN"),
152 align_timeout_cnt
.eq(align_timeout_cnt
-1)
154 self
.comb
+= align_timeout
.eq(align_timeout_cnt
== 0)
157 If(fsm
.ongoing("RESET") | fsm
.ongoing("AWAIT_NO_COMINIT"),
158 retry_timeout_cnt
.eq(us(10000, clk_freq
))
159 ).Elif(fsm
.ongoing("AWAIT_COMINIT") | fsm
.ongoing("AWAIT_COMWAKE"),
160 retry_timeout_cnt
.eq(retry_timeout_cnt
-1)
162 self
.comb
+= retry_timeout
.eq(retry_timeout_cnt
== 0)
165 If(fsm
.ongoing("SEND_ALIGN"),
167 If(self
.sink
.data
[0:8] == 0x7C,
168 non_align_cnt
.eq(non_align_cnt
+ 1)
175 class K7SATAPHYDeviceCtrl(Module
):
176 def __init__(self
, gtx
, crg
, clk_freq
):
177 self
.ready
= Signal()
179 self
.sink
= Sink(phy_description(32))
180 self
.source
= Source(phy_description(32))
182 align_detect
= Signal()
183 align_timeout
= Signal()
184 align_timeout_cnt
= Signal(32)
186 retry_timeout_cnt
= Signal(32)
187 retry_timeout
= Signal()
193 self
.source
.stb
.eq(1),
197 fsm
= FSM(reset_state
="RESET")
198 self
.submodules
+= fsm
201 gtx
.txelecidle
.eq(1),
203 NextState("AWAIT_COMINIT")
206 fsm
.act("AWAIT_COMINIT",
207 gtx
.txelecidle
.eq(1),
209 NextState("AWAIT_NO_COMINIT")
212 fsm
.act("AWAIT_NO_COMINIT",
213 gtx
.txelecidle
.eq(1),
214 If(~gtx
.rxcominitdet
,
219 gtx
.txelecidle
.eq(1),
222 NextState("AWAIT_COMWAKE")
225 fsm
.act("AWAIT_COMWAKE",
226 gtx
.txelecidle
.eq(1),
228 NextState("AWAIT_NO_COMWAKE")
235 fsm
.act("AWAIT_NO_COMWAKE",
236 gtx
.txelecidle
.eq(1),
237 If(~gtx
.rxcomwakedet
,
238 NextState("CALIBRATE")
242 gtx
.txelecidle
.eq(1),
246 gtx
.txelecidle
.eq(1),
249 NextState("RESET_CRG"),
254 gtx
.txelecidle
.eq(0),
256 NextState("SEND_ALIGN")
259 fsm
.act("SEND_ALIGN",
260 gtx
.txelecidle
.eq(0),
262 self
.source
.data
.eq(primitives
["ALIGN"]),
263 self
.source
.charisk
.eq(0b0001),
266 ).Elif(align_timeout
,
271 gtx
.txelecidle
.eq(0),
279 gtx
.txelecidle
.eq(1),
283 txcominit_d
= Signal()
284 txcomwake_d
= Signal()
286 txcominit_d
.eq(txcominit
),
287 txcomwake_d
.eq(txcomwake
),
288 gtx
.txcominit
.eq(txcominit
& ~txcominit_d
),
289 gtx
.txcomwake
.eq(txcomwake
& ~txcomwake_d
),
292 self
.comb
+= align_detect
.eq(self
.sink
.stb
& (self
.sink
.data
== primitives
["ALIGN"]));
294 If(fsm
.ongoing("RESET"),
295 align_timeout_cnt
.eq(us(55, clk_freq
))
296 ).Elif(fsm
.ongoing("AWAIT_ALIGN"),
297 align_timeout_cnt
.eq(align_timeout_cnt
-1)
299 self
.comb
+= align_timeout
.eq(align_timeout_cnt
== 0)
302 If(fsm
.ongoing("RESET"),
303 retry_timeout_cnt
.eq(us(10000, clk_freq
))
304 ).Elif(fsm
.ongoing("AWAIT_COMWAKE"),
305 retry_timeout_cnt
.eq(retry_timeout_cnt
-1)
307 self
.comb
+= retry_timeout
.eq(retry_timeout_cnt
== 0)