3 from lib
.sata
.common
import *
6 clk_period_us
= 1000000/clk_freq
7 return ceil(t
/clk_period_us
)
9 class SATAPHYHostCtrlTimeout(Module
):
10 def __init__(self
, load
):
13 self
.reached
= Signal()
15 cnt
= Signal(max=load
+1)
19 ).Elif(self
.dec
& ~self
.reached
,
22 self
.comb
+= self
.reached
.eq(cnt
== 0)
24 class SATAPHYHostCtrl(Module
):
25 def __init__(self
, trx
, crg
, clk_freq
):
27 self
.sink
= sink
= Sink(phy_description(32))
28 self
.source
= source
= Source(phy_description(32))
36 retry_timeout
= SATAPHYHostCtrlTimeout(us(10000, clk_freq
))
37 align_timeout
= SATAPHYHostCtrlTimeout(us(873, clk_freq
))
38 self
.submodules
+= align_timeout
, retry_timeout
40 align_detect
= Signal()
41 non_align_cnt
= Signal(4)
43 fsm
= FSM(reset_state
="RESET")
44 self
.submodules
+= fsm
48 retry_timeout
.load
.eq(1),
49 align_timeout
.load
.eq(1),
56 trx
.tx_cominit_stb
.eq(1),
57 If(trx
.tx_cominit_ack
& ~trx
.rx_cominit_stb
,
58 NextState("AWAIT_COMINIT")
61 fsm
.act("AWAIT_COMINIT",
63 retry_timeout
.dec
.eq(1),
64 If(trx
.rx_cominit_stb
,
65 NextState("AWAIT_NO_COMINIT")
67 If(retry_timeout
.reached
,
72 fsm
.act("AWAIT_NO_COMINIT",
74 retry_timeout
.load
.eq(1),
75 If(~trx
.rx_cominit_stb
,
76 NextState("CALIBRATE")
85 trx
.tx_comwake_stb
.eq(1),
86 If(trx
.tx_comwake_ack
,
87 NextState("AWAIT_COMWAKE")
90 fsm
.act("AWAIT_COMWAKE",
92 retry_timeout
.dec
.eq(1),
93 If(trx
.rx_comwake_stb
,
94 NextState("AWAIT_NO_COMWAKE")
96 If(retry_timeout
.reached
,
101 fsm
.act("AWAIT_NO_COMWAKE",
103 If(~trx
.rx_comwake_stb
,
104 NextState("AWAIT_NO_RX_IDLE")
107 fsm
.act("AWAIT_NO_RX_IDLE",
109 source
.data
.eq(0x4A4A4A4A), #D10.2
110 source
.charisk
.eq(0b0000),
112 NextState("AWAIT_ALIGN"),
117 fsm
.act("AWAIT_ALIGN",
119 source
.data
.eq(0x4A4A4A4A), #D10.2
120 source
.charisk
.eq(0b0000),
122 align_timeout
.dec
.eq(1),
123 If(align_detect
& ~trx
.rx_idle
,
124 NextState("SEND_ALIGN")
125 ).Elif(align_timeout
.reached
,
129 fsm
.act("SEND_ALIGN",
132 source
.data
.eq(primitives
["ALIGN"]),
133 source
.charisk
.eq(0b0001),
134 If(non_align_cnt
== 3,
141 source
.data
.eq(primitives
["SYNC"]),
142 source
.charisk
.eq(0b0001),
150 align_detect
.eq(self
.sink
.stb
& (self
.sink
.data
== primitives
["ALIGN"]))
152 If(fsm
.ongoing("SEND_ALIGN"),
154 If(sink
.data
[0:8] == 0x7C,
155 non_align_cnt
.eq(non_align_cnt
+ 1)
162 class SATAPHYDeviceCtrl(Module
):
163 def __init__(self
, trx
, crg
, clk_freq
):
164 self
.ready
= Signal()
166 sink
= Sink(phy_description(32))
167 source
= Source(phy_description(32))
176 retry_timeout
= SATAPHYHostCtrlTimeout(us(10000, clk_freq
))
177 align_timeout
= SATAPHYHostCtrlTimeout(us(873, clk_freq
))
178 self
.submodules
+= align_timeout
, retry_timeout
180 fsm
= FSM(reset_state
="RESET")
181 self
.submodules
+= fsm
185 retry_timeout
.load
.eq(1),
186 align_timeout
.load
.eq(1),
188 NextState("AWAIT_COMINIT")
191 fsm
.act("AWAIT_COMINIT",
193 If(trx
.rx_cominit_stb
,
194 NextState("AWAIT_NO_COMINIT")
197 fsm
.act("AWAIT_NO_COMINIT",
199 If(~trx
.rx_cominit_stb
,
205 trx
.tx_cominit_stb
.eq(1),
206 If(trx
.tx_cominit_ack
,
207 NextState("AWAIT_COMWAKE")
210 fsm
.act("AWAIT_COMWAKE",
212 retry_timeout
.dec
.eq(1),
213 If(trx
.rx_comwake_stb
,
214 NextState("AWAIT_NO_COMWAKE")
216 If(retry_timeout
.reached
,
221 fsm
.act("AWAIT_NO_COMWAKE",
223 If(~trx
.rx_comwake_stb
,
224 NextState("CALIBRATE")
233 trx
.tx_comwake_stb
.eq(1),
234 If(trx
.tx_comwake_stb
,
235 NextState("RESET_CRG"),
242 NextState("SEND_ALIGN")
245 fsm
.act("SEND_ALIGN",
248 source
.data
.eq(primitives
["ALIGN"]),
249 source
.charisk
.eq(0b0001),
250 align_timeout
.dec
.eq(1),
253 ).Elif(align_timeout
.reached
,
271 align_detect
.eq(sink
.stb
& (sink
.data
== primitives
["ALIGN"]))