1 from litesata
.common
import *
2 from litesata
.core
.link
.scrambler
import Scrambler
4 from migen
.fhdl
.decorators
import ModuleDecorator
5 from migen
.bank
.description
import *
7 class LiteSATABISTGenerator(Module
):
8 def __init__(self
, user_port
):
10 self
.sector
= Signal(48)
11 self
.count
= Signal(16)
12 self
.random
= Signal()
15 self
.aborted
= Signal()
16 self
.errors
= Signal(32) # Note: Not used for writes
20 source
, sink
= user_port
.sink
, user_port
.source
22 counter
= Counter(bits_sign
=32)
23 self
.submodules
+= counter
25 scrambler
= scrambler
= InsertReset(Scrambler())
26 self
.submodules
+= scrambler
28 scrambler
.reset
.eq(counter
.reset
),
29 scrambler
.ce
.eq(counter
.ce
)
32 self
.fsm
= fsm
= FSM(reset_state
="IDLE")
33 self
.submodules
+= fsm
38 NextState("SEND_CMD_AND_DATA")
42 source
.sop
.eq(counter
.value
== 0),
43 source
.eop
.eq(counter
.value
== (logical_sector_size
//4*self
.count
)-1),
45 source
.sector
.eq(self
.sector
),
46 source
.count
.eq(self
.count
),
48 source
.data
.eq(scrambler
.value
)
50 source
.data
.eq(counter
.value
)
53 fsm
.act("SEND_CMD_AND_DATA",
55 If(source
.stb
& source
.ack
,
68 self
.sync
+= If(sink
.stb
& sink
.ack
, self
.aborted
.eq(sink
.failed
))
70 class LiteSATABISTChecker(Module
):
71 def __init__(self
, user_port
):
73 self
.sector
= Signal(48)
74 self
.count
= Signal(16)
75 self
.random
= Signal()
78 self
.aborted
= Signal()
79 self
.errors
= Signal(32)
83 source
, sink
= user_port
.sink
, user_port
.source
85 counter
= Counter(bits_sign
=32)
86 error_counter
= Counter(self
.errors
, bits_sign
=32)
87 self
.submodules
+= counter
, error_counter
89 scrambler
= InsertReset(Scrambler())
90 self
.submodules
+= scrambler
92 scrambler
.reset
.eq(counter
.reset
),
93 scrambler
.ce
.eq(counter
.ce
)
96 self
.fsm
= fsm
= FSM(reset_state
="IDLE")
97 self
.submodules
+= self
.fsm
102 error_counter
.reset
.eq(1),
103 NextState("SEND_CMD")
110 source
.sector
.eq(self
.sector
),
111 source
.count
.eq(self
.count
),
117 NextState("WAIT_ACK")
121 If(sink
.stb
& sink
.read
,
122 NextState("RECEIVE_DATA")
125 expected_data
= Signal(32)
128 expected_data
.eq(scrambler
.value
)
130 expected_data
.eq(counter
.value
)
132 fsm
.act("RECEIVE_DATA",
136 If(sink
.data
!= expected_data
,
137 error_counter
.ce
.eq(~sink
.last
)
143 NextState("WAIT_ACK")
148 self
.sync
+= If(sink
.stb
& sink
.ack
, self
.aborted
.eq(sink
.failed
))
150 class LiteSATABISTUnitCSR(Module
, AutoCSR
):
151 def __init__(self
, bist_unit
):
153 self
._sector
= CSRStorage(48)
154 self
._count
= CSRStorage(16)
155 self
._loops
= CSRStorage(8)
156 self
._random
= CSRStorage()
158 self
._done
= CSRStatus()
159 self
._aborted
= CSRStatus()
160 self
._errors
= CSRStatus(32)
161 self
._cycles
= CSRStatus(32)
165 self
.submodules
+= bist_unit
167 start
= self
._start
.r
& self
._start
.re
168 done
= self
._done
.status
169 loops
= self
._loops
.storage
172 bist_unit
.sector
.eq(self
._sector
.storage
),
173 bist_unit
.count
.eq(self
._count
.storage
),
174 bist_unit
.random
.eq(self
._random
.storage
),
176 self
._aborted
.status
.eq(bist_unit
.aborted
),
177 self
._errors
.status
.eq(bist_unit
.errors
)
180 self
.fsm
= fsm
= FSM(reset_state
="IDLE")
181 loop_counter
= Counter(bits_sign
=8)
182 self
.submodules
+= fsm
, loop_counter
184 self
._done
.status
.eq(1),
185 loop_counter
.reset
.eq(1),
191 If(loop_counter
.value
< loops
,
198 bist_unit
.start
.eq(1),
199 NextState("WAIT_DONE")
203 loop_counter
.ce
.eq(1),
208 cycles_counter
= Counter(self
._cycles
.status
)
209 self
.submodules
+= cycles_counter
211 cycles_counter
.reset
.eq(start
),
212 cycles_counter
.ce
.eq(~fsm
.ongoing("IDLE"))
215 class LiteSATABISTIdentify(Module
):
216 def __init__(self
, user_port
):
217 self
.start
= Signal()
220 fifo
= SyncFIFO([("data", 32)], 512, buffered
=True)
221 self
.submodules
+= fifo
222 self
.source
= fifo
.source
226 source
, sink
= user_port
.sink
, user_port
.source
228 self
.fsm
= fsm
= FSM(reset_state
="IDLE")
232 NextState("SEND_CMD")
238 source
.identify
.eq(1),
242 If(source
.stb
& source
.ack
,
243 NextState("WAIT_ACK")
247 If(sink
.stb
& sink
.identify
,
248 NextState("RECEIVE_DATA")
251 self
.comb
+= fifo
.sink
.data
.eq(sink
.data
)
252 fsm
.act("RECEIVE_DATA",
253 sink
.ack
.eq(fifo
.sink
.ack
),
262 class LiteSATABISTIdentifyCSR(Module
, AutoCSR
):
263 def __init__(self
, bist_identify
):
265 self
._done
= CSRStatus()
266 self
._source
_stb
= CSRStatus()
267 self
._source
_ack
= CSR()
268 self
._source
_data
= CSRStatus(32)
272 self
.submodules
+= bist_identify
274 bist_identify
.start
.eq(self
._start
.r
& self
._start
.re
),
275 self
._done
.status
.eq(bist_identify
.done
),
277 self
._source
_stb
.status
.eq(bist_identify
.source
.stb
),
278 self
._source
_data
.status
.eq(bist_identify
.source
.data
),
279 bist_identify
.source
.ack
.eq(self
._source
_ack
.r
& self
._source
_ack
.re
)
282 class LiteSATABIST(Module
, AutoCSR
):
283 def __init__(self
, crossbar
, with_csr
=False):
284 generator
= LiteSATABISTGenerator(crossbar
.get_port())
285 checker
= LiteSATABISTChecker(crossbar
.get_port())
286 identify
= LiteSATABISTIdentify(crossbar
.get_port())
288 generator
= LiteSATABISTUnitCSR(generator
)
289 checker
= LiteSATABISTUnitCSR(checker
)
290 identify
= LiteSATABISTIdentifyCSR(identify
)
291 self
.submodules
+= generator
, checker
, identify