From: Florent Kermarrec Date: Sun, 22 Sep 2013 09:45:30 +0000 (+0200) Subject: move trigger/recorder X-Git-Tag: 24jan2021_ls180~2575^2~91 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=980a83a74c6fd3c5e0edfe301636a5b3a6c50784;p=litex.git move trigger/recorder --- diff --git a/examples/de0_nano/top.py b/examples/de0_nano/top.py index 04f14f03..4aca2af1 100644 --- a/examples/de0_nano/top.py +++ b/examples/de0_nano/top.py @@ -19,9 +19,11 @@ from migen.bus import csr from migen.bank import csrgen from miscope.std.misc import * -from miscope.triggering import * -from miscope.recording import * -from miscope import miio, mila + +from miscope.trigger import Term, Sum, Trigger +from miscope.storage import Recorder +from miscope.miio import MiIo +from miscope.mila import MiLa from miscope.com import uart2csr @@ -52,14 +54,14 @@ class SoC(Module): def __init__(self, platform): # MiIo - self.submodules.miio = miio.MiIo(8) + self.submodules.miio = MiIo(8) # MiLa term = Term(trig_w) trigger = Trigger(trig_w, [term]) recorder = Recorder(dat_w, rec_size) - self.submodules.mila = mila.MiLa(trigger, recorder) + self.submodules.mila = MiLa(trigger, recorder) # Uart2Csr self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200) diff --git a/miscope/recording/__init__.py b/miscope/recording/__init__.py deleted file mode 100644 index 064991cd..00000000 --- a/miscope/recording/__init__.py +++ /dev/null @@ -1,86 +0,0 @@ -from migen.fhdl.std import * -from migen.flow.actor import * -from migen.flow.network import * -from migen.fhdl.specials import Memory -from migen.bus import csr -from migen.bank import description, csrgen -from migen.bank.description import * -from migen.actorlib.fifo import SyncFIFO - -class Recorder(Module, AutoCSR): - def __init__(self, width, depth): - self.width = width - - self.sink = Sink([("hit", 1), ("d", width)]) - - self._r_trigger = CSR() - self._r_length = CSRStorage(bits_for(depth)) - self._r_offset = CSRStorage(bits_for(depth)) - self._r_done = CSRStatus() - - self._r_read_en = CSR() - self._r_read_empty = CSRStatus() - self._r_read_dat = CSRStatus(width) - - ### - - length = self._r_length.storage - offset = self._r_offset.storage - done = Signal(reset=1) - ongoing = Signal() - - cnt = Signal(max=depth) - - fifo = SyncFIFO([("d", width)], depth) - self.submodules += fifo - - # Write fifo is done only when done = 0 - # Fifo must always be pulled by software between - # acquisition (Todo: add a flush funtionnality) - self.comb +=[ - fifo.sink.stb.eq(self.sink.stb & ~done), - fifo.sink.payload.d.eq(self.sink.payload.d), - self.sink.ack.eq(1) - ] - - # Done, Ongoing: - # 0, 0 : Storage triggered but hit was not yet seen - # Data are recorded to fifo, if "offset" datas - # in the fifo, ack is set on fifo.source to - # store only "offset" datas. - # - # 0, 1 : Hit was seen, ack is no longer set on fifo.source - # we are storing "length"-"offset" data in this - # phase - # - # 1, 0 : We have stored "length" datas in fifo. Write to - # fifo is disabled. - # Software must now read data from the fifo until - # it is empty - - # done & ongoing - self.sync += [ - If(self._r_trigger.re & self._r_trigger.r, done.eq(0) - ).Elif(cnt==length, done.eq(1)), - - If(self.sink.stb & self.sink.payload.hit & ~done, ongoing.eq(1) - ).Elif(done, ongoing.eq(0)), - ] - - # fifo ack & csr connection - self.comb += [ - If(~done & ~ongoing & (cnt >= offset), fifo.source.ack.eq(1) - ).Else(fifo.source.ack.eq(self._r_read_en.re & self._r_read_en.r)), - self._r_read_empty.status.eq(~fifo.source.stb), - self._r_read_dat.status.eq(fifo.source.payload.d), - self._r_done.status.eq(done) - ] - - # cnt - self.sync += [ - If(done == 1, - cnt.eq(0) - ).Elif(fifo.sink.stb & fifo.sink.ack & ~(fifo.source.stb & fifo.source.ack), - cnt.eq(cnt+1), - ) - ] \ No newline at end of file diff --git a/miscope/storage.py b/miscope/storage.py new file mode 100644 index 00000000..064991cd --- /dev/null +++ b/miscope/storage.py @@ -0,0 +1,86 @@ +from migen.fhdl.std import * +from migen.flow.actor import * +from migen.flow.network import * +from migen.fhdl.specials import Memory +from migen.bus import csr +from migen.bank import description, csrgen +from migen.bank.description import * +from migen.actorlib.fifo import SyncFIFO + +class Recorder(Module, AutoCSR): + def __init__(self, width, depth): + self.width = width + + self.sink = Sink([("hit", 1), ("d", width)]) + + self._r_trigger = CSR() + self._r_length = CSRStorage(bits_for(depth)) + self._r_offset = CSRStorage(bits_for(depth)) + self._r_done = CSRStatus() + + self._r_read_en = CSR() + self._r_read_empty = CSRStatus() + self._r_read_dat = CSRStatus(width) + + ### + + length = self._r_length.storage + offset = self._r_offset.storage + done = Signal(reset=1) + ongoing = Signal() + + cnt = Signal(max=depth) + + fifo = SyncFIFO([("d", width)], depth) + self.submodules += fifo + + # Write fifo is done only when done = 0 + # Fifo must always be pulled by software between + # acquisition (Todo: add a flush funtionnality) + self.comb +=[ + fifo.sink.stb.eq(self.sink.stb & ~done), + fifo.sink.payload.d.eq(self.sink.payload.d), + self.sink.ack.eq(1) + ] + + # Done, Ongoing: + # 0, 0 : Storage triggered but hit was not yet seen + # Data are recorded to fifo, if "offset" datas + # in the fifo, ack is set on fifo.source to + # store only "offset" datas. + # + # 0, 1 : Hit was seen, ack is no longer set on fifo.source + # we are storing "length"-"offset" data in this + # phase + # + # 1, 0 : We have stored "length" datas in fifo. Write to + # fifo is disabled. + # Software must now read data from the fifo until + # it is empty + + # done & ongoing + self.sync += [ + If(self._r_trigger.re & self._r_trigger.r, done.eq(0) + ).Elif(cnt==length, done.eq(1)), + + If(self.sink.stb & self.sink.payload.hit & ~done, ongoing.eq(1) + ).Elif(done, ongoing.eq(0)), + ] + + # fifo ack & csr connection + self.comb += [ + If(~done & ~ongoing & (cnt >= offset), fifo.source.ack.eq(1) + ).Else(fifo.source.ack.eq(self._r_read_en.re & self._r_read_en.r)), + self._r_read_empty.status.eq(~fifo.source.stb), + self._r_read_dat.status.eq(fifo.source.payload.d), + self._r_done.status.eq(done) + ] + + # cnt + self.sync += [ + If(done == 1, + cnt.eq(0) + ).Elif(fifo.sink.stb & fifo.sink.ack & ~(fifo.source.stb & fifo.source.ack), + cnt.eq(cnt+1), + ) + ] \ No newline at end of file diff --git a/miscope/trigger.py b/miscope/trigger.py new file mode 100644 index 00000000..3a328ae8 --- /dev/null +++ b/miscope/trigger.py @@ -0,0 +1,95 @@ +from migen.fhdl.std import * +from migen.flow.actor import * +from migen.flow.network import * +from migen.fhdl.specials import Memory +from migen.bus import csr +from migen.bank import description, csrgen +from migen.bank.description import * + +class Term(Module, AutoCSR): + def __init__(self, width): + self.width = width + + self.sink = Sink([("d", width)]) + self.source = Source([("hit", 1)]) + + self.busy = Signal() + + self._r_trig = CSRStorage(width) + self._r_mask = CSRStorage(width) + + ### + + trig = self._r_trig.storage + mask = self._r_mask.storage + + hit = Signal() + + self.comb +=[ + hit.eq((self.sink.payload.d & mask) == trig), + self.source.stb.eq(self.sink.stb), + self.sink.ack.eq(self.sink.ack), + self.source.payload.hit.eq(hit) + ] + +class Sum(Module, AutoCSR): + def __init__(self, ports=4): + + self.sinks = [Sink([("hit", 1)]) for p in range(ports)] + self.source = Source([("hit", 1)]) + + self._r_prog_we = CSRStorage() + self._r_prog_adr = CSRStorage(ports) #FIXME + self._r_prog_dat = CSRStorage() + + 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 + self.comb +=[ + prog_port.we.eq(self._r_prog_we.storage), + prog_port.adr.eq(self._r_prog_adr.storage), + prog_port.dat_w.eq(self._r_prog_dat.storage) + ] + + # Lut read + for i, sink in enumerate(self.sinks): + self.comb += lut_port.adr[i].eq(sink.payload.hit) + + # Drive source + self.comb +=[ + self.source.stb.eq(optree("&", [sink.stb for sink in self.sinks])), + self.source.payload.hit.eq(lut_port.dat_r), + [sink.ack.eq(self.source.ack) for sink in self.sinks] + ] + + +class Trigger(Module, AutoCSR): + def __init__(self, width, ports): + self.width = width + self.ports = ports + + self.submodules.sum = Sum(len(ports)) + + # FIXME : when self.submodules += is used, + # get_csrs() is not called + for i, port in enumerate(ports): + tmp = "self.submodules.port"+str(i)+" = port" + exec(tmp) + + self.sink = Sink([("d", width)]) + self.source = self.sum.source + self.busy = Signal() + + ### + for i, port in enumerate(ports): + self.comb +=[ + port.sink.stb.eq(self.sink.stb), + port.sink.payload.d.eq(self.sink.payload.d), + port.source.connect(self.sum.sinks[i]) + ] \ No newline at end of file diff --git a/miscope/triggering/__init__.py b/miscope/triggering/__init__.py deleted file mode 100644 index 3a328ae8..00000000 --- a/miscope/triggering/__init__.py +++ /dev/null @@ -1,95 +0,0 @@ -from migen.fhdl.std import * -from migen.flow.actor import * -from migen.flow.network import * -from migen.fhdl.specials import Memory -from migen.bus import csr -from migen.bank import description, csrgen -from migen.bank.description import * - -class Term(Module, AutoCSR): - def __init__(self, width): - self.width = width - - self.sink = Sink([("d", width)]) - self.source = Source([("hit", 1)]) - - self.busy = Signal() - - self._r_trig = CSRStorage(width) - self._r_mask = CSRStorage(width) - - ### - - trig = self._r_trig.storage - mask = self._r_mask.storage - - hit = Signal() - - self.comb +=[ - hit.eq((self.sink.payload.d & mask) == trig), - self.source.stb.eq(self.sink.stb), - self.sink.ack.eq(self.sink.ack), - self.source.payload.hit.eq(hit) - ] - -class Sum(Module, AutoCSR): - def __init__(self, ports=4): - - self.sinks = [Sink([("hit", 1)]) for p in range(ports)] - self.source = Source([("hit", 1)]) - - self._r_prog_we = CSRStorage() - self._r_prog_adr = CSRStorage(ports) #FIXME - self._r_prog_dat = CSRStorage() - - 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 - self.comb +=[ - prog_port.we.eq(self._r_prog_we.storage), - prog_port.adr.eq(self._r_prog_adr.storage), - prog_port.dat_w.eq(self._r_prog_dat.storage) - ] - - # Lut read - for i, sink in enumerate(self.sinks): - self.comb += lut_port.adr[i].eq(sink.payload.hit) - - # Drive source - self.comb +=[ - self.source.stb.eq(optree("&", [sink.stb for sink in self.sinks])), - self.source.payload.hit.eq(lut_port.dat_r), - [sink.ack.eq(self.source.ack) for sink in self.sinks] - ] - - -class Trigger(Module, AutoCSR): - def __init__(self, width, ports): - self.width = width - self.ports = ports - - self.submodules.sum = Sum(len(ports)) - - # FIXME : when self.submodules += is used, - # get_csrs() is not called - for i, port in enumerate(ports): - tmp = "self.submodules.port"+str(i)+" = port" - exec(tmp) - - self.sink = Sink([("d", width)]) - self.source = self.sum.source - self.busy = Signal() - - ### - for i, port in enumerate(ports): - self.comb +=[ - port.sink.stb.eq(self.sink.stb), - port.sink.payload.d.eq(self.sink.payload.d), - port.source.connect(self.sum.sinks[i]) - ] \ No newline at end of file diff --git a/sim/tb_recorder_csr.py b/sim/tb_recorder_csr.py index a14eba00..c4a98fd4 100644 --- a/sim/tb_recorder_csr.py +++ b/sim/tb_recorder_csr.py @@ -5,10 +5,9 @@ from migen.sim.generic import Simulator, TopLevel from migen.sim.icarus import Runner from migen.bus.transactions import * -from miscope.recording import * -from miscope.std.truthtable import * - from miscope.std import cif +from miscope.std.truthtable import * +from miscope.storage import * from mibuild.tools import write_to_file diff --git a/sim/tb_trigger_csr.py b/sim/tb_trigger_csr.py index d2be9214..f669ac84 100644 --- a/sim/tb_trigger_csr.py +++ b/sim/tb_trigger_csr.py @@ -5,10 +5,9 @@ from migen.sim.generic import Simulator, TopLevel from migen.sim.icarus import Runner from migen.bus.transactions import * -from miscope.triggering import * -from miscope.std.truthtable import * - from miscope.std import cif +from miscope.std.truthtable import * +from miscope.trigger import * from mibuild.tools import write_to_file