def me0_elink_scan(system, oh_select, vfat_list): print("ME0 Elink Scan") n_err_vfat_elink = {} for vfat in vfat_list: # Loop over all vfats n_err_vfat_elink[vfat] = {} for elink in range(0, 28): # Loop for all 28 RX elinks print("VFAT%02d , ELINK %02d" % (vfat, elink)) # Disable RX elink under test setVfatRxEnable(system, oh_select, vfat, 0, elink) # Reset the link, give some time to accumulate any sync errors and then check VFAT comms sleep(0.1) gem_utils.gem_link_reset() sleep(0.001) gbt, gbt_select, elink_old, gpio = gem_utils.me0_vfat_to_gbt_elink_gpio( vfat) oh_ver = get_oh_ver(oh_select, gbt_select) gem_utils.check_gbt_link_ready(oh_select, gbt_select) hwid_node = gem_utils.get_backend_node( "BEFE.GEM.OH.OH%d.GEB.VFAT%d.HW_ID" % (oh_select, vfat)) n_err = 0 for iread in range(10): hwid = gem_utils.simple_read_backend_reg(hwid_node, -9999) if hwid == -9999: n_err += 1 n_err_vfat_elink[vfat][elink] = n_err setVfatRxEnable(system, oh_select, vfat, 1, elink) print("") sleep(0.1) gem_utils.gem_link_reset() print("Elink mapping results: \n") for vfat in vfat_list: for elink in range(0, 28): sys.stdout.write("VFAT%02d , ELINK %02d:" % (vfat, elink)) if n_err_vfat_elink[vfat][elink] == 10: char = Colors.GREEN + "+\n" + Colors.ENDC else: char = Colors.RED + "-\n" + Colors.ENDC sys.stdout.write("%s" % char) sys.stdout.flush() print("")
def gbt_phase_scan(gem, system, oh_select, daq_err, vfat_list, depth, bestphase_list): print("ME0 Phase Scan depth=%s transactions" % (str(depth))) if bestphase_list != {}: print("Setting phases for VFATs only, not scanning") for vfat in vfat_list: set_bestphase = bestphase_list[vfat] setVfatRxPhase(system, oh_select, vfat, set_bestphase) print("Phase set for VFAT#%02d to: %s" % (vfat, hex(set_bestphase))) return resultDir = "results" try: os.makedirs(resultDir) # create directory for results except FileExistsError: # skip if directory already exists pass vfatDir = "results/vfat_data" try: os.makedirs(vfatDir) # create directory for VFAT data except FileExistsError: # skip if directory already exists pass dataDir = "results/vfat_data/vfat_phase_scan_results" try: os.makedirs(dataDir) # create directory for data except FileExistsError: # skip if directory already exists pass now = str(datetime.datetime.now())[:16] now = now.replace(":", "_") now = now.replace(" ", "_") filename = dataDir + "/%s_OH%d_vfat_phase_scan_results_" % ( gem, oh_select) + now + ".txt" file_out = open(filename, "w") filename_data = dataDir + "/%s_OH%d_vfat_phase_scan_data_" % ( gem, oh_select) + now + ".txt" file_out_data = open(filename_data, "w") file_out.write("vfat phase\n") link_good = [[0 for phase in range(16)] for vfat in range(24)] sync_err_cnt = [[0 for phase in range(16)] for vfat in range(24)] cfg_run = [[0 for phase in range(16)] for vfat in range(24)] daq_crc_error = [[0 for phase in range(16)] for vfat in range(24)] errs = [[0 for phase in range(16)] for vfat in range(24)] gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 0) for vfat in vfat_list: gbt, gbt_select, elink, gpio = gem_utils.me0_vfat_to_gbt_elink_gpio( vfat) oh_ver = get_oh_ver(oh_select, gbt_select) gem_utils.check_gbt_link_ready(oh_select, gbt_select) #print("Configuring VFAT %d" % (vfat)) #hwid_node = gem_utils.get_backend_node("BEFE.GEM.OH.OH%d.GEB.VFAT%d.HW_ID" % (oh_select, vfat)) #output = gem_utils.simple_read_backend_reg(hwid_node, -9999) #if output == -9999: # setVfatRxPhase(system, oh_select, vfat, 6) # output = simple_read_backend_reg(hwid_node, -9999) # if output == -9999: # setVfatRxPhase(system, oh_select, vfat, 12) # output = gem_utils.simple_read_backend_reg(hwid_node, -9999) # if output == -9999: # setVfatRxPhase(system, oh_select, vfat, 0) # print (Colors.RED + "Cannot configure VFAT %d"%(vfat) + Colors.ENDC) # terminate() #configureVfat(1, vfat, oh_select, 0) #for i in range(128): # enableVfatchannel(vfat, oh_select, i, 0, 0) # unmask all channels and disable calpulsing #gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_RUN"%(oh_select,vfat)), 0) # Configure TTC Generator gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.RESET"), 1) gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE"), 1) gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_L1A_GAP"), 500) # 80 kHz gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.CYCLIC_CALPULSE_TO_L1A_GAP"), 0) # Disable Calpulse gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_L1A_COUNT"), 10000) cyclic_running_node = gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.CYCLIC_RUNNING") for phase in range(0, 16): print("Scanning phase %d" % phase) # set phases for all vfats under test for vfat in vfat_list: setVfatRxPhase(system, oh_select, vfat, phase) # read cfg_run some number of times, check link good status and sync errors print("Checking errors: ") for vfat in vfat_list: gbt, gbt_select, elink, gpio = gem_utils.me0_vfat_to_gbt_elink_gpio( vfat) oh_ver = get_oh_ver(oh_select, gbt_select) # Reset the link, give some time to accumulate any sync errors and then check VFAT comms sleep(0.1) gem_utils.gem_link_reset() sleep(0.1) # Check Slow Control cfg_node = gem_utils.get_backend_node( "BEFE.GEM.OH.OH%d.GEB.VFAT%d.CFG_RUN" % (oh_select, vfat)) for iread in range(depth): vfat_cfg_run = gem_utils.simple_read_backend_reg( cfg_node, 9999) if vfat_cfg_run != 0 and vfat_cfg_run != 1: cfg_run[vfat][phase] = 1 break #cfg_run[vfat][phase] += (vfat_cfg_run != 0 and vfat_cfg_run != 1) # Check Link Good and Sync Errors link_node = gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.VFAT%d.LINK_GOOD" % (oh_select, vfat)) sync_node = gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.VFAT%d.SYNC_ERR_CNT" % (oh_select, vfat)) link_good[vfat][phase] = gem_utils.simple_read_backend_reg( link_node, 0) sync_err_cnt[vfat][phase] = gem_utils.simple_read_backend_reg( sync_node, 9999) daq_crc_error[vfat][phase] = -1 # Check DAQ event counter and CRC errors with L1A if link and slow control good if daq_err: if system == "dryrun" or (link_good[vfat][phase] == 1 and sync_err_cnt[vfat][phase] == 0 and cfg_run[vfat][phase] == 0): configureVfat(1, vfat, oh_select, 1) # configure VFAT with low threshold #write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_THR_ARM_DAC"%(oh_select,vfat)), 0) # low threshold for random data #write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_RUN"%(oh_select,vfat)), 1) for i in range(128): enableVfatchannel( vfat, oh_select, i, 0, 0) # unmask all channels and disable calpulsing # Send L1A to get DAQ events from VFATs gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.CYCLIC_START"), 1) cyclic_running = 1 while cyclic_running: cyclic_running = gem_utils.read_backend_reg( cyclic_running_node) daq_event_counter = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.VFAT%d.DAQ_EVENT_CNT" % (oh_select, vfat))) if system == "dryrun": daq_crc_error[vfat][phase] = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.VFAT%d.DAQ_CRC_ERROR_CNT" % (oh_select, vfat))) else: if daq_event_counter == 10000 % (2**16): daq_crc_error[vfat][ phase] = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.VFAT%d.DAQ_CRC_ERROR_CNT" % (oh_select, vfat))) else: print(Colors.YELLOW + "\tProblem with DAQ event counter=%d" % (daq_event_counter) + Colors.ENDC) configureVfat(0, vfat, oh_select, 0) # unconfigure VFAT #write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_RUN"%(oh_select,vfat)), 0) else: daq_crc_error[vfat][phase] = 0 result_str = "" if link_good[vfat][phase] == 1 and sync_err_cnt[vfat][ phase] == 0 and cfg_run[vfat][ phase] == 0 and daq_crc_error[vfat][phase] == 0: result_str += Colors.GREEN else: result_str += Colors.RED if daq_err: result_str += "\tResults of VFAT#%02d: link_good=%d, sync_err_cnt=%d, slow_control_bad=%d, daq_crc_errors=%d" % ( vfat, link_good[vfat][phase], sync_err_cnt[vfat][phase], cfg_run[vfat][phase], daq_crc_error[vfat][phase]) else: result_str += "\tResults of VFAT#%02d: link_good=%d, sync_err_cnt=%d, slow_control_bad=%d" % ( vfat, link_good[vfat][phase], sync_err_cnt[vfat][phase], cfg_run[vfat][phase]) result_str += Colors.ENDC print(result_str) gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.RESET"), 1) gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE"), 0) centers = 24 * [0] widths = 24 * [0] for vfat in vfat_list: for phase in range(0, 16): errs[vfat][phase] = (not link_good[vfat][phase] == 1) + ( not sync_err_cnt[vfat][phase] == 0) + (not cfg_run[vfat][phase] == 0) + (not daq_crc_error[vfat][phase] == 0) centers[vfat], widths[vfat] = find_phase_center(errs[vfat]) print("\nPhase Scan Results:") file_out_data.write("\nPhase Scan Results:\n") bestphase_vfat = 24 * [0] for vfat in vfat_list: phase_print = "VFAT%02d: " % (vfat) for phase in range(0, 16): if (widths[vfat] > 0 and phase == centers[vfat]): char = Colors.GREEN + "+" + Colors.ENDC bestphase_vfat[vfat] = phase elif (errs[vfat][phase]): char = Colors.RED + "-" + Colors.ENDC else: char = Colors.YELLOW + "x" + Colors.ENDC phase_print += "%s" % char if widths[vfat] < 3: phase_print += Colors.RED + " (center=%d, width=%d) BAD" % ( centers[vfat], widths[vfat]) + Colors.ENDC elif widths[vfat] < 5: phase_print += Colors.YELLOW + " (center=%d, width=%d) WARNING" % ( centers[vfat], widths[vfat]) + Colors.ENDC else: phase_print += Colors.GREEN + " (center=%d, width=%d) GOOD" % ( centers[vfat], widths[vfat]) + Colors.ENDC print(phase_print) file_out_data.write(phase_print + "\n") # set phases for all vfats under test print("\nSetting all VFAT phases to best phases: ") for vfat in vfat_list: set_bestphase = bestphase_vfat[vfat] setVfatRxPhase(system, oh_select, vfat, set_bestphase) print("Phase set for VFAT#%02d to: %s" % (vfat, hex(set_bestphase))) for vfat in range(0, 24): file_out.write("%d 0x%x\n" % (vfat, bestphase_vfat[vfat])) sleep(0.1) gem_utils.gem_link_reset() print("") file_out.close() file_out_data.close()
def main(system, oh_select, gbt_list, relay_number, niter): if sys.version_info[0] < 3: raise Exception("Python version 3.x required") relay_object = ethernet_relay.ethernet_relay() connect_status = relay_object.connectToDevice() if not connect_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() # Get first list of registers to compare print( "Turning on power and getting initial list of registers and turning off power" ) set_status = relay_object.relay_set(relay_number, 1) if not set_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() read_status = relay_object.relay_read(relay_number) if not read_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() sleep(10) reg_list_boss = {} reg_list_sub = {} n_rw_reg = 0 for gbt in gbt_list["boss"]: reg_list_boss[gbt] = {} oh_ver = get_oh_ver(str(oh_select), str(gbt)) if oh_ver == 1: n_rw_reg = (0x13C + 1) if oh_ver == 2: n_rw_reg = (0x14F + 1) select_ic_link(oh_select, gbt) for reg in range(n_rw_reg): reg_list_boss[gbt][reg] = mpeek(reg) for gbt in gbt_list["sub"]: reg_list_sub[gbt] = {} oh_ver = get_oh_ver(str(oh_select), str(gbt)) select_ic_link(oh_select, gbt) if oh_ver == 1: for i in range(0, 10): test_read = mpeek(0x00) n_rw_reg = (0x13C + 1) if oh_ver == 2: n_rw_reg = (0x14F + 1) for reg in range(n_rw_reg): reg_list_sub[gbt][reg] = mpeek(reg) set_status = relay_object.relay_set(relay_number, 0) if not set_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() read_status = relay_object.relay_read(relay_number) if not read_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() sleep(10) n_error_backend_ready_boss = {} n_error_backend_ready_sub = {} n_error_uplink_fec_boss = {} n_error_uplink_fec_sub = {} n_error_pusm_ready_boss = {} n_error_pusm_ready_sub = {} n_error_mode_boss = {} n_error_mode_sub = {} n_error_reg_list_boss = {} n_error_reg_list_sub = {} for gbt in gbt_list["boss"]: n_error_backend_ready_boss[gbt] = 0 n_error_uplink_fec_boss[gbt] = 0 n_error_pusm_ready_boss[gbt] = 0 n_error_mode_boss[gbt] = 0 n_error_reg_list_boss[gbt] = 0 for gbt in gbt_list["sub"]: n_error_backend_ready_sub[gbt] = 0 n_error_uplink_fec_sub[gbt] = 0 n_error_pusm_ready_sub[gbt] = 0 n_error_mode_sub[gbt] = 0 n_error_reg_list_sub[gbt] = 0 print("Begin powercycle iteration\n") # Power cycle interations for n in range(0, niter): print("Iteration: %d\n" % (n + 1)) # Turn on relay set_status = relay_object.relay_set(relay_number, 1) if not set_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() read_status = relay_object.relay_read(relay_number) if not read_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() sleep(10) # Link reset gem_utils.gem_link_reset() sleep(2) # Check lpGBT status # Boss for gbt in gbt_list["boss"]: oh_ver = get_oh_ver(str(oh_select), str(gbt)) select_ic_link(oh_select, gbt) n_rw_reg = 0 print("Boss lpGBT %d: " % gbt) # Check Link Ready link_ready = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%s.GBT%s_READY" % (oh_select, gbt))) if (link_ready != 1): print(Colors.YELLOW + " Link NOT READY" + Colors.ENDC) n_error_backend_ready_boss[gbt] += 1 else: print(Colors.GREEN + " Link READY" + Colors.ENDC) # Check Uplink FEC Errors n_fec_errors = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.GBT%d_FEC_ERR_CNT" % (oh_select, gbt))) if n_fec_errors != 0: print(Colors.YELLOW + " FEC Errors: %d" % (n_fec_errors) + Colors.ENDC) n_error_uplink_fec_boss[gbt] += 1 else: print(Colors.GREEN + " No FEC Errors" + Colors.ENDC) # Check lpGBT PUSM READY and MODE if oh_ver == 1: ready_value = 18 mode_value = 11 mode = (mpeek(0x140) & 0xF0) >> 4 pusmstate = mpeek(0x1C7) elif oh_ver == 2: ready_value = 19 mode_value = 11 mode = (mpeek(0x150) & 0xF0) >> 4 pusmstate = mpeek(0x1D9) if mode != mode_value: n_error_mode_boss[gbt] += 1 print(Colors.YELLOW + " Incorrect mode: %d" % mode + Colors.ENDC) else: print(Colors.GREEN + " Correct mode: %d" % mode + Colors.ENDC) if pusmstate != ready_value: n_error_pusm_ready_boss[gbt] += 1 print(Colors.YELLOW + " Incorrect PUSM State: %d" % pusmstate + Colors.ENDC) else: print(Colors.GREEN + " Correct PUSM State: %d" % pusmstate + Colors.ENDC) # Check register list if oh_ver == 1: n_rw_reg = (0x13C + 1) if oh_ver == 2: n_rw_reg = (0x14F + 1) for reg in range(n_rw_reg): val = mpeek(reg) if val != reg_list_boss[gbt][reg]: n_error_reg_list_boss[gbt] += 1 print(Colors.YELLOW + " Register 0x%02X value mismatch" % reg + Colors.ENDC) # Sub for gbt in gbt_list["sub"]: oh_ver = get_oh_ver(str(oh_select), str(gbt)) select_ic_link(oh_select, gbt) n_rw_reg = 0 print("Sub lpGBT %d: " % gbt) # Check Link Ready link_ready = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%s.GBT%s_READY" % (oh_select, gbt))) if (link_ready != 1): print(Colors.YELLOW + " Link NOT READY" + Colors.ENDC) n_error_backend_ready_sub[gbt] += 1 else: print(Colors.GREEN + " Link READY" + Colors.ENDC) # Check Uplink FEC Errors n_fec_errors = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.GBT%d_FEC_ERR_CNT" % (oh_select, gbt))) if n_fec_errors != 0: print(Colors.YELLOW + " FEC Errors: %d" % (n_fec_errors) + Colors.ENDC) n_error_uplink_fec_sub[gbt] += 1 else: print(Colors.GREEN + " No FEC Errors" + Colors.ENDC) # Check lpGBT PUSM READY and MODE if oh_ver == 1: for i in range(0, 10): test_read = mpeek(0x00) ready_value = 18 mode_value = 9 mode = (mpeek(0x140) & 0xF0) >> 4 pusmstate = mpeek(0x1C7) elif oh_ver == 2: ready_value = 19 mode_value = 9 mode = (mpeek(0x150) & 0xF0) >> 4 pusmstate = mpeek(0x1D9) if mode != mode_value: n_error_mode_sub[gbt] += 1 print(Colors.YELLOW + " Incorrect mode: %d" % mode + Colors.ENDC) else: print(Colors.GREEN + " Correct mode: %d" % mode + Colors.ENDC) if pusmstate != ready_value: n_error_pusm_ready_sub[gbt] += 1 print(Colors.YELLOW + " Incorrect PUSM State: %d" % pusmstate + Colors.ENDC) else: print(Colors.GREEN + " Correct PUSM State: %d" % pusmstate + Colors.ENDC) # Check register list if oh_ver == 1: n_rw_reg = (0x13C + 1) if oh_ver == 2: n_rw_reg = (0x14F + 1) for reg in range(n_rw_reg): val = mpeek(reg) if val != reg_list_sub[gbt][reg]: n_error_reg_list_sub[gbt] += 1 print(Colors.YELLOW + " Register 0x%02X value mismatch" % reg + Colors.ENDC) print("") # Turn off relay set_status = relay_object.relay_set(relay_number, 0) if not set_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() read_status = relay_object.relay_read(relay_number) if not read_status: print(Colors.RED + "ERROR: Exiting" + Colors.ENDC) rw_terminate() sleep(10) # To allow power supply to ramp down print("\nEnd of powercycle iteration") print("Number of iterations: %d\n" % niter) # Results print("Result For lpGBTs: \n") for gbt in gbt_list["boss"]: print("Boss lpGBT %d: " % gbt) str_n_error_backend_ready_boss = "" str_n_error_uplink_fec_boss = "" str_n_error_mode_boss = "" str_n_error_pusm_ready_boss = "" str_n_error_reg_list_boss = "" if n_error_backend_ready_boss[gbt] == 0: str_n_error_backend_ready_boss += Colors.GREEN else: str_n_error_backend_ready_boss += Colors.YELLOW if n_error_uplink_fec_boss[gbt] == 0: str_n_error_uplink_fec_boss += Colors.GREEN else: str_n_error_uplink_fec_boss += Colors.YELLOW if n_error_mode_boss[gbt] == 0: str_n_error_mode_boss += Colors.GREEN else: str_n_error_mode_boss += Colors.YELLOW if n_error_pusm_ready_boss[gbt] == 0: str_n_error_pusm_ready_boss += Colors.GREEN else: str_n_error_pusm_ready_boss += Colors.YELLOW if n_error_reg_list_boss[gbt] == 0: str_n_error_reg_list_boss += Colors.GREEN else: str_n_error_reg_list_boss += Colors.YELLOW str_n_error_backend_ready_boss += " Number of Backend READY Status Errors: %d" % ( n_error_backend_ready_boss[gbt]) str_n_error_uplink_fec_boss += " Number of Powercycles with Uplink FEC Errors: %d" % n_error_uplink_fec_boss[ gbt] str_n_error_mode_boss += " Number of Mode Errors: %d" % n_error_mode_boss[ gbt] str_n_error_pusm_ready_boss += " Number of PUSMSTATE Errors: %d" % n_error_pusm_ready_boss[ gbt] str_n_error_reg_list_boss += " Number of Register Value Errors: %d" % n_error_reg_list_boss[ gbt] str_n_error_backend_ready_boss += Colors.ENDC str_n_error_uplink_fec_boss += Colors.ENDC str_n_error_mode_boss += Colors.ENDC str_n_error_pusm_ready_boss += Colors.ENDC str_n_error_reg_list_boss += Colors.ENDC print(str_n_error_backend_ready_boss) print(str_n_error_uplink_fec_boss) print(str_n_error_mode_boss) print(str_n_error_pusm_ready_boss) print(str_n_error_reg_list_boss) print("") for gbt in gbt_list["sub"]: print("Sub lpGBT %d: " % gbt) str_n_error_backend_ready_sub = "" str_n_error_uplink_fec_sub = "" str_n_error_mode_sub = "" str_n_error_pusm_ready_sub = "" str_n_error_reg_list_sub = "" if n_error_backend_ready_sub[gbt] == 0: str_n_error_backend_ready_sub += Colors.GREEN else: str_n_error_backend_ready_sub += Colors.YELLOW if n_error_uplink_fec_sub[gbt] == 0: str_n_error_uplink_fec_sub += Colors.GREEN else: str_n_error_uplink_fec_sub += Colors.YELLOW if n_error_mode_sub[gbt] == 0: str_n_error_mode_sub += Colors.GREEN else: str_n_error_mode_sub += Colors.YELLOW if n_error_pusm_ready_sub[gbt] == 0: str_n_error_pusm_ready_sub += Colors.GREEN else: str_n_error_pusm_ready_sub += Colors.YELLOW if n_error_reg_list_sub[gbt] == 0: str_n_error_reg_list_sub += Colors.GREEN else: str_n_error_reg_list_sub += Colors.YELLOW str_n_error_backend_ready_sub += " Number of Backend READY Status Errors: %d" % ( n_error_backend_ready_sub[gbt]) str_n_error_uplink_fec_sub += " Number of Powercycles with Uplink FEC Errors: %d" % n_error_uplink_fec_sub[ gbt] str_n_error_mode_sub += " Number of Mode Errors: %d" % n_error_mode_sub[ gbt] str_n_error_pusm_ready_sub += " Number of PUSMSTATE Errors: %d" % n_error_pusm_ready_sub[ gbt] str_n_error_reg_list_sub += " Number of Register Value Errors: %d" % n_error_reg_list_sub[ gbt] str_n_error_backend_ready_sub += Colors.ENDC str_n_error_uplink_fec_sub += Colors.ENDC str_n_error_mode_sub += Colors.ENDC str_n_error_pusm_ready_sub += Colors.ENDC str_n_error_reg_list_sub += Colors.ENDC print(str_n_error_backend_ready_sub) print(str_n_error_uplink_fec_sub) print(str_n_error_mode_sub) print(str_n_error_pusm_ready_sub) print(str_n_error_reg_list_sub) print("")
def vfat_sbit(gem, system, oh_select, vfat_list, nl1a, calpulse_only, align_phases, l1a_bxgap, set_cal_mode, cal_dac, min_error_limit, bestphase_list): print("%s VFAT S-Bit Phase Scan\n" % gem) if bestphase_list != {}: print("Setting phases for VFATs only, not scanning") for vfat in vfat_list: sbit_elinks = gem_utils.me0_vfat_to_sbit_elink(vfat) for elink in range(0, 8): set_bestphase = bestphase_list[vfat][elink] setVfatSbitPhase(system, oh_select, vfat, sbit_elinks[elink], set_bestphase) print("VFAT %02d: Phase set for ELINK %02d to: %s" % (vfat, elink, hex(set_bestphase))) return resultDir = "results" try: os.makedirs(resultDir) # create directory for results except FileExistsError: # skip if directory already exists pass vfatDir = "results/vfat_data" try: os.makedirs(vfatDir) # create directory for VFAT data except FileExistsError: # skip if directory already exists pass dataDir = "results/vfat_data/vfat_sbit_phase_scan_results" try: os.makedirs(dataDir) # create directory for data except FileExistsError: # skip if directory already exists pass now = str(datetime.datetime.now())[:16] now = now.replace(":", "_") now = now.replace(" ", "_") filename = dataDir + "/%s_OH%d_vfat_sbit_phase_scan_results_" % ( gem, oh_select) + now + ".txt" file_out = open(filename, "w") filename_data = dataDir + "/%s_OH%d_vfat_sbit_phase_scan_data_" % ( gem, oh_select) + now + ".txt" file_out_data = open(filename_data, "w") file_out.write("vfat elink phase\n") errs = [[[0 for phase in range(16)] for elink in range(0, 8)] for vfat in range(24)] gem_utils.global_reset() sleep(0.1) gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 1) # Reading S-bit counters cyclic_running_node = gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.CYCLIC_RUNNING") l1a_node = gem_utils.get_backend_node("BEFE.GEM.TTC.CMD_COUNTERS.L1A") calpulse_node = gem_utils.get_backend_node( "BEFE.GEM.TTC.CMD_COUNTERS.CALPULSE") gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TRIGGER.SBIT_MONITOR.OH_SELECT"), oh_select) reset_sbit_monitor_node = gem_utils.get_backend_node( "BEFE.GEM.TRIGGER.SBIT_MONITOR.RESET") # To reset S-bit Monitor reset_sbit_cluster_node = get_backend_node( "BEFE.GEM.TRIGGER.CTRL.CNT_RESET") # To reset Cluster Counter sbit_monitor_nodes = [] cluster_count_nodes = [] for i in range(0, 8): sbit_monitor_nodes.append( gem_utils.get_backend_node( "BEFE.GEM.TRIGGER.SBIT_MONITOR.CLUSTER%d" % i)) cluster_count_nodes.append( gem_utils.get_backend_node( "BEFE.GEM.TRIGGER.OH%d.CLUSTER_COUNT_%d_CNT" % (oh_select, i))) # Configure TTC generator ttc_cnt_reset_node = gem_utils.get_backend_node( "BEFE.GEM.TTC.CTRL.MODULE_RESET") gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.RESET"), 1) if calpulse_only: gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE"), 0) gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.ENABLE_CALPULSE_ONLY"), 1) else: gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE"), 1) gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.ENABLE_CALPULSE_ONLY"), 0) gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_L1A_GAP"), l1a_bxgap) gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_L1A_COUNT"), nl1a) if l1a_bxgap >= 40: gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.CYCLIC_CALPULSE_TO_L1A_GAP"), 25) else: gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.CYCLIC_CALPULSE_TO_L1A_GAP"), 2) # Configure all VFATs for vfat in vfat_list: gbt, gbt_select, elink_daq, gpio = gem_utils.me0_vfat_to_gbt_elink_gpio( vfat) oh_ver = get_oh_ver(oh_select, gbt_select) gem_utils.check_gbt_link_ready(oh_select, gbt_select) link_good = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.VFAT%d.LINK_GOOD" % (oh_select, vfat))) sync_err = gem_utils.read_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH_LINKS.OH%d.VFAT%d.SYNC_ERR_CNT" % (oh_select, vfat))) if system != "dryrun" and (link_good == 0 or sync_err > 0): print(Colors.RED + "Link is bad for VFAT# %02d" % (vfat) + Colors.ENDC) gem_utils.terminate() # Configure the pulsing VFAT print("Configuring VFAT %d" % (vfat)) configureVfat(1, vfat, oh_select, 0) if set_cal_mode == "voltage": gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_MODE" % (oh_select, vfat)), 1) gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_DUR" % (oh_select, vfat)), 200) elif set_cal_mode == "current": gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_MODE" % (oh_select, vfat)), 2) gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_DUR" % (oh_select, vfat)), 0) else: gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_MODE" % (oh_select, vfat)), 0) gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_DUR" % (oh_select, vfat)), 0) gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_DAC" % (oh_select, vfat)), cal_dac) for i in range(128): enableVfatchannel(vfat, oh_select, i, 1, 0) # mask all channels and disable calpulsing # Reset the link, give some time to accumulate any sync errors and then check VFAT comms sleep(0.1) gem_utils.gem_link_reset() sleep(0.1) s_bit_cluster_mapping = {} print("") # Starting Phase loop for phase in range(0, 16): print("Scanning phase %d" % phase) # set phases for all elinks in all vfats for vfat in vfat_list: sbit_elinks = gem_utils.me0_vfat_to_sbit_elink(vfat) for elink in range(0, 8): setVfatSbitPhase(system, oh_select, vfat, sbit_elinks[elink], phase) # Reset the link, give some time to accumulate any sync errors and then check VFAT comms sleep(0.1) gem_utils.gem_link_reset() sleep(0.1) print("Checking errors: ") # Starting VFAT loop for vfat in vfat_list: s_bit_cluster_mapping[vfat] = {} # Looping over all channels for channel in range(0, 128): s_bit_cluster_mapping[vfat][channel] = {} s_bit_cluster_mapping[vfat][channel]["calpulse_counter"] = 0 s_bit_cluster_mapping[vfat][channel]["cluster_count"] = [] s_bit_cluster_mapping[vfat][channel][ "sbit_monitor_cluster_size"] = [] s_bit_cluster_mapping[vfat][channel][ "sbit_monitor_cluster_address"] = [] # Enabling the pulsing channel enableVfatchannel( vfat, oh_select, channel, 0, 1) # unmask this channel and enable calpulsing # Reset L1A, CalPulse and S-bit monitor gem_utils.write_backend_reg(ttc_cnt_reset_node, 1) gem_utils.write_backend_reg(reset_sbit_monitor_node, 1) gem_utils.write_backend_reg(reset_sbit_cluster_node, 1) # Start the cyclic generator gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.CYCLIC_START"), 1) cyclic_running = gem_utils.read_backend_reg( cyclic_running_node) while cyclic_running: cyclic_running = gem_utils.read_backend_reg( cyclic_running_node) # Stop the cyclic generator gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.RESET"), 1) l1a_counter = gem_utils.read_backend_reg(l1a_node) calpulse_counter = gem_utils.read_backend_reg(calpulse_node) for i in range(0, 8): s_bit_cluster_mapping[vfat][channel][ "calpulse_counter"] = calpulse_counter s_bit_cluster_mapping[vfat][channel][ "cluster_count"].append( gem_utils.read_backend_reg(cluster_count_nodes[i])) sbit_monitor_value = gem_utils.read_backend_reg( sbit_monitor_nodes[i]) sbit_cluster_address = sbit_monitor_value & 0x7ff sbit_cluster_size = ((sbit_monitor_value >> 11) & 0x7) + 1 s_bit_cluster_mapping[vfat][channel][ "sbit_monitor_cluster_size"].append(sbit_cluster_size) s_bit_cluster_mapping[vfat][channel][ "sbit_monitor_cluster_address"].append( sbit_cluster_address) # Disabling the pulsing channels enableVfatchannel( vfat, oh_select, channel, 1, 0) # mask this channel and disable calpulsing # Detecting bad phase for each Elink for elink in range(0, 8): for channel in range(elink * 16, elink * 16 + 16): multiple_cluster_counts = 0 for i in range(1, 8): if i == 1: if s_bit_cluster_mapping[vfat][channel][ "cluster_count"][ i] != s_bit_cluster_mapping[vfat][ channel]["calpulse_counter"]: multiple_cluster_counts = 1 else: if s_bit_cluster_mapping[vfat][channel][ "cluster_count"][i] != 0: multiple_cluster_counts = 1 n_clusters = 0 for i in range(0, 8): if (s_bit_cluster_mapping[vfat][channel] ["sbit_monitor_cluster_address"][i] == 0x7ff and s_bit_cluster_mapping[vfat][channel] ["sbit_monitor_cluster_size"][i] == 0x7): continue n_clusters += 1 if n_clusters > 1 or multiple_cluster_counts == 1: errs[vfat][elink][phase] += 1 if errs[vfat][elink][phase] == 0: print( Colors.GREEN + "Phase: %d, VFAT %02d SBit ELINK %02d: nr. of channel errors=%d" % (phase, vfat, elink, errs[vfat][elink][phase]) + Colors.ENDC) elif errs[vfat][elink][phase] < 16: print( Colors.YELLOW + "Phase: %d, VFAT %02d SBit ELINK %02d: nr. of channel errors=%d" % (phase, vfat, elink, errs[vfat][elink][phase]) + Colors.ENDC) else: print( Colors.RED + "Phase: %d, VFAT %02d SBit ELINK %02d: nr. of channel errors=%d" % (phase, vfat, elink, errs[vfat][elink][phase]) + Colors.ENDC) # End of Elink loop print("") print("") # End of VFAT loop # End of Phase loop if calpulse_only: gem_utils.write_backend_reg( gem_utils.get_backend_node( "BEFE.GEM.TTC.GENERATOR.ENABLE_CALPULSE_ONLY"), 0) else: gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE"), 0) # Unconfigure all VFATs for vfat in vfat_list: print("Unconfiguring VFAT %d" % (vfat)) configureVfat(0, vfat, oh_select, 0) sleep(0.1) aligned_phases_center = [[-9999 for elink in range(8)] for vfat in range(24)] for vfat in vfat_list: find_aligned_phase_center(vfat, errs[vfat], aligned_phases_center, min_error_limit) bestphase_vfat_elink = [[0 for elink in range(8)] for vfat in range(24)] print("\nPhase Scan Results:") file_out_data.write("\nPhase Scan Results:\n") for vfat in vfat_list: centers = 8 * [0] widths = 8 * [0] for elink in range(0, 8): centers[elink], widths[elink] = find_phase_center( errs[vfat][elink], min_error_limit) if not align_phases: if centers[elink] == 7 and (widths[elink] == 15 or widths[elink] == 14): if elink != 0: centers[elink] = centers[elink - 1] else: new_center = aligned_phases_center[vfat][elink] if new_center != -9999: if centers[elink] > new_center: if new_center != 14: bad_phase = -9999 for p in range(new_center, centers[elink] + 1): if errs[vfat][elink][p] != 0: bad_phase = p break if bad_phase == -9999: centers[elink] = new_center + 1 else: centers[elink] = new_center else: centers[elink] = new_center elif centers[elink] < new_center: if new_center != 0: bad_phase = -9999 for p in range(centers[elink], new_center + 1): if errs[vfat][elink][p] != 0: bad_phase = p break if bad_phase == -9999: centers[elink] = new_center - 1 else: centers[elink] = new_center else: centers[elink] = new_center else: centers[elink] = new_center print("\nVFAT %02d :" % (vfat)) file_out_data.write("\nVFAT %02d :\n" % (vfat)) for elink in range(0, 8): phase_print = " ELINK %02d: " % (elink) min_errors = min(errs[vfat][elink]) if min_errors > min_error_limit: min_errors = 0 for phase in range(0, 16): if (widths[elink] > 0 and phase == centers[elink]): char = Colors.GREEN + "+" + Colors.ENDC bestphase_vfat_elink[vfat][elink] = phase elif (errs[vfat][elink][phase] > min_errors): char = Colors.RED + "-" + Colors.ENDC else: char = Colors.YELLOW + "x" + Colors.ENDC phase_print += "%s" % char if widths[elink] < 3: phase_print += Colors.RED + " (center=%d, width=%d) BAD" % ( centers[elink], widths[elink]) + Colors.ENDC elif widths[elink] < 5: phase_print += Colors.YELLOW + " (center=%d, width=%d) WARNING" % ( centers[elink], widths[elink]) + Colors.ENDC else: phase_print += Colors.GREEN + " (center=%d, width=%d) GOOD" % ( centers[elink], widths[elink]) + Colors.ENDC print(phase_print) file_out_data.write(phase_print + "\n") # set phases for all elinks for this vfat print("\nVFAT %02d: Setting all ELINK phases to best phases: " % (vfat)) sbit_elinks = gem_utils.me0_vfat_to_sbit_elink(vfat) for elink in range(0, 8): set_bestphase = bestphase_vfat_elink[vfat][elink] setVfatSbitPhase(system, oh_select, vfat, sbit_elinks[elink], set_bestphase) print("VFAT %02d: Phase set for ELINK %02d to: %s" % (vfat, elink, hex(set_bestphase))) for vfat in range(0, 24): for elink in range(0, 8): file_out.write("%d %d 0x%x\n" % (vfat, elink, bestphase_vfat_elink[vfat][elink])) sleep(0.1) gem_utils.gem_link_reset() print("") file_out.close() file_out_data.close() gem_utils.write_backend_reg( gem_utils.get_backend_node("BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 0) print("\nS-bit phase scan done\n")
def sbit_phase_scan(ohN, vfatNMin=0, vfatNMax=11, verbose=False, print_result=True): VFAT_SBITS_out = [] addrSbitMonReset = get_node( 'BEFE.GEM.OH.OH%d.FPGA.TRIG.SBIT_MONITOR.RESET' % ohN) write_reg(get_node("BEFE.GEM.TRIGGER.SBIT_MONITOR.OH_SELECT"), ohN) ################## # hard reset ################## for vfatN in range(vfatNMin, vfatNMax + 1): if print_result: print("") print( "####################################################################################################" ) print("Scanning VFAT %i" % vfatN) print( "####################################################################################################" ) print("") write_reg(get_node('BEFE.GEM.SLOW_CONTROL.SCA.CTRL.MODULE_RESET'), 0x1) gem.gem_hard_reset() sleep(0.3) gem.gem_link_reset() sleep(0.1) ################## # ################## addrCluster = [0] * 8 for i in range(8): addrCluster[i] = get_node( 'BEFE.GEM.OH.OH%d.FPGA.TRIG.SBIT_MONITOR.CLUSTER%i' % (ohN, i)) configureVfatForPulsing(vfatN, ohN) err_matrix = [[0 for i in range(0, 2 * SCAN_RANGE + 1)] for j in range(8)] write_reg( get_node("BEFE.GEM.OH.OH%i.FPGA.TRIG.CTRL.ALIGNED_COUNT_TO_READY" % ohN), 0xfff) sot_reg = get_node( 'BEFE.GEM.OH.OH%d.FPGA.TRIG.TIMING.SOT_TAP_DELAY_VFAT%s' % (ohN, vfatN)) sot_dly_original = read_reg(sot_reg) for sot_dly in range(2): dly_offset = 0 if (sot_dly == 0): dly_offset = SCAN_RANGE else: dly_offset = 0 write_reg(sot_reg, dly_offset) sleep(0.0001) # otherwise too fast on CVP13 :) sot_rdy = read_reg( get_node("BEFE.GEM.OH.OH%i.FPGA.TRIG.CTRL.SBIT_SOT_READY" % ohN)) sleep(0.1) if (not (sot_rdy >> vfatN) & 0x1): print("Sot not ready... cannot scan") sys.exit() for ibit in range(8): # Set the SoT delay to 0 (min) tap_dly_reg = get_node( 'BEFE.GEM.OH.OH%d.FPGA.TRIG.TIMING.TAP_DELAY_VFAT%i_BIT%i' % (ohN, vfatN, ibit)) tap_dly_original = read_reg(tap_dly_reg) # sbit_monitor_cluster_reg = get_node('BEFE.GEM.OH.OH%d.FPGA.TRIG.SBIT_MONITOR.CLUSTER0' % (ohN)) # sbit_monitor_reset_reg = get_node('BEFE.GEM.OH.OH%d.FPGA.TRIG.SBIT_MONITOR.RESET' % (ohN)) sbit_hitmap_msb_reg = get_node( 'BEFE.GEM.OH.OH%d.FPGA.TRIG.SBIT_HITMAP.VFAT%d_MSB' % (ohN, vfatN)) sbit_hitmap_lsb_reg = get_node( 'BEFE.GEM.OH.OH%d.FPGA.TRIG.SBIT_HITMAP.VFAT%d_LSB' % (ohN, vfatN)) sbit_hitmap_reset_reg = get_node( 'BEFE.GEM.OH.OH%d.FPGA.TRIG.SBIT_HITMAP.RESET' % (ohN)) sbit_hitmap_ack_reg = get_node( 'BEFE.GEM.OH.OH%d.FPGA.TRIG.SBIT_HITMAP.ACQUIRE' % (ohN)) write_reg( get_node( "BEFE.GEM.OH.OH%i.FPGA.TRIG.CTRL.TU_MASK.VFAT%i_TU_MASK" % (ohN, vfatN)), 0xff ^ (1 << (ibit))) for delay in range(SCAN_RANGE + 1): write_reg(tap_dly_reg, delay) for islice in range(8): trigger_channel = ibit * 8 + islice for strip_odd in range(1): strip = trigger_channel * 2 + strip_odd write_reg( get_node( "BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 1) write_reg( get_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.VFAT_CHANNELS.CHANNEL%i" % (ohN, vfatN, strip)), 0x8000) # enable calpulse and unmask write_reg( get_node( "BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 0) for ipulse in range(1): sleep(0.0001) write_reg(sbit_hitmap_reset_reg, 1) write_reg(sbit_hitmap_ack_reg, 1) sleep(0.0001) write_reg(sbit_hitmap_ack_reg, 0) hit_map = (read_reg(sbit_hitmap_msb_reg) << 32) + read_reg(sbit_hitmap_lsb_reg) hit_map_expected = 1 << trigger_channel err = hit_map_expected != hit_map if (err): err_matrix[ibit][delay - dly_offset + SCAN_RANGE] += 1 if (hit_map != 0): if (err): if (verbose): print("FAIL:"), else: if (verbose): print("PASS:"******"ibit=%d, delay=%3i, slice=%i, ch_expect = %2d, hitmap=%s" % (ibit, delay - dly_offset, islice, trigger_channel, hex(hit_map))) else: if (verbose): print("FAIL: no cluster found") write_reg( get_node( "BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 1) write_reg( get_node( "BEFE.GEM.OH.OH%i.GEB.VFAT%i.VFAT_CHANNELS.CHANNEL%i" % (ohN, vfatN, strip)), 0x4000) # disable calpulse and mask write_reg( get_node( "BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 0) write_reg(tap_dly_reg, tap_dly_original) ngood_center = [0 for i in range(8)] ngood_width = [0 for i in range(8)] best_tap_delay = [0 for i in range(8)] min_center = 1000 line = " " for dly in range(2 * SCAN_RANGE + 1): text = "%2X" % (abs(dly - SCAN_RANGE) % 16) line = line + text print(line) for ibit in range(8): ngood = 0 ngood_max = 0 ngood_edge = 0 for dly in range(2 * SCAN_RANGE + 1): if (err_matrix[ibit][dly] == 0): ngood += 1 if (dly == 2 * SCAN_RANGE): if (ngood > 0 and ngood >= ngood_max): ngood_max = ngood ngood_edge = dly ngood = 0 else: if (ngood > 0 and ngood >= ngood_max): ngood_max = ngood ngood_edge = dly ngood = 0 #print("%3i" % err_matrix[ibit][dly]), if (ngood_max > 0): ngood_width[ibit] = ngood_max # even windows if (ngood_max % 2 == 0): ngood_center[ibit] = ngood_edge - (ngood_max / 2) - 1 if (err_matrix[ibit][ngood_edge] > err_matrix[ibit][ngood_edge - ngood_max - 1]): ngood_center[ibit] = ngood_center[ibit] else: ngood_center[ibit] = ngood_center[ibit] + 1 # oddwindows if (ngood_max % 2 == 1): ngood_center[ibit] = ngood_edge - (ngood_max / 2) - 1 # minimum if (ngood_center[ibit] < min_center): min_center = ngood_center[ibit] ################################################################################ # Printout Timing Window ################################################################################ for ibit in range(8): line = ("Sbit%i: " % ibit) for dly in range(2 * SCAN_RANGE + 1): if (err_matrix[ibit][dly] == 0): if (dly == ngood_center[ibit]): line = line + Colors.GREEN + "| " else: line = line + Colors.GREEN + "- " else: line = line + Colors.RED + "x " line = line + Colors.ENDC if print_result: print(line) ################################################################################ # Printout Summary ################################################################################ if print_result: print("min center = %i" % min_center) best_sot_tap_delay = 99 if (min_center - SCAN_RANGE < 0): best_sot_tap_delay = -1 * (min_center - SCAN_RANGE) else: best_sot_tap_delay = min_center if print_result: print("sot : best_dly=% 2d" % (best_sot_tap_delay)) ngood_center_offset = [] for ibit in range(8): best_tap_delay[ibit] = ngood_center[ibit] - min_center if print_result: print("bit%i: center=% 2d best_dly=% 2d width=% 2d (%f ns)" % (ibit, ngood_center[ibit] - SCAN_RANGE, best_tap_delay[ibit], ngood_width[ibit], ngood_width[ibit] * 78. / 1000)) ngood_center_offset.append(ngood_center[ibit] - SCAN_RANGE) VFAT_SBITS_out.append( VFAT_SBIT(vfatN, ngood_center_offset, best_tap_delay, ngood_width)) if print_result: print("") print("bye now..") return VFAT_SBITS_out
def vfat_sbit(gem, system, oh_select, vfat_list, nl1a, calpulse_only, align_phases, l1a_bxgap, set_cal_mode, cal_dac, min_error_limit, n_allowed_missing_hits, bestphase_list): print ("%s VFAT S-Bit Phase Scan\n"%gem) if bestphase_list!={}: print ("Setting phases for VFATs only, not scanning") for vfat in vfat_list: sbit_elinks = gem_utils.me0_vfat_to_sbit_elink(vfat) for elink in range(0,8): set_bestphase = bestphase_list[vfat][elink] setVfatSbitPhase(system, oh_select, vfat, sbit_elinks[elink], set_bestphase) print ("VFAT %02d: Phase set for ELINK %02d to: %s" % (vfat, elink, hex(set_bestphase))) return resultDir = "results" try: os.makedirs(resultDir) # create directory for results except FileExistsError: # skip if directory already exists pass vfatDir = "results/vfat_data" try: os.makedirs(vfatDir) # create directory for VFAT data except FileExistsError: # skip if directory already exists pass dataDir = "results/vfat_data/vfat_sbit_phase_scan_results" try: os.makedirs(dataDir) # create directory for data except FileExistsError: # skip if directory already exists pass now = str(datetime.datetime.now())[:16] now = now.replace(":", "_") now = now.replace(" ", "_") filename = dataDir + "/%s_OH%d_vfat_sbit_phase_scan_results_"%(gem,oh_select) + now + ".txt" file_out = open(filename, "w") filename_data = dataDir + "/%s_OH%d_vfat_sbit_phase_scan_data_"%(gem,oh_select) + now + ".txt" file_out_data = open(filename_data, "w") file_out.write("vfat elink phase\n") errs = [[[0 for phase in range(16)] for elink in range(0,8)] for vfat in range(24)] gem_utils.global_reset() sleep(0.1) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 1) # Reading S-bit counters cyclic_running_node = gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_RUNNING") l1a_node = gem_utils.get_backend_node("BEFE.GEM.TTC.CMD_COUNTERS.L1A") calpulse_node = gem_utils.get_backend_node("BEFE.GEM.TTC.CMD_COUNTERS.CALPULSE") write_backend_reg(get_backend_node("BEFE.GEM.SBIT_ME0.TEST_SEL_OH_SBIT_ME0"), oh_select) elink_sbit_select_node = gem_utils.get_backend_node("BEFE.GEM.SBIT_ME0.TEST_SEL_ELINK_SBIT_ME0") # Node for selecting Elink to count channel_sbit_select_node = gem_utils.get_backend_node("BEFE.GEM.SBIT_ME0.TEST_SEL_SBIT_ME0") # Node for selecting S-bit to count elink_sbit_counter_node = gem_utils.get_backend_node("BEFE.GEM.SBIT_ME0.TEST_SBIT0XE_COUNT_ME0") # S-bit counter for elink channel_sbit_counter_node = gem_utils.get_backend_node("BEFE.GEM.SBIT_ME0.TEST_SBIT0XS_COUNT_ME0") # S-bit counter for specific channel reset_sbit_counter_node = gem_utils.get_backend_node("BEFE.GEM.SBIT_ME0.CTRL.SBIT_TEST_RESET") # To reset all S-bit counters # Configure TTC generator ttc_cnt_reset_node = gem_utils.get_backend_node("BEFE.GEM.TTC.CTRL.MODULE_RESET") gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.RESET"), 1) if calpulse_only: gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE"), 0) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE_CALPULSE_ONLY"), 1) else: gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE"), 1) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE_CALPULSE_ONLY"), 0) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_L1A_GAP"), l1a_bxgap) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_L1A_COUNT"), nl1a) if l1a_bxgap >= 40: gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_CALPULSE_TO_L1A_GAP"), 25) else: gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_CALPULSE_TO_L1A_GAP"), 2) # Configure all VFATs for vfat in vfat_list: gbt, gbt_select, elink_daq, gpio = gem_utils.me0_vfat_to_gbt_elink_gpio(vfat) oh_ver = get_oh_ver(oh_select, gbt_select) gem_utils.check_gbt_link_ready(oh_select, gbt_select) link_good = gem_utils.read_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH_LINKS.OH%d.VFAT%d.LINK_GOOD" % (oh_select, vfat))) sync_err = gem_utils.read_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH_LINKS.OH%d.VFAT%d.SYNC_ERR_CNT" % (oh_select, vfat))) if system!="dryrun" and (link_good == 0 or sync_err > 0): print (Colors.RED + "Link is bad for VFAT# %02d"%(vfat) + Colors.ENDC) gem_utils.terminate() # Configure the pulsing VFAT print("Configuring VFAT %d" % (vfat)) configureVfat(1, vfat, oh_select, 0) if set_cal_mode == "voltage": gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_MODE"% (oh_select, vfat)), 1) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_DUR"% (oh_select, vfat)), 200) elif set_cal_mode == "current": gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_MODE"% (oh_select, vfat)), 2) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_DUR"% (oh_select, vfat)), 0) else: gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_MODE"% (oh_select, vfat)), 0) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_DUR"% (oh_select, vfat)), 0) gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.OH.OH%i.GEB.VFAT%i.CFG_CAL_DAC"% (oh_select, vfat)), cal_dac) for i in range(128): enableVfatchannel(vfat, oh_select, i, 1, 0) # mask all channels and disable calpulsing # Reset the link, give some time to accumulate any sync errors and then check VFAT comms sleep(0.1) gem_utils.gem_link_reset() sleep(0.1) s_bit_channel_mapping = {} print ("") # Starting Phase loop for phase in range(0, 16): print ("Scanning phase %d"%phase) # set phases for all elinks in all vfats for vfat in vfat_list: sbit_elinks = gem_utils.me0_vfat_to_sbit_elink(vfat) for elink in range(0,8): setVfatSbitPhase(system, oh_select, vfat, sbit_elinks[elink], phase) # Reset the link, give some time to accumulate any sync errors and then check VFAT comms sleep(0.1) gem_utils.gem_link_reset() sleep(0.1) print ("Checking errors: ") # Starting VFAT loop for vfat in vfat_list: gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.SBIT_ME0.TEST_SEL_VFAT_SBIT_ME0"), vfat) # Select VFAT for reading S-bits s_bit_channel_mapping[vfat] = {} # Looping over all 8 elinks for elink in range(0,8): gem_utils.write_backend_reg(elink_sbit_select_node, elink) # Select elink for S-bit counter s_bit_channel_mapping[vfat][elink] = {} s_bit_matches = {} for sbit in range(elink*8,elink*8+8): s_bit_matches[sbit] = 0 # Looping over all channels in that elink for channel in range(elink*16,elink*16+16): # Enabling the pulsing channel enableVfatchannel(vfat, oh_select, channel, 0, 1) # unmask this channel and enable calpulsing channel_sbit_counter_final = {} sbit_channel_match = 0 s_bit_channel_mapping[vfat][elink][channel] = -9999 # Looping over all S-bits in that elink for sbit in range(elink*8,elink*8+8): # Reset L1A, CalPulse and S-bit counters gem_utils.write_backend_reg(ttc_cnt_reset_node, 1) gem_utils.write_backend_reg(reset_sbit_counter_node, 1) gem_utils.write_backend_reg(channel_sbit_select_node, sbit) # Select S-bit for S-bit counter # Start the cyclic generator gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.CYCLIC_START"), 1) cyclic_running = gem_utils.read_backend_reg(cyclic_running_node) while cyclic_running: cyclic_running = gem_utils.read_backend_reg(cyclic_running_node) # Stop the cyclic generator gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.RESET"), 1) elink_sbit_counter_final = gem_utils.read_backend_reg(elink_sbit_counter_node) l1a_counter = gem_utils.read_backend_reg(l1a_node) calpulse_counter = gem_utils.read_backend_reg(calpulse_node) if abs(elink_sbit_counter_final - calpulse_counter) > n_allowed_missing_hits: # Elink did not register the correct number of hits s_bit_channel_mapping[vfat][elink][channel] = -9999 break channel_sbit_counter_final[sbit] = gem_utils.read_backend_reg(channel_sbit_counter_node) if calpulse_counter == 0: # Calpulse Counter is 0 s_bit_channel_mapping[vfat][elink][channel] = -9999 break if abs(channel_sbit_counter_final[sbit] - calpulse_counter) <= n_allowed_missing_hits: if sbit_channel_match == 1: # Multiple S-bits registered hits for calpulse on this channel s_bit_channel_mapping[vfat][elink][channel] = -9999 break if s_bit_matches[sbit] >= 2: # S-bit already matched to 2 channels s_bit_channel_mapping[vfat][elink][channel] = -9999 break if s_bit_matches[sbit] == 1: if channel%2==0: # S-bit already matched to an earlier odd numbered channel s_bit_channel_mapping[vfat][elink][channel] = -9999 break if s_bit_channel_mapping[vfat][elink][channel-1] != sbit: # S-bit matched to a different channel than the previous one s_bit_channel_mapping[vfat][elink][channel] = -9999 break s_bit_channel_mapping[vfat][elink][channel] = sbit sbit_channel_match = 1 s_bit_matches[sbit] += 1 # End of S-bit loop for this channel if s_bit_channel_mapping[vfat][elink][channel] == -9999: errs[vfat][elink][phase] += 1 # Disabling the pulsing channels enableVfatchannel(vfat, oh_select, channel, 1, 0) # mask this channel and disable calpulsing # End of Channel loop if errs[vfat][elink][phase] == 0: print (Colors.GREEN + "Phase: %d, VFAT %02d SBit ELINK %02d: nr. of channel errors=%d"%(phase, vfat, elink, errs[vfat][elink][phase]) + Colors.ENDC) elif errs[vfat][elink][phase] < 16: print (Colors.YELLOW + "Phase: %d, VFAT %02d SBit ELINK %02d: nr. of channel errors=%d"%(phase, vfat, elink, errs[vfat][elink][phase]) + Colors.ENDC) else: print (Colors.RED + "Phase: %d, VFAT %02d SBit ELINK %02d: nr. of channel errors=%d"%(phase, vfat, elink, errs[vfat][elink][phase]) + Colors.ENDC) # End of Elink loop print ("") print ("") # End of VFAT loop # End of Phase loop if calpulse_only: gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE_CALPULSE_ONLY"), 0) else: gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.TTC.GENERATOR.ENABLE"), 0) # Unconfigure all VFATs for vfat in vfat_list: print("Unconfiguring VFAT %d" % (vfat)) configureVfat(0, vfat, oh_select, 0) sleep(0.1) aligned_phases_center = [[-9999 for elink in range(8)] for vfat in range(24)] for vfat in vfat_list: find_aligned_phase_center(vfat, errs[vfat], aligned_phases_center, min_error_limit) bestphase_vfat_elink = [[0 for elink in range(8)] for vfat in range(24)] print ("\nPhase Scan Results:") file_out_data.write("\nPhase Scan Results:\n") for vfat in vfat_list: centers = 8*[0] widths = 8*[0] for elink in range(0,8): centers[elink], widths[elink] = find_phase_center(errs[vfat][elink], min_error_limit) if not align_phases: if centers[elink] == 7 and (widths[elink]==15 or widths[elink]==14): if elink!=0: centers[elink] = centers[elink-1] else: new_center = aligned_phases_center[vfat][elink] if new_center != -9999: if centers[elink] > new_center: if new_center != 14: bad_phase = -9999 for p in range(new_center, centers[elink]+1): if errs[vfat][elink][p] != 0: bad_phase = p break if bad_phase == -9999: centers[elink] = new_center + 1 else: centers[elink] = new_center else: centers[elink] = new_center elif centers[elink] < new_center: if new_center != 0: bad_phase = -9999 for p in range(centers[elink], new_center+1): if errs[vfat][elink][p] != 0: bad_phase = p break if bad_phase == -9999: centers[elink] = new_center - 1 else: centers[elink] = new_center else: centers[elink] = new_center else: centers[elink] = new_center print ("\nVFAT %02d :" %(vfat)) file_out_data.write("\nVFAT %02d :\n" %(vfat)) for elink in range(0,8): phase_print = " ELINK %02d: " % (elink) min_errors = min(errs[vfat][elink]) if min_errors > min_error_limit: min_errors = 0 for phase in range(0, 16): if (widths[elink]>0 and phase==centers[elink]): char=Colors.GREEN + "+" + Colors.ENDC bestphase_vfat_elink[vfat][elink] = phase elif (errs[vfat][elink][phase] > min_errors): char=Colors.RED + "-" + Colors.ENDC else: char = Colors.YELLOW + "x" + Colors.ENDC phase_print += "%s" %char if widths[elink]<3: phase_print += Colors.RED + " (center=%d, width=%d) BAD" % (centers[elink], widths[elink]) + Colors.ENDC elif widths[elink]<5: phase_print += Colors.YELLOW + " (center=%d, width=%d) WARNING" % (centers[elink], widths[elink]) + Colors.ENDC else: phase_print += Colors.GREEN + " (center=%d, width=%d) GOOD" % (centers[elink], widths[elink]) + Colors.ENDC print(phase_print) file_out_data.write(phase_print + "\n") # set phases for all elinks for this vfat print ("\nVFAT %02d: Setting all ELINK phases to best phases: "%(vfat)) sbit_elinks = gem_utils.me0_vfat_to_sbit_elink(vfat) for elink in range(0,8): set_bestphase = bestphase_vfat_elink[vfat][elink] setVfatSbitPhase(system, oh_select, vfat, sbit_elinks[elink], set_bestphase) print ("VFAT %02d: Phase set for ELINK %02d to: %s" % (vfat, elink, hex(set_bestphase))) for vfat in range(0,24): for elink in range(0,8): file_out.write("%d %d 0x%x\n"%(vfat,elink,bestphase_vfat_elink[vfat][elink])) sleep(0.1) gem_utils.gem_link_reset() print ("") file_out.close() file_out_data.close() gem_utils.write_backend_reg(gem_utils.get_backend_node("BEFE.GEM.GEM_SYSTEM.VFAT3.SC_ONLY_MODE"), 0) print ("\nS-bit phase scan done\n")