make ctrl/datapath in phy vendor agnostics and simplify imports
[litex.git] / lib / sata / link / scrambler.py
1 from lib.sata.common import *
2
3 from migen.fhdl.std import *
4 from migen.genlib.misc import optree
5
6 @DecorateModule(InsertCE)
7 class Scrambler(Module):
8 """SATA Scrambler
9
10 Implement a SATA Scrambler
11
12 Attributes
13 ----------
14 value : out
15 Scrambled value.
16 """
17 def __init__(self):
18 self.value = Signal(32)
19
20 ###
21
22 context = Signal(16, reset=0xf0f6)
23 next_value = Signal(32)
24 self.sync += context.eq(next_value[16:32])
25
26 # XXX: from SATA specification, replace it with
27 # a generic implementation using polynoms.
28 lfsr_coefs = (
29 (15, 13, 4, 0), #0
30 (15, 14, 13, 5, 4, 1, 0),
31 (14, 13, 6, 5, 4, 2,1, 0),
32 (15, 14, 7, 6, 5, 3,2, 1),
33 (13, 8, 7, 6, 3, 2, 0),
34 (14, 9, 8, 7, 4, 3, 1),
35 (15, 10, 9, 8, 5, 4, 2),
36 (15, 13, 11, 10, 9, 6, 5, 4, 3, 0),
37 (15, 14, 13, 12, 11, 10,7, 6, 5, 1, 0),
38 (14, 12, 11, 8, 7, 6, 4, 2, 1, 0),
39 (15, 13, 12, 9, 8, 7, 5, 3, 2, 1),
40 (15, 14, 10, 9, 8, 6, 3, 2, 0),
41 (13, 11, 10, 9, 7, 3, 1, 0),
42 (14, 12, 11, 10, 8, 4, 2, 1),
43 (15, 13, 12, 11, 9, 5, 3, 2),
44 (15, 14, 12, 10, 6, 3, 0),
45
46 (11, 7, 1, 0), #16
47 (12, 8, 2, 1),
48 (13, 9, 3, 2),
49 (14, 10, 4, 3),
50 (15, 11, 5, 4),
51 (15, 13, 12, 6, 5, 4, 0),
52 (15, 14, 7, 6, 5, 4, 1, 0),
53 (13, 8, 7, 6, 5, 4, 2, 1, 0),
54 (14, 9, 8,7, 6, 5, 3, 2, 1),
55 (15, 10, 9, 8, 7, 6, 4, 3, 2),
56 (15, 13, 11, 10, 9, 8, 7, 5, 3, 0),
57 (15, 14, 13, 12, 11, 10, 9, 8, 6, 1, 0),
58 (14, 12, 11, 10, 9, 7, 4, 2, 1, 0),
59 (15, 13, 12, 11, 10, 8, 5, 3, 2, 1),
60 (15, 14, 12, 11, 9, 6, 3, 2, 0),
61 (12, 10, 7, 3, 1, 0),
62 )
63
64 for n, coefs in enumerate(lfsr_coefs):
65 eq = [context[i] for i in coefs]
66 self.comb += next_value[n].eq(optree("^", eq))
67
68 self.comb += self.value.eq(next_value)
69
70 @DecorateModule(InsertReset)
71 class SATAScrambler(Module):
72 def __init__(self, description):
73 self.sink = sink = Sink(description)
74 self.source = source = Source(description)
75
76 ###
77
78 self.submodules.scrambler = Scrambler()
79 self.comb += [
80 self.scrambler.ce.eq(sink.stb & sink.ack),
81 Record.connect(sink, source),
82 source.d.eq(sink.d ^ self.scrambler.value)
83 ]