2015-02-28 04:27:16 -05:00
|
|
|
from misoclib.tools.litescope.common import *
|
|
|
|
from misoclib.tools.litescope.core.trigger import LiteScopeTrigger
|
|
|
|
from misoclib.tools.litescope.core.storage import LiteScopeSubSampler, LiteScopeRecorder, LiteScopeRunLengthEncoder
|
2013-09-22 07:28:12 -04:00
|
|
|
|
2014-10-01 04:06:59 -04:00
|
|
|
from mibuild.tools import write_to_file
|
|
|
|
|
2015-01-22 15:40:07 -05:00
|
|
|
class LiteScopeLA(Module, AutoCSR):
|
2015-01-27 06:02:59 -05:00
|
|
|
def __init__(self, layout, depth, clk_domain="sys",
|
2015-02-19 04:42:13 -05:00
|
|
|
with_input_buffer=False,
|
|
|
|
with_rle=False, rle_length=256,
|
|
|
|
with_subsampler=False):
|
2015-01-25 07:41:09 -05:00
|
|
|
self.layout = layout
|
|
|
|
self.data = Cat(*layout)
|
|
|
|
self.dw = flen(self.data)
|
2015-02-19 04:42:13 -05:00
|
|
|
if with_rle:
|
2015-02-23 03:41:18 -05:00
|
|
|
self.dw = max(self.dw, log2_int(rle_length))
|
2015-02-19 04:42:13 -05:00
|
|
|
self.dw += 1
|
2014-05-20 07:16:24 -04:00
|
|
|
self.depth = depth
|
2014-10-10 09:32:36 -04:00
|
|
|
self.clk_domain = clk_domain
|
2015-01-27 06:02:59 -05:00
|
|
|
self.with_rle = with_rle
|
2015-02-19 04:42:13 -05:00
|
|
|
self.rle_length = rle_length
|
2015-01-27 06:02:59 -05:00
|
|
|
self.with_input_buffer = with_input_buffer
|
|
|
|
self.with_subsampler = with_subsampler
|
2014-10-10 09:32:36 -04:00
|
|
|
|
2015-01-25 07:41:09 -05:00
|
|
|
self.sink = Sink(data_layout(self.dw))
|
|
|
|
self.comb += [
|
|
|
|
self.sink.stb.eq(1),
|
|
|
|
self.sink.data.eq(self.data)
|
|
|
|
]
|
2013-09-22 07:28:12 -04:00
|
|
|
|
2015-01-25 07:41:09 -05:00
|
|
|
self.submodules.trigger = trigger = LiteScopeTrigger(self.dw)
|
|
|
|
self.submodules.recorder = recorder = LiteScopeRecorder(self.dw, self.depth)
|
2013-09-22 12:41:44 -04:00
|
|
|
|
2014-10-10 09:32:36 -04:00
|
|
|
def do_finalize(self):
|
2015-01-27 06:02:59 -05:00
|
|
|
sink = self.sink
|
2015-01-25 07:41:09 -05:00
|
|
|
# insert Buffer on sink (optional, can be used to improve timings)
|
2015-01-27 06:02:59 -05:00
|
|
|
if self.with_input_buffer:
|
2015-02-19 05:41:54 -05:00
|
|
|
input_buffer = Buffer(self.sink.description)
|
|
|
|
if self.clk_domain is not "sys":
|
|
|
|
self.submodules += RenameClockDomains(input_buffer, clk_domain)
|
|
|
|
else:
|
|
|
|
self.submodules += input_buffer
|
|
|
|
self.comb += Record.connect(sink, intput_buffer.d)
|
|
|
|
sink = intput_buffer.q
|
2014-10-28 15:53:26 -04:00
|
|
|
|
2015-01-25 07:41:09 -05:00
|
|
|
# clock domain crossing (optional, required when capture_clk is not sys_clk)
|
|
|
|
# XXX : sys_clk must be faster than capture_clk, add Converter on data to remove this limitation
|
2014-10-10 09:32:36 -04:00
|
|
|
if self.clk_domain is not "sys":
|
2015-01-25 07:41:09 -05:00
|
|
|
self.submodules.fifo = AsyncFIFO(self.sink.description, 32)
|
|
|
|
self.submodules += RenameClockDomains(self.fifo, {"write": self.clk_domain, "read": "sys"})
|
2015-01-27 06:02:59 -05:00
|
|
|
self.comb += Record.connect(sink, self.fifo.sink)
|
|
|
|
sink = self.fifo.source
|
2014-10-06 04:24:21 -04:00
|
|
|
|
2015-01-27 06:02:59 -05:00
|
|
|
# connect trigger
|
2013-09-22 12:41:44 -04:00
|
|
|
self.comb += [
|
2015-01-27 06:02:59 -05:00
|
|
|
self.trigger.sink.stb.eq(sink.stb),
|
|
|
|
self.trigger.sink.data.eq(sink.data),
|
2013-02-22 08:28:05 -05:00
|
|
|
]
|
2015-01-27 06:02:59 -05:00
|
|
|
|
|
|
|
# insert subsampler (optional)
|
|
|
|
if self.with_subsampler:
|
|
|
|
self.submodules.subsampler = LiteScopeSubSampler(self.dw)
|
|
|
|
self.comb += Record.connect(sink, self.subsampler.sink)
|
|
|
|
sink = self.subsampler.source
|
|
|
|
|
|
|
|
# connect recorder
|
|
|
|
self.comb += Record.connect(self.trigger.source, self.recorder.trigger_sink)
|
2014-10-10 09:32:36 -04:00
|
|
|
if self.with_rle:
|
2015-02-19 04:42:13 -05:00
|
|
|
self.submodules.rle = LiteScopeRunLengthEncoder(self.dw, self.rle_length)
|
2014-09-24 16:09:11 -04:00
|
|
|
self.comb += [
|
2015-02-18 17:35:41 -05:00
|
|
|
Record.connect(sink, self.rle.sink),
|
2015-02-19 04:26:34 -05:00
|
|
|
Record.connect(self.rle.source, self.recorder.data_sink),
|
|
|
|
self.rle.external_enable.eq(self.recorder.post_hit)
|
2014-09-24 16:09:11 -04:00
|
|
|
]
|
|
|
|
else:
|
2015-01-27 14:14:07 -05:00
|
|
|
self.submodules.delay_buffer = Buffer(self.sink.description)
|
|
|
|
self.comb += [
|
|
|
|
Record.connect(sink, self.delay_buffer.d),
|
|
|
|
Record.connect(self.delay_buffer.q, self.recorder.data_sink)
|
|
|
|
]
|
2014-05-20 05:36:10 -04:00
|
|
|
|
2015-01-25 07:41:09 -05:00
|
|
|
def export(self, vns, filename):
|
2014-05-20 07:16:24 -04:00
|
|
|
def format_line(*args):
|
|
|
|
return ",".join(args) + "\n"
|
2015-01-23 09:31:25 -05:00
|
|
|
r = ""
|
2015-01-25 07:41:09 -05:00
|
|
|
r += format_line("config", "dw", str(self.dw))
|
2014-05-20 07:16:24 -04:00
|
|
|
r += format_line("config", "depth", str(self.depth))
|
|
|
|
r += format_line("config", "with_rle", str(int(self.with_rle)))
|
2015-02-19 04:52:57 -05:00
|
|
|
if not isinstance(self.layout, tuple):
|
|
|
|
self.layout = [self.layout]
|
2015-01-25 07:41:09 -05:00
|
|
|
for e in self.layout:
|
2015-01-23 03:04:22 -05:00
|
|
|
r += format_line("layout", vns.get_name(e), str(flen(e)))
|
2014-10-01 04:06:59 -04:00
|
|
|
write_to_file(filename, r)
|