litex/litescope/core/storage.py

106 lines
2.6 KiB
Python
Raw Normal View History

from litescope.common import *
2013-09-21 07:04:07 -04:00
class LiteScopeRunLengthEncoder(Module):
def __init__(self, dw, length=1024):
self.dw = dw
2013-09-22 06:35:46 -04:00
self.length = length
self.sink = sink = Sink(data_layout(dw))
self.source = source = Source(data_layout(dw))
2014-09-24 16:09:11 -04:00
self.enable = Signal()
2014-05-13 15:30:32 -04:00
###
sink_d = Sink(data_layout(dw))
self.sync += If(sink.stb, sink_d.eq(sink))
2013-09-22 06:35:46 -04:00
cnt = Signal(max=length)
cnt_inc = Signal()
cnt_reset = Signal()
cnt_max = Signal()
2013-09-22 06:35:46 -04:00
2014-05-20 03:02:35 -04:00
self.sync += \
If(cnt_reset,
cnt.eq(1),
).Elif(cnt_inc,
cnt.eq(cnt+1)
2013-09-22 06:35:46 -04:00
)
self.comb += cnt_max.eq(cnt == length)
2013-09-22 06:35:46 -04:00
change = Signal()
self.comb += change.eq(sink.stb & (sink.dat != sink_d.dat))
2014-05-22 12:14:03 -04:00
fsm = FSM(reset_state="BYPASS")
self.submodules += fsm
fsm.act("BYPASS",
Record.connect(sink_d, source),
cnt_reset.eq(1),
If(self.enable & ~change & sink.stb, NextState("COUNT"))
)
fsm.act("COUNT",
cnt_inc.eq(sink.stb),
If(change | cnt_max | ~self.enable,
source.stb.eq(1),
source.dat[dw-1].eq(1), # Set RLE bit
source.dat[:flen(cnt)].eq(cnt),
NextState("BYPASS")
2014-05-20 03:02:35 -04:00
)
)
class LiteScopeRunLengthEncoderCSR(Module, AutoCSR):
def __init__(self, rle):
self.submodules += rle
self._enable = CSRStorage()
###
self.comb += rle.enable.eq(self_enable.storage)
2013-09-22 06:35:46 -04:00
class LiteScopeRecorder(Module, AutoCSR):
def __init__(self, dw, depth):
self.dw = dw
2013-09-21 07:04:07 -04:00
self.trigger_sink = trigger_sink = Sink(hit_layout())
self.data_sink = data_sink = Sink(data_layout(dw))
2013-09-21 07:04:07 -04:00
2014-09-24 16:09:11 -04:00
self._trigger = CSR()
self._length = CSRStorage(bits_for(depth))
self._offset = CSRStorage(bits_for(depth))
self._done = CSRStatus()
2013-09-21 07:04:07 -04:00
self._source_stb = CSRStatus()
self._source_ack = CSR()
self._source_data = CSRStatus(dw)
2013-09-21 07:04:07 -04:00
###
fifo = InsertReset(SyncFIFO(data_layout(dw), depth, buffered=True))
2013-09-21 07:04:07 -04:00
self.submodules += fifo
2014-05-13 15:30:32 -04:00
fsm = FSM(reset_state="IDLE")
self.submodules += fsm
2013-09-21 07:04:07 -04:00
self.comb += [
self._source_stb.status.eq(fifo.source.stb),
self._source_data.status.eq(fifo.source.data)
2013-09-21 07:04:07 -04:00
]
2014-05-13 15:30:32 -04:00
fsm.act("IDLE",
self._done.status.eq(1),
If(self._trigger.re,
2014-05-13 15:30:32 -04:00
NextState("PRE_HIT_RECORDING"),
2014-08-01 04:36:15 -04:00
fifo.reset.eq(1),
2014-05-13 15:30:32 -04:00
),
fifo.source.ack.eq(self._source_ack.re)
2014-05-13 15:30:32 -04:00
)
fsm.act("PRE_HIT_RECORDING",
fifo.sink.stb.eq(data_sink.stb),
fifo.sink.data.eq(data_sink.data),
data_sink.ack.eq(fifo.sink.ack),
2014-05-13 15:30:32 -04:00
fifo.source.ack.eq(fifo.fifo.level >= self._offset.storage),
If(trigger_sink.stb & trigger_sink.hit, NextState("POST_HIT_RECORDING"))
2014-05-13 15:30:32 -04:00
)
fsm.act("POST_HIT_RECORDING",
fifo.sink.stb.eq(data_sink.stb),
fifo.sink.data.eq(data_sink.data),
data_sink.ack.eq(fifo.sink.ack),
2014-05-13 15:30:32 -04:00
If(~fifo.sink.ack | (fifo.fifo.level >= self._length.storage), NextState("IDLE"))
2014-05-13 15:30:32 -04:00
)