2014-10-10 09:15:58 -04:00
|
|
|
from migen.fhdl.std import *
|
2014-10-01 04:06:59 -04:00
|
|
|
from migen.fhdl import verilog
|
2013-02-22 08:28:05 -05:00
|
|
|
from migen.bank.description import *
|
2014-10-10 09:15:58 -04:00
|
|
|
from migen.actorlib.fifo import AsyncFIFO
|
2013-02-22 08:28:05 -05:00
|
|
|
|
2015-01-22 15:40:07 -05:00
|
|
|
from litescope.common import *
|
|
|
|
from litescope.core.trigger import LiteScopeTrigger
|
|
|
|
from litescope.core.storage import 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
|
|
|
|
|
2014-10-10 09:32:36 -04:00
|
|
|
def _getattr_all(l, attr):
|
|
|
|
it = iter(l)
|
|
|
|
r = getattr(next(it), attr)
|
|
|
|
for e in it:
|
|
|
|
if getattr(e, attr) != r:
|
|
|
|
raise ValueError
|
|
|
|
return r
|
|
|
|
|
2015-01-22 15:40:07 -05:00
|
|
|
class LiteScopeLA(Module, AutoCSR):
|
2014-10-28 15:53:26 -04:00
|
|
|
def __init__(self, depth, dat, with_rle=False, clk_domain="sys", pipe=False):
|
2014-05-20 07:16:24 -04:00
|
|
|
self.depth = depth
|
|
|
|
self.with_rle = with_rle
|
2014-10-10 09:32:36 -04:00
|
|
|
self.clk_domain = clk_domain
|
2014-10-28 15:53:26 -04:00
|
|
|
self.pipe = pipe
|
2014-10-10 09:32:36 -04:00
|
|
|
self.ports = []
|
|
|
|
self.width = flen(dat)
|
|
|
|
|
|
|
|
self.stb = Signal(reset=1)
|
|
|
|
self.dat = dat
|
2013-09-22 07:28:12 -04:00
|
|
|
|
2014-10-10 09:32:36 -04:00
|
|
|
def add_port(self, port_class):
|
|
|
|
port = port_class(self.width)
|
|
|
|
self.ports.append(port)
|
2013-09-22 12:41:44 -04:00
|
|
|
|
2014-10-10 09:32:36 -04:00
|
|
|
def do_finalize(self):
|
2014-10-28 15:53:26 -04:00
|
|
|
stb = self.stb
|
|
|
|
dat = self.dat
|
|
|
|
if self.pipe:
|
|
|
|
sync = getattr(self.sync, self.clk_domain)
|
|
|
|
stb_new = Signal()
|
|
|
|
dat_new = Signal(flen(dat))
|
|
|
|
sync += [
|
|
|
|
stb_new.eq(stb),
|
|
|
|
dat_new.eq(dat)
|
|
|
|
]
|
|
|
|
stb = stb_new
|
|
|
|
dat = dat_new
|
|
|
|
|
2014-10-10 09:32:36 -04:00
|
|
|
if self.clk_domain is not "sys":
|
|
|
|
fifo = AsyncFIFO([("dat", self.width)], 32)
|
|
|
|
self.submodules += RenameClockDomains(fifo, {"write": self.clk_domain, "read": "sys"})
|
2014-10-06 04:24:21 -04:00
|
|
|
self.comb += [
|
2014-10-28 15:53:26 -04:00
|
|
|
fifo.sink.stb.eq(stb),
|
|
|
|
fifo.sink.dat.eq(dat)
|
2014-10-06 04:24:21 -04:00
|
|
|
]
|
2014-10-10 09:32:36 -04:00
|
|
|
sink = Record(dat_layout(self.width))
|
2014-10-06 04:24:21 -04:00
|
|
|
self.comb += [
|
|
|
|
sink.stb.eq(fifo.source.stb),
|
|
|
|
sink.dat.eq(fifo.source.dat),
|
|
|
|
fifo.source.ack.eq(1)
|
|
|
|
]
|
|
|
|
else:
|
2014-10-10 09:32:36 -04:00
|
|
|
sink = Record(dat_layout(self.width))
|
|
|
|
self.comb += [
|
2014-10-28 15:53:26 -04:00
|
|
|
sink.stb.eq(stb),
|
|
|
|
sink.dat.eq(dat)
|
2014-10-10 09:32:36 -04:00
|
|
|
]
|
2014-10-06 04:24:21 -04:00
|
|
|
|
2015-01-22 15:40:07 -05:00
|
|
|
self.submodules.trigger = trigger = LiteScopeTrigger(self.width, self.ports)
|
|
|
|
self.submodules.recorder = recorder = LiteScopeRecorder(self.width, self.depth)
|
2013-09-22 12:41:44 -04:00
|
|
|
self.comb += [
|
2014-10-06 04:24:21 -04:00
|
|
|
sink.connect(trigger.sink),
|
2014-05-20 03:02:35 -04:00
|
|
|
trigger.source.connect(recorder.trig_sink)
|
2013-02-22 08:28:05 -05:00
|
|
|
]
|
2013-09-21 07:04:07 -04:00
|
|
|
|
2014-10-10 09:32:36 -04:00
|
|
|
if self.with_rle:
|
2015-01-22 15:40:07 -05:00
|
|
|
self.submodules.rle = rle = LiteScopeRunLengthEncoder(self.width)
|
2014-09-24 16:09:11 -04:00
|
|
|
self.comb += [
|
2014-10-06 04:24:21 -04:00
|
|
|
sink.connect(rle.sink),
|
2014-09-24 16:09:11 -04:00
|
|
|
rle.source.connect(recorder.dat_sink)
|
|
|
|
]
|
|
|
|
else:
|
2014-10-06 06:30:06 -04:00
|
|
|
self.comb += sink.connect(recorder.dat_sink)
|
2014-05-20 05:36:10 -04:00
|
|
|
|
2014-10-01 04:06:59 -04:00
|
|
|
def export(self, design, layout, filename):
|
|
|
|
ret, ns = verilog.convert(design, return_ns=True)
|
2014-05-20 05:36:10 -04:00
|
|
|
r = ""
|
2014-05-20 07:16:24 -04:00
|
|
|
def format_line(*args):
|
|
|
|
return ",".join(args) + "\n"
|
|
|
|
|
|
|
|
r += format_line("config", "width", str(self.width))
|
|
|
|
r += format_line("config", "depth", str(self.depth))
|
|
|
|
r += format_line("config", "with_rle", str(int(self.with_rle)))
|
|
|
|
|
|
|
|
for e in layout:
|
2014-08-03 11:01:58 -04:00
|
|
|
r += format_line("layout", ns.get_name(e), str(flen(e)))
|
2014-10-01 04:06:59 -04:00
|
|
|
write_to_file(filename, r)
|