From ba2b667cc6035db1c6091f4e640e4956fb75c24f Mon Sep 17 00:00:00 2001 From: dspitzba <daniel.spitzbart@cern.ch> Date: Thu, 3 Mar 2022 14:28:17 -0500 Subject: [PATCH] find uplink alignment in ETROC emulator mode and FIFO debugging --- configs/uplink_alignment_RB02_data.yaml | 102 ++++++++++++++++++++++++ tamalero/FIFO.py | 23 ++++-- tamalero/ReadoutBoard.py | 84 ++++++++++++++----- test_tamalero.py | 4 +- 4 files changed, 183 insertions(+), 30 deletions(-) create mode 100644 configs/uplink_alignment_RB02_data.yaml diff --git a/configs/uplink_alignment_RB02_data.yaml b/configs/uplink_alignment_RB02_data.yaml new file mode 100644 index 0000000..09cda01 --- /dev/null +++ b/configs/uplink_alignment_RB02_data.yaml @@ -0,0 +1,102 @@ +daq: + alignment: + 0: 0 + 1: 0 + 2: 0 + 3: 0 + 4: 0 + 5: 0 + 6: 4 + 7: 0 + 8: 0 + 9: 0 + 10: 3 + 11: 0 + 12: 0 + 13: 0 + 14: 0 + 15: 0 + 16: 0 + 17: 0 + 18: 0 + 19: 0 + 20: 0 + 21: 0 + 22: 0 + 23: 0 + inversion: + 0: 0 + 1: 0 + 2: 0 + 3: 0 + 4: 0 + 5: 0 + 6: 1 + 7: 0 + 8: 0 + 9: 0 + 10: 0 + 11: 0 + 12: 0 + 13: 0 + 14: 0 + 15: 0 + 16: 0 + 17: 0 + 18: 0 + 19: 0 + 20: 0 + 21: 0 + 22: 0 + 23: 0 +trigger: + alignment: + 0: 0 + 1: 0 + 2: 0 + 3: 0 + 4: 0 + 5: 0 + 6: 0 + 7: 0 + 8: 0 + 9: 0 + 10: 0 + 11: 0 + 12: 0 + 13: 0 + 14: 0 + 15: 0 + 16: 0 + 17: 0 + 18: 0 + 19: 0 + 20: 0 + 21: 0 + 22: 0 + 23: 0 + inversion: + 0: 0 + 1: 0 + 2: 0 + 3: 0 + 4: 0 + 5: 0 + 6: 0 + 7: 0 + 8: 0 + 9: 0 + 10: 0 + 11: 0 + 12: 0 + 13: 0 + 14: 0 + 15: 0 + 16: 0 + 17: 0 + 18: 0 + 19: 0 + 20: 0 + 21: 0 + 22: 0 + 23: 0 diff --git a/tamalero/FIFO.py b/tamalero/FIFO.py index 8663ec5..6488c91 100644 --- a/tamalero/FIFO.py +++ b/tamalero/FIFO.py @@ -12,6 +12,10 @@ class FIFO: def __init__(self, rb, elink=0, ETROC='ETROC1'): self.rb = rb self.rb.kcu.write_node("READOUT_BOARD_%s.FIFO_ELINK_SEL"%self.rb.rb, elink) + self.rb.kcu.write_node("READOUT_BOARD_%s.LPGBT.DAQ.DOWNLINK.DL_SRC"%self.rb.rb, 3) + self.rb.kcu.write_node("READOUT_BOARD_%s.LPGBT.DAQ.DOWNLINK.FAST_CMD_IDLE"%self.rb.rb, 0xC1) + self.rb.kcu.write_node("READOUT_BOARD_%s.LPGBT.DAQ.DOWNLINK.FAST_CMD_DATA"%self.rb.rb, 0xC5) + self.rb.kcu.write_node("READOUT_BOARD_%s.FIFO_TRIG0"%self.rb.rb, 0x00) self.rb.kcu.write_node("READOUT_BOARD_%s.FIFO_TRIG0_MASK"%self.rb.rb, 0x00) @@ -39,15 +43,18 @@ class FIFO: #self.rb.kcu.write_node("READOUT_BOARD_%s.FIFO_FORCE_TRIG" % self.rb.rb, 1) def dump(self, block=255): - # make sure the fifo is not empty - #while (self.rb.kcu.read_node("READOUT_BOARD_%s.FIFO_EMPTY"%self.rb.rb)): - # print(self.rb.kcu.read_node("READOUT_BOARD_%s.FIFO_ARMED"%self.rb.rb)) - # pass - self.rb.kcu.hw.dispatch() + self.rb.kcu.write_node("READOUT_BOARD_%s.LPGBT.DAQ.DOWNLINK.FAST_CMD_PULSE"%self.rb.rb, 0x01) # FIXME confirm this + for i in range(10): + if self.rb.kcu.read_node("READOUT_BOARD_%s.FIFO_EMPTY"%self.rb.rb).value() < 1: break res = self.rb.kcu.hw.getNode("DAQ_0.FIFO").readBlock(block) - self.rb.kcu.hw.dispatch() - hex_dump = [ '{0:0{1}x}'.format(r,2) for r in res.value() ] - return hex_dump + try: + self.rb.kcu.hw.dispatch() + hex_dump = [ '{0:0{1}x}'.format(r,2) for r in res.value() ] + return hex_dump + except: + # NOTE: not entirely understood, but it seems this happens if FIFO is (suddenly?) empty + return [] + def giant_dump(self, block=3000, subblock=255): res = [] diff --git a/tamalero/ReadoutBoard.py b/tamalero/ReadoutBoard.py index dd9b183..80f03c3 100644 --- a/tamalero/ReadoutBoard.py +++ b/tamalero/ReadoutBoard.py @@ -1,7 +1,7 @@ import os from tamalero.LPGBT import LPGBT from tamalero.SCA import SCA -from tamalero.utils import get_temp +from tamalero.utils import get_temp, chunk from tamalero.VTRX import VTRX from time import sleep @@ -76,7 +76,7 @@ class ReadoutBoard: self.DAQ_LPGBT.set_gpio(bit, 0) self.DAQ_LPGBT.set_gpio(bit, 1) - def find_uplink_alignment(self, scan_time=0.01, default=0): # default scan time of 0.01 is enough + def find_uplink_alignment(self, scan_time=0.01, default=0, data_mode=False): # default scan time of 0.01 is enough # TODO: check the FEC mode and set the number of links appropriately n_links = 24 # NOTE: there are 28 e-links if the board is in FEC5 mode, but we are operating in FEC12 where there are only 24 print ("Scanning for uplink alignment") @@ -90,25 +90,41 @@ class ReadoutBoard: # TODO: the scan should check the pattern checkers first, and skip the scan for any where the pattern check is already ok # now, scan - for inv in [False, True]: - for shift in range(8): - for channel in range(n_links): - self.DAQ_LPGBT.set_uplink_alignment(channel, shift, quiet=True) - self.DAQ_LPGBT.set_uplink_invert(channel, inv) - if self.trigger: - self.TRIG_LPGBT.set_uplink_alignment(channel, shift, quiet=True) - self.TRIG_LPGBT.set_uplink_invert(channel, inv) - self.DAQ_LPGBT.set_uplink_group_data_source("normal") # actually needed?? - self.DAQ_LPGBT.set_downlink_data_src('upcnt') - self.DAQ_LPGBT.reset_pattern_checkers() - sleep(scan_time) - res = self.DAQ_LPGBT.read_pattern_checkers(log_dir=None, quiet=True) - for link in ['Link 0', 'Link 1']: - for channel in range(n_links): - if res[link]['UPCNT'][channel]['error'][0] == 0: - print ("Found uplink alignment for %s, channel %s: %s, inverted: %s"%(link, channel, shift, inv==0x0a)) + if data_mode: + link = 'Link 0' + for channel in range(n_links): + res = 0 + for inv in [False, True]: + for shift in range(8): + self.DAQ_LPGBT.set_uplink_alignment(channel, shift, quiet=True) + self.DAQ_LPGBT.set_uplink_invert(channel, inv) + tmp = self.check_data_integrity(channel=channel) + if tmp>res: + print ("Found improved uplink alignment for %s, channel %s: %s, inverted: %s"%(link, channel, shift, inv)) + print (tmp, res) alignment[link][channel] = shift inversion[link][channel] = inv + res = tmp + else: + for inv in [False, True]: + for shift in range(8): + for channel in range(n_links): + self.DAQ_LPGBT.set_uplink_alignment(channel, shift, quiet=True) + self.DAQ_LPGBT.set_uplink_invert(channel, inv) + if self.trigger: + self.TRIG_LPGBT.set_uplink_alignment(channel, shift, quiet=True) + self.TRIG_LPGBT.set_uplink_invert(channel, inv) + self.DAQ_LPGBT.set_uplink_group_data_source("normal") # actually needed?? + self.DAQ_LPGBT.set_downlink_data_src('upcnt') + self.DAQ_LPGBT.reset_pattern_checkers() + sleep(scan_time) + res = self.DAQ_LPGBT.read_pattern_checkers(log_dir=None, quiet=True) + for link in ['Link 0', 'Link 1']: + for channel in range(n_links): + if res[link]['UPCNT'][channel]['error'][0] == 0: + print ("Found uplink alignment for %s, channel %s: %s, inverted: %s"%(link, channel, shift, inv)) + alignment[link][channel] = shift + inversion[link][channel] = inv # Reset alignment to default values for the channels where no good alignment has been found print ("Now setting uplink alignment to optimal values (default values if no good alignment was found)") @@ -163,6 +179,32 @@ class ReadoutBoard: self.kcu.print_reg(self.kcu.hw.getNode("READOUT_BOARD_%s.LPGBT.TRIGGER.UPLINK.READY" % self.rb), use_color=True) self.kcu.print_reg(self.kcu.hw.getNode("READOUT_BOARD_%s.LPGBT.TRIGGER.UPLINK.FEC_ERR_CNT" % self.rb), use_color=True, invert=True) + def check_data_integrity(self, channel=0): + ''' + Not sure where this function should live. + It's not necessarily a part of the RB. + FIXME: Needs to become transparent to the data format. + ''' + from tamalero.FIFO import FIFO + fifo = FIFO(self, elink=channel) + fifo.set_trigger(word0=0x35, word1=0x55, mask0=0xff, mask1=0xff) + fifo.reset() + n_header = 0 + n_trailer = 0 + data = [] + for i in range(10): + data += ['35', '55'] + fifo.giant_dump(3000) # + ['35', '55'] + fifo.giant_dump(3000) + fifo.reset() + + long_st = ''.join(data) + for line in chunk(data, 5): + n_header += (line[0:3] == ['35','55','55']) + n_trailer += (line[0:3] == ['95','55','55']) + + #print (n_header, n_trailer) + return n_header + n_trailer + + def get_FEC_error_count(self, quiet=False): if not quiet: print("{:<8}{:<8}{:<50}{:<8}".format("Address", "Perm.", "Name", "Value")) @@ -182,7 +224,7 @@ class ReadoutBoard: print("Error counts after reset:") self.get_FEC_error_count() - def configure(self, alignment=None): + def configure(self, alignment=None, data_mode=False): ## DAQ #for i in range(28): @@ -207,7 +249,7 @@ class ReadoutBoard: if alignment is not None: self.load_uplink_alignment(alignment) else: - _ = self.find_uplink_alignment() + _ = self.find_uplink_alignment(data_mode=data_mode) # SCA init self.sca_hard_reset() diff --git a/test_tamalero.py b/test_tamalero.py index 11bfd53..a481922 100644 --- a/test_tamalero.py +++ b/test_tamalero.py @@ -31,6 +31,8 @@ if __name__ == '__main__': header() + if args.read_fifo: data_mode = True + print ("Using KCU at address: %s"%args.kcu) kcu = KCU(name="my_device", @@ -74,7 +76,7 @@ if __name__ == '__main__': alignment = load_alignment_from_file(args.load_alignment) else: alignment = None - rb_0.configure(alignment=alignment) # this is very slow, especially for the trigger lpGBT. + rb_0.configure(alignment=alignment, data_mode=data_mode) # this is very slow, especially for the trigger lpGBT. if rb_0.trigger: rb_0.DAQ_LPGBT.reset_trigger_mgts() time.sleep(1.0) -- GitLab