frontend/logic_analyzer: add Converter for the cases where clk_domain frequency > system frequency

This commit is contained in:
Florent Kermarrec 2016-03-30 20:22:42 +02:00
parent 97a0785e28
commit 4f03da20ab
2 changed files with 28 additions and 14 deletions

View File

@ -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:

View File

@ -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()