1 from litesata
.common
import *
4 clk_period_us
= 1000000/clk_freq
5 return math
.ceil(t
/clk_period_us
)
7 class LiteSATAPHYCtrl(Module
):
8 def __init__(self
, trx
, crg
, clk_freq
):
10 self
.need_reset
= Signal()
11 self
.sink
= sink
= Sink(phy_description(32))
12 self
.source
= source
= Source(phy_description(32))
20 retry_timeout
= Timeout(us(10000, clk_freq
))
21 align_timeout
= Timeout(us(873, clk_freq
))
22 self
.submodules
+= align_timeout
, retry_timeout
24 align_detect
= Signal()
25 non_align_cnt
= Signal(4)
27 self
.fsm
= fsm
= FSM(reset_state
="RESET")
28 self
.submodules
+= fsm
31 retry_timeout
.reset
.eq(1),
32 align_timeout
.reset
.eq(1),
39 trx
.tx_cominit_stb
.eq(1),
40 If(trx
.tx_cominit_ack
& ~trx
.rx_cominit_stb
,
41 NextState("AWAIT_COMINIT")
44 fsm
.act("AWAIT_COMINIT",
46 retry_timeout
.ce
.eq(1),
47 If(trx
.rx_cominit_stb
,
48 NextState("AWAIT_NO_COMINIT")
50 If(retry_timeout
.reached
,
55 fsm
.act("AWAIT_NO_COMINIT",
57 retry_timeout
.reset
.eq(1),
58 If(~trx
.rx_cominit_stb
,
59 NextState("CALIBRATE")
68 trx
.tx_comwake_stb
.eq(1),
69 If(trx
.tx_comwake_ack
,
70 NextState("AWAIT_COMWAKE")
73 fsm
.act("AWAIT_COMWAKE",
75 retry_timeout
.ce
.eq(1),
76 If(trx
.rx_comwake_stb
,
77 NextState("AWAIT_NO_COMWAKE")
79 If(retry_timeout
.reached
,
84 fsm
.act("AWAIT_NO_COMWAKE",
86 If(~trx
.rx_comwake_stb
,
87 NextState("AWAIT_NO_RX_IDLE")
90 fsm
.act("AWAIT_NO_RX_IDLE",
92 source
.data
.eq(0x4A4A4A4A), #D10.2
93 source
.charisk
.eq(0b0000),
95 NextState("AWAIT_ALIGN"),
100 fsm
.act("AWAIT_ALIGN",
102 source
.data
.eq(0x4A4A4A4A), #D10.2
103 source
.charisk
.eq(0b0000),
105 align_timeout
.ce
.eq(1),
106 If(align_detect
& ~trx
.rx_idle
,
107 NextState("SEND_ALIGN")
108 ).Elif(align_timeout
.reached
,
112 fsm
.act("SEND_ALIGN",
115 source
.data
.eq(primitives
["ALIGN"]),
116 source
.charisk
.eq(0b0001),
117 If(non_align_cnt
== 3,
124 source
.data
.eq(primitives
["SYNC"]),
125 source
.charisk
.eq(0b0001),
132 reset_timeout
= Timeout(clk_freq
//16)
133 self
.submodules
+= reset_timeout
135 reset_timeout
.ce
.eq(~self
.ready
),
136 self
.need_reset
.eq(reset_timeout
.reached
)
140 align_detect
.eq(self
.sink
.stb
& (self
.sink
.data
== primitives
["ALIGN"]))
142 If(fsm
.ongoing("SEND_ALIGN"),
144 If(sink
.data
[0:8] == 0x7C,
145 non_align_cnt
.eq(non_align_cnt
+ 1)