1 from migen
.fhdl
.std
import *
2 from migen
.genlib
.misc
import optree
4 from lib
.sata
.common
import *
5 from lib
.sata
.link
.scrambler
import Scrambler
7 class SATACONTInserter(Module
):
8 def __init__(self
, description
):
9 self
.sink
= sink
= Sink(description
)
10 self
.source
= source
= Source(description
)
14 # Detect consecutive primitives
16 counter
= Counter(max=4)
17 self
.submodules
+= counter
19 is_primitive
= Signal()
20 last_was_primitive
= Signal()
21 last_primitive
= Signal(32)
24 cont_insert
= Signal()
25 scrambler_insert
= Signal()
26 last_primitive_insert
= Signal()
27 last_primitive_insert_d
= Signal()
30 is_primitive
.eq(sink
.charisk
!= 0),
31 change
.eq((sink
.data
!= last_primitive
) | ~is_primitive
),
32 cont_insert
.eq(~change
& (counter
.value
== 1)),
33 scrambler_insert
.eq(~change
& (counter
.value
== 2)),
34 last_primitive_insert
.eq((counter
.value
== 2) & (
35 (~is_primitive
& last_was_primitive
) |
36 (is_primitive
& (last_primitive
== primitives
["HOLD"]) & (last_primitive
!= sink
.data
))))
40 If(sink
.stb
& source
.ack
,
41 last_primitive_insert_d
.eq(last_primitive_insert
),
43 last_primitive
.eq(sink
.data
),
44 last_was_primitive
.eq(1)
46 last_was_primitive
.eq(0)
50 If(sink
.stb
& source
.ack
,
51 If(change | last_primitive_insert_d
,
54 counter
.ce
.eq(~scrambler_insert
)
58 # scrambler (between CONT and next primitive)
59 scrambler
= InsertReset(Scrambler())
60 self
.submodules
+= scrambler
62 scrambler
.reset
.eq(ResetSignal()), #XXX: should be reseted on COMINIT / COMRESET
63 scrambler
.ce
.eq(scrambler_insert
& source
.stb
& source
.ack
)
68 Record
.connect(sink
, source
),
71 source
.charisk
.eq(0b0001),
72 source
.data
.eq(primitives
["CONT"])
73 ).Elif(scrambler_insert
,
74 source
.charisk
.eq(0b0000),
75 source
.data
.eq(scrambler
.value
)
76 ).Elif(last_primitive_insert
,
79 source
.charisk
.eq(0b0001),
80 source
.data
.eq(last_primitive
)
85 class SATACONTRemover(Module
):
86 def __init__(self
, description
):
87 self
.sink
= sink
= Sink(description
)
88 self
.source
= source
= Source(description
)
93 is_primitive
= Signal()
96 cont_ongoing
= Signal()
99 is_primitive
.eq(sink
.charisk
!= 0),
100 is_cont
.eq(is_primitive
& (sink
.data
== primitives
["CONT"]))
108 self
.comb
+= cont_ongoing
.eq(is_cont |
(in_cont
& ~is_primitive
))
111 last_primitive
= Signal()
113 If(is_primitive
& ~is_cont
,
114 last_primitive
.eq(sink
.data
)
118 Record
.connect(sink
, source
),
120 source
.charisk
.eq(0b0001),
121 source
.data
.eq(last_primitive
)