litex/litescope/core/trigger.py

141 lines
3.2 KiB
Python
Raw Normal View History

2013-09-21 07:04:07 -04:00
from migen.fhdl.std import *
from migen.fhdl.specials import Memory
from migen.bank.description import *
2014-08-03 02:38:37 -04:00
from migen.genlib.record import *
2013-09-21 07:04:07 -04:00
from litescope.common import *
class LiteScopeTerm(Module, AutoCSR):
2013-09-21 07:04:07 -04:00
def __init__(self, width):
self.width = width
2014-08-03 02:38:37 -04:00
self.sink = Record(dat_layout(width))
self.source = Record(hit_layout())
2013-09-21 07:04:07 -04:00
2014-09-24 16:09:11 -04:00
self._trig = CSRStorage(width)
self._mask = CSRStorage(width)
2013-09-21 07:04:07 -04:00
2013-09-22 12:41:44 -04:00
###
2013-09-21 07:04:07 -04:00
2014-09-24 16:09:11 -04:00
trig = self._trig.storage
mask = self._mask.storage
dat = self.sink.dat
hit = self.source.hit
2013-09-21 07:04:07 -04:00
2014-08-03 02:38:37 -04:00
self.comb += [
hit.eq((dat & mask) == trig),
2014-05-20 03:02:35 -04:00
self.source.stb.eq(self.sink.stb)
2013-09-21 07:04:07 -04:00
]
class LiteScopeRangeDetector(Module, AutoCSR):
def __init__(self, width):
self.width = width
2014-08-03 02:38:37 -04:00
self.sink = Record(dat_layout(width))
self.source = Record(hit_layout())
2014-09-24 16:09:11 -04:00
self._low = CSRStorage(width)
self._high = CSRStorage(width)
###
2014-05-20 03:02:35 -04:00
2014-09-24 16:09:11 -04:00
low = self._low.storage
high = self._high.storage
dat = self.sink.dat
hit = self.source.hit
2014-08-03 02:38:37 -04:00
self.comb += [
hit.eq((dat >= low) & (dat <= high)),
2014-05-20 03:02:35 -04:00
self.source.stb.eq(self.sink.stb)
]
class LiteScopeEdgeDetector(Module, AutoCSR):
def __init__(self, width):
self.width = width
2014-09-24 16:09:11 -04:00
2014-08-03 02:38:37 -04:00
self.sink = Record(dat_layout(width))
self.source = Record(hit_layout())
2014-09-24 16:09:11 -04:00
self._rising_mask = CSRStorage(width)
self._falling_mask = CSRStorage(width)
self._both_mask = CSRStorage(width)
###
2014-05-20 03:02:35 -04:00
2014-09-24 16:09:11 -04:00
rising_mask = self._rising_mask.storage
falling_mask = self._falling_mask.storage
both_mask = self._both_mask.storage
dat = self.sink.dat
dat_d = Signal(width)
rising_hit = Signal()
falling_hit = Signal()
both_hit = Signal()
hit = self.source.hit
self.sync += dat_d.eq(dat)
2014-08-03 02:38:37 -04:00
self.comb += [
rising_hit.eq(rising_mask & dat & ~dat_d),
falling_hit.eq(rising_mask & ~dat & dat_d),
both_hit.eq((both_mask & dat) != (both_mask & dat_d)),
hit.eq(rising_hit | falling_hit | both_hit),
2014-05-20 03:02:35 -04:00
self.source.stb.eq(self.sink.stb)
]
class LiteScopeSum(Module, AutoCSR):
2013-09-21 07:04:07 -04:00
def __init__(self, ports=4):
2014-08-03 02:38:37 -04:00
self.sinks = [Record(hit_layout()) for p in range(ports)]
self.source = Record(hit_layout())
2014-09-24 16:09:11 -04:00
self._prog_we = CSRStorage()
self._prog_adr = CSRStorage(ports) #FIXME
self._prog_dat = CSRStorage()
2013-09-21 07:04:07 -04:00
mem = Memory(1, 2**ports)
lut_port = mem.get_port()
prog_port = mem.get_port(write_capable=True)
self.specials += mem, lut_port, prog_port
###
# Lut prog
2014-08-03 02:38:37 -04:00
self.comb += [
2014-09-24 16:09:11 -04:00
prog_port.we.eq(self._prog_we.storage),
prog_port.adr.eq(self._prog_adr.storage),
prog_port.dat_w.eq(self._prog_dat.storage)
2013-09-21 07:04:07 -04:00
]
# Lut read
for i, sink in enumerate(self.sinks):
self.comb += lut_port.adr[i].eq(sink.hit)
2013-09-21 07:04:07 -04:00
# Drive source
2014-08-03 02:38:37 -04:00
self.comb += [
2013-09-21 07:04:07 -04:00
self.source.stb.eq(optree("&", [sink.stb for sink in self.sinks])),
self.source.hit.eq(lut_port.dat_r),
2013-09-21 07:04:07 -04:00
]
class LiteScopeTrigger(Module, AutoCSR):
2013-09-21 07:04:07 -04:00
def __init__(self, width, ports):
self.width = width
self.ports = ports
self.submodules.sum = LiteScopeSum(len(ports))
2013-09-21 07:04:07 -04:00
for i, port in enumerate(ports):
setattr(self.submodules, "port"+str(i), port)
2013-09-21 07:04:07 -04:00
2014-08-03 02:38:37 -04:00
self.sink = Record(dat_layout(width))
2013-09-21 07:04:07 -04:00
self.source = self.sum.source
###
2014-08-03 02:38:37 -04:00
2013-09-21 07:04:07 -04:00
for i, port in enumerate(ports):
2014-08-03 02:38:37 -04:00
self.comb += [
2014-05-20 03:02:35 -04:00
self.sink.connect(port.sink),
2013-09-21 07:04:07 -04:00
port.source.connect(self.sum.sinks[i])
2014-08-03 02:38:37 -04:00
]