litex/lib/sata/link/cont.py

119 lines
2.5 KiB
Python
Raw Normal View History

from lib.sata.common import *
2014-12-03 05:12:26 -05:00
from lib.sata.link.scrambler import Scrambler
from migen.genlib.misc import optree
2014-12-03 05:12:26 -05:00
class SATACONTInserter(Module):
2014-12-14 04:52:56 -05:00
def __init__(self, description):
self.sink = sink = Sink(description)
self.source = source = Source(description)
2014-12-03 05:12:26 -05:00
###
counter = Counter(max=4)
self.submodules += counter
2014-12-19 05:15:01 -05:00
is_data = Signal()
was_data = Signal()
2014-12-03 05:12:26 -05:00
change = Signal()
2014-12-19 05:15:01 -05:00
self.comb += is_data.eq(sink.charisk == 0)
2014-12-03 05:12:26 -05:00
2014-12-19 05:15:01 -05:00
last_data = Signal(32)
last_primitive = Signal(32)
last_charisk = Signal(4)
self.sync += [
2014-12-03 05:12:26 -05:00
If(sink.stb & source.ack,
2014-12-19 05:15:01 -05:00
last_data.eq(sink.data),
last_charisk.eq(sink.charisk),
If(~is_data,
2014-12-03 05:12:26 -05:00
last_primitive.eq(sink.data),
2014-12-19 05:15:01 -05:00
),
was_data.eq(is_data)
2014-12-03 05:12:26 -05:00
)
2014-12-19 05:15:01 -05:00
]
was_hold = last_primitive == primitives["HOLD"]
self.comb += change.eq(
(sink.data != last_data) |
(sink.charisk != last_charisk) |
is_data
)
2014-12-03 05:12:26 -05:00
2014-12-19 05:15:01 -05:00
# scrambler
2014-12-05 14:26:09 -05:00
scrambler = InsertReset(Scrambler())
2014-12-03 05:12:26 -05:00
self.submodules += scrambler
# Datapath
self.comb += [
Record.connect(sink, source),
2014-12-03 10:32:55 -05:00
If(sink.stb,
2014-12-19 05:15:01 -05:00
If(~change,
counter.ce.eq(sink.ack & (counter.value !=2)),
# insert CONT
If(counter.value == 1,
source.charisk.eq(0b0001),
source.data.eq(primitives["CONT"])
# insert scrambled data for EMI
).Elif(counter.value == 2,
scrambler.ce.eq(sink.ack),
source.charisk.eq(0b0000),
source.data.eq(scrambler.value)
)
).Else(
counter.reset.eq(source.ack),
If(counter.value == 2,
# Reinsert last primitive
If(is_data | (~is_data & was_hold),
source.stb.eq(1),
sink.ack.eq(0),
source.charisk.eq(0b0001),
source.data.eq(last_primitive)
)
)
2014-12-03 05:12:26 -05:00
)
)
]
2014-12-03 05:50:31 -05:00
class SATACONTRemover(Module):
2014-12-14 04:52:56 -05:00
def __init__(self, description):
self.sink = sink = Sink(description)
self.source = source = Source(description)
2014-12-03 05:50:31 -05:00
###
2014-12-19 05:15:01 -05:00
is_data = Signal()
2014-12-03 05:50:31 -05:00
is_cont = Signal()
in_cont = Signal()
cont_ongoing = Signal()
self.comb += [
2014-12-19 05:15:01 -05:00
is_data.eq(sink.charisk == 0),
is_cont.eq(~is_data & (sink.data == primitives["CONT"]))
2014-12-03 05:50:31 -05:00
]
self.sync += \
2014-12-19 05:15:01 -05:00
If(sink.stb & sink.ack,
If(is_cont,
in_cont.eq(1)
).Elif(~is_data,
in_cont.eq(0)
)
2014-12-03 05:50:31 -05:00
)
2014-12-19 05:15:01 -05:00
self.comb += cont_ongoing.eq(is_cont | (in_cont & is_data))
2014-12-03 05:50:31 -05:00
# Datapath
2014-12-19 05:15:01 -05:00
last_primitive = Signal(32)
2014-12-03 05:50:31 -05:00
self.sync += [
2014-12-19 05:15:01 -05:00
If(sink.stb & sink.ack,
If(~is_data & ~is_cont,
last_primitive.eq(sink.data)
)
2014-12-03 05:50:31 -05:00
)
]
self.comb += [
Record.connect(sink, source),
If(cont_ongoing,
2014-12-03 10:32:55 -05:00
source.charisk.eq(0b0001),
source.data.eq(last_primitive)
2014-12-03 05:50:31 -05:00
)
]