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