litex/lib/sata/link/cont.py

124 lines
3.0 KiB
Python
Raw Normal View History

2014-12-03 05:12:26 -05:00
from migen.fhdl.std import *
from migen.genlib.misc import optree
from lib.sata.common import *
2014-12-03 05:12:26 -05:00
from lib.sata.link.scrambler import Scrambler
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
###
# Detect consecutive primitives
2014-12-03 05:50:31 -05:00
# tn insert CONT
counter = Counter(max=4)
self.submodules += counter
2014-12-03 05:12:26 -05:00
is_primitive = Signal()
last_was_primitive = Signal()
last_primitive = Signal(32)
change = Signal()
cont_insert = Signal()
scrambler_insert = Signal()
last_primitive_insert = Signal()
2014-12-05 19:23:03 -05:00
last_primitive_insert_d = Signal()
2014-12-03 05:12:26 -05:00
self.comb += [
is_primitive.eq(sink.charisk != 0),
change.eq((sink.data != last_primitive) | ~is_primitive),
cont_insert.eq(~change & (counter.value == 1)),
scrambler_insert.eq(~change & (counter.value == 2)),
last_primitive_insert.eq((counter.value == 2) & (
2014-12-05 19:23:03 -05:00
(~is_primitive & last_was_primitive) |
(is_primitive & (last_primitive == primitives["HOLD"]) & (last_primitive != sink.data))))
2014-12-03 05:12:26 -05:00
]
2014-12-05 19:23:03 -05:00
2014-12-03 05:12:26 -05:00
self.sync += \
If(sink.stb & source.ack,
2014-12-05 19:23:03 -05:00
last_primitive_insert_d.eq(last_primitive_insert),
2014-12-03 05:12:26 -05:00
If(is_primitive,
last_primitive.eq(sink.data),
last_was_primitive.eq(1)
).Else(
last_was_primitive.eq(0)
2014-12-15 14:00:19 -05:00
)
)
self.comb += \
If(sink.stb & source.ack,
2014-12-05 19:23:03 -05:00
If(change | last_primitive_insert_d,
counter.reset.eq(1)
2014-12-03 05:12:26 -05:00
).Else(
counter.ce.eq(~scrambler_insert)
2014-12-03 05:12:26 -05:00
)
)
2014-12-03 10:32:55 -05:00
# scrambler (between CONT and next primitive)
2014-12-05 14:26:09 -05:00
scrambler = InsertReset(Scrambler())
2014-12-03 05:12:26 -05:00
self.submodules += scrambler
self.comb += [
2014-12-03 10:32:55 -05:00
scrambler.reset.eq(ResetSignal()), #XXX: should be reseted on COMINIT / COMRESET
scrambler.ce.eq(scrambler_insert & source.stb & source.ack)
2014-12-03 05:12:26 -05:00
]
# Datapath
self.comb += [
Record.connect(sink, source),
2014-12-03 10:32:55 -05:00
If(sink.stb,
2014-12-03 05:12:26 -05:00
If(cont_insert,
source.charisk.eq(0b0001),
source.data.eq(primitives["CONT"])
).Elif(scrambler_insert,
source.charisk.eq(0b0000),
source.data.eq(scrambler.value)
).Elif(last_primitive_insert,
source.stb.eq(1),
sink.ack.eq(0),
source.charisk.eq(0b0001),
source.data.eq(last_primitive)
)
)
]
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
###
# Detect CONT
is_primitive = Signal()
is_cont = Signal()
in_cont = Signal()
cont_ongoing = Signal()
self.comb += [
is_primitive.eq(sink.charisk != 0),
2014-12-05 19:23:03 -05:00
is_cont.eq(is_primitive & (sink.data == primitives["CONT"]))
2014-12-03 05:50:31 -05:00
]
self.sync += \
If(is_cont,
in_cont.eq(1)
).Elif(is_primitive,
in_cont.eq(0)
)
self.comb += cont_ongoing.eq(is_cont | (in_cont & ~is_primitive))
# Datapath
last_primitive = Signal()
self.sync += [
If(is_primitive & ~is_cont,
last_primitive.eq(sink.data)
)
]
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
)
]