From 4f03da20ab83bc4a7a7fe855ccf8598e868939ce Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 30 Mar 2016 20:22:42 +0200 Subject: [PATCH] frontend/logic_analyzer: add Converter for the cases where clk_domain frequency > system frequency --- litescope/frontend/logic_analyzer.py | 35 ++++++++++++--------- litescope/software/driver/logic_analyzer.py | 7 +++++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/litescope/frontend/logic_analyzer.py b/litescope/frontend/logic_analyzer.py index 8e7dca6..2ea40de 100644 --- a/litescope/frontend/logic_analyzer.py +++ b/litescope/frontend/logic_analyzer.py @@ -6,10 +6,11 @@ from litex.build.tools import write_to_file class LiteScopeLogicAnalyzer(Module, AutoCSR): - def __init__(self, layout, depth, clk_domain="sys", + def __init__(self, layout, depth, with_input_buffer=False, with_rle=False, rle_length=256, - with_subsampler=False): + with_subsampler=False, + clk_domain="sys", clk_ratio=1): self.layout = layout self.data = Cat(*layout) self.dw = len(self.data) @@ -17,11 +18,12 @@ class LiteScopeLogicAnalyzer(Module, AutoCSR): self.dw = max(self.dw, log2_int(rle_length)) self.dw += 1 self.depth = depth - self.clk_domain = clk_domain self.with_rle = with_rle self.rle_length = rle_length self.with_input_buffer = with_input_buffer self.with_subsampler = with_subsampler + self.clk_domain = clk_domain + self.clk_ratio = clk_ratio self.sink = stream.Endpoint(data_layout(self.dw)) self.comb += [ @@ -29,8 +31,8 @@ class LiteScopeLogicAnalyzer(Module, AutoCSR): self.sink.data.eq(self.data) ] - self.submodules.trigger = trigger = LiteScopeTrigger(self.dw) - self.submodules.recorder = recorder = LiteScopeRecorder(self.dw, self.depth) + self.submodules.trigger = trigger = LiteScopeTrigger(self.dw*self.clk_ratio) + self.submodules.recorder = recorder = LiteScopeRecorder(self.dw*self.clk_ratio, self.depth) def do_finalize(self): sink = self.sink @@ -38,20 +40,24 @@ class LiteScopeLogicAnalyzer(Module, AutoCSR): if self.with_input_buffer: input_buffer = Buffer(self.sink.description) if self.clk_domain is not "sys": - self.submodules += RenameClockDomains(input_buffer, clk_domain) + self.submodules += ClockDomainsRenamer(self.clk_domain)(input_buffer) else: self.submodules += input_buffer self.comb += sink.connect(intput_buffer.sink) - sink = intput_buffer.source + sink = input_buffer.source # 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 += sink.connect(self.fifo.sink) - sink = self.fifo.source + converter = StrideConverter(data_layout(self.dw), + data_layout(self.dw*self.clk_ratio)) + self.submodules += ClockDomainsRenamer(self.clk_domain)(converter) + fifo = AsyncFIFO(converter.source.description, 32) + self.submodules += ClockDomainsRenamer({"write": self.clk_domain, "read": "sys"})(fifo) + self.comb += [ + sink.connect(converter.sink), + converter.source.connect(fifo.sink) + ] + sink = fifo.source # connect trigger self.comb += [ @@ -75,7 +81,7 @@ class LiteScopeLogicAnalyzer(Module, AutoCSR): self.rle.external_enable.eq(self.recorder.post_hit) ] else: - self.submodules.delay_buffer = Buffer(self.sink.description) + self.submodules.delay_buffer = Buffer(sink.description) self.comb += [ sink.connect(self.delay_buffer.sink), self.delay_buffer.source.connect(self.recorder.data_sink) @@ -88,6 +94,7 @@ class LiteScopeLogicAnalyzer(Module, AutoCSR): r += format_line("config", "dw", str(self.dw)) r += format_line("config", "depth", str(self.depth)) r += format_line("config", "with_rle", str(int(self.with_rle))) + r += format_line("config", "clk_ratio", str(int(self.clk_ratio))) if not isinstance(self.layout, tuple): self.layout = [self.layout] for e in self.layout: diff --git a/litescope/software/driver/logic_analyzer.py b/litescope/software/driver/logic_analyzer.py index 94170a8..7cb55f1 100644 --- a/litescope/software/driver/logic_analyzer.py +++ b/litescope/software/driver/logic_analyzer.py @@ -1,5 +1,6 @@ from struct import * from litex.gen.fhdl.structure import * +from litescope.software.dump.common import * from litescope.software.dump import * from litescope.software.driver.truthtable import * @@ -116,6 +117,12 @@ class LiteScopeLogicAnalyzerDriver(): while self.recorder_source_valid.read(): self.data.append(self.recorder_source_data.read()) self.recorder_source_ready.write(1) + if self.clk_ratio > 1: + new_data = DumpData(self.dw) + for data in self.data: + for i in range(self.clk_ratio): + new_data.append(*get_bits([data], i*self.dw, (i+1)*self.dw)) + self.data = new_data if self.with_rle: if self.rle_enable.read(): self.data = self.data.decode_rle()