diff --git a/configs/dataformat.yaml b/configs/dataformat.yaml index 11d78b1c938ccf4590971e6188890a53c9a85928..4b4b3f9467ba43e88db9f7b714d8c4cf1d627545 100644 --- a/configs/dataformat.yaml +++ b/configs/dataformat.yaml @@ -196,6 +196,24 @@ ETROC2: mask: 0x00000000FF shift: 0 filler: + elink: + mask: 0xFF0000000000 + shift: 40 + sof: + mask: 0x1000000000000 + shift: 48 + eof: + mask: 0x2000000000000 + shift: 49 + full: + mask: 0x4000000000000 + shift: 50 + any_full: + mask: 0x8000000000000 + shift: 51 + global_full: + mask: 0xF0000000000000 + shift: 52 l1counter: mask: 0x00003FC000 shift: 14 diff --git a/tamalero/ETROC.py b/tamalero/ETROC.py index a128ac0e23a05e758b8ceae073deb7b6811cffd6..018c3159a388a1fe2d084ac4ac378abe30ce60d4 100644 --- a/tamalero/ETROC.py +++ b/tamalero/ETROC.py @@ -22,6 +22,7 @@ class ETROC(): elink=0, usefake=False, verbose=False, + strict=True, ): self.usefake = usefake if usefake: @@ -64,7 +65,8 @@ class ETROC(): print("Warning: ETROC default configuration failed!") pass - self.consistency(verbose=verbose) + if strict: + self.consistency(verbose=verbose) # ========================= # === UTILITY FUNCTIONS === diff --git a/tamalero/FIFO.py b/tamalero/FIFO.py index 697dbac3fa7071ae0b56fabc2e7e03d772d6bd9a..a38b78469bf6d52054fca170a7cffe7f42d2ab9b 100644 --- a/tamalero/FIFO.py +++ b/tamalero/FIFO.py @@ -16,9 +16,18 @@ def revbits(x): return int(f'{x:08b}'[::-1],2) def merge_words(res): - empty_frame_mask = np.array(res[0::2]) > (2**8) # masking empty fifo entries - len_cut = min(len(res[0::2]), len(res[1::2])) # ensuring equal length of arrays downstream + ''' + this function merges 32 bit words from the fifo into 64 bit words (40bit ETROC2 + added meta data in the DAQ) + it strips empty entries and removes orphan 32 bit words that could be present at the end of a FIFO read + ''' if len(res) > 0: + # offset is only needed when zero suppression is turned off, and packet boundaries are not defined + # it relies on the fact that the second 32 bit word is half empty (8 bit ETROC data + 12 bits meta data) + # if we ever add more meta data this has to be revisited + offset = 1 if (res[1] > res[0]) else 0 + res = res[offset:] + empty_frame_mask = np.array(res[0::2]) > (2**8) # masking empty fifo entries + len_cut = min(len(res[0::2]), len(res[1::2])) # ensuring equal length of arrays downstream return list (np.array(res[0::2])[:len_cut][empty_frame_mask[:len_cut]] | (np.array(res[1::2]) << 32)[:len_cut][empty_frame_mask[:len_cut]]) else: return [] @@ -26,7 +35,8 @@ def merge_words(res): class FIFO: def __init__(self, rb, block=255): self.rb = rb - self.block = 255 + self.block = block + self.reset() def get_zero_suppress_status(self): return self.rb.kcu.read_node("READOUT_BOARD_%s.ZERO_SUPRESS"%self.rb.rb).value() @@ -35,8 +45,15 @@ class FIFO: self.rb.kcu.write_node("READOUT_BOARD_%s.ZERO_SUPRESS"%self.rb.rb, 0xfffffff) self.reset() - def disable_zero_surpress(self): - self.rb.kcu.write_node("READOUT_BOARD_%s.ZERO_SUPRESS"%self.rb.rb, 0x0) + def disable_zero_surpress(self, only=None): + ''' + turn off zero suppression for all channels + use only if you only want to disable zero suppression for one elink + ''' + if only != None: + self.rb.kcu.write_node("READOUT_BOARD_%s.ZERO_SUPRESS"%self.rb.rb, 0xfffffff ^ (1 << only)) + else: + self.rb.kcu.write_node("READOUT_BOARD_%s.ZERO_SUPRESS"%self.rb.rb, 0x0) self.reset() def use_fixed_pattern(self): @@ -52,6 +69,9 @@ class FIFO: rate_setting = rate / 25E-9 / (0xffffffff) * 10000 self.rb.kcu.write_node("SYSTEM.L1A_RATE", int(rate_setting)) time.sleep(0.5) + return self.get_trigger_rate() + + def get_trigger_rate(self): rate = self.rb.kcu.read_node("SYSTEM.L1A_RATE_CNT").value() return rate @@ -62,6 +82,13 @@ class FIFO: def reset(self): self.rb.kcu.write_node("READOUT_BOARD_%s.FIFO_RESET" % self.rb.rb, 0x01) + def select_elink(self, elink, lpgbt=0): + ''' + only needed for ILA debugging + ''' + self.rb.kcu.write_node("READOUT_BOARD_%s.FIFO_ELINK_SEL0" % self.rb.rb, elink) + self.rb.kcu.write_node("READOUT_BOARD_%s.FIFO_LPGBT_SEL0" % self.rb.rb, lpgbt) + def read_block(self, block, dispatch=False): try: if dispatch: