From 5bda9b7febd07522ace3bdca6e3106b858ff31b8 Mon Sep 17 00:00:00 2001
From: dspitzba <daniel.spitzbart@cern.ch>
Date: Wed, 1 Mar 2023 14:03:10 -0500
Subject: [PATCH 1/5] fifo debugging

---
 tamalero/ETROC.py |  4 +++-
 tamalero/FIFO.py  | 12 +++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/tamalero/ETROC.py b/tamalero/ETROC.py
index a128ac0..018c315 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 697dbac..531e469 100644
--- a/tamalero/FIFO.py
+++ b/tamalero/FIFO.py
@@ -19,14 +19,19 @@ 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
     if len(res) > 0:
-        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]])
+        # NOTE: this is a dangerous solution for when the byte order in the FIFO is shifted.
+        if res[1] < res[0]:
+            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 list (np.array(res[1::2])[:len_cut][empty_frame_mask[:len_cut]] | (np.array(res[0::2]) << 32)[:len_cut][empty_frame_mask[:len_cut]])
     else:
         return []
 
 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()
@@ -81,7 +86,8 @@ class FIFO:
             last_block = occupancy % self.block
             data = []
             if (num_blocks_to_read):
-                reads = num_blocks_to_read * [self.read_block(self.block)] + [self.read_block(last_block)]
+                reads = [self.read_block(self.block)]
+                #reads = num_blocks_to_read * [self.read_block(self.block)] + [self.read_block(last_block)]
                 self.rb.kcu.hw.dispatch()
                 for read in reads:
                     data += read.value()
-- 
GitLab


From dc39d344837c6762fe3563e6eba1176a9199a3cc Mon Sep 17 00:00:00 2001
From: dspitzba <daniel.spitzbart@cern.ch>
Date: Wed, 1 Mar 2023 15:45:22 -0500
Subject: [PATCH 2/5] debugging features

---
 configs/dataformat.yaml | 18 ++++++++++++++++++
 tamalero/FIFO.py        | 18 ++++++++++++++++--
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/configs/dataformat.yaml b/configs/dataformat.yaml
index 11d78b1..4b4b3f9 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/FIFO.py b/tamalero/FIFO.py
index 531e469..00b48d5 100644
--- a/tamalero/FIFO.py
+++ b/tamalero/FIFO.py
@@ -40,8 +40,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):
@@ -67,6 +74,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:
-- 
GitLab


From 0cc1ee6e0c00b77ff5a2683581f5856566be3da4 Mon Sep 17 00:00:00 2001
From: dspitzba <daniel.spitzbart@cern.ch>
Date: Wed, 1 Mar 2023 17:29:09 -0500
Subject: [PATCH 3/5] get trigger rate function

---
 tamalero/FIFO.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tamalero/FIFO.py b/tamalero/FIFO.py
index 00b48d5..81f4d2c 100644
--- a/tamalero/FIFO.py
+++ b/tamalero/FIFO.py
@@ -64,6 +64,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
 
-- 
GitLab


From 22bdeb9bc87ee810b0befe2724fb132fddab4700 Mon Sep 17 00:00:00 2001
From: dspitzba <daniel.spitzbart@cern.ch>
Date: Wed, 1 Mar 2023 17:33:26 -0500
Subject: [PATCH 4/5] stupid test reverted. should have never been comitted

---
 tamalero/FIFO.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tamalero/FIFO.py b/tamalero/FIFO.py
index 81f4d2c..d9aee2f 100644
--- a/tamalero/FIFO.py
+++ b/tamalero/FIFO.py
@@ -103,8 +103,7 @@ class FIFO:
             last_block = occupancy % self.block
             data = []
             if (num_blocks_to_read):
-                reads = [self.read_block(self.block)]
-                #reads = num_blocks_to_read * [self.read_block(self.block)] + [self.read_block(last_block)]
+                reads = num_blocks_to_read * [self.read_block(self.block)] + [self.read_block(last_block)]
                 self.rb.kcu.hw.dispatch()
                 for read in reads:
                     data += read.value()
-- 
GitLab


From 874c452e8531b6e85aca790c1f674589086f7e48 Mon Sep 17 00:00:00 2001
From: dspitzba <daniel.spitzbart@cern.ch>
Date: Thu, 2 Mar 2023 14:15:19 -0500
Subject: [PATCH 5/5] adding proper offset in merge_words function

---
 tamalero/FIFO.py | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/tamalero/FIFO.py b/tamalero/FIFO.py
index d9aee2f..a38b784 100644
--- a/tamalero/FIFO.py
+++ b/tamalero/FIFO.py
@@ -16,14 +16,19 @@ 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:
-        # NOTE: this is a dangerous solution for when the byte order in the FIFO is shifted.
-        if res[1] < res[0]:
-            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 list (np.array(res[1::2])[:len_cut][empty_frame_mask[:len_cut]] | (np.array(res[0::2]) << 32)[:len_cut][empty_frame_mask[:len_cut]])
+        # 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 []
 
-- 
GitLab