From fc96b20225cd1db386a64d17a0f78047545de429 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 27 Jan 2015 12:02:59 +0100 Subject: [PATCH] add optional subsampler --- litescope/core/storage.py | 23 ++++++++++++++++++++++ litescope/frontend/la.py | 41 +++++++++++++++++++++++++-------------- litescope/host/driver.py | 5 ++++- targets/simple.py | 2 +- test/test_la.py | 1 + 5 files changed, 55 insertions(+), 17 deletions(-) diff --git a/litescope/core/storage.py b/litescope/core/storage.py index e98ed5efb..be1ac211e 100644 --- a/litescope/core/storage.py +++ b/litescope/core/storage.py @@ -1,5 +1,28 @@ from litescope.common import * +class LiteScopeSubSamplerUnit(Module): + def __init__(self, dw): + self.sink = sink = Sink(data_layout(dw)) + self.source = source = Source(data_layout(dw)) + self.value = Signal(32) + ### + self.submodules.counter = Counter(bits_sign=32) + done = Signal() + self.comb += [ + done.eq(self.counter.value >= self.value), + Record.connect(sink, source), + source.stb.eq(sink.stb & done), + self.counter.ce.eq(source.ack), + self.counter.reset.eq(source.stb & source.ack & done) + ] + +class LiteScopeSubSampler(LiteScopeSubSamplerUnit, AutoCSR): + def __init__(self, dw): + LiteScopeSubSamplerUnit.__init__(self, dw) + self._value = CSRStorage(32) + ### + self.comb += self.value.eq(self._value.storage) + class LiteScopeRunLengthEncoderUnit(Module): def __init__(self, dw, length=1024): self.dw = dw diff --git a/litescope/frontend/la.py b/litescope/frontend/la.py index f3025fc72..4defc02ac 100644 --- a/litescope/frontend/la.py +++ b/litescope/frontend/la.py @@ -1,18 +1,20 @@ from litescope.common import * from litescope.core.trigger import LiteScopeTrigger -from litescope.core.storage import LiteScopeRecorder, LiteScopeRunLengthEncoder +from litescope.core.storage import LiteScopeSubSampler, LiteScopeRecorder, LiteScopeRunLengthEncoder from mibuild.tools import write_to_file class LiteScopeLA(Module, AutoCSR): - def __init__(self, layout, depth, clk_domain="sys", input_buffer=False, with_rle=False): + def __init__(self, layout, depth, clk_domain="sys", + with_input_buffer=False, with_rle=False, with_subsampler=False): self.layout = layout self.data = Cat(*layout) self.dw = flen(self.data) self.depth = depth - self.with_rle = with_rle self.clk_domain = clk_domain - self.input_buffer = input_buffer + self.with_rle = with_rle + self.with_input_buffer = with_input_buffer + self.with_subsampler = with_subsampler self.sink = Sink(data_layout(self.dw)) self.comb += [ @@ -24,35 +26,44 @@ class LiteScopeLA(Module, AutoCSR): self.submodules.recorder = recorder = LiteScopeRecorder(self.dw, self.depth) def do_finalize(self): + sink = self.sink # insert Buffer on sink (optional, can be used to improve timings) - if self.input_buffer: + if self.with_input_buffer: self.submodules.buffer = Buffer(self.sink.description) - self.comb += Record.connect(self.sink, self.buffer.d) - self.sink = self.buffer.q + self.comb += Record.connect(sink, self.buffer.d) + sink = self.buffer.q # 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 if self.clk_domain is not "sys": self.submodules.fifo = AsyncFIFO(self.sink.description, 32) self.submodules += RenameClockDomains(self.fifo, {"write": self.clk_domain, "read": "sys"}) - self.comb += Record.connect(self.sink, self.fifo.sink) - self.sink = self.fifo.source + self.comb += Record.connect(sink, self.fifo.sink) + sink = self.fifo.source - # connect everything + # connect trigger self.comb += [ - self.trigger.sink.stb.eq(self.sink.stb), - self.trigger.sink.data.eq(self.sink.data), - Record.connect(self.trigger.source, self.recorder.trigger_sink) + self.trigger.sink.stb.eq(sink.stb), + self.trigger.sink.data.eq(sink.data), ] + + # 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) if self.with_rle: rle = LiteScopeRunLengthEncoder(self.dw) self.submodules += rle self.comb += [ - Record.connect(self.sink, rle.sink), + Record.connect(sink, rle.sink), Record.connect(rle.source, self.recorder.data_sink) ] else: - self.comb += Record.connect(self.sink, self.recorder.data_sink) + self.comb += Record.connect(sink, self.recorder.data_sink) def export(self, vns, filename): def format_line(*args): diff --git a/litescope/host/driver.py b/litescope/host/driver.py index 3e5711d3a..4c305a0e1 100644 --- a/litescope/host/driver.py +++ b/litescope/host/driver.py @@ -184,7 +184,10 @@ class LiteScopeLADriver(): self.trigger_sum_prog_dat.write(dat) self.trigger_sum_prog_we.write(1) - def set_rle(self, v): + def configure_subsampler(self, n): + self.subsampler_value.write(n-1) + + def configure_rle(self, v): self.rle_enable.write(v) def done(self): diff --git a/targets/simple.py b/targets/simple.py index 009c95a83..9f9dca608 100644 --- a/targets/simple.py +++ b/targets/simple.py @@ -97,7 +97,7 @@ class LiteScopeSoC(GenSoC, AutoCSR): cnt0, cnt1 ) - self.submodules.la = LiteScopeLA(self.debug, 512) + self.submodules.la = LiteScopeLA(self.debug, 512, with_subsampler=True) self.la.trigger.add_port(LiteScopeTerm(self.la.dw)) atexit.register(self.exit, platform) diff --git a/test/test_la.py b/test/test_la.py index 4cfa78eac..4904aa081 100644 --- a/test/test_la.py +++ b/test/test_la.py @@ -8,6 +8,7 @@ la = LiteScopeLADriver(wb.regs, "la", debug=True) cond = {"cnt0" : 128} # trigger on cnt0 = 128 la.configure_term(port=0, cond=cond) la.configure_sum("term") +la.configure_subsampler(16) la.run(offset=128, length=256) while not la.done():