1e9be70864d4faab585a9c597ea6753560b84d73
1 from migen
.fhdl
.std
import *
2 from migen
.genlib
.fsm
import FSM
, NextState
3 from migen
.actorlib
.fifo
import SyncFIFO
5 from lib
.sata
.common
import *
6 from lib
.sata
.link
.crc
import SATACRCInserter
, SATACRCChecker
7 from lib
.sata
.link
.scrambler
import SATAScrambler
8 from lib
.sata
.link
.cont
import SATACONTInserter
, SATACONTRemover
16 class SATALinkTX(Module
):
17 def __init__(self
, phy
):
18 self
.sink
= Sink(link_description(32))
19 self
.from_rx
= Sink(from_rx
)
23 fsm
= FSM(reset_state
="IDLE")
24 self
.submodules
+= fsm
27 crc
= SATACRCInserter(link_description(32))
28 self
.submodules
+= crc
31 scrambler
= SATAScrambler(link_description(32))
32 self
.submodules
+= scrambler
34 # connect CRC / scrambler
36 Record
.connect(self
.sink
, crc
.sink
),
37 Record
.connect(crc
.source
, scrambler
.sink
)
40 # inserter CONT and scrambled data between
41 # CONT and next primitive
42 cont
= SATACONTInserter(phy_description(32))
43 self
.submodules
+= cont
45 # datas / primitives mux
48 If(self
.from_rx
.insert
,
50 cont
.sink
.data
.eq(self
.from_rx
.insert
),
51 cont
.sink
.charisk
.eq(0x0001),
55 cont
.sink
.data
.eq(insert
),
56 cont
.sink
.charisk
.eq(0x0001),
57 ).Elif(fsm
.ongoing("COPY"),
58 cont
.sink
.stb
.eq(scrambler
.source
.stb
),
59 cont
.sink
.data
.eq(scrambler
.source
.d
),
60 scrambler
.source
.ack
.eq(cont
.sink
.ack
),
61 cont
.sink
.charisk
.eq(0)
64 self
.comb
+= Record
.connect(cont
.source
, phy
.sink
)
68 scrambler
.reset
.eq(1),
70 insert
.eq(primitives
["SYNC"]),
71 If(scrambler
.source
.stb
& scrambler
.source
.sop
,
77 insert
.eq(primitives
["X_RDY"]),
78 If(~self
.from_rx
.idle
,
80 ).Elif(self
.from_rx
.det
== primitives
["R_RDY"],
85 insert
.eq(primitives
["SOF"]),
91 If(self
.from_rx
.det
== primitives
["HOLD"],
92 insert
.eq(primitives
["HOLDA"]),
93 ).Elif(~scrambler
.source
.stb
,
94 insert
.eq(primitives
["HOLD"]),
95 ).Elif(scrambler
.source
.stb
& scrambler
.source
.eop
& scrambler
.source
.ack
,
100 insert
.eq(primitives
["EOF"]),
106 insert
.eq(primitives
["WTRM"]),
107 If(self
.from_rx
.det
== primitives
["R_OK"],
109 ).Elif(self
.from_rx
.det
== primitives
["R_ERR"],
114 class SATALinkRX(Module
):
115 def __init__(self
, phy
):
116 self
.source
= Source(link_description(32))
117 self
.to_tx
= Source(from_rx
)
121 fsm
= FSM(reset_state
="IDLE")
122 self
.submodules
+= fsm
125 cont
= SATACONTRemover(phy_description(32))
126 self
.submodules
+= cont
127 self
.comb
+= Record
.connect(phy
.source
, cont
.sink
)
129 # datas / primitives detection
133 If(cont
.source
.stb
& (cont
.source
.charisk
== 0b0001),
134 det
.eq(cont
.source
.data
)
138 scrambler
= SATAScrambler(link_description(32))
139 self
.submodules
+= scrambler
142 crc
= SATACRCChecker(link_description(32))
143 self
.submodules
+= crc
147 If(fsm
.ongoing("RDY"),
149 ).Elif(scrambler
.sink
.stb
& scrambler
.sink
.ack
,
153 # small fifo to manage HOLD
154 self
.submodules
.fifo
= SyncFIFO(link_description(32), 32)
158 If(fsm
.ongoing("COPY") & (det
== 0),
159 scrambler
.sink
.stb
.eq(cont
.source
.stb
& (cont
.source
.charisk
== 0)),
160 scrambler
.sink
.d
.eq(cont
.source
.data
),
162 scrambler
.sink
.stb
.eq(0)
165 scrambler
.sink
.sop
.eq(sop
),
166 scrambler
.sink
.eop
.eq(det
== primitives
["EOF"]),
167 cont
.source
.ack
.eq(1),
168 Record
.connect(scrambler
.source
, crc
.sink
),
169 Record
.connect(crc
.source
, self
.fifo
.sink
),
170 Record
.connect(self
.fifo
.source
, self
.source
)
175 scrambler
.reset
.eq(1),
176 If(det
== primitives
["X_RDY"],
181 insert
.eq(primitives
["R_RDY"]),
182 If(det
== primitives
["SOF"],
187 insert
.eq(primitives
["R_IP"]),
188 If(det
== primitives
["HOLD"],
189 insert
.eq(primitives
["HOLDA"])
190 ).Elif(det
== primitives
["EOF"],
192 ).Elif(self
.fifo
.fifo
.level
> 8,
193 insert
.eq(primitives
["HOLD"])
197 If(det
== primitives
["WTRM"],
202 insert
.eq(primitives
["R_OK"]),
203 If(det
== primitives
["SYNC"],
210 self
.to_tx
.idle
.eq(fsm
.ongoing("IDLE")),
211 self
.to_tx
.insert
.eq(insert
),
212 self
.to_tx
.det
.eq(det
)
215 class SATALink(Module
):
216 def __init__(self
, phy
):
217 self
.submodules
.tx
= SATALinkTX(phy
)
218 self
.submodules
.rx
= SATALinkRX(phy
)
219 self
.comb
+= Record
.connect(self
.rx
.to_tx
, self
.tx
.from_rx
)
220 self
.sink
, self
.source
= self
.tx
.sink
, self
.rx
.source