dff6a28faf0e07dca442d038b96ec32da4509976
[litex.git] / litesata / core / link / cont.py
1 from litesata.common import *
2 from litesata.core.link.scrambler import Scrambler
3
4 class LiteSATACONTInserter(Module):
5 def __init__(self, description):
6 self.sink = sink = Sink(description)
7 self.source = source = Source(description)
8
9 ###
10
11 self.counter = counter = Counter(max=4)
12
13 is_data = Signal()
14 was_data = Signal()
15 was_hold = Signal()
16 change = Signal()
17 self.comb += is_data.eq(sink.charisk == 0)
18
19 last_data = Signal(32)
20 last_primitive = Signal(32)
21 last_charisk = Signal(4)
22 self.sync += [
23 If(sink.stb & source.ack,
24 last_data.eq(sink.data),
25 last_charisk.eq(sink.charisk),
26 If(~is_data,
27 last_primitive.eq(sink.data),
28 ),
29 was_data.eq(is_data),
30 was_hold.eq(last_primitive == primitives["HOLD"])
31 )
32 ]
33 self.comb += change.eq(
34 (sink.data != last_data) |
35 (sink.charisk != last_charisk) |
36 is_data
37 )
38
39 # scrambler
40 self.scrambler = scrambler = InsertReset(Scrambler())
41
42 # Datapath
43 self.comb += [
44 Record.connect(sink, source),
45 If(sink.stb,
46 If(~change,
47 counter.ce.eq(sink.ack & (counter.value !=2)),
48 # insert CONT
49 If(counter.value == 1,
50 source.charisk.eq(0b0001),
51 source.data.eq(primitives["CONT"])
52 # insert scrambled data for EMI
53 ).Elif(counter.value == 2,
54 scrambler.ce.eq(sink.ack),
55 source.charisk.eq(0b0000),
56 source.data.eq(scrambler.value)
57 )
58 ).Else(
59 counter.reset.eq(source.ack),
60 If(counter.value == 2,
61 # Reinsert last primitive
62 If(is_data | (~is_data & was_hold),
63 source.stb.eq(1),
64 sink.ack.eq(0),
65 source.charisk.eq(0b0001),
66 source.data.eq(last_primitive)
67 )
68 )
69 )
70 )
71 ]
72
73 class LiteSATACONTRemover(Module):
74 def __init__(self, description):
75 self.sink = sink = Sink(description)
76 self.source = source = Source(description)
77
78 ###
79
80 is_data = Signal()
81 is_cont = Signal()
82 in_cont = Signal()
83 cont_ongoing = Signal()
84
85 self.comb += [
86 is_data.eq(sink.charisk == 0),
87 is_cont.eq(~is_data & (sink.data == primitives["CONT"]))
88 ]
89 self.sync += \
90 If(sink.stb & sink.ack,
91 If(is_cont,
92 in_cont.eq(1)
93 ).Elif(~is_data,
94 in_cont.eq(0)
95 )
96 )
97 self.comb += cont_ongoing.eq(is_cont | (in_cont & is_data))
98
99 # Datapath
100 last_primitive = Signal(32)
101 self.sync += [
102 If(sink.stb & sink.ack,
103 If(~is_data & ~is_cont,
104 last_primitive.eq(sink.data)
105 )
106 )
107 ]
108 self.comb += [
109 Record.connect(sink, source),
110 If(cont_ongoing,
111 source.charisk.eq(0b0001),
112 source.data.eq(last_primitive)
113 )
114 ]