litex/misoclib/mem/litesata/core/link/scrambler.py

84 lines
2.5 KiB
Python
Raw Normal View History

from misoclib.mem.litesata.common import *
2014-11-04 05:40:43 -05:00
2015-04-13 09:12:39 -04:00
2014-11-04 05:40:43 -05:00
@DecorateModule(InsertCE)
2014-11-04 11:35:46 -05:00
class Scrambler(Module):
"""SATA Scrambler
2014-11-04 05:40:43 -05:00
Implement a SATA Scrambler
2014-11-04 05:40:43 -05:00
Attributes
----------
value : out
Scrambled value.
"""
def __init__(self):
self.value = Signal(32)
2014-11-04 05:40:43 -05:00
2015-04-13 09:55:22 -04:00
# # #
2014-11-04 05:40:43 -05:00
context = Signal(16, reset=0xf0f6)
next_value = Signal(32)
self.sync += context.eq(next_value[16:32])
2014-11-04 05:40:43 -05:00
# XXX: from SATA specification, replace it with
# a generic implementation using polynoms.
lfsr_coefs = (
2015-04-13 09:51:17 -04:00
(15, 13, 4, 0), # 0
(15, 14, 13, 5, 4, 1, 0),
2015-04-13 09:19:34 -04:00
(14, 13, 6, 5, 4, 2, 1, 0),
(15, 14, 7, 6, 5, 3, 2, 1),
(13, 8, 7, 6, 3, 2, 0),
(14, 9, 8, 7, 4, 3, 1),
(15, 10, 9, 8, 5, 4, 2),
(15, 13, 11, 10, 9, 6, 5, 4, 3, 0),
2015-04-13 09:19:34 -04:00
(15, 14, 13, 12, 11, 10, 7, 6, 5, 1, 0),
(14, 12, 11, 8, 7, 6, 4, 2, 1, 0),
(15, 13, 12, 9, 8, 7, 5, 3, 2, 1),
(15, 14, 10, 9, 8, 6, 3, 2, 0),
(13, 11, 10, 9, 7, 3, 1, 0),
(14, 12, 11, 10, 8, 4, 2, 1),
(15, 13, 12, 11, 9, 5, 3, 2),
(15, 14, 12, 10, 6, 3, 0),
2014-11-04 05:40:43 -05:00
2015-04-13 09:51:17 -04:00
(11, 7, 1, 0), # 16
(12, 8, 2, 1),
(13, 9, 3, 2),
(14, 10, 4, 3),
(15, 11, 5, 4),
(15, 13, 12, 6, 5, 4, 0),
(15, 14, 7, 6, 5, 4, 1, 0),
(13, 8, 7, 6, 5, 4, 2, 1, 0),
2015-04-13 09:19:34 -04:00
(14, 9, 8, 7, 6, 5, 3, 2, 1),
(15, 10, 9, 8, 7, 6, 4, 3, 2),
(15, 13, 11, 10, 9, 8, 7, 5, 3, 0),
(15, 14, 13, 12, 11, 10, 9, 8, 6, 1, 0),
(14, 12, 11, 10, 9, 7, 4, 2, 1, 0),
(15, 13, 12, 11, 10, 8, 5, 3, 2, 1),
(15, 14, 12, 11, 9, 6, 3, 2, 0),
(12, 10, 7, 3, 1, 0),
)
2014-11-04 05:40:43 -05:00
for n, coefs in enumerate(lfsr_coefs):
eq = [context[i] for i in coefs]
self.comb += next_value[n].eq(optree("^", eq))
2014-11-04 05:40:43 -05:00
self.comb += self.value.eq(next_value)
2014-11-04 11:35:46 -05:00
2015-04-13 09:12:39 -04:00
2014-12-05 14:26:09 -05:00
@DecorateModule(InsertReset)
2015-01-16 17:52:41 -05:00
class LiteSATAScrambler(Module):
def __init__(self, description):
self.sink = sink = Sink(description)
self.source = source = Source(description)
2014-11-04 11:35:46 -05:00
2015-04-13 09:55:22 -04:00
# # #
2014-11-04 11:35:46 -05:00
scrambler = Scrambler()
self.submodules += scrambler
self.comb += [
scrambler.ce.eq(sink.stb & sink.ack),
Record.connect(sink, source),
source.d.eq(sink.d ^ scrambler.value)
]