From d34c8774011096137fc0320ce31ff448513e45ef Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sun, 26 Aug 2012 21:30:23 +0200 Subject: [PATCH] split migScope to trigger & recorder --- migScope/__init__.py | 440 ------------------------------------------- migScope/recorder.py | 173 +++++++++++++++++ migScope/trigger.py | 245 ++++++++++++++++++++++++ sim/tb_TriggerCsr.py | 13 +- top.py | 39 ++-- 5 files changed, 442 insertions(+), 468 deletions(-) create mode 100644 migScope/recorder.py create mode 100644 migScope/trigger.py diff --git a/migScope/__init__.py b/migScope/__init__.py index 91f275ce..e69de29b 100644 --- a/migScope/__init__.py +++ b/migScope/__init__.py @@ -1,440 +0,0 @@ -from migen.fhdl.structure import * -from migen.bus import csr -from migen.bank import description, csrgen -from migen.bank.description import * -from migen.corelogic.misc import optree - -class Term: - def __init__(self, width, pipe=False): - self.width = width - self.pipe = pipe - - self.i = Signal(BV(self.width)) - self.t = Signal(BV(self.width)) - self.o = Signal() - - def get_fragment(self): - frag = [ - self.o.eq(self.i==self.t) - ] - if self.pipe: - return Fragment(sync=frag) - else: - return Fragment(comb=frag) - -class RangeDetector: - def __init__(self, width, pipe=False): - self.width = width - self.pipe = pipe - - self.i = Signal(BV(self.width)) - self.low = Signal(BV(self.width)) - self.high = Signal(BV(self.width)) - self.o = Signal() - - def get_fragment(self): - frag = [ - self.o.eq((self.i >= self.low) & ((self.i <= self.high))) - ] - if self.pipe: - return Fragment(sync=frag) - else: - return Fragment(comb=frag) - -class EdgeDetector: - def __init__(self, width, pipe=False, mode = "RFB"): - self.width = width - self.pipe = pipe - self.mode = mode - - self.i = Signal(BV(self.width)) - self.i_d = Signal(BV(self.width)) - if "R" in mode: - self.r_mask = Signal(BV(self.width)) - self.ro = Signal() - if "F" in mode: - self.f_mask = Signal(BV(self.width)) - self.fo = Signal() - if "B" in mode: - self.b_mask = Signal(BV(self.width)) - self.bo = Signal() - self.o = Signal() - - def get_fragment(self): - comb = [] - sync = [] - sync += [self.i_d.eq(self.i)] - # Rising Edge - if "R" in self.mode: - r_eq = [self.ro.eq(self.r_mask & self.i & (~self.i_d))] - if self.pipe: - sync += r_eq - else: - comb += r_eq - else: - comb += [self.ro.eq(0)] - # Falling Edge - if "F" in self.mode: - f_eq = [self.fo.eq(self.f_mask & (~ self.i) & self.i_d)] - if self.pipe: - sync += f_eq - else: - comb += f_eq - else: - comb += [self.fo.eq(0)] - # Both - if "B" in self.mode: - b_eq = [self.bo.eq(self.b_mask & self.i != self.i_d)] - if self.pipe: - sync += b_eq - else: - comb += b_eq - else: - comb += [self.bo.eq(0)] - #Output - comb += [self.o.eq(self.ro | self.fo | self.bo)] - - return Fragment(comb, sync) - -class Timer: - def __init__(self, width): - self.width = width - - self.start = Signal() - self.stop = Signal() - self.clear = Signal() - - self.enable = Signal() - self.cnt = Signal(BV(self.width)) - self.cnt_max = Signal(BV(self.width)) - - self.o = Signal() - - def get_fragment(self): - comb = [] - sync = [] - sync += [ - If(self.stop, - self.enable.eq(0), - self.cnt.eq(0), - self.o.eq(0) - ).Elif(self.clear, - self.cnt.eq(0), - self.o.eq(0) - ).Elif(self.start, - self.enable.eq(1) - ).Elif(self.enable, - If(self.cnt <= self.cnt_max, - self.cnt.eq(self.cnt+1) - ).Else( - self.o.eq(1) - ) - ), - If(self.enable, - self.enable.eq(0), - self.cnt.eq(0) - ).Elif(self.clear, - self.cnt.eq(0) - ).Elif(self.start, - self.enable.eq(1) - ) - - ] - - return Fragment(comb, sync) - -class Sum: - def __init__(self,width=4,pipe=False): - self.width = width - self.pipe = pipe - - self.i = Signal(BV(self.width)) - self._o = Signal() - self.o = Signal() - self._lut_port = MemoryPort(adr=self.i, dat_r=self._o) - - self.prog = Signal() - self.prog_adr = Signal(BV(width)) - self.prog_dat = Signal() - self._prog_port = MemoryPort(adr=self.prog_adr, we=self.prog, dat_w=self.prog_dat) - - self._mem = Memory(1, 2**self.width, self._lut_port, self._prog_port) - - def get_fragment(self): - comb = [] - sync = [] - memories = [self._mem] - if self.pipe: - sync += [self.o.eq(self._o)] - else: - comb += [self.o.eq(self._o)] - return Fragment(comb=comb,sync=sync,memories=memories) - - -class Trigger: - def __init__(self,address, trig_width, dat_width, ports): - self.address = address - self.trig_width = trig_width - self.dat_width = dat_width - self.ports = ports - assert (len(self.ports) <= 4), "Nb Ports > 4 (This version support 4 ports Max)" - self._sum = Sum(len(self.ports)) - - self.in_trig = Signal(BV(self.trig_width)) - self.in_dat = Signal(BV(self.dat_width)) - - self.hit = Signal() - self.dat = Signal(BV(self.dat_width)) - - # Csr interface - for i in range(len(self.ports)): - if isinstance(self.ports[i],Term): - setattr(self,"_term_reg%d"%i,RegisterField("rst", 1*self.trig_width, reset=0, - access_bus=WRITE_ONLY, access_dev=READ_ONLY)) - elif isinstance(self.ports[i],EdgeDetector): - setattr(self,"_edge_reg%d"%i,RegisterField("rst", 3*self.trig_width, reset=0, - access_bus=WRITE_ONLY, access_dev=READ_ONLY)) - elif isinstance(self.ports[i],RangeDetector): - setattr(self,"_range_reg%d"%i,RegisterField("rst", 2*self.trig_width, reset=0, - access_bus=WRITE_ONLY, access_dev=READ_ONLY)) - self._sum_reg = RegisterField("_sum_reg", 32, reset=0,access_bus=WRITE_ONLY, access_dev=READ_ONLY) - - regs = [] - objects = self.__dict__ - for object in sorted(objects): - if "_reg" in object: - print(object) - regs.append(objects[object]) - self.bank = csrgen.Bank(regs,address=address) - - def get_fragment(self): - comb = [] - sync = [] - # Connect in_trig to input of trig elements - comb+= [port.i.eq(self.in_trig) for port in self.ports] - - # Connect output of trig elements to sum - comb+= [self._sum.i[j].eq(self.ports[j].o) for j in range(len(self.ports))] - - # Connect sum ouput to hit - comb+= [self.hit.eq(self._sum.o)] - - # Add ports & sum to frag - frag = self.bank.get_fragment() - frag += self._sum.get_fragment() - for port in self.ports: - frag += port.get_fragment() - comb+= [self.dat.eq(self.in_dat)] - - #Connect Registers - for i in range(len(self.ports)): - if isinstance(self.ports[i],Term): - comb += [self.ports[i].t.eq(getattr(self,"_term_reg%d"%i).field.r[0:self.trig_width])] - elif isinstance(self.ports[i],EdgeDetector): - comb += [self.ports[i].r_mask.eq(getattr(self,"_edge_reg%d"%i).field.r[0:1*self.trig_width])] - comb += [self.ports[i].f_mask.eq(getattr(self,"_edge_reg%d"%i).field.r[1*self.trig_width:2*self.trig_width])] - comb += [self.ports[i].b_mask.eq(getattr(self,"_edge_reg%d"%i).field.r[2*self.trig_width:3*self.trig_width])] - elif isinstance(self.ports[i],RangeDetector): - comb += [self.ports[i].low.eq(getattr(self,"_range_reg%d"%i).field.r[0:1*self.trig_width])] - comb += [self.ports[i].high.eq(getattr(self,"_range_reg%d"%i).field.r[1*self.trig_width:2*self.trig_width])] - - comb += [ - self._sum.prog_adr.eq(self._sum_reg.field.r[0:16]), - self._sum.prog_dat.eq(self._sum_reg.field.r[16]), - self._sum.prog.eq(self._sum_reg.field.r[17]) - ] - return frag + Fragment(comb=comb, sync=sync) - - -class Storage: - def __init__(self, width, depth): - self.width = width - self.depth = depth - self.depth_width = bits_for(self.depth) - #Control - self.rst = Signal() - self.start = Signal() - self.offset = Signal(BV(self.depth_width)) - self.size = Signal(BV(self.depth_width)) - self.done = Signal() - #Write Path - self.put = Signal() - self.put_dat = Signal(BV(self.width)) - self._put_cnt = Signal(BV(self.depth_width)) - self._put_ptr = Signal(BV(self.depth_width)) - self._put_port = MemoryPort(adr=self._put_ptr, we=self.put, dat_w=self.put_dat) - #Read Path - self.get = Signal() - self.get_dat = Signal(BV(self.width)) - self._get_cnt = Signal(BV(self.depth_width)) - self._get_ptr = Signal(BV(self.depth_width)) - self._get_port = MemoryPort(adr=self._get_ptr, re=self.get, dat_r=self.get_dat) - #Others - self._mem = Memory(self.width, self.depth, self._put_port, self._get_port) - - - def get_fragment(self): - comb = [] - sync = [] - memories = [self._mem] - size_minus_offset = Signal(BV(self.depth_width)) - comb += [size_minus_offset.eq(self.size-self.offset)] - - #Control - sync += [ - If(self.rst, - self._put_cnt.eq(0), - self._put_ptr.eq(0), - self._get_cnt.eq(0), - self._get_ptr.eq(0), - self.done.eq(0) - ).Elif(self.start, - self._put_cnt.eq(0), - self._get_cnt.eq(0), - self._get_ptr.eq(self._put_ptr-size_minus_offset) - ), - If(self.put, - self._put_cnt.eq(self._put_cnt+1), - self._put_ptr.eq(self._put_ptr+1) - ), - If(self.get, - self._get_cnt.eq(self._get_cnt+1), - self._get_ptr.eq(self._get_ptr+1) - ) - ] - comb += [ - If(self._put_cnt == size_minus_offset-1, - self.done.eq(1) - ).Elif(self._get_cnt == size_minus_offset-1, - self.done.eq(1) - ).Else( - self.done.eq(0) - ) - ] - return Fragment(comb=comb, sync=sync, memories=memories) - -class Sequencer: - def __init__(self,depth): - self.depth = depth - self.depth_width = bits_for(self.depth) - # Controller interface - self.ctl_rst = Signal() - self.ctl_offset = Signal(BV(self.depth_width)) - self.ctl_size = Signal(BV(self.depth_width)) - self.ctl_arm = Signal() - self.ctl_done = Signal() - # Triggers interface - self.trig_hit = Signal() - # Recorder interface - self.rec_offset = Signal(BV(self.depth_width)) - self.rec_size = Signal(BV(self.depth_width)) - self.rec_start = Signal() - self.rec_done = Signal() - # Others - self.enable = Signal() - - def get_fragment(self): - comb = [] - sync = [] - #Control - sync += [ - If(self.ctl_rst, - self.enable.eq(0) - ).Elif(self.ctl_arm, - self.enable.eq(1) - ).Elif(self.rec_done, - self.enable.eq(0) - ) - ] - comb += [ - self.rec_offset.eq(self.ctl_offset), - self.rec_size.eq(self.ctl_size), - self.rec_start.eq(self.enable & self.trig_hit), - self.ctl_done.eq(~self.enable) - ] - return Fragment(comb=comb, sync=sync) - -class Recorder: - def __init__(self,address, width, depth): - self.address = address - self.width = width - self.depth = depth - self.depth_width = bits_for(self.depth) - - self.storage = Storage(self.width, self.depth) - self.sequencer = Sequencer(self.depth) - - # Csr interface - self._rst = RegisterField("rst", reset=1) - self._arm = RegisterField("arm", reset=0) - self._done = RegisterField("done", reset=0, access_bus=READ_ONLY, access_dev=WRITE_ONLY) - - self._size = RegisterField("size", self.depth_width, reset=1) - self._offset = RegisterField("offset", self.depth_width, reset=1) - - self._get = RegisterField("get", reset=1) - self._get_dat = RegisterField("get_dat", self.width, reset=1,access_bus=READ_ONLY, access_dev=WRITE_ONLY) - - regs = [self._rst, self._arm, self._done, - self._size, self._offset, - self._get, self._get_dat] - - self.bank = csrgen.Bank(regs,address=address) - - # Trigger Interface - self.trig_hit = Signal() - self.trig_dat = Signal(BV(self.width)) - - def get_fragment(self): - comb = [] - sync = [] - #Bank <--> Storage / Sequencer - comb += [ - self.sequencer.ctl_rst.eq(self._rst.field.r), - self.storage.rst.eq(self._rst.field.r), - self.sequencer.ctl_offset.eq(self._offset.field.r), - self.sequencer.ctl_size.eq(self._size.field.r), - self.sequencer.ctl_arm.eq(self._arm.field.r), - self._done.field.w.eq(self.sequencer.ctl_done) - ] - - #Storage <--> Sequencer <--> Trigger - comb += [ - self.storage.offset.eq(self.sequencer.rec_offset), - self.storage.size.eq(self.sequencer.rec_size), - self.storage.start.eq(self.sequencer.rec_start), - self.sequencer.rec_done.eq(self.storage.done), - self.sequencer.trig_hit.eq(self.trig_hit), - self.storage.put.eq(self.sequencer.enable), - self.storage.put_dat.eq(self.trig_dat) - - ] - - return self.bank.get_fragment()+\ - self.storage.get_fragment()+self.sequencer.get_fragment()+\ - Fragment(comb=comb, sync=sync) - -class MigCon: - pass - -class MigLa: - pass - -class MigIo: - def __init__(self, width, mode = "IO"): - self.width = width - self.mode = mode - self.ireg = description.RegisterField("i", 0, READ_ONLY, WRITE_ONLY) - self.oreg = description.RegisterField("o", 0) - if "I" in self.mode: - self.inputs = Signal(BV(self.width)) - self.ireg = description.RegisterField("i", self.width, READ_ONLY, WRITE_ONLY) - self.ireg.field.w.name_override = "inputs" - if "O" in self.mode: - self.outputs = Signal(BV(self.width)) - self.oreg = description.RegisterField("o", self.width) - self.oreg.field.r.name_override = "ouptuts" - self.bank = csrgen.Bank([self.oreg, self.ireg]) - - def get_fragment(self): - return self.bank.get_fragment() diff --git a/migScope/recorder.py b/migScope/recorder.py new file mode 100644 index 00000000..d8f654b3 --- /dev/null +++ b/migScope/recorder.py @@ -0,0 +1,173 @@ +from migen.fhdl.structure import * +from migen.bus import csr +from migen.bank import description, csrgen +from migen.bank.description import * +from migen.corelogic.misc import optree + +class Storage: + def __init__(self, width, depth): + self.width = width + self.depth = depth + self.depth_width = bits_for(self.depth) + #Control + self.rst = Signal() + self.start = Signal() + self.offset = Signal(BV(self.depth_width)) + self.size = Signal(BV(self.depth_width)) + self.done = Signal() + #Write Path + self.put = Signal() + self.put_dat = Signal(BV(self.width)) + self._put_cnt = Signal(BV(self.depth_width)) + self._put_ptr = Signal(BV(self.depth_width)) + self._put_port = MemoryPort(adr=self._put_ptr, we=self.put, dat_w=self.put_dat) + #Read Path + self.get = Signal() + self.get_dat = Signal(BV(self.width)) + self._get_cnt = Signal(BV(self.depth_width)) + self._get_ptr = Signal(BV(self.depth_width)) + self._get_port = MemoryPort(adr=self._get_ptr, re=self.get, dat_r=self.get_dat) + #Others + self._mem = Memory(self.width, self.depth, self._put_port, self._get_port) + + + def get_fragment(self): + comb = [] + sync = [] + memories = [self._mem] + size_minus_offset = Signal(BV(self.depth_width)) + comb += [size_minus_offset.eq(self.size-self.offset)] + + #Control + sync += [ + If(self.rst, + self._put_cnt.eq(0), + self._put_ptr.eq(0), + self._get_cnt.eq(0), + self._get_ptr.eq(0), + self.done.eq(0) + ).Elif(self.start, + self._put_cnt.eq(0), + self._get_cnt.eq(0), + self._get_ptr.eq(self._put_ptr-size_minus_offset) + ), + If(self.put, + self._put_cnt.eq(self._put_cnt+1), + self._put_ptr.eq(self._put_ptr+1) + ), + If(self.get, + self._get_cnt.eq(self._get_cnt+1), + self._get_ptr.eq(self._get_ptr+1) + ) + ] + comb += [ + If(self._put_cnt == size_minus_offset-1, + self.done.eq(1) + ).Elif(self._get_cnt == size_minus_offset-1, + self.done.eq(1) + ).Else( + self.done.eq(0) + ) + ] + return Fragment(comb=comb, sync=sync, memories=memories) + +class Sequencer: + def __init__(self,depth): + self.depth = depth + self.depth_width = bits_for(self.depth) + # Controller interface + self.ctl_rst = Signal() + self.ctl_offset = Signal(BV(self.depth_width)) + self.ctl_size = Signal(BV(self.depth_width)) + self.ctl_arm = Signal() + self.ctl_done = Signal() + # Triggers interface + self.trig_hit = Signal() + # Recorder interface + self.rec_offset = Signal(BV(self.depth_width)) + self.rec_size = Signal(BV(self.depth_width)) + self.rec_start = Signal() + self.rec_done = Signal() + # Others + self.enable = Signal() + + def get_fragment(self): + comb = [] + sync = [] + #Control + sync += [ + If(self.ctl_rst, + self.enable.eq(0) + ).Elif(self.ctl_arm, + self.enable.eq(1) + ).Elif(self.rec_done, + self.enable.eq(0) + ) + ] + comb += [ + self.rec_offset.eq(self.ctl_offset), + self.rec_size.eq(self.ctl_size), + self.rec_start.eq(self.enable & self.trig_hit), + self.ctl_done.eq(~self.enable) + ] + return Fragment(comb=comb, sync=sync) + +class Recorder: + def __init__(self,address, width, depth): + self.address = address + self.width = width + self.depth = depth + self.depth_width = bits_for(self.depth) + + self.storage = Storage(self.width, self.depth) + self.sequencer = Sequencer(self.depth) + + # Csr interface + self._rst = RegisterField("rst", reset=1) + self._arm = RegisterField("arm", reset=0) + self._done = RegisterField("done", reset=0, access_bus=READ_ONLY, access_dev=WRITE_ONLY) + + self._size = RegisterField("size", self.depth_width, reset=1) + self._offset = RegisterField("offset", self.depth_width, reset=1) + + self._get = RegisterField("get", reset=1) + self._get_dat = RegisterField("get_dat", self.width, reset=1,access_bus=READ_ONLY, access_dev=WRITE_ONLY) + + regs = [self._rst, self._arm, self._done, + self._size, self._offset, + self._get, self._get_dat] + + self.bank = csrgen.Bank(regs,address=address) + + # Trigger Interface + self.trig_hit = Signal() + self.trig_dat = Signal(BV(self.width)) + + def get_fragment(self): + comb = [] + sync = [] + #Bank <--> Storage / Sequencer + comb += [ + self.sequencer.ctl_rst.eq(self._rst.field.r), + self.storage.rst.eq(self._rst.field.r), + self.sequencer.ctl_offset.eq(self._offset.field.r), + self.sequencer.ctl_size.eq(self._size.field.r), + self.sequencer.ctl_arm.eq(self._arm.field.r), + self._done.field.w.eq(self.sequencer.ctl_done) + ] + + #Storage <--> Sequencer <--> Trigger + comb += [ + self.storage.offset.eq(self.sequencer.rec_offset), + self.storage.size.eq(self.sequencer.rec_size), + self.storage.start.eq(self.sequencer.rec_start), + self.sequencer.rec_done.eq(self.storage.done), + self.sequencer.trig_hit.eq(self.trig_hit), + self.storage.put.eq(self.sequencer.enable), + self.storage.put_dat.eq(self.trig_dat) + + ] + + return self.bank.get_fragment()+\ + self.storage.get_fragment()+self.sequencer.get_fragment()+\ + Fragment(comb=comb, sync=sync) \ No newline at end of file diff --git a/migScope/trigger.py b/migScope/trigger.py new file mode 100644 index 00000000..165df324 --- /dev/null +++ b/migScope/trigger.py @@ -0,0 +1,245 @@ +from migen.fhdl.structure import * +from migen.bus import csr +from migen.bank import description, csrgen +from migen.bank.description import * +from migen.corelogic.misc import optree + +class Term: + def __init__(self, width, pipe=False): + self.width = width + self.pipe = pipe + + self.i = Signal(BV(self.width)) + self.t = Signal(BV(self.width)) + self.o = Signal() + + def get_fragment(self): + frag = [ + self.o.eq(self.i==self.t) + ] + if self.pipe: + return Fragment(sync=frag) + else: + return Fragment(comb=frag) + +class RangeDetector: + def __init__(self, width, pipe=False): + self.width = width + self.pipe = pipe + + self.i = Signal(BV(self.width)) + self.low = Signal(BV(self.width)) + self.high = Signal(BV(self.width)) + self.o = Signal() + + def get_fragment(self): + frag = [ + self.o.eq((self.i >= self.low) & ((self.i <= self.high))) + ] + if self.pipe: + return Fragment(sync=frag) + else: + return Fragment(comb=frag) + +class EdgeDetector: + def __init__(self, width, pipe=False, mode = "RFB"): + self.width = width + self.pipe = pipe + self.mode = mode + + self.i = Signal(BV(self.width)) + self.i_d = Signal(BV(self.width)) + if "R" in mode: + self.r_mask = Signal(BV(self.width)) + self.ro = Signal() + if "F" in mode: + self.f_mask = Signal(BV(self.width)) + self.fo = Signal() + if "B" in mode: + self.b_mask = Signal(BV(self.width)) + self.bo = Signal() + self.o = Signal() + + def get_fragment(self): + comb = [] + sync = [] + sync += [self.i_d.eq(self.i)] + # Rising Edge + if "R" in self.mode: + r_eq = [self.ro.eq(self.r_mask & self.i & (~self.i_d))] + if self.pipe: + sync += r_eq + else: + comb += r_eq + else: + comb += [self.ro.eq(0)] + # Falling Edge + if "F" in self.mode: + f_eq = [self.fo.eq(self.f_mask & (~ self.i) & self.i_d)] + if self.pipe: + sync += f_eq + else: + comb += f_eq + else: + comb += [self.fo.eq(0)] + # Both + if "B" in self.mode: + b_eq = [self.bo.eq(self.b_mask & self.i != self.i_d)] + if self.pipe: + sync += b_eq + else: + comb += b_eq + else: + comb += [self.bo.eq(0)] + #Output + comb += [self.o.eq(self.ro | self.fo | self.bo)] + + return Fragment(comb, sync) + +class Timer: + def __init__(self, width): + self.width = width + + self.start = Signal() + self.stop = Signal() + self.clear = Signal() + + self.enable = Signal() + self.cnt = Signal(BV(self.width)) + self.cnt_max = Signal(BV(self.width)) + + self.o = Signal() + + def get_fragment(self): + comb = [] + sync = [] + sync += [ + If(self.stop, + self.enable.eq(0), + self.cnt.eq(0), + self.o.eq(0) + ).Elif(self.clear, + self.cnt.eq(0), + self.o.eq(0) + ).Elif(self.start, + self.enable.eq(1) + ).Elif(self.enable, + If(self.cnt <= self.cnt_max, + self.cnt.eq(self.cnt+1) + ).Else( + self.o.eq(1) + ) + ), + If(self.enable, + self.enable.eq(0), + self.cnt.eq(0) + ).Elif(self.clear, + self.cnt.eq(0) + ).Elif(self.start, + self.enable.eq(1) + ) + + ] + + return Fragment(comb, sync) + +class Sum: + def __init__(self,width=4,pipe=False): + self.width = width + self.pipe = pipe + + self.i = Signal(BV(self.width)) + self._o = Signal() + self.o = Signal() + self._lut_port = MemoryPort(adr=self.i, dat_r=self._o) + + self.prog = Signal() + self.prog_adr = Signal(BV(width)) + self.prog_dat = Signal() + self._prog_port = MemoryPort(adr=self.prog_adr, we=self.prog, dat_w=self.prog_dat) + + self._mem = Memory(1, 2**self.width, self._lut_port, self._prog_port) + + def get_fragment(self): + comb = [] + sync = [] + memories = [self._mem] + if self.pipe: + sync += [self.o.eq(self._o)] + else: + comb += [self.o.eq(self._o)] + return Fragment(comb=comb,sync=sync,memories=memories) + + +class Trigger: + def __init__(self,address, trig_width, dat_width, ports): + self.address = address + self.trig_width = trig_width + self.dat_width = dat_width + self.ports = ports + assert (len(self.ports) <= 4), "Nb Ports > 4 (This version support 4 ports Max)" + self._sum = Sum(len(self.ports)) + + self.in_trig = Signal(BV(self.trig_width)) + self.in_dat = Signal(BV(self.dat_width)) + + self.hit = Signal() + self.dat = Signal(BV(self.dat_width)) + + # Csr interface + for i in range(len(self.ports)): + if isinstance(self.ports[i],Term): + setattr(self,"_term_reg%d"%i,RegisterField("rst", 1*self.trig_width, reset=0, + access_bus=WRITE_ONLY, access_dev=READ_ONLY)) + elif isinstance(self.ports[i],EdgeDetector): + setattr(self,"_edge_reg%d"%i,RegisterField("rst", 3*self.trig_width, reset=0, + access_bus=WRITE_ONLY, access_dev=READ_ONLY)) + elif isinstance(self.ports[i],RangeDetector): + setattr(self,"_range_reg%d"%i,RegisterField("rst", 2*self.trig_width, reset=0, + access_bus=WRITE_ONLY, access_dev=READ_ONLY)) + self._sum_reg = RegisterField("_sum_reg", 32, reset=0,access_bus=WRITE_ONLY, access_dev=READ_ONLY) + + regs = [] + objects = self.__dict__ + for object in sorted(objects): + if "_reg" in object: + regs.append(objects[object]) + self.bank = csrgen.Bank(regs,address=address) + + def get_fragment(self): + comb = [] + sync = [] + # Connect in_trig to input of trig elements + comb+= [port.i.eq(self.in_trig) for port in self.ports] + + # Connect output of trig elements to sum + comb+= [self._sum.i[j].eq(self.ports[j].o) for j in range(len(self.ports))] + + # Connect sum ouput to hit + comb+= [self.hit.eq(self._sum.o)] + + # Add ports & sum to frag + frag = self.bank.get_fragment() + frag += self._sum.get_fragment() + for port in self.ports: + frag += port.get_fragment() + comb+= [self.dat.eq(self.in_dat)] + + #Connect Registers + for i in range(len(self.ports)): + if isinstance(self.ports[i],Term): + comb += [self.ports[i].t.eq(getattr(self,"_term_reg%d"%i).field.r[0:self.trig_width])] + elif isinstance(self.ports[i],EdgeDetector): + comb += [self.ports[i].r_mask.eq(getattr(self,"_edge_reg%d"%i).field.r[0:1*self.trig_width])] + comb += [self.ports[i].f_mask.eq(getattr(self,"_edge_reg%d"%i).field.r[1*self.trig_width:2*self.trig_width])] + comb += [self.ports[i].b_mask.eq(getattr(self,"_edge_reg%d"%i).field.r[2*self.trig_width:3*self.trig_width])] + elif isinstance(self.ports[i],RangeDetector): + comb += [self.ports[i].low.eq(getattr(self,"_range_reg%d"%i).field.r[0:1*self.trig_width])] + comb += [self.ports[i].high.eq(getattr(self,"_range_reg%d"%i).field.r[1*self.trig_width:2*self.trig_width])] + + comb += [ + self._sum.prog_adr.eq(self._sum_reg.field.r[0:16]), + self._sum.prog_dat.eq(self._sum_reg.field.r[16]), + self._sum.prog.eq(self._sum_reg.field.r[17]) + ] + return frag + Fragment(comb=comb, sync=sync) diff --git a/sim/tb_TriggerCsr.py b/sim/tb_TriggerCsr.py index 7356bfc1..3bf02785 100644 --- a/sim/tb_TriggerCsr.py +++ b/sim/tb_TriggerCsr.py @@ -7,7 +7,8 @@ from migen.bus.transactions import * import sys sys.path.append("../") -import migScope + +from migScope import trigger from migScope.tools.truthtable import * @@ -67,11 +68,11 @@ def main(): csr_master0 = csr.Initiator(csr_transactions()) # Trigger - term0 = migScope.Term(32) - term1 = migScope.Term(32) - term2 = migScope.Term(32) - term3 = migScope.Term(32) - trigger0 = migScope.Trigger(0, 32, 64, [term0, term1, term2, term3]) + term0 = trigger.Term(32) + term1 = trigger.Term(32) + term2 = trigger.Term(32) + term3 = trigger.Term(32) + trigger0 = trigger.Trigger(0, 32, 64, [term0, term1, term2, term3]) # Csr Interconnect csrcon0 = csr.Interconnect(csr_master0.bus, diff --git a/top.py b/top.py index d731a958..d6c662f8 100644 --- a/top.py +++ b/top.py @@ -5,7 +5,9 @@ from migen.fhdl.structure import * from migen.fhdl import verilog, autofragment from migen.bus import csr -import migScope +from migScope import trigger +from migScope import recorder + import spi2Csr from migScope.tools.truthtable import * @@ -13,76 +15,69 @@ from migScope.tools.truthtable import * # #Test Term # -#term = migScope.Term(32,True) +#term = trigger.Term(32,True) #v = verilog.convert(term.get_fragment()) #print(v) # #Test RangeDetector # -#rangeDetector = migScope.RangeDetector (32,True) +#rangeDetector = trigger.RangeDetector (32,True) #v = verilog.convert(rangeDetector.get_fragment()) #print(v) # #Test EdgeDetector # -#edgeDetector = migScope.EdgeDetector (32,True,"RFB") +#edgeDetector = trigger.EdgeDetector (32,True,"RFB") #v = verilog.convert(edgeDetector.get_fragment()) #print(v) # #Test Timer # -#timer = migScope.Timer(32) +#timer = trigger.Timer(32) #v = verilog.convert(timer.get_fragment()) #print(v) # #Test Sum # -#sum = migScope.Sum(4,pipe=False) +#sum = trigger.Sum(4,pipe=False) #v = verilog.convert(sum.get_fragment()) #print(v) -# -#Test MigIo -# -#migIo = migScope.MigIo(32,"IO") -#v = verilog.convert(migIo.get_fragment()) -#print(v) - # #Test Storage # -#storage = migScope.Storage(32,1024) +#storage = recorder.Storage(32,1024) #v = verilog.convert(storage.get_fragment()) #print(v) # #Test Sequencer # -#sequencer = migScope.Sequencer(1024) +#sequencer = recorder.Sequencer(1024) #v = verilog.convert(sequencer.get_fragment()) #print(v) # #Test Recorder # -#recorder = migScope.Recorder(0,32,1024) +#recorder = recorder.Recorder(0,32,1024) #v = verilog.convert(recorder.get_fragment()) #print(v) # #Test Trigger # -term0 = migScope.Term(32) -term1 = migScope.RangeDetector(32) -term2 = migScope.EdgeDetector(32) -term3 = migScope.Term(32) +term0 = trigger.Term(32) +term1 = trigger.RangeDetector(32) +term2 = trigger.EdgeDetector(32) +term3 = trigger.Term(32) -trigger0 = migScope.Trigger(0,32,64,[term0, term1, term2, term3]) -recorder0 = migScope.Recorder(0,32,1024) +trigger0 = trigger.Trigger(0,32,64,[term0, term1, term2, term3]) +recorder0 = recorder.Recorder(0,32,1024) v = verilog.convert(trigger0.get_fragment()+recorder0.get_fragment()) print(v) -- 2.30.2