|
|
|
|
|
import logging, argparse, time, sys, math, os
|
|
|
|
|
|
import yaml, json
|
|
|
|
|
|
from typing import List, Optional, Tuple
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
import pandas as pd
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
import pdb
|
|
|
|
|
|
import subprocess
|
|
|
|
|
|
import concurrent.futures
|
|
|
|
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
sys.path.append('C:\\ws\\tmp\\NexusBench-baihe-br\\nexusbench')
|
|
|
|
|
|
sys.path.append(os.path.dirname(__file__))
|
|
|
|
|
|
|
|
|
|
|
|
from parser.topology_parser import TopoMappingParser
|
|
|
|
|
|
from parser.ibias_rssi_map_parser import IbiasRssiMapParser
|
|
|
|
|
|
from toolbox.rssi_ibias_test import find_best_ibias_for_expected_rssi,find_best_ibias_for_expected_rssi_old
|
|
|
|
|
|
from gpu.biren.exp_util import DevWhiteRiverExp
|
|
|
|
|
|
from gpu.biren.smbus_http_util import SmbusHttpUtil
|
|
|
|
|
|
from gpu.biren.vuart_util import VuartUtil
|
|
|
|
|
|
from log.logger import Logger
|
|
|
|
|
|
from parser.transceiver_config_parser import TransceiverConfigParser, RegisterInfo
|
|
|
|
|
|
from toolbox.mgc_tuning_tool import MgcTuningTool, LaneErrInfo
|
|
|
|
|
|
import zlib
|
|
|
|
|
|
from functools import partial
|
|
|
|
|
|
from toolbox.regs_save_load_tool import LaneRegInfo, RouteInfo, SlotInfo, ExpInfo, HostRegInfo, OptRegValueManager
|
|
|
|
|
|
from toolbox.lowfreq_tuning_tool import LowFreqTuningTool
|
|
|
|
|
|
from toolbox.eq_tune_tool import EqTuneTool, RetimerLaneSetting
|
|
|
|
|
|
from toolbox.recv_ce_tool import RetimerLinkState, RecvCeTool
|
|
|
|
|
|
from toolbox.opt_reg_access_tool import OptRegAccessTool
|
|
|
|
|
|
from toolbox.prbs_tool import PrbsTool
|
|
|
|
|
|
print(zlib.ZLIB_VERSION)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def Authentication(bmc: DevWhiteRiverExp, exp_id: int, slot_id: int):
|
|
|
|
|
|
bmc.SetOpticalModuleRegs(exp_id, slot_id, 0, 0, 0x7a, 4, 'EA987654')
|
|
|
|
|
|
bmc.SetOpticalModuleRegs(exp_id, slot_id, 0, 0, 0xE9, 1, '04')
|
|
|
|
|
|
# bmc.SetOpticalModuleRegs(exp_id, slot_id, 0, 0xB4, 0x88, 1, '01')
|
|
|
|
|
|
|
|
|
|
|
|
def ReadModuleType(bmc: DevWhiteRiverExp, exp_id: int, slot_id: int):
|
|
|
|
|
|
res_data = bmc.GetOpticalModuleRegs(exp_id, slot_id, 0,0xB0, 0xB0, 9)
|
|
|
|
|
|
logging.debug(res_data)
|
|
|
|
|
|
bytes_data = bytes.fromhex(res_data)
|
|
|
|
|
|
type = bytes_data.decode('ascii', errors='ignore')
|
|
|
|
|
|
logging.debug(f'----------------SLOT: {slot_id}, Module type:{type}')
|
|
|
|
|
|
return type
|
|
|
|
|
|
|
|
|
|
|
|
def ExpColdReset(bmc: DevWhiteRiverExp, exp_id: int):
|
|
|
|
|
|
ret = bmc.ExpColdReset(exp_id)
|
|
|
|
|
|
logging.info(f'Exp cold reset, exp id: {exp_id}, result: {ret}')
|
|
|
|
|
|
|
|
|
|
|
|
def AutoTuneMGC(host: str, bmc: DevWhiteRiverExp, remote_bmc: DevWhiteRiverExp,
|
|
|
|
|
|
reg_tool: OptRegAccessTool, remote_reg_access_tool: OptRegAccessTool,
|
|
|
|
|
|
exp_id: int, slot_list: List[int], lane_list: List[int],
|
|
|
|
|
|
reg_table: TransceiverConfigParser, cmd: str, route_name: str):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune MGC: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
if rtmr_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in rtmr_list]
|
|
|
|
|
|
|
|
|
|
|
|
if remote_bmc is None:
|
|
|
|
|
|
remote_bmc = bmc
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool = PrbsTool(bmc, remote_bmc, reg_tool, remote_reg_access_tool, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
topo_map.parse()
|
|
|
|
|
|
|
|
|
|
|
|
logging.info('-------------step 3:')
|
|
|
|
|
|
mgc_tool = MgcTuningTool(host, reg_table, reg_tool, remote_reg_access_tool, bmc, topo_map, prbs_tool, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
remote_mgc_tool = None
|
|
|
|
|
|
if remote_bmc != bmc:
|
|
|
|
|
|
remote_prbs_tool = PrbsTool(remote_bmc, bmc, remote_reg_access_tool, reg_tool, route_name)
|
|
|
|
|
|
remote_mgc_tool = MgcTuningTool(host, reg_table, remote_reg_access_tool, reg_tool, remote_bmc, topo_map, remote_prbs_tool, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info('-------------step 4:')
|
|
|
|
|
|
# 对每个slot执行自动调优
|
|
|
|
|
|
# if route_name == '786-1-oneta' or route_name == '786-1-onoc2':
|
|
|
|
|
|
if cmd == 'mgc-auto-tune2':
|
|
|
|
|
|
|
|
|
|
|
|
mgc_tool.auto_tune2(exp_id, retimers)
|
|
|
|
|
|
elif cmd == 'tiapeak-auto-tune':
|
|
|
|
|
|
mgc_tool.auto_tia_peak_tune(exp_id, retimers)
|
|
|
|
|
|
elif cmd == 'lowfreq-auto-tune':
|
|
|
|
|
|
mgc_tool.auto_lowfreq_tune(exp_id, retimers)
|
|
|
|
|
|
elif cmd == 'highfreq-auto-tune':
|
|
|
|
|
|
mgc_tool.auto_highfreq_tune(exp_id, retimers)
|
|
|
|
|
|
elif cmd == 'opcurrent-auto-tune':
|
|
|
|
|
|
mgc_tool.auto_opcurrent_tune_test(exp_id, retimers)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'opcurrent-auto-tune-test':
|
|
|
|
|
|
mgc_tool.auto_ibias_tune2(exp_id, retimers)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'rt-ibias':
|
|
|
|
|
|
mgc_tool.rt_ibias(exp_id, retimers)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'plot-mgc-vpeak':
|
|
|
|
|
|
prbs_tool.ResetRetimerAndEnablePrbs(exp_id, retimers, 9)
|
|
|
|
|
|
for slot in slot_list:
|
|
|
|
|
|
mgc_tool.debug_calc_target_vpeak_new(exp_id, slot)
|
|
|
|
|
|
|
|
|
|
|
|
if cmd == 'mgc-auto-tune':
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool.ResetRetimerAndEnablePrbs(exp_id, retimers, 9)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"---------- slot_list: {slot_list}")
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
if cmd == 'mgc-auto-tune':
|
|
|
|
|
|
mgc_tool.auto_tune(exp_id, slot_id, lane_list)
|
|
|
|
|
|
|
|
|
|
|
|
if remote_mgc_tool is not None:
|
|
|
|
|
|
remote_mgc_tool.auto_tune(exp_id, slot_id, lane_list)
|
|
|
|
|
|
|
|
|
|
|
|
# mgc_tool2 = MgcTuningTool(host, reg_table, reg_tool, remote_reg_access_tool, bmc, topo_map, prbs_tool, route_name)
|
|
|
|
|
|
# mgc_tool.auto_tune(exp_id, slot_id, lane_list)
|
|
|
|
|
|
elif cmd == 'mgc-manual-tune':
|
|
|
|
|
|
mgc_tool.manual_tune(exp_id, slot_id)
|
|
|
|
|
|
elif cmd == 'mgc-calc-target-vpeak':
|
|
|
|
|
|
mgc_tool.calc_target_vpeak_new(exp_id, slot_id, lane_list)
|
|
|
|
|
|
|
|
|
|
|
|
def AutoTuneLowFreq(host: str, bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, reg_table_file: str, cmd: str):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune low freq: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
# 加载寄存器表
|
|
|
|
|
|
reg_table = TransceiverConfigParser(reg_table_file)
|
|
|
|
|
|
|
|
|
|
|
|
# 创建Low Freq 调优工具实例
|
|
|
|
|
|
lowfreq_tool = LowFreqTuningTool(host, reg_table, bmc)
|
|
|
|
|
|
logging.info('-------------step 4:')
|
|
|
|
|
|
# 对每个slot执行自动调优
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
lowfreq_tool.auto_tune(exp_id, slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def TuneHighFreq(reg_tool: OptRegAccessTool, exp_id: int):
|
|
|
|
|
|
# 3500 ~ 5500
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [1,3,5], ['tia_peak'], '150')
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,2,4,6,7], ['tia_peak'], '112')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [3,4], ['highfreq_eq'], '130')
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [2,6,7], ['highfreq_eq'], '50')
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0], ['highfreq_eq'], '100')
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [1], ['highfreq_eq'], '180')
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [5], ['highfreq_eq'], '180')
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [4,7], ['highfreq_eq'], '0')
|
|
|
|
|
|
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7], ['lowfreq_eq'], '128')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# exp_id 需替换为实际值
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7], ['opcurrent'], '140')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7], ['highfreq_eq'], '200')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7], ['tia_peak'], '112')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0], [3], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [1], [2], ['highfreq_eq'], '50')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [1], [5], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [1], [5], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [2], [0], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [2], [1], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [2], [3], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [2], [6], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [2], [7], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3], [0], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3], [1], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3], [2], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3], [4], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3], [5], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3], [6], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3], [7], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [4], [0], ['highfreq_eq'], '50')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [4], [1], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [4], [2], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [4], [3], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [4], [5], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [4], [6], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [4], [7], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [0], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [1], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [2], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [3], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [4], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [5], ['highfreq_eq'], '50')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [6], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [7], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [6], [0], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [6], [1], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [6], [2], ['highfreq_eq'], '50')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [6], [4], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [6], [5], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [6], [6], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [7], [0], ['highfreq_eq'], '50')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [7], [1], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [7], [2], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [7], [3], ['highfreq_eq'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [7], [6], ['highfreq_eq'], '100')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# all_lane_reg_values: List[LaneRegInfo] = reg_tool.read_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7], ['highfreq_eq'])
|
|
|
|
|
|
# for lane_reg in all_lane_reg_values:
|
|
|
|
|
|
# if lane_reg.highfreq_eq >=200:
|
|
|
|
|
|
# reg_tool.write_opcurrent_reg(exp_id, lane_reg.slot_id, lane_reg.logic_lane, 150)
|
|
|
|
|
|
# elif lane_reg.highfreq_eq >=100:
|
|
|
|
|
|
# reg_tool.write_opcurrent_reg(exp_id, lane_reg.slot_id, lane_reg.logic_lane, 160)
|
|
|
|
|
|
# elif lane_reg.highfreq_eq >=50:
|
|
|
|
|
|
# reg_tool.write_opcurrent_reg(exp_id, lane_reg.slot_id, lane_reg.logic_lane, 165)
|
|
|
|
|
|
# elif lane_reg.highfreq_eq >=0:
|
|
|
|
|
|
# reg_tool.write_opcurrent_reg(exp_id, lane_reg.slot_id, lane_reg.logic_lane, 170)
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7], ['opcurrent'], '138')
|
|
|
|
|
|
|
|
|
|
|
|
# # < 3000
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [2], [4], ['highfreq_eq'], '200')
|
|
|
|
|
|
# # < 3000 -3500
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5,6,7], [4], ['highfreq_eq'], '150')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3,7], [5], ['highfreq_eq'], '150')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [5], [1], ['highfreq_eq'], '150')
|
|
|
|
|
|
|
|
|
|
|
|
# # > 5500
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [7], [3], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,1], [6], ['highfreq_eq'], '0')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [1,5], [2], ['highfreq_eq'], '0')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def SaveRegsToFile(reg_tool: OptRegAccessTool, host: str, exp_id: int,
|
|
|
|
|
|
slot_list: List[int], route_name: str,lane_list: List[int], regs: List[str],
|
|
|
|
|
|
save_file_name: str):
|
|
|
|
|
|
|
|
|
|
|
|
host_reg_info = OptRegValueManager.load_from_yaml(save_file_name)
|
|
|
|
|
|
|
|
|
|
|
|
if host_reg_info.host != '' and host_reg_info.host != host:
|
|
|
|
|
|
logging.error(f'save_file {save_file_name} is not match!')
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
if host_reg_info.host == '':
|
|
|
|
|
|
host_reg_info.host = host
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
logging.info(f'------------------2: regs: {regs}')
|
|
|
|
|
|
|
|
|
|
|
|
laneRegValueList = reg_tool.read_opt_registers_by_slot(exp_id, slot_id, lane_list, regs)
|
|
|
|
|
|
logging.info(f'------------------3: laneRegValueList: {laneRegValueList}')
|
|
|
|
|
|
|
|
|
|
|
|
# --- Find or Create ExpInfo ---
|
|
|
|
|
|
target_exp: Optional[ExpInfo] = None
|
|
|
|
|
|
for exp in host_reg_info.exps:
|
|
|
|
|
|
if exp.exp_id == exp_id:
|
|
|
|
|
|
target_exp = exp
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
if target_exp is None:
|
|
|
|
|
|
target_exp = ExpInfo(exp_id=exp_id)
|
|
|
|
|
|
host_reg_info.exps.append(target_exp)
|
|
|
|
|
|
logging.info(f"Created new ExpInfo for exp_id {exp_id}")
|
|
|
|
|
|
|
|
|
|
|
|
# --- Find or Create SlotInfo within ExpInfo ---
|
|
|
|
|
|
target_slot: Optional[SlotInfo] = None
|
|
|
|
|
|
for slot in target_exp.slots:
|
|
|
|
|
|
if slot.slot_id == slot_id:
|
|
|
|
|
|
target_slot = slot
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
if target_slot is None:
|
|
|
|
|
|
target_slot = SlotInfo(slot_id=slot_id)
|
|
|
|
|
|
target_exp.slots.append(target_slot)
|
|
|
|
|
|
logging.info(f"Created new SlotInfo for slot_id {slot_id}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if route_name == '':
|
|
|
|
|
|
logging.error(f'route name is empty!')
|
|
|
|
|
|
exit(0)
|
|
|
|
|
|
|
|
|
|
|
|
# --- Find or Update/Create RouteInfo within SlotInfo ---
|
|
|
|
|
|
route_found = False
|
|
|
|
|
|
for route in target_slot.modes:
|
|
|
|
|
|
if route.mode_name == route_name:
|
|
|
|
|
|
route.lanes = laneRegValueList # Overwrite existing lanes
|
|
|
|
|
|
route_found = True
|
|
|
|
|
|
logging.info(f"Updated lanes for existing RouteInfo '{route_name}'")
|
|
|
|
|
|
break # Exit the loop once found and updated
|
|
|
|
|
|
|
|
|
|
|
|
if not route_found:
|
|
|
|
|
|
# If the route was not found, create a new one and add it
|
|
|
|
|
|
new_route = RouteInfo(mode_name=route_name, lanes=laneRegValueList)
|
|
|
|
|
|
target_slot.modes.append(new_route)
|
|
|
|
|
|
logging.info(f"Added new RouteInfo '{route_name}' with lanes")
|
|
|
|
|
|
|
|
|
|
|
|
# --- Save the updated host_reg_info ---
|
|
|
|
|
|
OptRegValueManager.save_to_yaml(host_reg_info, save_file_name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def LoadRegsToFile(reg_tool: OptRegAccessTool, host: str, exp_id: int, slot_list: List[int],
|
|
|
|
|
|
route_name: str, regs: List[str], load_file_name: str):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'-----------slot_list: {slot_list}')
|
|
|
|
|
|
|
|
|
|
|
|
host_reg_info = OptRegValueManager.load_from_yaml(load_file_name)
|
|
|
|
|
|
# logging.info(host_reg_info)
|
|
|
|
|
|
if host_reg_info.host != host or host_reg_info.host == '':
|
|
|
|
|
|
logging.error(f'load_file {load_file_name} is not match!')
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
logging.info(f'------------------2: regs: {regs}')
|
|
|
|
|
|
|
|
|
|
|
|
for exp in host_reg_info.exps:
|
|
|
|
|
|
if exp_id == exp.exp_id:
|
|
|
|
|
|
for save_slot in exp.slots:
|
|
|
|
|
|
if slot_id == save_slot.slot_id:
|
|
|
|
|
|
for save_mode in save_slot.modes:
|
|
|
|
|
|
if route_name == save_mode.mode_name:
|
|
|
|
|
|
for lane_info in save_mode.lanes:
|
|
|
|
|
|
|
|
|
|
|
|
params_to_write = {
|
|
|
|
|
|
'mgc': lane_info.mgc,
|
|
|
|
|
|
# 'vpeak': lane_info.vpeak,
|
|
|
|
|
|
'tia_peak': lane_info.tia_peak,
|
|
|
|
|
|
'ibias': lane_info.ibias,
|
|
|
|
|
|
'ipcurrent': lane_info.ipcurrent,
|
|
|
|
|
|
'opcurrent': lane_info.opcurrent,
|
|
|
|
|
|
'lowfreq_eq': lane_info.lowfreq_eq,
|
|
|
|
|
|
'highfreq_eq': lane_info.highfreq_eq,
|
|
|
|
|
|
'vgc_set': lane_info.vgc_set,
|
|
|
|
|
|
# 'drv_vpeak': lane_info.drv_vpeak
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for reg_name, param_value in params_to_write.items():
|
|
|
|
|
|
if param_value == -1:
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
reg_tool.write_opt_reg(exp_id, slot_id, lane_info.logic_lane, param_value, reg_name)
|
|
|
|
|
|
logging.info(f"Written {reg_name}={param_value} to exp={exp.exp_id}, slot={slot_id}, lane={lane_info.logic_lane}")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"Error writing {reg_name} for lane {lane_info.logic_lane}: {e}")
|
|
|
|
|
|
break
|
|
|
|
|
|
break
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_search_values(min_val: int, max_val: int, step: int) -> List[int]:
|
|
|
|
|
|
# 生成所有可能的值
|
|
|
|
|
|
all_values = list(range(min_val, max_val + 1, step))
|
|
|
|
|
|
|
|
|
|
|
|
if not all_values:
|
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
# 找到中间值的索引
|
|
|
|
|
|
mid_index = len(all_values) // 2
|
|
|
|
|
|
mid_val = all_values[mid_index]
|
|
|
|
|
|
|
|
|
|
|
|
# 从中间开始,交替向左右添加
|
|
|
|
|
|
search_values = [mid_val]
|
|
|
|
|
|
left_index = mid_index - 1
|
|
|
|
|
|
right_index = mid_index + 1
|
|
|
|
|
|
|
|
|
|
|
|
# 交替从左右两边取值
|
|
|
|
|
|
take_from_right = True # 先从右边开始(可调整)
|
|
|
|
|
|
while left_index >= 0 or right_index < len(all_values):
|
|
|
|
|
|
if take_from_right and right_index < len(all_values):
|
|
|
|
|
|
search_values.append(all_values[right_index])
|
|
|
|
|
|
right_index += 1
|
|
|
|
|
|
elif left_index >= 0: # 如果右边取完了或轮到左边
|
|
|
|
|
|
search_values.append(all_values[left_index])
|
|
|
|
|
|
left_index -= 1
|
|
|
|
|
|
# 切换方向
|
|
|
|
|
|
take_from_right = not take_from_right
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"Search order for lane {search_values}")
|
|
|
|
|
|
return search_values
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# def AutoTuneIbias(host: str, bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
# reg_table_parser: TransceiverConfigParser, route_name: str):
|
|
|
|
|
|
|
|
|
|
|
|
# ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
# ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
# if len(lane_list) == 8: # all, 8 is default value
|
|
|
|
|
|
# lane_list = [0,1,2,3]
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
|
|
|
|
|
|
# substandard_slot = []
|
|
|
|
|
|
|
|
|
|
|
|
# for slot_id in slot_list:
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f"start auto tune ibias: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
# for ibias_lane in lane_list:
|
|
|
|
|
|
# rssi_lanes = ibias_rssi_map.get_rssi_lane(route_name, ibias_lane)
|
|
|
|
|
|
# if rssi_lanes is None:
|
|
|
|
|
|
# logging.error(f'-----------------rssi lanes is none')
|
|
|
|
|
|
# continue
|
|
|
|
|
|
# # SetPrivateLinkRegister(bmc, host, exp_id, slot_id, [ibias_lane], ['ibias'], reg_table_file, )
|
|
|
|
|
|
# # 一个一个ibias的校准
|
|
|
|
|
|
|
|
|
|
|
|
# ibias_reg = reg_table_parser.get_register_by_logic_lane("ibias", ibias_lane)
|
|
|
|
|
|
|
|
|
|
|
|
# if not ibias_reg or not ibias_reg.valid_range or \
|
|
|
|
|
|
# not ibias_reg.step or len(ibias_reg.valid_range) < 2:
|
|
|
|
|
|
# logging.error(f'-----------invalid ibias_reg or valid_range or step for ibias_reg')
|
|
|
|
|
|
# continue
|
|
|
|
|
|
|
|
|
|
|
|
# min_val = ibias_reg.valid_range[0]
|
|
|
|
|
|
# max_val = ibias_reg.valid_range[1]
|
|
|
|
|
|
|
|
|
|
|
|
# step = ibias_reg.step
|
|
|
|
|
|
# logging.info(f'-------min_val: {min_val}, max_val: {max_val}, step: {step}')
|
|
|
|
|
|
# #search_values = get_search_values(min_val, max_val, step)
|
|
|
|
|
|
# search_values = list(range(min_val, max_val + 1, step))
|
|
|
|
|
|
# # search_values.sort(reverse=True)
|
|
|
|
|
|
# logging.info(f'-------search_values: {search_values}')
|
|
|
|
|
|
|
|
|
|
|
|
# measurements_map1 = []
|
|
|
|
|
|
# measurements_map2 = []
|
|
|
|
|
|
# expect_value = -1
|
|
|
|
|
|
# for ibias_value in search_values:
|
|
|
|
|
|
# value_hex_str = f"{ibias_value:04X}"
|
|
|
|
|
|
# result = bmc.SetOpticalModuleRegs(exp_id, slot_id, ibias_reg.bank, ibias_reg.page,
|
|
|
|
|
|
# ibias_reg.offset, 2, value_hex_str)
|
|
|
|
|
|
|
|
|
|
|
|
# for index, rssi_lane in enumerate(rssi_lanes):
|
|
|
|
|
|
# reg = reg_table_parser.get_register_by_logic_lane("rssi", rssi_lane)
|
|
|
|
|
|
# if not reg or not reg.valid_range:
|
|
|
|
|
|
# logging.error(f'------------- rssi reg or valid range is none')
|
|
|
|
|
|
# continue
|
|
|
|
|
|
|
|
|
|
|
|
# value = bmc.GetOpticalModuleRegs(exp_id, slot_id, reg.bank, reg.page, reg.offset, 2)
|
|
|
|
|
|
# rssi_value = int(value, 16)
|
|
|
|
|
|
# dbm = round(10 * math.log10(rssi_value / 10000), 3)
|
|
|
|
|
|
# logging.info(f'----------rssi_lane: {rssi_lane}, ibias: {ibias_value}, rssi value: {rssi_value}, dbm: {dbm}')
|
|
|
|
|
|
|
|
|
|
|
|
# min_val = reg.valid_range[0]
|
|
|
|
|
|
# max_val = reg.valid_range[1]
|
|
|
|
|
|
# expect_value = reg.value
|
|
|
|
|
|
# if expect_value is None:
|
|
|
|
|
|
# expect_value = 7080
|
|
|
|
|
|
# if rssi_value >= int(min_val) and rssi_value <= int(max_val):
|
|
|
|
|
|
# if index == 0:
|
|
|
|
|
|
# measurements_map1.append((ibias_value, rssi_value))
|
|
|
|
|
|
# elif index == 1:
|
|
|
|
|
|
# measurements_map2.append((ibias_value, rssi_value))
|
|
|
|
|
|
|
|
|
|
|
|
# # logging.info(f'rssi1 map: {measurements_map1}')
|
|
|
|
|
|
# # logging.info(f'rssi1 map: {measurements_map2}')
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f'rssi1 map: {measurements_map1}')
|
|
|
|
|
|
# logging.info(f'rssi2 map: {measurements_map2}')
|
|
|
|
|
|
# result = find_best_ibias_for_expected_rssi(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
# if result:
|
|
|
|
|
|
# ibias, rssi1, rssi2 = result
|
|
|
|
|
|
# logging.info(f"best ibias: {ibias}")
|
|
|
|
|
|
# logging.info(f" RSSI1: {rssi1}")
|
|
|
|
|
|
# logging.info(f" RSSI2: {rssi2}")
|
|
|
|
|
|
|
|
|
|
|
|
# value_hex_str = f"{ibias:04X}"
|
|
|
|
|
|
# logging.info(f'set best ibias value')
|
|
|
|
|
|
# result = bmc.SetOpticalModuleRegs(exp_id, slot_id, ibias_reg.bank, ibias_reg.page,
|
|
|
|
|
|
# ibias_reg.offset, 2, value_hex_str)
|
|
|
|
|
|
# else:
|
|
|
|
|
|
# logging.error("No ibias value present in both maps was found.")
|
|
|
|
|
|
# substandard_slot.append(slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info("Substandard SLOT:")
|
|
|
|
|
|
# for slot in substandard_slot:
|
|
|
|
|
|
# logging.error(f"exp: {exp_id}, slot: {slot}, MODULE: QDD{slot + 1}")
|
|
|
|
|
|
|
|
|
|
|
|
def AutoTuneIbiasOnetNew(host: str, bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool,
|
|
|
|
|
|
reg_table_file: str, route_name: str, ibias_rssi_map: IbiasRssiMapParser):
|
|
|
|
|
|
reg_table = TransceiverConfigParser(reg_table_file)
|
|
|
|
|
|
|
|
|
|
|
|
if len(lane_list) == 8: # all, 8 is default value
|
|
|
|
|
|
lane_list = [0,1,2,3]
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
|
|
|
|
|
|
substandard_slot = []
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune ibias: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
for ibias_lane in lane_list:
|
|
|
|
|
|
rssi_lanes = ibias_rssi_map.get_rssi_lane(route_name, ibias_lane)
|
|
|
|
|
|
if rssi_lanes is None:
|
|
|
|
|
|
logging.error(f'-----------------rssi lanes is none')
|
|
|
|
|
|
continue
|
|
|
|
|
|
# 一个一个ibias的校准
|
|
|
|
|
|
|
|
|
|
|
|
ibias_reg = reg_table.get_register_by_lane("ibias", ibias_lane)
|
|
|
|
|
|
if not ibias_reg or not ibias_reg.valid_range or \
|
|
|
|
|
|
not ibias_reg.step or len(ibias_reg.valid_range) < 2:
|
|
|
|
|
|
logging.error(f'-----------invalid ibias_reg or valid_range or step for ibias_reg')
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
min_val = ibias_reg.valid_range[0]
|
|
|
|
|
|
max_val = ibias_reg.valid_range[1]
|
|
|
|
|
|
|
|
|
|
|
|
step = ibias_reg.step
|
|
|
|
|
|
logging.info(f'-------min_val: {min_val}, max_val: {max_val}, step: {step}')
|
|
|
|
|
|
#search_values = get_search_values(min_val, max_val, step)
|
|
|
|
|
|
search_values = list(range(min_val, max_val + 1, step))
|
|
|
|
|
|
# search_values.sort(reverse=True)
|
|
|
|
|
|
logging.info(f'-------search_values: {search_values}')
|
|
|
|
|
|
|
|
|
|
|
|
measurements_map1 = []
|
|
|
|
|
|
measurements_map2 = []
|
|
|
|
|
|
expect_value = -1
|
|
|
|
|
|
for ibias_value in search_values:
|
|
|
|
|
|
value_hex_str = f"{ibias_value:04X}"
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
result = remote_bmc.SetOpticalModuleRegs(exp_id, slot_id, ibias_reg.bank, ibias_reg.page,
|
|
|
|
|
|
ibias_reg.offset, 2, value_hex_str)
|
|
|
|
|
|
time.sleep(0.2)
|
|
|
|
|
|
for index, rssi_lane in enumerate(rssi_lanes):
|
|
|
|
|
|
reg = reg_table.get_register_by_lane("rssi", rssi_lane)
|
|
|
|
|
|
if not reg or not reg.valid_range:
|
|
|
|
|
|
logging.error(f'------------- rssi reg or valid range is none')
|
|
|
|
|
|
continue
|
|
|
|
|
|
value = bmc.GetOpticalModuleRegs(exp_id, slot_id, reg.bank, reg.page, reg.offset, 2)
|
|
|
|
|
|
rssi_value = int(value, 16)
|
|
|
|
|
|
dbm = round(10 * math.log10(rssi_value / 10000), 3)
|
|
|
|
|
|
logging.info(f'{bmc.m_smbus.server_id}<-{remote_bmc.m_smbus.server_id} slot:{slot_id}, ibias_lane: {ibias_lane}, ibias: {ibias_value}, rssi_lane: {rssi_lane}, rssi value: {rssi_value}, dbm: {dbm}')
|
|
|
|
|
|
|
|
|
|
|
|
min_val = reg.valid_range[0]
|
|
|
|
|
|
max_val = reg.valid_range[1]
|
|
|
|
|
|
# expect_value = reg.value
|
|
|
|
|
|
# if expect_value is None:
|
|
|
|
|
|
expect_value = 5623 #-2.5, old 6310 (-2.0)
|
|
|
|
|
|
# if rssi_value >= int(min_val) and rssi_value <= int(max_val):
|
|
|
|
|
|
if index == 0:
|
|
|
|
|
|
measurements_map1.append((ibias_value, rssi_value))
|
|
|
|
|
|
elif index == 1:
|
|
|
|
|
|
measurements_map2.append((ibias_value, rssi_value))
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f'rssi1 map: {measurements_map1}')
|
|
|
|
|
|
# logging.info(f'rssi1 map: {measurements_map2}')
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'rssi1 map: {measurements_map1}')
|
|
|
|
|
|
logging.info(f'rssi2 map: {measurements_map2}')
|
|
|
|
|
|
dbm = round(10 * math.log10(expect_value / 10000), 3)
|
|
|
|
|
|
logging.info(f'expect_value: {expect_value}, {dbm}dbm')
|
|
|
|
|
|
result = find_best_ibias_for_expected_rssi(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
# rssi_val1 = next((r for i, r in measurements_map1 if i == 2047), None)
|
|
|
|
|
|
# rssi_val2 = next((r for i, r in measurements_map2 if i == 2047), None)
|
|
|
|
|
|
# dbm1 = round(10 * math.log10(rssi_val1 / 10000), 3)
|
|
|
|
|
|
# dbm2 = round(10 * math.log10(rssi_val2 / 10000), 3)
|
|
|
|
|
|
# if dbm1 < -4 or dbm2 < -4:
|
|
|
|
|
|
# substandard_slot.append(slot_id)
|
|
|
|
|
|
# break
|
|
|
|
|
|
|
|
|
|
|
|
# elif dbm1 < -3.5 or dbm2 < -3.5: # -3.5 ~ -4
|
|
|
|
|
|
# except_dbm = -2.8
|
|
|
|
|
|
# expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
# elif dbm1 < -2.5 or dbm2 < -2.5: # -2.5 ~ -3.5
|
|
|
|
|
|
# except_dbm = -2.7
|
|
|
|
|
|
# expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
# elif dbm1 < -1.5 or dbm2 < -1.5: # -1.5 ~ -2.5
|
|
|
|
|
|
# except_dbm = -1.5
|
|
|
|
|
|
# expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
|
|
|
|
|
|
if result:
|
|
|
|
|
|
ibias, rssi1, rssi2 = result
|
|
|
|
|
|
|
|
|
|
|
|
if ibias < 2500:
|
|
|
|
|
|
except_dbm = -1.6
|
|
|
|
|
|
expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
logging.info(f' < 2500, use except_dbm {except_dbm}, old ibias: {ibias}')
|
|
|
|
|
|
result = find_best_ibias_for_expected_rssi_old(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
ibias, rssi1, rssi2 = result
|
|
|
|
|
|
|
|
|
|
|
|
if ibias > 2900:
|
|
|
|
|
|
except_dbm = -2.8
|
|
|
|
|
|
expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
logging.info(f' > 2900, use except_dbm {except_dbm}, old ibias: {ibias}')
|
|
|
|
|
|
result = find_best_ibias_for_expected_rssi(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
ibias, rssi1, rssi2 = result
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"{bmc.m_smbus.server_id}->{remote_bmc.m_smbus.server_id} ibias_lane: {ibias_lane}, best ibias: {ibias}")
|
|
|
|
|
|
logging.info(f"rssi_lane: {rssi_lanes[0]}, RSSI1: {rssi1}")
|
|
|
|
|
|
logging.info(f"rssi_lane: {rssi_lanes[1]} RSSI2: {rssi2}")
|
|
|
|
|
|
|
|
|
|
|
|
value_hex_str = f"{ibias:04X}"
|
|
|
|
|
|
logging.info(f'set best ibias value')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
result = remote_bmc.SetOpticalModuleRegs(exp_id, slot_id, ibias_reg.bank, ibias_reg.page,
|
|
|
|
|
|
ibias_reg.offset, 2, value_hex_str)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.warning(f'default expect_value{expect_value} not match! use 7586(-1.2dbm)')
|
|
|
|
|
|
expect_value = 7586 # -1.2
|
|
|
|
|
|
result = find_best_ibias_for_expected_rssi(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
if result:
|
|
|
|
|
|
ibias, rssi1, rssi2 = result
|
|
|
|
|
|
if ibias <= 2547:
|
|
|
|
|
|
logging.info(f"{bmc.m_smbus.server_id}->{remote_bmc.m_smbus.server_id} ibias_lane: {ibias_lane}, best ibias: {ibias}")
|
|
|
|
|
|
logging.info(f"rssi_lane: {rssi_lanes[0]}, RSSI1: {rssi1}")
|
|
|
|
|
|
logging.info(f"rssi_lane: {rssi_lanes[1]} RSSI2: {rssi2}")
|
|
|
|
|
|
|
|
|
|
|
|
value_hex_str = f"{ibias:04X}"
|
|
|
|
|
|
logging.info(f'set best ibias value')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
result = remote_bmc.SetOpticalModuleRegs(exp_id, slot_id, ibias_reg.bank, ibias_reg.page,
|
|
|
|
|
|
ibias_reg.offset, 2, value_hex_str)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.error("No ibias value present in both maps was found.")
|
|
|
|
|
|
substandard_slot.append(slot_id)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.error("No ibias value present in both maps was found.")
|
|
|
|
|
|
substandard_slot.append(slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info("Substandard SLOT:")
|
|
|
|
|
|
for slot in substandard_slot:
|
|
|
|
|
|
logging.error(f"exp: {exp_id}, slot: {slot}, MODULE: QDD{slot + 1}")
|
|
|
|
|
|
|
|
|
|
|
|
def AutoTuneIbiasOnet(host: str, bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, reg_table_file: str, route_name: str, ibias_rssi_map: IbiasRssiMapParser):
|
|
|
|
|
|
reg_table = TransceiverConfigParser(reg_table_file)
|
|
|
|
|
|
|
|
|
|
|
|
if len(lane_list) == 8: # all, 8 is default value
|
|
|
|
|
|
lane_list = [0,1,2,3]
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
|
|
|
|
|
|
substandard_slot = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
remote_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0, 0xB4, 0x88, 1, '00')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune ibias: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
for ibias_lane in lane_list:
|
|
|
|
|
|
rssi_lanes = ibias_rssi_map.get_rssi_lane(route_name, ibias_lane)
|
|
|
|
|
|
if rssi_lanes is None:
|
|
|
|
|
|
logging.error(f'-----------------rssi lanes is none')
|
|
|
|
|
|
continue
|
|
|
|
|
|
# 一个一个ibias的校准
|
|
|
|
|
|
|
|
|
|
|
|
ibias_reg = reg_table.get_register_by_lane("ibias", ibias_lane)
|
|
|
|
|
|
if not ibias_reg or not ibias_reg.valid_range or \
|
|
|
|
|
|
not ibias_reg.step or len(ibias_reg.valid_range) < 2:
|
|
|
|
|
|
logging.error(f'-----------invalid ibias_reg or valid_range or step for ibias_reg')
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
min_val = ibias_reg.valid_range[0]
|
|
|
|
|
|
max_val = ibias_reg.valid_range[1]
|
|
|
|
|
|
|
|
|
|
|
|
step = ibias_reg.step
|
|
|
|
|
|
logging.info(f'-------min_val: {min_val}, max_val: {max_val}, step: {step}')
|
|
|
|
|
|
#search_values = get_search_values(min_val, max_val, step)
|
|
|
|
|
|
search_values = list(range(min_val, max_val + 1, step))
|
|
|
|
|
|
# search_values.sort(reverse=True)
|
|
|
|
|
|
logging.info(f'-------search_values: {search_values}')
|
|
|
|
|
|
|
|
|
|
|
|
measurements_map1 = []
|
|
|
|
|
|
measurements_map2 = []
|
|
|
|
|
|
expect_value = -1
|
|
|
|
|
|
for ibias_value in search_values:
|
|
|
|
|
|
value_hex_str = f"{ibias_value:04X}"
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
result = remote_bmc.SetOpticalModuleRegs(exp_id, slot_id, ibias_reg.bank, ibias_reg.page,
|
|
|
|
|
|
ibias_reg.offset, 2, value_hex_str)
|
|
|
|
|
|
time.sleep(0.2)
|
|
|
|
|
|
for index, rssi_lane in enumerate(rssi_lanes):
|
|
|
|
|
|
reg = reg_table.get_register_by_lane("rssi", rssi_lane)
|
|
|
|
|
|
if not reg or not reg.valid_range:
|
|
|
|
|
|
logging.error(f'------------- rssi reg or valid range is none')
|
|
|
|
|
|
continue
|
|
|
|
|
|
value = bmc.GetOpticalModuleRegs(exp_id, slot_id, reg.bank, reg.page, reg.offset, 2)
|
|
|
|
|
|
rssi_value = int(value, 16)
|
|
|
|
|
|
dbm = round(10 * math.log10(rssi_value / 10000), 3)
|
|
|
|
|
|
logging.info(f'{bmc.m_smbus.server_id}<-{remote_bmc.m_smbus.server_id} slot:{slot_id}, ibias_lane: {ibias_lane}, ibias: {ibias_value}, rssi_lane: {rssi_lane}, rssi value: {rssi_value}, dbm: {dbm}')
|
|
|
|
|
|
|
|
|
|
|
|
min_val = reg.valid_range[0]
|
|
|
|
|
|
max_val = reg.valid_range[1]
|
|
|
|
|
|
# expect_value = reg.value
|
|
|
|
|
|
# if expect_value is None:
|
|
|
|
|
|
expect_value = 5623 #-2.5, old 6310 (-2.0)
|
|
|
|
|
|
# if rssi_value >= int(min_val) and rssi_value <= int(max_val):
|
|
|
|
|
|
if index == 0:
|
|
|
|
|
|
measurements_map1.append((ibias_value, rssi_value))
|
|
|
|
|
|
elif index == 1:
|
|
|
|
|
|
measurements_map2.append((ibias_value, rssi_value))
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f'rssi1 map: {measurements_map1}')
|
|
|
|
|
|
# logging.info(f'rssi1 map: {measurements_map2}')
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'rssi1 map: {measurements_map1}')
|
|
|
|
|
|
logging.info(f'rssi2 map: {measurements_map2}')
|
|
|
|
|
|
dbm = round(10 * math.log10(expect_value / 10000), 3)
|
|
|
|
|
|
logging.info(f'expect_value: {expect_value}, {dbm}dbm')
|
|
|
|
|
|
result = find_best_ibias_for_expected_rssi(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
# rssi_val1 = next((r for i, r in measurements_map1 if i == 2047), None)
|
|
|
|
|
|
# rssi_val2 = next((r for i, r in measurements_map2 if i == 2047), None)
|
|
|
|
|
|
# dbm1 = round(10 * math.log10(rssi_val1 / 10000), 3)
|
|
|
|
|
|
# dbm2 = round(10 * math.log10(rssi_val2 / 10000), 3)
|
|
|
|
|
|
# if dbm1 < -4 or dbm2 < -4:
|
|
|
|
|
|
# substandard_slot.append(slot_id)
|
|
|
|
|
|
# break
|
|
|
|
|
|
|
|
|
|
|
|
# elif dbm1 < -3.5 or dbm2 < -3.5: # -3.5 ~ -4
|
|
|
|
|
|
# except_dbm = -2.8
|
|
|
|
|
|
# expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
# elif dbm1 < -2.5 or dbm2 < -2.5: # -2.5 ~ -3.5
|
|
|
|
|
|
# except_dbm = -2.7
|
|
|
|
|
|
# expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
# elif dbm1 < -1.5 or dbm2 < -1.5: # -1.5 ~ -2.5
|
|
|
|
|
|
# except_dbm = -1.5
|
|
|
|
|
|
# expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
|
|
|
|
|
|
if result:
|
|
|
|
|
|
ibias, rssi1, rssi2 = result
|
|
|
|
|
|
|
|
|
|
|
|
if ibias < 2500:
|
|
|
|
|
|
except_dbm = -1.6
|
|
|
|
|
|
expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
logging.info(f' < 2500, use except_dbm {except_dbm}, old ibias: {ibias}')
|
|
|
|
|
|
result = find_best_ibias_for_expected_rssi_old(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
ibias, rssi1, rssi2 = result
|
|
|
|
|
|
|
|
|
|
|
|
if ibias > 2900:
|
|
|
|
|
|
except_dbm = -2.8
|
|
|
|
|
|
expect_value = int(10000 * (10 ** (except_dbm / 10)))
|
|
|
|
|
|
logging.info(f' > 2900, use except_dbm {except_dbm}, old ibias: {ibias}')
|
|
|
|
|
|
result = find_best_ibias_for_expected_rssi(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
ibias, rssi1, rssi2 = result
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"{bmc.m_smbus.server_id}->{remote_bmc.m_smbus.server_id} ibias_lane: {ibias_lane}, best ibias: {ibias}")
|
|
|
|
|
|
logging.info(f"rssi_lane: {rssi_lanes[0]}, RSSI1: {rssi1}")
|
|
|
|
|
|
logging.info(f"rssi_lane: {rssi_lanes[1]} RSSI2: {rssi2}")
|
|
|
|
|
|
|
|
|
|
|
|
value_hex_str = f"{ibias:04X}"
|
|
|
|
|
|
logging.info(f'set best ibias value')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
result = remote_bmc.SetOpticalModuleRegs(exp_id, slot_id, ibias_reg.bank, ibias_reg.page,
|
|
|
|
|
|
ibias_reg.offset, 2, value_hex_str)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.warning(f'default expect_value{expect_value} not match! use 7586(-1.2dbm)')
|
|
|
|
|
|
expect_value = 7586 # -1.2
|
|
|
|
|
|
result = find_best_ibias_for_expected_rssi(measurements_map1, measurements_map2, expect_value)
|
|
|
|
|
|
if result:
|
|
|
|
|
|
ibias, rssi1, rssi2 = result
|
|
|
|
|
|
if ibias <= 2547:
|
|
|
|
|
|
logging.info(f"{bmc.m_smbus.server_id}->{remote_bmc.m_smbus.server_id} ibias_lane: {ibias_lane}, best ibias: {ibias}")
|
|
|
|
|
|
logging.info(f"rssi_lane: {rssi_lanes[0]}, RSSI1: {rssi1}")
|
|
|
|
|
|
logging.info(f"rssi_lane: {rssi_lanes[1]} RSSI2: {rssi2}")
|
|
|
|
|
|
|
|
|
|
|
|
value_hex_str = f"{ibias:04X}"
|
|
|
|
|
|
logging.info(f'set best ibias value')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
result = remote_bmc.SetOpticalModuleRegs(exp_id, slot_id, ibias_reg.bank, ibias_reg.page,
|
|
|
|
|
|
ibias_reg.offset, 2, value_hex_str)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.error("No ibias value present in both maps was found.")
|
|
|
|
|
|
substandard_slot.append(slot_id)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.error("No ibias value present in both maps was found.")
|
|
|
|
|
|
substandard_slot.append(slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info("Substandard SLOT:")
|
|
|
|
|
|
for slot in substandard_slot:
|
|
|
|
|
|
logging.error(f"exp: {exp_id}, slot: {slot}, MODULE: QDD{slot + 1}")
|
|
|
|
|
|
|
|
|
|
|
|
# reg_access_tool, bmc, host, exp_id, slot_list, ibias_rssi_map, route_name
|
|
|
|
|
|
def RssiCheck(reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool,
|
|
|
|
|
|
bmc: DevWhiteRiverExp, host: str, exp_id: int, slot_list: List[int],
|
|
|
|
|
|
ibias_rssi_map: IbiasRssiMapParser, route_name):
|
|
|
|
|
|
|
|
|
|
|
|
bad_modules = []
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
for ibias_lane in [0, 1, 2, 3]:
|
|
|
|
|
|
ibias_value = remote_reg_tool.read_ibias_reg_by_ibias_lane(exp_id, slot_id, ibias_lane)
|
|
|
|
|
|
|
|
|
|
|
|
rssi_lanes = ibias_rssi_map.get_rssi_lane(route_name, ibias_lane)
|
|
|
|
|
|
if rssi_lanes is None:
|
|
|
|
|
|
logging.error(f'RSSI lanes not found for exp: {exp_id}, slot: {slot_id}, ibias_lane: {ibias_lane}')
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
rssi1_value = reg_tool.read_rssi_reg(exp_id, slot_id, rssi_lanes[0])
|
|
|
|
|
|
rssi2_value = reg_tool.read_rssi_reg(exp_id, slot_id, rssi_lanes[1])
|
|
|
|
|
|
dbm1 = round(10 * math.log10(rssi1_value / 10000), 3)
|
|
|
|
|
|
dbm2 = round(10 * math.log10(rssi2_value / 10000), 3)
|
|
|
|
|
|
|
|
|
|
|
|
if abs(dbm1 - dbm2) > 2.0:
|
|
|
|
|
|
bad_modules.append({
|
|
|
|
|
|
'exp_id': exp_id,
|
|
|
|
|
|
'slot_id': slot_id,
|
|
|
|
|
|
'ibias_lane': ibias_lane,
|
|
|
|
|
|
'rssi1_lane': rssi_lanes[0],
|
|
|
|
|
|
'rssi2_lane': rssi_lanes[1],
|
|
|
|
|
|
'ibias': ibias_value,
|
|
|
|
|
|
'dbm1': dbm1,
|
|
|
|
|
|
'dbm2': dbm2,
|
|
|
|
|
|
'diff': abs(dbm1 - dbm2)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if ibias_value > 2800 and ((dbm1 < -3) or (dbm2 < -3)):
|
|
|
|
|
|
bad_modules.append({
|
|
|
|
|
|
'exp_id': exp_id,
|
|
|
|
|
|
'slot_id': slot_id,
|
|
|
|
|
|
'ibias_lane': ibias_lane,
|
|
|
|
|
|
'rssi1_lane': rssi_lanes[0],
|
|
|
|
|
|
'rssi2_lane': rssi_lanes[1],
|
|
|
|
|
|
'ibias': ibias_value,
|
|
|
|
|
|
'dbm1': dbm1,
|
|
|
|
|
|
'dbm2': dbm2,
|
|
|
|
|
|
'diff': abs(dbm1 - dbm2)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if ibias_value > 3000 and ((dbm1 < -2.5) or (dbm2 < -2.5)):
|
|
|
|
|
|
bad_modules.append({
|
|
|
|
|
|
'exp_id': exp_id,
|
|
|
|
|
|
'slot_id': slot_id,
|
|
|
|
|
|
'ibias_lane': ibias_lane,
|
|
|
|
|
|
'rssi1_lane': rssi_lanes[0],
|
|
|
|
|
|
'rssi2_lane': rssi_lanes[1],
|
|
|
|
|
|
'ibias': ibias_value,
|
|
|
|
|
|
'dbm1': dbm1,
|
|
|
|
|
|
'dbm2': dbm2,
|
|
|
|
|
|
'diff': abs(dbm1 - dbm2)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if bad_modules:
|
|
|
|
|
|
logging.error("❌ Found bad optical modules (|dBm1 - dBm2| > 2.0):")
|
|
|
|
|
|
for mod in bad_modules:
|
|
|
|
|
|
logging.error(
|
|
|
|
|
|
f"host:{host}, exp:{mod['exp_id']}, slot:{mod['slot_id']},"
|
|
|
|
|
|
f"ibias_lane:{mod['ibias_lane']} "
|
|
|
|
|
|
f"ibias:{mod['ibias']} "
|
|
|
|
|
|
f"rssi_lane{mod['rssi1_lane']}={mod['dbm1']}, "
|
|
|
|
|
|
f"rssi_lane{mod['rssi2_lane']}={mod['dbm2']} "
|
|
|
|
|
|
f"(diff:{mod['diff']:.3f}) → BAD"
|
|
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.info("✅ All modules passed RSSI consistency check.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def TiaPeakTune(reg_tool: OptRegAccessTool, bmc: DevWhiteRiverExp, host: str, exp_id: int, slot_list: List[int],
|
|
|
|
|
|
lane_list: List[int], regs: List[str]):
|
|
|
|
|
|
|
|
|
|
|
|
# all
|
|
|
|
|
|
reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7], ['tia_peak'], '138')
|
|
|
|
|
|
# # > 5500
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0], ['tia_peak'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [2], [3], ['tia_peak'], '100')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,1], [2], ['tia_peak'], '100')
|
|
|
|
|
|
# # > 4500 - 5500
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,1,3,4,5,6,7], [3], ['tia_peak'], '150')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0], [6], ['tia_peak'], '150')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [2,3,4,5,6,7], [2], ['tia_peak'], '150')
|
|
|
|
|
|
# # < 3500
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [3,4,5], [4], ['tia_peak'], '200')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [4,5,6], [5], ['tia_peak'], '200')
|
|
|
|
|
|
# reg_tool.write_opt_regs(exp_id, [0,2,3], [1], ['tia_peak'], '200')
|
|
|
|
|
|
|
|
|
|
|
|
def MgcTune(reg_tool: OptRegAccessTool, bmc: DevWhiteRiverExp, host: str, exp_id: int, slot_list: List[int],
|
|
|
|
|
|
lane_list: List[int], reg_wt_value):
|
|
|
|
|
|
if reg_wt_value != '':
|
|
|
|
|
|
ext_value = int(reg_wt_value)
|
|
|
|
|
|
else:
|
|
|
|
|
|
ext_value = 5
|
|
|
|
|
|
|
|
|
|
|
|
all_lane_reg_values = reg_tool.read_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7], ['mgc'])
|
|
|
|
|
|
# all_lane_reg_values = reg_tool.read_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [1,5], ['mgc'])
|
|
|
|
|
|
# logging.info(f'ret data: {all_lane_reg_values}')
|
|
|
|
|
|
for lane_reg in all_lane_reg_values:
|
|
|
|
|
|
# logging.info(f'------step 1')
|
|
|
|
|
|
if lane_reg.mgc != -1:
|
|
|
|
|
|
# logging.info(f'------step 2')
|
|
|
|
|
|
new_mgc = lane_reg.mgc - ext_value
|
|
|
|
|
|
# logging.info(f'------step 3, new_mgc: {new_mgc}')
|
|
|
|
|
|
reg_tool.write_mgc_reg(exp_id, lane_reg.slot_id, lane_reg.logic_lane, new_mgc)
|
|
|
|
|
|
# logging.info(f'------step 4')
|
|
|
|
|
|
reg_tool.write_confirm_reg(exp_id, lane_reg.slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
# all_lane_reg_values = reg_tool.read_opt_regs(exp_id, [0,1,2,3,4,5,6,7], [0], ['mgc'])
|
|
|
|
|
|
# for lane_reg in all_lane_reg_values:
|
|
|
|
|
|
# if lane_reg.mgc != -1:
|
|
|
|
|
|
# new_mgc = lane_reg.mgc + ext_value
|
|
|
|
|
|
# reg_tool.write_mgc_reg(exp_id, lane_reg.slot_id, lane_reg.logic_lane, new_mgc)
|
|
|
|
|
|
# reg_tool.write_confirm_reg(exp_id, lane_reg.slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# all_lane_reg_values = reg_tool.read_opt_regs(exp_id, [2], [3], ['mgc'])
|
|
|
|
|
|
# for lane_reg in all_lane_reg_values:
|
|
|
|
|
|
# if lane_reg.mgc != -1:
|
|
|
|
|
|
# new_mgc = lane_reg.mgc + ext_value
|
|
|
|
|
|
# reg_tool.write_mgc_reg(exp_id, lane_reg.slot_id, lane_reg.logic_lane, new_mgc)
|
|
|
|
|
|
# reg_tool.write_confirm_reg(exp_id, lane_reg.slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
# all_lane_reg_values = reg_tool.read_opt_regs(exp_id, [0,1], [2], ['mgc'])
|
|
|
|
|
|
# for lane_reg in all_lane_reg_values:
|
|
|
|
|
|
# if lane_reg.mgc != -1:
|
|
|
|
|
|
# new_mgc = lane_reg.mgc + ext_value
|
|
|
|
|
|
# reg_tool.write_mgc_reg(exp_id, lane_reg.slot_id, lane_reg.logic_lane, new_mgc)
|
|
|
|
|
|
# reg_tool.write_confirm_reg(exp_id, lane_reg.slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def SwaAutoTune(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune eq: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xD0, 0x8A, 1, "01")
|
|
|
|
|
|
for lane_id in lane_list:
|
|
|
|
|
|
max_index, max_value, min_index, min_value = get_swa_adc_per_lane(local_bmc, exp_id, slot_id, lane_id)
|
|
|
|
|
|
if max_value != 0 and min_value != 0:
|
|
|
|
|
|
# swa: max -> onoc min-> onet, swb: max -> onetb
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, max_index, 'swa_onoc_h')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, max_index, 'swa_onoc_m')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, max_index, 'swa_onoc_l')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, min_index, 'swa_onet_h')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, min_index, 'swa_onet_m')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, min_index, 'swa_onet_l')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.error(f'Read swa pic failed')
|
|
|
|
|
|
|
|
|
|
|
|
def SwbAutoTune(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune eq: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xD0, 0x8A, 1, "01")
|
|
|
|
|
|
for lane_id in lane_list:
|
|
|
|
|
|
max_index, max_value, min_index, min_value = get_swb_adc_per_lane(local_bmc, exp_id, slot_id, lane_id)
|
|
|
|
|
|
if max_value != 0 and min_value != 0:
|
|
|
|
|
|
# swa: max -> onoc min-> onet, swb: max -> onetb
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, max_index, 'swb_onetb_h')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, max_index, 'swb_onetb_m')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, max_index, 'swb_onetb_l')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, min_index, 'swb_oneta_h')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, min_index, 'swb_oneta_m')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, min_index, 'swb_oneta_l')
|
|
|
|
|
|
time.sleep(0.08)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.error(f'Read swb pic failed')
|
|
|
|
|
|
|
|
|
|
|
|
def get_swa_adc_per_lane(local_bmc: DevWhiteRiverExp, exp_id: int, slot_id: int, lane_id: int):
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAB, 1, "02")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAC, 1, f"{lane_id:02x}")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAD, 1, f"{lane_id:02x}")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAE, 1, f"01")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAF, 1, f"01")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAA, 1, "07")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
logging.info('step 1')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(3)
|
|
|
|
|
|
status = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xB0, 1)
|
|
|
|
|
|
if status == 'aa':
|
|
|
|
|
|
|
|
|
|
|
|
swa_adc1 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA0, 0x80, 128)
|
|
|
|
|
|
swa_adc2 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA1, 0x80, 128)
|
|
|
|
|
|
swa_adc3 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA2, 0x80, 128)
|
|
|
|
|
|
swa_adc4 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA3, 0x80, 128)
|
|
|
|
|
|
swa_adc5 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA4, 0x80, 128)
|
|
|
|
|
|
swa_adc6 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA5, 0x80, 128)
|
|
|
|
|
|
swa_adc7 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA6, 0x80, 128)
|
|
|
|
|
|
swa_adc8 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA7, 0x80, 128)
|
|
|
|
|
|
|
|
|
|
|
|
full_hex_string = swa_adc1 + swa_adc2 + swa_adc3 + swa_adc4 + swa_adc5 + swa_adc6 + swa_adc7 + swa_adc8
|
|
|
|
|
|
|
|
|
|
|
|
byte_strings = [full_hex_string[i:i+4] for i in range(0, len(full_hex_string), 4)]
|
|
|
|
|
|
|
|
|
|
|
|
data_values = [int(byte_str, 16) for byte_str in byte_strings]
|
|
|
|
|
|
|
|
|
|
|
|
max_value = max(data_values)
|
|
|
|
|
|
min_value = min(data_values)
|
|
|
|
|
|
max_index = data_values.index(max_value)
|
|
|
|
|
|
min_index = data_values.index(min_value)
|
|
|
|
|
|
|
|
|
|
|
|
x = list(range(len(data_values)))
|
|
|
|
|
|
plt.figure(figsize=(12, 6))
|
|
|
|
|
|
plt.plot(x, data_values, linewidth=1.5)
|
|
|
|
|
|
plt.title('Data Curve Plot', fontsize=16)
|
|
|
|
|
|
plt.xlabel('idac', fontsize=12)
|
|
|
|
|
|
plt.ylabel('mpd', fontsize=12)
|
|
|
|
|
|
plt.grid(True, alpha=0.3)
|
|
|
|
|
|
plt.tight_layout()
|
|
|
|
|
|
|
|
|
|
|
|
plt.savefig('data_curve.png', dpi=300, bbox_inches='tight')
|
|
|
|
|
|
plt.close()
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f"full_hex_string: {full_hex_string}")
|
|
|
|
|
|
# logging.info(f'data_values: {data_values}')
|
|
|
|
|
|
logging.info(f"max value: {max_value}, index: {max_index}")
|
|
|
|
|
|
logging.info(f"min value: {min_value}, index: {min_index}")
|
|
|
|
|
|
|
|
|
|
|
|
return (max_index, max_value, min_index, min_value)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return (0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
|
|
def get_swb_adc_per_lane(local_bmc: DevWhiteRiverExp, exp_id: int, slot_id: int, lane_id: int):
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAB, 1, "03")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAC, 1, f"{lane_id:02x}")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAD, 1, f"{lane_id:02x}")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAE, 1, f"01")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAF, 1, f"01")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAA, 1, "07")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
logging.info('step 1')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(3)
|
|
|
|
|
|
status = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xB0, 1)
|
|
|
|
|
|
if status == 'aa':
|
|
|
|
|
|
|
|
|
|
|
|
swb_adc1 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA0, 0x80, 128)
|
|
|
|
|
|
swb_adc2 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA1, 0x80, 128)
|
|
|
|
|
|
swb_adc3 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA2, 0x80, 128)
|
|
|
|
|
|
swb_adc4 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA3, 0x80, 128)
|
|
|
|
|
|
swb_adc5 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA4, 0x80, 128)
|
|
|
|
|
|
swb_adc6 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA5, 0x80, 128)
|
|
|
|
|
|
swb_adc7 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA6, 0x80, 128)
|
|
|
|
|
|
swb_adc8 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA7, 0x80, 128)
|
|
|
|
|
|
|
|
|
|
|
|
full_hex_string = swb_adc1 + swb_adc2 + swb_adc3 + swb_adc4 + swb_adc5 + swb_adc6 + swb_adc7 + swb_adc8
|
|
|
|
|
|
|
|
|
|
|
|
byte_strings = [full_hex_string[i:i+4] for i in range(0, len(full_hex_string), 4)]
|
|
|
|
|
|
|
|
|
|
|
|
data_values = [int(byte_str, 16) for byte_str in byte_strings]
|
|
|
|
|
|
|
|
|
|
|
|
max_value = max(data_values)
|
|
|
|
|
|
min_value = min(data_values)
|
|
|
|
|
|
max_index = data_values.index(max_value)
|
|
|
|
|
|
min_index = data_values.index(min_value)
|
|
|
|
|
|
|
|
|
|
|
|
x = list(range(len(data_values)))
|
|
|
|
|
|
plt.figure(figsize=(12, 6))
|
|
|
|
|
|
plt.plot(x, data_values, linewidth=1.5)
|
|
|
|
|
|
plt.title('Data Curve Plot', fontsize=16)
|
|
|
|
|
|
plt.xlabel('idac', fontsize=12)
|
|
|
|
|
|
plt.ylabel('mpd', fontsize=12)
|
|
|
|
|
|
plt.grid(True, alpha=0.3)
|
|
|
|
|
|
plt.tight_layout()
|
|
|
|
|
|
|
|
|
|
|
|
plt.savefig(f'main_data/data_curve/data_curve_{lane_id}.png', dpi=300, bbox_inches='tight')
|
|
|
|
|
|
plt.close()
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f"full_hex_string: {full_hex_string}")
|
|
|
|
|
|
# logging.info(f'data_values: {data_values}')
|
|
|
|
|
|
logging.info(f"max value: {max_value}, index: {max_index}")
|
|
|
|
|
|
logging.info(f"min value: {min_value}, index: {min_index}")
|
|
|
|
|
|
|
|
|
|
|
|
return (max_index, max_value, min_index, min_value)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return (0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
|
|
def find_rising_edge_47_percent(y_data):
|
|
|
|
|
|
if not y_data or len(y_data) < 2:
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
y_min = min(y_data)
|
|
|
|
|
|
y_max = max(y_data)
|
|
|
|
|
|
if y_max == y_min:
|
|
|
|
|
|
return None # 无变化
|
|
|
|
|
|
|
|
|
|
|
|
target_y = y_min + 0.47 * (y_max - y_min)
|
|
|
|
|
|
|
|
|
|
|
|
# 从左到右扫描上升沿
|
|
|
|
|
|
for i in range(len(y_data) - 1):
|
|
|
|
|
|
y_curr = y_data[i]
|
|
|
|
|
|
y_next = y_data[i + 1]
|
|
|
|
|
|
|
|
|
|
|
|
# 必须是上升趋势
|
|
|
|
|
|
if y_next > y_curr and y_curr <= target_y < y_next:
|
|
|
|
|
|
# 线性插值
|
|
|
|
|
|
x_curr = i * 8
|
|
|
|
|
|
x_next = (i + 1) * 8
|
|
|
|
|
|
# 避免除零(虽然 y_next > y_curr 已保证)
|
|
|
|
|
|
slope = (y_next - y_curr) / (x_next - x_curr)
|
|
|
|
|
|
x_target = x_curr + (target_y - y_curr) / slope
|
|
|
|
|
|
return x_target
|
|
|
|
|
|
|
|
|
|
|
|
# 如果没找到,可能目标值在最后一点之后?再检查是否等于最后一个点
|
|
|
|
|
|
if abs(y_data[-1] - target_y) < 1e-6:
|
|
|
|
|
|
return (len(y_data) - 1) * 8
|
|
|
|
|
|
|
|
|
|
|
|
# 未找到上升沿穿越点
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def MzmAutoTune(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune eq: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xD0, 0x8A, 1, "01")
|
|
|
|
|
|
for lane_id in lane_list:
|
|
|
|
|
|
|
|
|
|
|
|
best_mpd = 0
|
|
|
|
|
|
best_idac = 0
|
|
|
|
|
|
for vadc in range(0, 4096, 800):
|
|
|
|
|
|
local_reg_tool.write_opt_reg(exp_id, slot_id, lane_id, vadc, 'vdac_runtime')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
max_index, max_value, min_index, min_value = get_swa_adc_per_lane(local_bmc, exp_id, slot_id, lane_id)
|
|
|
|
|
|
if max_value > best_mpd:
|
|
|
|
|
|
best_mpd = max_value
|
|
|
|
|
|
best_idac = max_index
|
|
|
|
|
|
# set idac
|
|
|
|
|
|
logging.info(f"vadc: {vadc}, current_value: {max_value}, best: {best_idac}")
|
|
|
|
|
|
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAB, 1, "02")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAC, 1, f"{lane_id:02x}")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
idac_str = best_idac.to_bytes(2, 'big').hex()
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAD, 2, idac_str)
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAF, 1, f"00")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAA, 1, "02")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
|
status = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xB0, 1)
|
|
|
|
|
|
logging.info(f'slot:{slot_id}, lane:{lane_id}, write max idac: {idac_str}, return status: {status}')
|
|
|
|
|
|
|
|
|
|
|
|
# 细扫
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAB, 1, f"{lane_id:02x}")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAC, 1, f"08")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAD, 1, f"02")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAE, 1, f"01")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAF, 1, f"00")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xAA, 1, "0B")
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
logging.info('step 1')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(3)
|
|
|
|
|
|
status = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xB3, 0xB0, 1)
|
|
|
|
|
|
if status == 'aa':
|
|
|
|
|
|
|
|
|
|
|
|
swa_adc1 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA0, 0x80, 128)
|
|
|
|
|
|
swa_adc2 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA1, 0x80, 128)
|
|
|
|
|
|
swa_adc3 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA2, 0x80, 128)
|
|
|
|
|
|
swa_adc4 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA3, 0x80, 128)
|
|
|
|
|
|
swa_adc5 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA4, 0x80, 128)
|
|
|
|
|
|
swa_adc6 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA5, 0x80, 128)
|
|
|
|
|
|
swa_adc7 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA6, 0x80, 128)
|
|
|
|
|
|
swa_adc8 = local_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0x00, 0xA7, 0x80, 128)
|
|
|
|
|
|
|
|
|
|
|
|
full_hex_string = swa_adc1 + swa_adc2 + swa_adc3 + swa_adc4 + swa_adc5 + swa_adc6 + swa_adc7 + swa_adc8
|
|
|
|
|
|
|
|
|
|
|
|
byte_strings = [full_hex_string[i:i+4] for i in range(0, len(full_hex_string), 4)]
|
|
|
|
|
|
|
|
|
|
|
|
data_values = [int(byte_str, 16) for byte_str in byte_strings]
|
|
|
|
|
|
|
|
|
|
|
|
max_value = max(data_values)
|
|
|
|
|
|
min_value = min(data_values)
|
|
|
|
|
|
max_index = data_values.index(max_value)
|
|
|
|
|
|
min_index = data_values.index(min_value)
|
|
|
|
|
|
|
|
|
|
|
|
x = [i * 8 for i in range(len(data_values))]
|
|
|
|
|
|
plt.figure(figsize=(12, 6))
|
|
|
|
|
|
plt.plot(x, data_values, linewidth=1.5)
|
|
|
|
|
|
plt.title('Data Curve Plot', fontsize=16)
|
|
|
|
|
|
plt.xlabel('vdac', fontsize=12)
|
|
|
|
|
|
plt.ylabel('mpd', fontsize=12)
|
|
|
|
|
|
plt.grid(True, alpha=0.3)
|
|
|
|
|
|
plt.tight_layout()
|
|
|
|
|
|
|
|
|
|
|
|
plt.savefig(f'mzm_vdac_{lane_id}.png', dpi=300, bbox_inches='tight')
|
|
|
|
|
|
plt.close()
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"full_hex_string: {full_hex_string}")
|
|
|
|
|
|
logging.info(f'data_values: {data_values}')
|
|
|
|
|
|
logging.info(f"max value: {max_value}, index: {max_index}")
|
|
|
|
|
|
logging.info(f"min value: {min_value}, index: {min_index}")
|
|
|
|
|
|
|
|
|
|
|
|
x_at_47 = find_rising_edge_47_percent(data_values)
|
|
|
|
|
|
raw_vdac = local_reg_tool.read_opt_reg(exp_id, slot_id, lane_id, 'vdac')
|
|
|
|
|
|
logging.info(f'------------- raw_vdac: {raw_vdac}, new vdac: {x_at_47}')
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.info(f'-------- status: {status}')
|
|
|
|
|
|
|
|
|
|
|
|
def EyeCheck(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune eq: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
tool = EqTuneTool(local_bmc, remote_bmc, local_reg_tool, remote_reg_tool, ibias_rssi_map, topo_map, route_name)
|
|
|
|
|
|
tool.eye_check(host, exp_id, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
def RecvErrCheck(host: str, remote_host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, retimers: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool, is_only_recv = False, is_show_all = False):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune eq: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
eq_tool = EqTuneTool(local_bmc, remote_bmc, local_reg_tool, remote_reg_tool, ibias_rssi_map, topo_map, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
tool = RecvCeTool(local_bmc, remote_bmc, local_reg_tool, remote_reg_tool, eq_tool, ibias_rssi_map, topo_map, route_name)
|
|
|
|
|
|
tool.recv_err_check(host, exp_id, route_name, retimers, is_only_recv, is_show_all)
|
|
|
|
|
|
if remote_host != '' and remote_host != host:
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
remote_tool = RecvCeTool(remote_bmc, local_bmc, remote_reg_tool, local_reg_tool, eq_tool, ibias_rssi_map, topo_map, route_name)
|
|
|
|
|
|
remote_tool.recv_err_check(remote_host, exp_id, route_name, retimers, is_only_recv, is_show_all)
|
|
|
|
|
|
|
|
|
|
|
|
def CalcCtleMap(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
if param_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in param_list]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune eq: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
tool = EqTuneTool(local_bmc, remote_bmc, local_reg_tool, remote_reg_tool, ibias_rssi_map, topo_map, route_name)
|
|
|
|
|
|
# tool.eq_auto_tune(exp_id)
|
|
|
|
|
|
if param == '':
|
|
|
|
|
|
offset = 0
|
|
|
|
|
|
else:
|
|
|
|
|
|
offset = int(param)
|
|
|
|
|
|
# tool.calc_ctle_value_by_pcb_trace_tx_rx_decoup(offset)
|
|
|
|
|
|
tool.calc_ctle_value_by_pcb_trace_pre6_post0(offset)
|
|
|
|
|
|
|
|
|
|
|
|
def AutoTuneEq(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
if param_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in param_list]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start auto tune eq: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
tool = EqTuneTool(local_bmc, remote_bmc, local_reg_tool, remote_reg_tool, ibias_rssi_map, topo_map, route_name)
|
|
|
|
|
|
# tool.eq_auto_tune(exp_id)
|
|
|
|
|
|
|
|
|
|
|
|
# tool.tune_eq_by_rtmr_length(exp_id, [1,2,3,4], False)
|
|
|
|
|
|
tool.tune_eq_by_eye_width(exp_id, retimers)
|
|
|
|
|
|
# tool.tune_eq_by_eye_width_ctle(exp_id, retimers)
|
|
|
|
|
|
|
|
|
|
|
|
def TuneView(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool,
|
|
|
|
|
|
rtmr_id: int, rtmr_lane: int):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start manual tune view: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
tool = EqTuneTool(local_bmc, remote_bmc, local_reg_tool, remote_reg_tool, ibias_rssi_map, topo_map, route_name)
|
|
|
|
|
|
logging.info(f'------------- step 1')
|
|
|
|
|
|
tool.tune_view(exp_id, rtmr_id, rtmr_lane)
|
|
|
|
|
|
|
|
|
|
|
|
def TuneWrite(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list, lane_list: List[int],
|
|
|
|
|
|
remote_bmc: DevWhiteRiverExp, route_name: str,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, remote_reg_tool: OptRegAccessTool,
|
|
|
|
|
|
rtmr_id: int, rtmr_lane: int, reg_name: str, reg_value: int):
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'lane_list: {lane_list}')
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"start manual tune write: exp_id={exp_id}, slots={slot_list}")
|
|
|
|
|
|
tool = EqTuneTool(local_bmc, remote_bmc, local_reg_tool, remote_reg_tool, ibias_rssi_map, topo_map, route_name)
|
|
|
|
|
|
logging.info(f'------------- step 1')
|
|
|
|
|
|
tool.tune_write(exp_id, rtmr_id, rtmr_lane, reg_name, reg_value)
|
|
|
|
|
|
|
|
|
|
|
|
def SetPower(host: str, exp: int, local_bmc: DevWhiteRiverExp, param: str):
|
|
|
|
|
|
if param == '950':
|
|
|
|
|
|
logging.info(f'----host: {host} exp: {exp}, set power 950')
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp pause")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0 0")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x24 0x32 0x00")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0xDB 0x2E")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x21 0x2E 0x00")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x11")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp resume")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp")
|
|
|
|
|
|
elif param == '930':
|
|
|
|
|
|
logging.info(f'----host: {host} exp: {exp}, set power 930')
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp pause")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0 0")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x24 0x32 0x00")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0xDB 0x2C")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x21 0x2C 0x00")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x11")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp resume")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp")
|
|
|
|
|
|
elif param == '910':
|
|
|
|
|
|
logging.info(f'----host: {host} exp: {exp}, set power 910')
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp pause")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0 0")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x24 0x2D 0x00")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0xDB 0x2A")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x21 0x2A 0x00")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x11")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp resume")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp")
|
|
|
|
|
|
elif param == '950':
|
|
|
|
|
|
logging.info(f'----host: {host} exp: {exp}, set power 950')
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp pause")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0 0")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x24 0x32 0x00")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0xDB 0x2E")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x21 0x2E 0x00")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "iicm i2c@40008400 0x61 w 0x11")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp resume")
|
|
|
|
|
|
local_bmc.CmdVendorCommand(exp, "exp")
|
|
|
|
|
|
|
|
|
|
|
|
TCT_SN_FILE = "main_data/tct_sn.txt"
|
|
|
|
|
|
|
|
|
|
|
|
# 全局缓存,避免重复读取文件
|
|
|
|
|
|
_tct_sn_set = None
|
|
|
|
|
|
|
|
|
|
|
|
def load_tct_sn_from_file():
|
|
|
|
|
|
"""只加载一次 tct_sn.txt,返回包含所有已温循 SN 的集合"""
|
|
|
|
|
|
global _tct_sn_set
|
|
|
|
|
|
if _tct_sn_set is not None:
|
|
|
|
|
|
return _tct_sn_set
|
|
|
|
|
|
|
|
|
|
|
|
_tct_sn_set = set()
|
|
|
|
|
|
|
|
|
|
|
|
if not os.path.exists(TCT_SN_FILE):
|
|
|
|
|
|
logging.error(f"[TCT] 文件不存在: {TCT_SN_FILE}")
|
|
|
|
|
|
return _tct_sn_set
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
with open(TCT_SN_FILE, 'r', encoding='utf-8') as f:
|
|
|
|
|
|
for line_num, line in enumerate(f, 1):
|
|
|
|
|
|
stripped = line.strip()
|
|
|
|
|
|
# 跳过空行和注释行
|
|
|
|
|
|
if not stripped or stripped.startswith('#'):
|
|
|
|
|
|
continue
|
|
|
|
|
|
_tct_sn_set.add(stripped)
|
|
|
|
|
|
logging.info(f"[TCT] 已加载 {len(_tct_sn_set)} 个经过温循的 SN")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"[TCT] 读取 TCT SN 文件失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
return _tct_sn_set
|
|
|
|
|
|
|
|
|
|
|
|
def check_module_tct_status(host: str, bmc, exp_id: int, slot_list):
|
|
|
|
|
|
global _tct_sn_set
|
|
|
|
|
|
|
|
|
|
|
|
# 步骤1:加载 TCT SN 列表
|
|
|
|
|
|
if _tct_sn_set is None:
|
|
|
|
|
|
_tct_sn_set = load_tct_sn_from_file()
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
|
|
|
|
|
|
# 步骤2:从 BMC 读取模块 SN (字节 166 开始,共 16 字节)
|
|
|
|
|
|
try:
|
|
|
|
|
|
res_data = bmc.GetOpticalModuleRegs(exp_id, slot_id, 0, 0, 166, 16)
|
|
|
|
|
|
if not res_data:
|
|
|
|
|
|
raise ValueError("BMC 返回空数据")
|
|
|
|
|
|
|
|
|
|
|
|
bytes_data = bytes.fromhex(res_data)
|
|
|
|
|
|
# 解码为 ASCII,忽略非法字符,并去除首尾空白和填充字符(如 \x00, 空格)
|
|
|
|
|
|
raw_sn = bytes_data.decode('ascii', errors='ignore').strip('\x00 \t\n\r')
|
|
|
|
|
|
sn = raw_sn.strip() # 最终 SN
|
|
|
|
|
|
|
|
|
|
|
|
if not sn:
|
|
|
|
|
|
sn = "Unknown_SN"
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"[BMC] 读取 host:{host}, exp:{exp_id}, slot:{slot_id} SN 失败: {e}")
|
|
|
|
|
|
sn = "Read_Error"
|
|
|
|
|
|
|
|
|
|
|
|
# 步骤3:判断是否经过温循
|
|
|
|
|
|
is_tct_passed = sn in _tct_sn_set
|
|
|
|
|
|
|
|
|
|
|
|
# 步骤4:统一格式化输出
|
|
|
|
|
|
status_str = "Yes" if is_tct_passed else "No"
|
|
|
|
|
|
logging.info(
|
|
|
|
|
|
f"host: {host}, "
|
|
|
|
|
|
f"exp: {exp_id}, "
|
|
|
|
|
|
f"slot: {slot_id}, "
|
|
|
|
|
|
f"sn: {sn}, "
|
|
|
|
|
|
f"tct_passed: {status_str}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def run_remote_cmd(host, cmd_str, password='RCms@Zte3'):
|
|
|
|
|
|
full_cmd = [
|
|
|
|
|
|
'sshpass', '-p', password,
|
|
|
|
|
|
'ssh', '-o', 'StrictHostKeyChecking=no',
|
|
|
|
|
|
f'root@{host}',
|
|
|
|
|
|
cmd_str
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"[RUN] {host}: {cmd_str}")
|
|
|
|
|
|
|
|
|
|
|
|
# 启动进程,实时捕获输出
|
|
|
|
|
|
proc = subprocess.Popen(
|
|
|
|
|
|
full_cmd,
|
|
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
|
|
stderr=subprocess.STDOUT, # 合并 stderr 到 stdout
|
|
|
|
|
|
universal_newlines=True, # 返回字符串而非 bytes
|
|
|
|
|
|
bufsize=1 # 行缓冲
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# 实时读取输出并打印
|
|
|
|
|
|
for line in iter(proc.stdout.readline, ''):
|
|
|
|
|
|
if line:
|
|
|
|
|
|
logging.info(f"[{host}] {line.rstrip()}")
|
|
|
|
|
|
|
|
|
|
|
|
proc.stdout.close()
|
|
|
|
|
|
return_code = proc.wait()
|
|
|
|
|
|
|
|
|
|
|
|
if return_code != 0:
|
|
|
|
|
|
logging.error(f"[ERROR] Command failed on {host} (exit code: {return_code})", file=sys.stderr)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.info(f"[OK] Command succeeded on {host}")
|
|
|
|
|
|
|
|
|
|
|
|
return return_code
|
|
|
|
|
|
|
|
|
|
|
|
def gpu_cto_disable(os_host_list, password='RCms@Zte3', container='mysccl-zds'):
|
|
|
|
|
|
logging.info(">>> GPU reset on hosts: %s", os_host_list)
|
|
|
|
|
|
base_cmd_list = [
|
|
|
|
|
|
'/workspace/zds/gpu_debugger -i all -w 0x369098 0x00000010',
|
|
|
|
|
|
'/workspace/zds/gpu_debugger -i all -w 0x379098 0x00000010',
|
|
|
|
|
|
'/workspace/zds/gpu_debugger -i all -w 0x781098 0x00000010',
|
|
|
|
|
|
'/workspace/zds/gpu_debugger -i all -w 0x771098 0x00000010',
|
|
|
|
|
|
'/workspace/zds/gpu_debugger -i all -r 0x369098',
|
|
|
|
|
|
'/workspace/zds/gpu_debugger -i all -r 0x379098',
|
|
|
|
|
|
'/workspace/zds/gpu_debugger -i all -r 0x781098',
|
|
|
|
|
|
'/workspace/zds/gpu_debugger -i all -r 0x771098'
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def exec_on_host(host):
|
|
|
|
|
|
for base_cmd in base_cmd_list:
|
|
|
|
|
|
cmd = f"docker exec {container} {base_cmd}"
|
|
|
|
|
|
run_remote_cmd(host, cmd, password)
|
|
|
|
|
|
|
|
|
|
|
|
with concurrent.futures.ThreadPoolExecutor(max_workers=len(os_host_list)) as executor:
|
|
|
|
|
|
future_to_host = {executor.submit(exec_on_host, host): host for host in os_host_list}
|
|
|
|
|
|
for future in concurrent.futures.as_completed(future_to_host):
|
|
|
|
|
|
host = future_to_host[future]
|
|
|
|
|
|
try:
|
|
|
|
|
|
future.result()
|
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
|
logging.error("Host %s exception: %s", host, exc)
|
|
|
|
|
|
|
|
|
|
|
|
def gpu_reset(os_host_list, password='RCms@Zte3', container='mysccl-zds'):
|
|
|
|
|
|
base_cmd = "brsmi reset -g"
|
|
|
|
|
|
logging.info(">>> GPU reset on hosts: %s", os_host_list)
|
|
|
|
|
|
|
|
|
|
|
|
def reset_on_host(host):
|
|
|
|
|
|
cmd = f"docker exec {container} {base_cmd}"
|
|
|
|
|
|
run_remote_cmd(host, cmd, password)
|
|
|
|
|
|
|
|
|
|
|
|
with concurrent.futures.ThreadPoolExecutor(max_workers=len(os_host_list)) as executor:
|
|
|
|
|
|
future_to_host = {executor.submit(reset_on_host, host): host for host in os_host_list}
|
|
|
|
|
|
for future in concurrent.futures.as_completed(future_to_host):
|
|
|
|
|
|
host = future_to_host[future]
|
|
|
|
|
|
try:
|
|
|
|
|
|
future.result()
|
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
|
logging.error("Host %s exception: %s", host, exc)
|
|
|
|
|
|
|
|
|
|
|
|
def process_exp_cold_reset(host):
|
|
|
|
|
|
logging.info(f'-----------process: {host}, exp_list: {exp_list}')
|
|
|
|
|
|
for exp_id in exp_list:
|
|
|
|
|
|
exp_id = int(exp_id)
|
|
|
|
|
|
base_url = f"https://{host}"
|
|
|
|
|
|
# logging.info(f'-------step 0, base_url: {base_url}')
|
|
|
|
|
|
exp_util = SmbusHttpUtil(base_url, "root", "0penBmc", "test")
|
|
|
|
|
|
# logging.info(f'-------step 1')
|
|
|
|
|
|
# exp_util.lock(exp_id)
|
|
|
|
|
|
|
|
|
|
|
|
vuart_util = VuartUtil(host)
|
|
|
|
|
|
bmc = DevWhiteRiverExp(exp_util, vuart_util)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'start exec reset: {exp_id}')
|
|
|
|
|
|
ExpColdReset(bmc, exp_id)
|
|
|
|
|
|
logging.info(f'finish exec reset: {exp_id}')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(5)
|
|
|
|
|
|
|
|
|
|
|
|
sec = bmc.GetExpStatus(exp_id)
|
|
|
|
|
|
logging.info(f'------update:{sec}')
|
|
|
|
|
|
if sec is not None:
|
|
|
|
|
|
while sec > 8:
|
|
|
|
|
|
logging.error(f'host {host} exp {exp_id} reset failed, try again')
|
|
|
|
|
|
ExpColdReset(bmc, exp_id)
|
|
|
|
|
|
time.sleep(5)
|
|
|
|
|
|
|
|
|
|
|
|
sec = bmc.GetExpStatus(exp_id)
|
|
|
|
|
|
logging.info(f'------update:{sec}')
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'{host} done')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def process_rtmr_waram_reset(host):
|
|
|
|
|
|
logging.info(f'-----------process: {host}, exp_list: {exp_list}')
|
|
|
|
|
|
for exp_id in exp_list:
|
|
|
|
|
|
exp_id = int(exp_id)
|
|
|
|
|
|
base_url = f"https://{host}"
|
|
|
|
|
|
# logging.info(f'-------step 0, base_url: {base_url}')
|
|
|
|
|
|
exp_util = SmbusHttpUtil(base_url, "root", "0penBmc", "test")
|
|
|
|
|
|
# logging.info(f'-------step 1')
|
|
|
|
|
|
# exp_util.lock(exp_id)
|
|
|
|
|
|
|
|
|
|
|
|
vuart_util = VuartUtil(host)
|
|
|
|
|
|
bmc = DevWhiteRiverExp(exp_util, vuart_util)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'start exec retimer reset: {exp_id}')
|
|
|
|
|
|
rtmr_reset_and_port_reset(bmc, exp_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'{host} done')
|
|
|
|
|
|
|
|
|
|
|
|
def rtmr_reset_and_port_reset(bmc: DevWhiteRiverExp, exp_id):
|
|
|
|
|
|
|
|
|
|
|
|
bmc.CmdVendorCommand(exp_id, 'cmis mode lp')
|
|
|
|
|
|
time.sleep(0.15)
|
|
|
|
|
|
bmc.CmdVendorCommand(exp_id, 'rtmr 1 reset')
|
|
|
|
|
|
bmc.CmdVendorCommand(exp_id, 'rtmr 2 reset')
|
|
|
|
|
|
bmc.CmdVendorCommand(exp_id, 'rtmr 3 reset')
|
|
|
|
|
|
bmc.CmdVendorCommand(exp_id, 'rtmr 4 reset')
|
|
|
|
|
|
time.sleep(0.5) # 等待load成功
|
|
|
|
|
|
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, 1, 0x0414, '11')
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, 2, 0x0414, '11')
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, 3, 0x0414, '11')
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, 4, 0x0414, '11')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
|
|
|
|
bmc.CmdVendorCommand(exp_id, 'cmis mode hp')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(2)
|
|
|
|
|
|
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, 1, 0x0414, '00')
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, 2, 0x0414, '00')
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, 3, 0x0414, '00')
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, 4, 0x0414, '00')
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'finish exec retimer reset: {exp_id}')
|
|
|
|
|
|
|
|
|
|
|
|
def load_ctle_config(host: str, route_name: str, exp_id: int) -> List[RetimerLaneSetting]:
|
|
|
|
|
|
config_path = os.path.join("/xz/gyou/nexusbench/main_data", "ctle", f"{host}.json")
|
|
|
|
|
|
|
|
|
|
|
|
if not os.path.exists(config_path):
|
|
|
|
|
|
logging.info(f"CTLE config file not found: {config_path}")
|
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
with open(config_path, 'r', encoding='utf-8') as f:
|
|
|
|
|
|
full_config = json.load(f)
|
|
|
|
|
|
|
|
|
|
|
|
# 获取当前路由模式下的子配置
|
|
|
|
|
|
mode_config = full_config.get(route_name)
|
|
|
|
|
|
if mode_config is None:
|
|
|
|
|
|
logging.info(
|
|
|
|
|
|
f"No CTLE configuration found for routing mode '{route_name}' in {config_path}"
|
|
|
|
|
|
)
|
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
exps = mode_config.get("exps", {})
|
|
|
|
|
|
exp_key = str(exp_id)
|
|
|
|
|
|
if exp_key not in exps:
|
|
|
|
|
|
logging.info(
|
|
|
|
|
|
f"No CTLE config found for exp_id={exp_id} under route='{route_name}' in {config_path}"
|
|
|
|
|
|
)
|
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
retimers = exps[exp_key].get("retimers", {})
|
|
|
|
|
|
results = []
|
|
|
|
|
|
|
|
|
|
|
|
for rtmr_id_str, rtmr_data in retimers.items():
|
|
|
|
|
|
lanes = rtmr_data.get("lanes", {})
|
|
|
|
|
|
for lane_str, lane_data in lanes.items():
|
|
|
|
|
|
try:
|
|
|
|
|
|
ctle_val = lane_data.get("ctle")
|
|
|
|
|
|
if ctle_val is None:
|
|
|
|
|
|
continue
|
|
|
|
|
|
setting = RetimerLaneSetting(
|
|
|
|
|
|
rtmr_id=int(rtmr_id_str),
|
|
|
|
|
|
rtmr_lane=int(lane_str),
|
|
|
|
|
|
ctle=int(ctle_val)
|
|
|
|
|
|
)
|
|
|
|
|
|
results.append(setting)
|
|
|
|
|
|
except (ValueError, TypeError) as e:
|
|
|
|
|
|
logging.warning(
|
|
|
|
|
|
f"Invalid CTLE entry in {config_path} [route={route_name}, exp={exp_id}]: "
|
|
|
|
|
|
f"retimer={rtmr_id_str}, lane={lane_str}, data={lane_data} ({e})"
|
|
|
|
|
|
)
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(
|
|
|
|
|
|
f"Loaded {len(results)} CTLE settings for host={host}, route={route_name}, exp={exp_id}"
|
|
|
|
|
|
)
|
|
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
|
|
|
except json.JSONDecodeError as e:
|
|
|
|
|
|
logging.error(f"Failed to parse CTLE config file {config_path}: {e}")
|
|
|
|
|
|
return []
|
|
|
|
|
|
except (OSError, IOError) as e:
|
|
|
|
|
|
logging.error(f"Failed to read CTLE config file {config_path}: {e}")
|
|
|
|
|
|
return []
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"Unexpected error loading CTLE config: {e}")
|
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
def load_ctle_for_single_host_exp(host: str, port_list: List[int], need_lock = True):
|
|
|
|
|
|
for exp_id in port_list:
|
|
|
|
|
|
try:
|
|
|
|
|
|
exp_id = int(exp_id)
|
|
|
|
|
|
exp_util = SmbusHttpUtil(f"https://{host}", "root", "0penBmc", host)
|
|
|
|
|
|
vuart_util = VuartUtil(host)
|
|
|
|
|
|
bmc = DevWhiteRiverExp(exp_util, vuart_util)
|
|
|
|
|
|
|
|
|
|
|
|
if need_lock:
|
|
|
|
|
|
exp_util.lock(exp_id)
|
|
|
|
|
|
logging.info(f'----------process_host {host} exp {exp_id} locked')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
route_name = get_route_name(host, bmc, exp_id)
|
|
|
|
|
|
all_rtmr_lane_settings: List[RetimerLaneSetting] = load_ctle_config(host, route_name, exp_id)
|
|
|
|
|
|
|
|
|
|
|
|
for lane_setting in all_rtmr_lane_settings:
|
|
|
|
|
|
WriteRtmrCtle(host, exp_id, bmc, [lane_setting.rtmr_id], [lane_setting.rtmr_lane], lane_setting.ctle)
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
if all_rtmr_lane_settings:
|
|
|
|
|
|
CommitRtmrCtle(exp_id, bmc, [1, 2, 3, 4])
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
logging.info(f"✅ Completed {host} exp {exp_id}")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"❌ Failed to process {host} exp {exp_id}: {e}")
|
|
|
|
|
|
raise # 可选:是否让主线程感知失败
|
|
|
|
|
|
finally:
|
|
|
|
|
|
# 确保解锁(即使出错)
|
|
|
|
|
|
try:
|
|
|
|
|
|
if need_lock:
|
|
|
|
|
|
exp_util.unlock(exp_id)
|
|
|
|
|
|
logging.info(f'----------process_host {host} exp {exp_id} unlocked')
|
|
|
|
|
|
except Exception as unlock_err:
|
|
|
|
|
|
logging.warning(f"Failed to unlock {host} exp {exp_id}: {unlock_err}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def link_train(host_list, os_host_list, port_list, topo_file_name, password='RCms@Zte3', container='mysccl-zds'):
|
|
|
|
|
|
base_cmd = "/workspace/zds"
|
|
|
|
|
|
script_disable = f"{base_cmd}/scripts/disable_port_ltssm"
|
|
|
|
|
|
topo_tool = f"{base_cmd}/ocsTopo_s"
|
|
|
|
|
|
|
|
|
|
|
|
# === Step 1: Disable LTSSM for all (host, port) pairs ===
|
|
|
|
|
|
logging.info(">>> Step 1: Disabling LTSSM on all hosts and ports...")
|
|
|
|
|
|
for port in port_list:
|
|
|
|
|
|
for host in os_host_list:
|
|
|
|
|
|
cmd = f"docker exec {container} {script_disable} {port}"
|
|
|
|
|
|
run_remote_cmd(host, cmd, password)
|
|
|
|
|
|
|
|
|
|
|
|
# # === Step 2: ocs link reset (host, port) pairs ===
|
|
|
|
|
|
logging.info(">>> Step 2: ocs link reset on all hosts and ports...")
|
|
|
|
|
|
|
|
|
|
|
|
with ThreadPoolExecutor(max_workers=len(host_list)) as executor:
|
|
|
|
|
|
executor.map(process_exp_cold_reset, host_list)
|
|
|
|
|
|
#
|
|
|
|
|
|
time.sleep(6)
|
|
|
|
|
|
|
|
|
|
|
|
# === Step 3: Load topology on all hosts ===
|
|
|
|
|
|
logging.info("\n>>> Step 2: Loading topology on all hosts...")
|
|
|
|
|
|
topo_path = f"../../{base_cmd}/{topo_file_name}"
|
|
|
|
|
|
for host in os_host_list:
|
|
|
|
|
|
cmd = f"docker exec {container} {topo_tool} -s {topo_path}"
|
|
|
|
|
|
run_remote_cmd(host, cmd, password)
|
|
|
|
|
|
|
|
|
|
|
|
# === Step 4: Load ctle values to retimer
|
|
|
|
|
|
logging.info("\n>>> Step 4: Loading ctle values to retimer...")
|
|
|
|
|
|
|
|
|
|
|
|
if not host_list or not port_list:
|
|
|
|
|
|
logging.info("No hosts or ports to process.")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
max_workers = min(4, len(host_list))
|
|
|
|
|
|
logging.info(f"Starting parallel processing across {len(host_list)} hosts with max_workers={max_workers}")
|
|
|
|
|
|
|
|
|
|
|
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
|
|
|
|
future_to_host = {
|
|
|
|
|
|
executor.submit(load_ctle_for_single_host_exp, host, port_list): host
|
|
|
|
|
|
for host in host_list
|
|
|
|
|
|
}
|
|
|
|
|
|
for future in concurrent.futures.as_completed(future_to_host):
|
|
|
|
|
|
host = future_to_host[future]
|
|
|
|
|
|
try:
|
|
|
|
|
|
future.result()
|
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
|
logging.error(f"Unexpected error in host {host} task: {exc}")
|
|
|
|
|
|
# === Step 5: Start link training (-p) on all hosts ===
|
|
|
|
|
|
logging.info("\n>>> Step 3: Starting link training on all hosts...")
|
|
|
|
|
|
def run_on_host(host, port):
|
|
|
|
|
|
"""在指定 host 上执行指定 port 的命令"""
|
|
|
|
|
|
cmd = f"docker exec {container} {topo_tool} -p {port}"
|
|
|
|
|
|
return run_remote_cmd(host, cmd, password) # 假设该函数已定义
|
|
|
|
|
|
|
|
|
|
|
|
# 外层:按 port 串行
|
|
|
|
|
|
for port in port_list:
|
|
|
|
|
|
logging.info(">>> Starting link training for port %s on all hosts...", port)
|
|
|
|
|
|
|
|
|
|
|
|
# 内层:当前 port 下,所有 host 并行
|
|
|
|
|
|
with concurrent.futures.ThreadPoolExecutor(max_workers=len(os_host_list)) as executor:
|
|
|
|
|
|
# 提交任务:每个 host 执行当前 port
|
|
|
|
|
|
future_to_host = {
|
|
|
|
|
|
executor.submit(run_on_host, host, port): host
|
|
|
|
|
|
for host in os_host_list
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 等待当前 port 的所有 host 完成
|
|
|
|
|
|
for future in concurrent.futures.as_completed(future_to_host):
|
|
|
|
|
|
host = future_to_host[future]
|
|
|
|
|
|
try:
|
|
|
|
|
|
future.result() # 触发异常(如有)
|
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
|
logging.error("Host %s failed for port %s: %s", host, port, exc)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(">>> Completed port %s on all hosts.", port)
|
|
|
|
|
|
|
|
|
|
|
|
ENABLE_ADDR_MAP = {
|
|
|
|
|
|
0: 0x127000, 1: 0x127400, 2: 0x127800, 3: 0x127C00,
|
|
|
|
|
|
4: 0x137000, 5: 0x137400, 6: 0x137800, 7: 0x137C00,
|
|
|
|
|
|
8: 0x147000, 9: 0x147400, 10: 0x147800, 11: 0x147C00,
|
|
|
|
|
|
12: 0x157000, 13: 0x157400, 14: 0x157800, 15: 0x157C00
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
REG_ADDR_MAP = {
|
|
|
|
|
|
0: 0x127004, 1: 0x127404, 2: 0x127804, 3: 0x127C04,
|
|
|
|
|
|
4: 0x137004, 5: 0x137404, 6: 0x137804, 7: 0x137C04,
|
|
|
|
|
|
8: 0x147004, 9: 0x147404, 10: 0x147804, 11: 0x147C04,
|
|
|
|
|
|
12: 0x157004, 13: 0x157404, 14: 0x157804, 15: 0x157C04
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def WriteRtmrCtle(host: str, exp_id: int, bmc: DevWhiteRiverExp, rtmrs: List[int], rtmr_lanes: List[int], ctle_value: int):
|
|
|
|
|
|
enable_addr_value = 0xabcdabcd
|
|
|
|
|
|
enable_addr_value_str = enable_addr_value.to_bytes(4, 'little').hex()
|
|
|
|
|
|
ctle_value_str = ctle_value.to_bytes(4, 'little').hex()
|
|
|
|
|
|
for rtmr in rtmrs:
|
|
|
|
|
|
for rtmr_lane in rtmr_lanes:
|
|
|
|
|
|
logging.info(f'{host} WriteRtmrCtle exp:{exp_id}, rtmrs:{rtmr}, lane: {rtmr_lane}, addr: {ENABLE_ADDR_MAP[rtmr_lane]}, ctle: {ctle_value}')
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, rtmr, ENABLE_ADDR_MAP[rtmr_lane], enable_addr_value_str)
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, rtmr, REG_ADDR_MAP[rtmr_lane], ctle_value_str)
|
|
|
|
|
|
|
|
|
|
|
|
# value = 0x100
|
|
|
|
|
|
# value_str = value.to_bytes(4, 'little').hex()
|
|
|
|
|
|
# bmc.SetRetimerRegs(exp_id, rtmr, 0x414, value_str)
|
|
|
|
|
|
# time.sleep(0.5)
|
|
|
|
|
|
# value = 0x0
|
|
|
|
|
|
# value_str = value.to_bytes(4, 'little').hex()
|
|
|
|
|
|
# bmc.SetRetimerRegs(exp_id, rtmr, 0x414, value_str)
|
|
|
|
|
|
|
|
|
|
|
|
def CommitRtmrCtle(exp_id: int, bmc: DevWhiteRiverExp, rtmrs: List[int]):
|
|
|
|
|
|
logging.info(f'Commit Rtmr {rtmrs} Ctle')
|
|
|
|
|
|
for rtmr in rtmrs:
|
|
|
|
|
|
value = 0x100
|
|
|
|
|
|
value_str = value.to_bytes(4, 'little').hex()
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, rtmr, 0x414, value_str)
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
value = 0x0
|
|
|
|
|
|
value_str = value.to_bytes(4, 'little').hex()
|
|
|
|
|
|
bmc.SetRetimerRegs(exp_id, rtmr, 0x414, value_str)
|
|
|
|
|
|
|
|
|
|
|
|
def get_route_name(host, bmc, exp_id) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
route_info = bmc.GetOpticalRouteStatus(exp_id, 0)
|
|
|
|
|
|
# logging.info(f'--------GetOpticalRouteStatus route_info:{route_info}')
|
|
|
|
|
|
yaml_route_map = {
|
|
|
|
|
|
'1111111111111111': '786-1-oneta',
|
|
|
|
|
|
'1212121212121212': '786-1-onetb',
|
|
|
|
|
|
'0201040306050807': '786-1-onoc1',
|
|
|
|
|
|
'0403020108070605': '786-1-onoc2',
|
|
|
|
|
|
'0807060504030201': '786-1-onoc3',
|
|
|
|
|
|
'0304010207080506': '786-1-onoc4',
|
|
|
|
|
|
'0605080702010403': '786-1-onoc5',
|
|
|
|
|
|
'0708050603040102': '786-1-onoc6',
|
|
|
|
|
|
'0506070801020304': '786-1-onoc7',
|
|
|
|
|
|
}
|
|
|
|
|
|
route_name = yaml_route_map[route_info]
|
|
|
|
|
|
return route_name
|
|
|
|
|
|
|
|
|
|
|
|
raw_data_91 = {
|
|
|
|
|
|
0: [319, 329, 314, 326, 306, 332, 318, 320],
|
|
|
|
|
|
1: [317, 338, 320, 349, 320, 328, 318, 355],
|
|
|
|
|
|
2: [322, 336, 325, 341, 318, 325, 313, 316],
|
|
|
|
|
|
3: [315, 323, 316, 338, 304, 311, 302, 318],
|
|
|
|
|
|
4: [301, 315, 314, 327, 314, 317, 301, 316],
|
|
|
|
|
|
5: [303, 306, 300, 317, 308, 330, 306, 318],
|
|
|
|
|
|
6: [308, 320, 308, 326, 313, 340, 314, 295],
|
|
|
|
|
|
7: [305, 324, 313, 324, 307, 312, 288, 322],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
raw_data_94 = {
|
|
|
|
|
|
0: [307,316,303,325,320,335,321,326],
|
|
|
|
|
|
1: [316,333,320,345,308,338,310,324],
|
|
|
|
|
|
2: [347,334,344,322,311,333,328,337],
|
|
|
|
|
|
3: [316,339,321,337,322,337,321,332],
|
|
|
|
|
|
4: [286,307,308,313,301,323,314,321],
|
|
|
|
|
|
5: [222,234,216,236,222,244,226,234],
|
|
|
|
|
|
6: [332,325,344,344,330,339,329,353],
|
|
|
|
|
|
7: [296,305,295,322,302,320,294,315]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def print_general_err_matrix(host, exp, lane_data_list: List[LaneErrInfo], tune_value_list, excel_path="err_matrix.xlsx"):
|
|
|
|
|
|
tune_value_list = sorted(tune_value_list)
|
|
|
|
|
|
|
|
|
|
|
|
header_parts = ["Host", "Exp", "Preset", "Slot", "Lane", "RT_Id", "RT_Lane"] + [str(v) for v in tune_value_list]
|
|
|
|
|
|
|
|
|
|
|
|
header_format = "{:<16} {:<6} {:<8} {:<6} {:<6} {:<6} {:<10} " + " ".join("{:<6}" for _ in tune_value_list)
|
|
|
|
|
|
logging.info(header_format.format(*header_parts))
|
|
|
|
|
|
logging.info("-" * (len(header_format.format(*header_parts))))
|
|
|
|
|
|
|
|
|
|
|
|
rows = []
|
|
|
|
|
|
|
|
|
|
|
|
for info in lane_data_list:
|
|
|
|
|
|
try:
|
|
|
|
|
|
err_counts = []
|
|
|
|
|
|
for value in tune_value_list:
|
|
|
|
|
|
err = info.tmp_err_map.get(value, -2)
|
|
|
|
|
|
if err < 0:
|
|
|
|
|
|
err_str = "70000"
|
|
|
|
|
|
else:
|
|
|
|
|
|
err_str = str(err)
|
|
|
|
|
|
err_counts.append(err_str)
|
|
|
|
|
|
|
|
|
|
|
|
row_data = [
|
|
|
|
|
|
host,
|
|
|
|
|
|
exp,
|
|
|
|
|
|
info.preset,
|
|
|
|
|
|
info.slot_id,
|
|
|
|
|
|
info.logic_lane,
|
|
|
|
|
|
info.rt_phys_id,
|
|
|
|
|
|
info.rt_phys_lane,
|
|
|
|
|
|
] + err_counts
|
|
|
|
|
|
|
|
|
|
|
|
data_format = "{:<16} {:<6} {:<8} {:<6} {:<6} {:<6} {:<10} " + " ".join("{:<6}" for _ in tune_value_list)
|
|
|
|
|
|
logging.info(data_format.format(*row_data))
|
|
|
|
|
|
|
|
|
|
|
|
row_dict = dict(zip(header_parts, row_data))
|
|
|
|
|
|
row_dict["Timestamp"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
rows.append(row_dict)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"Error processing row for Slot {info.slot_id}, Lane {info.logic_lane}: {e}")
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
# === 写入 Excel(增量追加)===
|
|
|
|
|
|
try:
|
|
|
|
|
|
# ✅ 修复点:read_excel 也要指定 engine='openpyxl'
|
|
|
|
|
|
try:
|
|
|
|
|
|
existing_df = pd.read_excel(excel_path, engine='openpyxl')
|
|
|
|
|
|
except FileNotFoundError:
|
|
|
|
|
|
existing_df = pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
|
|
new_df = pd.DataFrame(rows)
|
|
|
|
|
|
updated_df = pd.concat([existing_df, new_df], ignore_index=True)
|
|
|
|
|
|
|
|
|
|
|
|
# ✅ 写入时也指定 engine(虽非必须,但更安全)
|
|
|
|
|
|
updated_df.to_excel(excel_path, index=False, engine='openpyxl')
|
|
|
|
|
|
logging.info(f"✅ Data appended to {excel_path}")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"Failed to write Excel file: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
def load_inmpd_data(file_path="main_data/vdac/inmpd.xlsx"):
|
|
|
|
|
|
logging.info(f'load_inmpd_data')
|
|
|
|
|
|
if not os.path.exists(file_path):
|
|
|
|
|
|
raise FileNotFoundError(f"Excel file not found: {file_path}")
|
|
|
|
|
|
try:
|
|
|
|
|
|
logging.info(f"Opening Excel file: {file_path}")
|
|
|
|
|
|
xls = pd.ExcelFile(file_path, engine='openpyxl')
|
|
|
|
|
|
logging.info(f"Excel file opened successfully. Sheets: {xls.sheet_names}")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise ValueError(f"Failed to open Excel file '{file_path}': {e}")
|
|
|
|
|
|
|
|
|
|
|
|
required_cols = ['sn', 'lane', 'inmpd', 'temp']
|
|
|
|
|
|
all_data = []
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f'step 1.1')
|
|
|
|
|
|
for sheet_name in xls.sheet_names:
|
|
|
|
|
|
try:
|
|
|
|
|
|
logging.info(f'step 2')
|
|
|
|
|
|
df = pd.read_excel(xls, sheet_name=sheet_name)
|
|
|
|
|
|
|
|
|
|
|
|
# 标准化列名:转小写并去除前后空格
|
|
|
|
|
|
df.columns = df.columns.astype(str).str.strip().str.lower()
|
|
|
|
|
|
logging.info(f'step 3')
|
|
|
|
|
|
# 检查是否包含所有必需列
|
|
|
|
|
|
if not all(col in df.columns for col in required_cols):
|
|
|
|
|
|
missing = set(required_cols) - set(df.columns)
|
|
|
|
|
|
print(f"⚠️ Sheet '{sheet_name}' skipped: missing columns {missing}")
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
# 提取所需列
|
|
|
|
|
|
selected = df[required_cols].copy()
|
|
|
|
|
|
all_data.append(selected)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"❌ Error reading sheet '{sheet_name}': {e}")
|
|
|
|
|
|
|
|
|
|
|
|
if not all_data:
|
|
|
|
|
|
raise ValueError("No valid sheet contains all required columns: sn, lane, inmpd, temp")
|
|
|
|
|
|
|
|
|
|
|
|
# 合并所有有效数据
|
|
|
|
|
|
combined_df = pd.concat(all_data, ignore_index=True)
|
|
|
|
|
|
return combined_df
|
|
|
|
|
|
|
|
|
|
|
|
def inmpd_check(host: str, local_bmc: DevWhiteRiverExp, exp_id: int, slot_list: list,
|
|
|
|
|
|
local_reg_tool: OptRegAccessTool, output_dir: str = "tmp_data/inmpd"):
|
|
|
|
|
|
logging.info('step 1')
|
|
|
|
|
|
inmpd_df = load_inmpd_data() # DataFrame with columns: sn, lane, inmpd, temp
|
|
|
|
|
|
logging.info(f'Loaded {len(inmpd_df)} rows from Excel')
|
|
|
|
|
|
|
|
|
|
|
|
results = [] # 🟢 用于收集所有结果
|
|
|
|
|
|
|
|
|
|
|
|
for slot in slot_list:
|
|
|
|
|
|
sn = local_reg_tool.read_sn(exp_id, slot)
|
|
|
|
|
|
temp = local_reg_tool.read_temp(exp_id, slot)
|
|
|
|
|
|
logging.info(f"Processing slot {slot}, SN: {sn}, TEMP: {temp}")
|
|
|
|
|
|
|
|
|
|
|
|
matched_rows = inmpd_df[inmpd_df['sn'] == sn]
|
|
|
|
|
|
if matched_rows.empty:
|
|
|
|
|
|
logging.warning(f"No data found in Excel for SN: {sn}")
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
# Step 1: 保存原始 IBIAS 并设置为 4096
|
|
|
|
|
|
ibias_lane_list = [0, 1, 2, 3]
|
|
|
|
|
|
raw_ibias_list = []
|
|
|
|
|
|
|
|
|
|
|
|
local_bmc.SetOpticalModuleRegs(exp_id, slot, 0, 0xB4, 0x88, 1, '01')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
for lane in ibias_lane_list:
|
|
|
|
|
|
# raw_ibias = local_reg_tool.read_ibias_reg_by_ibias_lane(exp_id, slot, lane)
|
|
|
|
|
|
# raw_ibias_list.append(raw_ibias)
|
|
|
|
|
|
# time.sleep(0.05)
|
|
|
|
|
|
local_reg_tool.write_vol_ibias_reg_by_ibias_lane(exp_id, slot, lane, 4096)
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(2)
|
|
|
|
|
|
|
|
|
|
|
|
# Step 2: 读取 INMPD,并恢复 IBIAS
|
|
|
|
|
|
for lane in ibias_lane_list:
|
|
|
|
|
|
ibias = local_reg_tool.read_vol_ibias_reg_by_ibias_lane(exp_id, slot, lane)
|
|
|
|
|
|
pic_inmpd = local_reg_tool.read_pic_inmpd(exp_id, slot, lane)
|
|
|
|
|
|
try:
|
|
|
|
|
|
pic_inmpd_dbm = round(10 * math.log10(pic_inmpd / 2 * 41.88034 / 10000), 3)
|
|
|
|
|
|
except (ValueError, ZeroDivisionError):
|
|
|
|
|
|
pic_inmpd_dbm = float('nan')
|
|
|
|
|
|
|
|
|
|
|
|
# time.sleep(0.05)
|
|
|
|
|
|
# local_reg_tool.write_ibias_reg_by_ibias_lane(exp_id, slot, lane, raw_ibias_list[lane])
|
|
|
|
|
|
# time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
cm_inmpd = -1
|
|
|
|
|
|
cm_inmpd_dbm = float('nan')
|
|
|
|
|
|
cm_temp = -1
|
|
|
|
|
|
|
|
|
|
|
|
target_inmpd_lane = (lane + 1) * 2
|
|
|
|
|
|
for _, row in matched_rows.iterrows():
|
|
|
|
|
|
inmpd_lane = int(row['lane'])
|
|
|
|
|
|
if inmpd_lane == target_inmpd_lane:
|
|
|
|
|
|
cm_inmpd = int(row['inmpd'])
|
|
|
|
|
|
try:
|
|
|
|
|
|
cm_inmpd_dbm = round(10 * math.log10(cm_inmpd / 2 * 41.88034 / 10000), 3)
|
|
|
|
|
|
except (ValueError, ZeroDivisionError):
|
|
|
|
|
|
cm_inmpd_dbm = float('nan')
|
|
|
|
|
|
cm_temp = int(row['temp'])
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
# 安全计算 ratio
|
|
|
|
|
|
if cm_inmpd == 0:
|
|
|
|
|
|
ratio = float('nan')
|
|
|
|
|
|
else:
|
|
|
|
|
|
ratio = (cm_inmpd - pic_inmpd) / cm_inmpd
|
|
|
|
|
|
|
|
|
|
|
|
result_entry = {
|
|
|
|
|
|
'host': host,
|
|
|
|
|
|
'exp_id': exp_id,
|
|
|
|
|
|
'sn': sn,
|
|
|
|
|
|
'slot': slot,
|
|
|
|
|
|
'lane': lane,
|
|
|
|
|
|
'current_temp': temp,
|
|
|
|
|
|
'cm_temp': cm_temp,
|
|
|
|
|
|
'ibias': ibias,
|
|
|
|
|
|
'current_inmpd': pic_inmpd,
|
|
|
|
|
|
'cm_inmpd': cm_inmpd,
|
|
|
|
|
|
'pic_inmpd_dbm': pic_inmpd_dbm,
|
|
|
|
|
|
'cm_inmpd_dbm': cm_inmpd_dbm,
|
|
|
|
|
|
'inmpd_ratio': ratio,
|
|
|
|
|
|
}
|
|
|
|
|
|
results.append(result_entry)
|
|
|
|
|
|
|
|
|
|
|
|
# ✅ 统一打印所有结果
|
|
|
|
|
|
for entry in results:
|
|
|
|
|
|
ratio_pct = entry['inmpd_ratio'] * 100 if not pd.isna(entry['inmpd_ratio']) else float('nan')
|
|
|
|
|
|
ratio_str = f"{ratio_pct:.2f}%" if not pd.isna(ratio_pct) else "N/A"
|
|
|
|
|
|
logging.info(
|
|
|
|
|
|
f"host: {entry['host']}, "
|
|
|
|
|
|
f"exp: {entry['exp_id']}, "
|
|
|
|
|
|
f"sn: {entry['sn']}, "
|
|
|
|
|
|
f"ibias: {entry['ibias']}, "
|
|
|
|
|
|
f"slot: {entry['slot']}, "
|
|
|
|
|
|
f"lane: {entry['lane']}, "
|
|
|
|
|
|
f"temp(current/cm): {entry['current_temp']}/{entry['cm_temp']}, "
|
|
|
|
|
|
f"inmpd(current/cm): {entry['current_inmpd']}/{entry['cm_inmpd']}, "
|
|
|
|
|
|
f"inmpd_dbm(current/cm): {entry['pic_inmpd_dbm']}/{entry['cm_inmpd_dbm']}, "
|
|
|
|
|
|
f"inmpd_ratio: {ratio_str}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# ✅ 保存到 Excel
|
|
|
|
|
|
if results:
|
|
|
|
|
|
df_results = pd.DataFrame(results)
|
|
|
|
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
|
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
|
|
|
|
filename = f"{output_dir}/inmpd_check_{host}_exp{exp_id}_{timestamp}.xlsx"
|
|
|
|
|
|
df_results.to_excel(filename, index=False)
|
|
|
|
|
|
logging.info(f"Results saved to: {filename}")
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.warning("No valid results to save.")
|
|
|
|
|
|
|
|
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
|
|
|
def process_host(host, reg_table_file, exp_list, slot_list, rtmr_list, lane_list, cmd: str, param, reg_wt_value, sl_file):
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f'-----------process: {host}')
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map_file = '/xz/gyou/nexusbench/main_data/ibias-rssi-map.json'
|
|
|
|
|
|
if Path(ibias_rssi_map_file).exists() == False:
|
|
|
|
|
|
logging.error(f'ibias_rssi_map_file {ibias_rssi_map_file} not found!')
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
ibias_rssi_map = IbiasRssiMapParser(ibias_rssi_map_file)
|
|
|
|
|
|
|
|
|
|
|
|
for exp_id in exp_list:
|
|
|
|
|
|
exp_id = int(exp_id)
|
|
|
|
|
|
|
|
|
|
|
|
exp_util = SmbusHttpUtil(f"https://{host}", "root", "0penBmc", host)
|
|
|
|
|
|
|
|
|
|
|
|
exp_util.lock(exp_id)
|
|
|
|
|
|
logging.info(f'----------process_host {host} lock')
|
|
|
|
|
|
|
|
|
|
|
|
vuart_util = VuartUtil(host)
|
|
|
|
|
|
bmc = DevWhiteRiverExp(exp_util, vuart_util)
|
|
|
|
|
|
|
|
|
|
|
|
route_info = bmc.GetOpticalRouteStatus(exp_id, 0)
|
|
|
|
|
|
# logging.info(f'--------GetOpticalRouteStatus route_info:{route_info}')
|
|
|
|
|
|
yaml_route_map = {
|
|
|
|
|
|
'1111111111111111': '786-1-oneta',
|
|
|
|
|
|
'1212121212121212': '786-1-onetb',
|
|
|
|
|
|
'0201040306050807': '786-1-onoc1',
|
|
|
|
|
|
'0403020108070605': '786-1-onoc2',
|
|
|
|
|
|
'0807060504030201': '786-1-onoc3',
|
|
|
|
|
|
'0304010207080506': '786-1-onoc4',
|
|
|
|
|
|
'0605080702010403': '786-1-onoc5',
|
|
|
|
|
|
'0708050603040102': '786-1-onoc6',
|
|
|
|
|
|
'0506070801020304': '786-1-onoc7',
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
reg_table_file = f'/xz/gyou/nexusbench/main_data/{yaml_route_map[route_info]}.yaml'
|
|
|
|
|
|
route_name = yaml_route_map[route_info]
|
|
|
|
|
|
# logging.info(f'input reg_table_file is empty, use default config file:{reg_table_file}, route_name:{route_name}')
|
|
|
|
|
|
|
|
|
|
|
|
if Path(reg_table_file).exists():
|
|
|
|
|
|
# print(f"File exists: {reg_table_file}")
|
|
|
|
|
|
reg_access_tool = OptRegAccessTool(host, reg_table_file, bmc)
|
|
|
|
|
|
logging.info(f'init reg_access_tool with reg_table_file:{reg_table_file}, route_name:{route_name}')
|
|
|
|
|
|
|
|
|
|
|
|
remote_reg_access_tool = reg_access_tool
|
|
|
|
|
|
# else:
|
|
|
|
|
|
# print(f"File NOT found: {file_path}")
|
|
|
|
|
|
remote_bmc = None
|
|
|
|
|
|
remote_exp_util = exp_util
|
|
|
|
|
|
remote_host = host
|
|
|
|
|
|
|
|
|
|
|
|
if cmd in ['ibias-auto-tune', 'plot-mgc-vpeak', 'eq-auto-tune', 'tune-rd', 'tune-wt', 'rssi-check', 'err-check',
|
|
|
|
|
|
'rtmr-prbs', 'rtmr-prbs-test', 'ctle-auto-tune', 'mgc-auto-tune', 'mgc-auto-tune2', 'lowfreq-auto-tune',
|
|
|
|
|
|
'highfreq-auto-tune', 'tiapeak-auto-tune', 'opcurrent-auto-tune', 'opcurrent-auto-tune-test', 'rt-ibias', 'rt-mgc'] and remote_ip != '':
|
|
|
|
|
|
logging.info(f'------- remote_host: {remote_ip}')
|
|
|
|
|
|
remote_host = remote_ip
|
|
|
|
|
|
remote_exp_util = SmbusHttpUtil(f"https://{remote_host}", "root", "0penBmc", remote_host)
|
|
|
|
|
|
remote_bmc = DevWhiteRiverExp(remote_exp_util, vuart_util)
|
|
|
|
|
|
remote_exp_util.lock(exp_id)
|
|
|
|
|
|
logging.info(f'----------process dst host {remote_host} lock')
|
|
|
|
|
|
|
|
|
|
|
|
remote_reg_access_tool = OptRegAccessTool(remote_host, reg_table_file, remote_bmc)
|
|
|
|
|
|
|
|
|
|
|
|
if cmd in ['eq-auto-tune', 'rtmr-prbs-test', 'tune-rd', 'tune-wt', 'mgc-auto-tune2', 'lowfreq-auto-tune', 'err-check', 'highfreq-tune',
|
|
|
|
|
|
'highfreq-auto-tune', 'tiapeak-auto-tune', 'opcurrent-auto-tune', 'opcurrent-auto-tune-test', 'rt-ibias', 'rt-mgc']:
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
|
|
|
|
|
|
if cmd in ['reg-rd', 'inmpd-check', 'reg-rd-test', 'tx-enable', 'tx-disable', 'rtmr-prbs-test', 'swa-auto-tune', 'swb-auto-tune', 'mzm-auto-tune', 'opcurrent-tune', 'reg-wt', 'rssi-check', 'eye-check', 'err-check', \
|
|
|
|
|
|
'topo-config', 'plot-mgc-vpeak', 'mgc-auto-tune', 'mgc-auto-tune2', 'lowfreq-auto-tune',
|
|
|
|
|
|
'highfreq-auto-tune', 'tiapeak-auto-tune', 'opcurrent-auto-tune', 'opcurrent-auto-tune-test', 'rt-ibias', 'rt-mgc', 'mgc-manual-tune',
|
|
|
|
|
|
'mgc-calc-target-vpeak', 'ibias-auto-tune', 'reg-save', 'reg-load',
|
|
|
|
|
|
'highfreq-tune', 'tia-peak-tune', 'eq-auto-tune', 'tune-rd', 'tune-wt']:
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
# read sn
|
|
|
|
|
|
logging.info('------------ Authentication 1')
|
|
|
|
|
|
Authentication(bmc, exp_id, slot_id)
|
|
|
|
|
|
# res_data = bmc.GetOpticalModuleRegs(exp_id, slot_id, 0, 0, 166, 16)
|
|
|
|
|
|
# logging.debug(res_data)
|
|
|
|
|
|
# bytes_data = bytes.fromhex(res_data)
|
|
|
|
|
|
# ascii_str = bytes_data.decode('ascii', errors='ignore')
|
|
|
|
|
|
# logging.info(f'----------------slot: {slot_id}, sn:{ascii_str}')
|
|
|
|
|
|
|
|
|
|
|
|
if remote_bmc:
|
|
|
|
|
|
logging.info('------------ Authentication 2')
|
|
|
|
|
|
Authentication(remote_bmc, exp_id, slot_id)
|
|
|
|
|
|
# res_data = remote_bmc.GetOpticalModuleRegs(exp_id, slot_id, 0, 0, 166, 16)
|
|
|
|
|
|
# logging.debug(res_data)
|
|
|
|
|
|
# bytes_data = bytes.fromhex(res_data)
|
|
|
|
|
|
# ascii_str = bytes_data.decode('ascii', errors='ignore')
|
|
|
|
|
|
# logging.info(f'----------------Remote slot: {slot_id}, sn:{ascii_str}')
|
|
|
|
|
|
|
|
|
|
|
|
# mod_type = ReadModuleType(bmc, exp_id, slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f'Raw mod_type: {repr(mod_type)}')
|
|
|
|
|
|
# file_module_type = reg_access_tool.parser.get_module_type()
|
|
|
|
|
|
|
|
|
|
|
|
# is_valid_combination = (
|
|
|
|
|
|
# (mod_type.startswith('0.0.0') and file_module_type == 'batch0') or
|
|
|
|
|
|
# (mod_type.startswith('ISGD5680H') and file_module_type == 'batch1') or
|
|
|
|
|
|
# (mod_type.startswith('XZDRV') and file_module_type == 'batch2'))
|
|
|
|
|
|
|
|
|
|
|
|
# if not is_valid_combination:
|
|
|
|
|
|
# logging.error(f'config file is not match!')
|
|
|
|
|
|
# sys.exit()
|
|
|
|
|
|
if cmd == 'read-sn':
|
|
|
|
|
|
logging.info(f'slot_list: {slot_list}')
|
|
|
|
|
|
check_module_tct_status(host, bmc, exp_id, slot_list)
|
|
|
|
|
|
# for slot_id in slot_list:
|
|
|
|
|
|
# res_data = bmc.GetOpticalModuleRegs(exp_id, slot_id, 0, 0, 166, 16)
|
|
|
|
|
|
# bytes_data = bytes.fromhex(res_data)
|
|
|
|
|
|
# ascii_str = bytes_data.decode('ascii', errors='ignore')
|
|
|
|
|
|
# logging.info(f'----------------host: {host}, exp: {exp_id}, slot: {slot_id}, sn:{ascii_str}')
|
|
|
|
|
|
elif cmd == 'reg-rd-test':
|
|
|
|
|
|
rd_regs = param_list
|
|
|
|
|
|
# all_lane_reg_values: List[LaneRegInfo] = reg_access_tool.read_opt_regs(exp_id, slot_list, lane_list, rd_regs)
|
|
|
|
|
|
|
|
|
|
|
|
for slot in slot_list:
|
|
|
|
|
|
value = bmc.GetOpticalModuleRegs(exp_id=exp_id, slot_id=slot, bank=0x00, page=0xCD, reg_offset=0xB0, size=14)
|
|
|
|
|
|
logging.info(f'00 CD B0: {value}')
|
|
|
|
|
|
value = bmc.GetOpticalModuleRegs(exp_id=exp_id, slot_id=slot, bank=0x00, page=0xCD, reg_offset=0x90, size=14)
|
|
|
|
|
|
logging.info(f'00 CD 90: {value}')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
bmc.SetOpticalModuleRegs(exp_id=exp_id, slot_id=slot, bank=0x00, page=0xCD, reg_offset=0xB0, size=14, hex_str='00c000c000c000c000c000c000c0')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
bmc.SetOpticalModuleRegs(exp_id=exp_id, slot_id=slot, bank=0x00, page=0xCD, reg_offset=0x90, size=14, hex_str='0080008000800080008000800080')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
value = bmc.GetOpticalModuleRegs(exp_id=exp_id, slot_id=slot, bank=0x00, page=0xCD, reg_offset=0xB0, size=14)
|
|
|
|
|
|
logging.info(f'00 CD B0: {value}')
|
|
|
|
|
|
value = bmc.GetOpticalModuleRegs(exp_id=exp_id, slot_id=slot, bank=0x00, page=0xCD, reg_offset=0x90, size=14)
|
|
|
|
|
|
logging.info(f'00 CD 90: {value}')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# value = bmc.GetOpticalModuleRegs(exp_id=exp_id, slot_id=0, bank=0x01, page=0xC2, reg_offset=0x88, size=16)
|
|
|
|
|
|
# logging.info(f'01 C2 88: {value}')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# value = bmc.GetOpticalModuleRegs(exp_id=exp_id, slot_id=0, bank=0x00, page=0xC5, reg_offset=0x80, size=128)
|
|
|
|
|
|
# logging.info(f'value: {value}')
|
|
|
|
|
|
|
|
|
|
|
|
# # 确保 value 是偶数长度(安全处理)
|
|
|
|
|
|
# if len(value) % 2 != 0:
|
|
|
|
|
|
# logging.warning("Hex string has odd length, padding with a leading zero.")
|
|
|
|
|
|
# value = '0' + value
|
|
|
|
|
|
|
|
|
|
|
|
# # 每两个字符一组,转为字节列表
|
|
|
|
|
|
# bytes_list = [value[i:i+2] for i in range(0, len(value), 2)]
|
|
|
|
|
|
|
|
|
|
|
|
# # 起始寄存器地址
|
|
|
|
|
|
# start_reg = 0x80
|
|
|
|
|
|
|
|
|
|
|
|
# # 打印每个字节及其对应寄存器地址
|
|
|
|
|
|
# for idx, byte_hex in enumerate(bytes_list):
|
|
|
|
|
|
# reg_addr = start_reg + idx
|
|
|
|
|
|
# logging.info(f"[0x{reg_addr:02X}] = 0x{byte_hex.upper()}")
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'reg-rd':
|
|
|
|
|
|
rd_regs = param_list
|
|
|
|
|
|
all_lane_reg_values: List[LaneRegInfo] = reg_access_tool.read_opt_regs(exp_id, slot_list, lane_list, rd_regs)
|
|
|
|
|
|
if not all_lane_reg_values:
|
|
|
|
|
|
print("No register data read.")
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 提取 slot 和 lane 顺序(只需一次)
|
|
|
|
|
|
slots = [item.slot_id for item in all_lane_reg_values]
|
|
|
|
|
|
lanes = [item.logic_lane for item in all_lane_reg_values]
|
|
|
|
|
|
|
|
|
|
|
|
# 对 rd_regs 中每个寄存器,单独打印
|
|
|
|
|
|
for reg_name in rd_regs:
|
|
|
|
|
|
values = []
|
|
|
|
|
|
for item in all_lane_reg_values:
|
|
|
|
|
|
try:
|
|
|
|
|
|
value = getattr(item, reg_name)
|
|
|
|
|
|
values.append(value)
|
|
|
|
|
|
except AttributeError:
|
|
|
|
|
|
# 寄存器不存在,跳过该项
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
if values: # 只有当找到至少一个有效值时才打印
|
|
|
|
|
|
print(f"host: {host} exp: {exp_id} reg: {reg_name} slot: {slot_list} lane: {lane_list}")
|
|
|
|
|
|
print(f"value: {values}\n")
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'reg-wt':
|
|
|
|
|
|
wt_regs = param_list
|
|
|
|
|
|
if 'ibias_runtime' in wt_regs:
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
bmc.SetOpticalModuleRegs(exp_id, slot_id, 0, 0xB4, 0x88, 1, '01')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
if 'ibias' in wt_regs:
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
bmc.SetOpticalModuleRegs(exp_id, slot_id, 0, 0xB4, 0x88, 1, '00')
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
reg_access_tool.write_opt_regs(exp_id, slot_list, lane_list, wt_regs, reg_wt_value)
|
|
|
|
|
|
|
|
|
|
|
|
if 'mgc' in wt_regs:
|
|
|
|
|
|
for slot_id in slot_list:
|
|
|
|
|
|
reg_access_tool.write_confirm_reg(exp_id, slot_id)
|
|
|
|
|
|
|
|
|
|
|
|
# if host == '10.57.216.91':
|
|
|
|
|
|
# for slot_id in slot_list: # 或 for slot_id in raw_data.keys()
|
|
|
|
|
|
# lane_values = raw_data_91[slot_id]
|
|
|
|
|
|
# logging.info(f"step 1, slot{slot_id} lane_values: {lane_values}")
|
|
|
|
|
|
# for lane_id in lane_list:
|
|
|
|
|
|
# value = lane_values[lane_id]
|
|
|
|
|
|
# logging.info("step 2")
|
|
|
|
|
|
# reg_access_tool.write_opt_regs(exp_id, [slot_id], [lane_id], ['swa_h','swa_m','swa_l'],str(value))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# if host == '10.57.216.94':
|
|
|
|
|
|
# for slot_id in slot_list: # 或 for slot_id in raw_data.keys()
|
|
|
|
|
|
# lane_values = raw_data_94[slot_id]
|
|
|
|
|
|
# logging.info(f"step 1, slot{slot_id} lane_values: {lane_values}")
|
|
|
|
|
|
# for lane_id in lane_list:
|
|
|
|
|
|
# value = lane_values[lane_id]
|
|
|
|
|
|
# logging.info("step 2")
|
|
|
|
|
|
# reg_access_tool.write_opt_regs(exp_id, [slot_id], [lane_id], ['swa_h','swa_m','swa_l'],str(value))
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'tx-enable':
|
|
|
|
|
|
wt_regs = param_list
|
|
|
|
|
|
for slot in slot_list:
|
|
|
|
|
|
reg_access_tool.tx_enable(exp_id, slot)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'tx-disable':
|
|
|
|
|
|
wt_regs = param_list
|
|
|
|
|
|
for slot in slot_list:
|
|
|
|
|
|
reg_access_tool.tx_disable(exp_id, slot)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'opcurrent-tune':
|
|
|
|
|
|
all_lane_reg_values: List[LaneRegInfo] = reg_access_tool.read_opt_regs(exp_id, slot_list, lane_list, ['opcurrent'])
|
|
|
|
|
|
for lane_reg_value in all_lane_reg_values:
|
|
|
|
|
|
if lane_reg_value.opcurrent < 140:
|
|
|
|
|
|
logging.info(f'exp_id:{exp_id}, slot: {[lane_reg_value.slot_id]}, lane: {[lane_reg_value.logic_lane]}, opcurrent: {lane_reg_value.opcurrent}, need change to 130')
|
|
|
|
|
|
reg_access_tool.write_opt_regs(exp_id, [lane_reg_value.slot_id], [lane_reg_value.logic_lane], ['opcurrent'], '130')
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'rssi-check':
|
|
|
|
|
|
RssiCheck(reg_access_tool, remote_reg_access_tool, bmc, host, exp_id, slot_list, ibias_rssi_map, route_name)
|
|
|
|
|
|
elif cmd == 'eye-check':
|
|
|
|
|
|
EyeCheck(host, bmc, exp_id, slot_list, lane_list, remote_bmc, route_name, reg_access_tool, remote_reg_access_tool)
|
|
|
|
|
|
elif cmd == 'err-check':
|
|
|
|
|
|
# logging.info(param)
|
|
|
|
|
|
# logging.info(param_list)
|
|
|
|
|
|
if rtmr_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in rtmr_list]
|
|
|
|
|
|
|
|
|
|
|
|
is_show_all = False
|
|
|
|
|
|
if param == 'show-all':
|
|
|
|
|
|
is_show_all = True
|
|
|
|
|
|
|
|
|
|
|
|
RecvErrCheck(host, remote_host, bmc, exp_id, slot_list, retimers, remote_bmc, route_name, reg_access_tool, remote_reg_access_tool, False, is_show_all)
|
|
|
|
|
|
elif cmd == 'recv-check':
|
|
|
|
|
|
if rtmr_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in rtmr_list]
|
|
|
|
|
|
|
|
|
|
|
|
RecvErrCheck(host, remote_host, bmc, exp_id, slot_list, retimers, remote_bmc, route_name, reg_access_tool, remote_reg_access_tool, True)
|
|
|
|
|
|
elif cmd == 'inmpd-check':
|
|
|
|
|
|
inmpd_check(host, bmc, exp_id, slot_list, reg_access_tool)
|
|
|
|
|
|
elif cmd == 'tia-peak-tune':
|
|
|
|
|
|
wt_regs = param_list
|
|
|
|
|
|
TiaPeakTune(reg_access_tool, bmc, host, exp_id, slot_list, lane_list, wt_regs)
|
|
|
|
|
|
elif cmd == 'mgc-tune':
|
|
|
|
|
|
MgcTune(reg_access_tool, bmc, host, exp_id, slot_list, lane_list, reg_wt_value)
|
|
|
|
|
|
elif cmd == 'exp-cold-reset':
|
|
|
|
|
|
ExpColdReset(bmc, exp_id)
|
|
|
|
|
|
elif cmd in ['plot-mgc-vpeak', 'mgc-auto-tune', 'mgc-auto-tune2', 'tiapeak-auto-tune', 'highfreq-auto-tune',
|
|
|
|
|
|
'lowfreq-auto-tune', 'opcurrent-auto-tune', 'opcurrent-auto-tune-test', 'rt-ibias', 'rt-mgc', 'mgc-manual-tune', 'mgc-calc-target-vpeak']:
|
|
|
|
|
|
logging.info(f'reg_table_file:{reg_table_file}')
|
|
|
|
|
|
|
|
|
|
|
|
AutoTuneMGC(host, bmc, remote_bmc, reg_access_tool, remote_reg_access_tool,
|
|
|
|
|
|
exp_id, slot_list, lane_list, reg_access_tool.parser, cmd, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'ibias-auto-tune':
|
|
|
|
|
|
logging.info(f'------------ param: {param}')
|
|
|
|
|
|
if rtmr_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in rtmr_list]
|
|
|
|
|
|
|
|
|
|
|
|
if remote_bmc is None:
|
|
|
|
|
|
remote_bmc = bmc
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool = PrbsTool(bmc, remote_bmc, reg_access_tool, remote_reg_access_tool, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
if param == '':
|
|
|
|
|
|
preset = 9
|
|
|
|
|
|
else:
|
|
|
|
|
|
preset = int(param)
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool.ResetRetimerAndEnablePrbs(exp_id, retimers, preset)
|
|
|
|
|
|
if remote_bmc == bmc:
|
|
|
|
|
|
# AutoTuneIbias(host, bmc, exp_id, slot_list, lane_list, reg_access_tool.parser, route_name)
|
|
|
|
|
|
AutoTuneIbiasOnet(host, bmc, exp_id, slot_list, lane_list, bmc, reg_table_file, route_name, ibias_rssi_map)
|
|
|
|
|
|
else:
|
|
|
|
|
|
# bmc.TopoConfig(exp_id, '32')
|
|
|
|
|
|
# remote_bmc.TopoConfig(exp_id, '32')
|
|
|
|
|
|
# bmc.TopoConfig(exp_id, '32')
|
|
|
|
|
|
# remote_bmc.TopoConfig(exp_id, '32')
|
|
|
|
|
|
|
|
|
|
|
|
AutoTuneIbiasOnet(host, bmc, exp_id, slot_list, lane_list, remote_bmc, reg_table_file, route_name, ibias_rssi_map)
|
|
|
|
|
|
|
|
|
|
|
|
AutoTuneIbiasOnet(host, remote_bmc, exp_id, slot_list, lane_list, bmc, reg_table_file, route_name, ibias_rssi_map)
|
|
|
|
|
|
# elif cmd == 'lowfreq-auto-tune':
|
|
|
|
|
|
# AutoTuneLowFreq(host, bmc, exp_id, slot_list, reg_table_file, cmd)
|
|
|
|
|
|
elif cmd == "highfreq-tune":
|
|
|
|
|
|
wt_regs = param_list
|
|
|
|
|
|
TuneHighFreq(reg_access_tool, exp_id)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'swa-auto-tune':
|
|
|
|
|
|
SwaAutoTune(host, bmc, exp_id, slot_list, lane_list, remote_bmc, route_name, reg_access_tool, remote_reg_access_tool)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'swb-auto-tune':
|
|
|
|
|
|
SwbAutoTune(host, bmc, exp_id, slot_list, lane_list, remote_bmc, route_name, reg_access_tool, remote_reg_access_tool)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'mzm-auto-tune':
|
|
|
|
|
|
MzmAutoTune(host, bmc, exp_id, slot_list, lane_list, remote_bmc, route_name, reg_access_tool, remote_reg_access_tool)
|
|
|
|
|
|
elif cmd == 'rtmr-prbs':
|
|
|
|
|
|
if remote_host != '':
|
|
|
|
|
|
host_list = f'{host},{remote_host}'
|
|
|
|
|
|
else:
|
|
|
|
|
|
host_list = host
|
|
|
|
|
|
|
|
|
|
|
|
cms_str = ["ocs_link_reset", "-i", f"{host_list}", "-e", f"{exp_id}"]
|
|
|
|
|
|
logging.info(f'---- cmd: {cms_str}')
|
|
|
|
|
|
result = subprocess.run(cms_str, timeout=30)
|
|
|
|
|
|
time.sleep(6)
|
|
|
|
|
|
if result.returncode == 0:
|
|
|
|
|
|
print("ocs link reset success")
|
|
|
|
|
|
else:
|
|
|
|
|
|
print("ocs link reset failed")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(param)
|
|
|
|
|
|
logging.info(param_list)
|
|
|
|
|
|
if param_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in param_list]
|
|
|
|
|
|
|
|
|
|
|
|
if remote_bmc is None:
|
|
|
|
|
|
remote_bmc = bmc
|
|
|
|
|
|
remote_reg_access_tool = reg_access_tool
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool = PrbsTool(bmc, remote_bmc, reg_access_tool, remote_reg_access_tool, route_name)
|
|
|
|
|
|
logging.info('--------step 2')
|
|
|
|
|
|
logging.info(f"------slot_list: {slot_list}")
|
|
|
|
|
|
prbs_tool.ResetRetimerAndEnablePrbs(exp_id, retimers)
|
|
|
|
|
|
elif cmd == 'rtmr-ctle-wt':
|
|
|
|
|
|
logging.info(f'--------- rtmr-ctle-wt, rtmr_list: {rtmr_list}')
|
|
|
|
|
|
|
|
|
|
|
|
WriteRtmrCtle(host, exp_id, bmc, rtmr_list, lane_list, int(param))
|
|
|
|
|
|
CommitRtmrCtle(exp_id, bmc, rtmr_list)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'rtmr-prbs-test':
|
|
|
|
|
|
if remote_host != '' and host != remote_host:
|
|
|
|
|
|
host_list = f'{host},{remote_host}'
|
|
|
|
|
|
else:
|
|
|
|
|
|
host_list = host
|
|
|
|
|
|
|
|
|
|
|
|
# cms_str = ["ocs_link_reset", "-i", f"{host_list}", "-e", f"{exp_id}"]
|
|
|
|
|
|
# logging.info(f'---- cmd: {cms_str}')
|
|
|
|
|
|
# result = subprocess.run(cms_str, timeout=30)
|
|
|
|
|
|
# time.sleep(6)
|
|
|
|
|
|
# if result.returncode == 0:
|
|
|
|
|
|
# print("ocs link reset success")
|
|
|
|
|
|
# else:
|
|
|
|
|
|
# print("ocs link reset failed")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(param)
|
|
|
|
|
|
logging.info(param_list)
|
|
|
|
|
|
if param_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in param_list]
|
|
|
|
|
|
|
|
|
|
|
|
if remote_bmc is None:
|
|
|
|
|
|
remote_bmc = bmc
|
|
|
|
|
|
remote_reg_access_tool = reg_access_tool
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool = PrbsTool(bmc, remote_bmc, reg_access_tool, remote_reg_access_tool, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"------slot_list: {slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info("----------step 1: reset retimer")
|
|
|
|
|
|
prbs_tool.ResetRetimer(exp_id, retimers)
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
logging.info("----------step 2: enable prbs")
|
|
|
|
|
|
|
|
|
|
|
|
# all_rtmr_lane_settings: List[RetimerLaneSetting] = load_ctle_config(host, route_name, exp_id)
|
|
|
|
|
|
# for lane_setting in all_rtmr_lane_settings:
|
|
|
|
|
|
# WriteRtmrCtle(host, exp_id, bmc, [lane_setting.rtmr_id], [lane_setting.rtmr_lane], lane_setting.ctle)
|
|
|
|
|
|
# time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
# if all_rtmr_lane_settings:
|
|
|
|
|
|
# CommitRtmrCtle(exp_id, bmc, retimers)
|
|
|
|
|
|
|
|
|
|
|
|
# prbs_tool.EnableTxPrbsDebug(exp_id, retimers)
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool.EnableTxPrbs(exp_id, retimers)
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool.prbs_check(exp_id, retimers, True)
|
|
|
|
|
|
time.sleep(2)
|
|
|
|
|
|
prbs_tool.prbs_check(exp_id, retimers, False)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == 'ctle-auto-tune':
|
|
|
|
|
|
if remote_host != '' and host != remote_host:
|
|
|
|
|
|
host_list = f'{host},{remote_host}'
|
|
|
|
|
|
else:
|
|
|
|
|
|
host_list = host
|
|
|
|
|
|
|
|
|
|
|
|
cms_str = ["ocs_link_reset", "-i", f"{host_list}", "-e", f"{exp_id}"]
|
|
|
|
|
|
logging.info(f'---- cmd: {cms_str}')
|
|
|
|
|
|
result = subprocess.run(cms_str, timeout=30)
|
|
|
|
|
|
time.sleep(6)
|
|
|
|
|
|
if result.returncode == 0:
|
|
|
|
|
|
print("ocs link reset success")
|
|
|
|
|
|
else:
|
|
|
|
|
|
print("ocs link reset failed")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(param)
|
|
|
|
|
|
logging.info(param_list)
|
|
|
|
|
|
if rtmr_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in rtmr_list]
|
|
|
|
|
|
|
|
|
|
|
|
if remote_bmc is None:
|
|
|
|
|
|
remote_bmc = bmc
|
|
|
|
|
|
remote_reg_access_tool = reg_access_tool
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool = PrbsTool(bmc, remote_bmc, reg_access_tool, remote_reg_access_tool, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"------slot_list: {slot_list}")
|
|
|
|
|
|
|
|
|
|
|
|
logging.info("----------step 1: reset retimer")
|
|
|
|
|
|
prbs_tool.ResetRetimer(exp_id, retimers)
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
logging.info("----------step 2: enable prbs")
|
|
|
|
|
|
|
|
|
|
|
|
# all_rtmr_lane_settings: List[RetimerLaneSetting] = load_ctle_config(host, route_name, exp_id)
|
|
|
|
|
|
# for lane_setting in all_rtmr_lane_settings:
|
|
|
|
|
|
# # WriteRtmrCtle(host, exp_id, bmc, [lane_setting.rtmr_id], [lane_setting.rtmr_lane], 0)
|
|
|
|
|
|
# WriteRtmrCtle(host, exp_id, bmc, [lane_setting.rtmr_id], [lane_setting.rtmr_lane], lane_setting.ctle)
|
|
|
|
|
|
# time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tune_value_list = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
|
|
|
|
|
|
# tune_value_list = [0, 18]
|
|
|
|
|
|
lane_data_list: List[LaneErrInfo] = []
|
|
|
|
|
|
|
|
|
|
|
|
topo_map = TopoMappingParser("/xz/gyou/nexusbench/main_data/topo_mapping.yaml")
|
|
|
|
|
|
topo_map.parse()
|
|
|
|
|
|
|
|
|
|
|
|
for slot_id in [0, 1, 2, 3, 4, 5, 6, 7]:
|
|
|
|
|
|
for lane in [0, 1, 2, 3, 4, 5, 6, 7]:
|
|
|
|
|
|
tmp_err_map = {value: -1 for value in tune_value_list}
|
|
|
|
|
|
|
|
|
|
|
|
result = topo_map.get_phys_rtmr_by_slot(slot_id, lane, route_name)
|
|
|
|
|
|
if result:
|
|
|
|
|
|
success, rt_phys_id, rt_phys_lane = result
|
|
|
|
|
|
if success == False:
|
|
|
|
|
|
logging.error(f'get_phys_rtmr_by_slot failed, result: {success}')
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
lane_info = LaneErrInfo(
|
|
|
|
|
|
slot_id=slot_id,
|
|
|
|
|
|
logic_lane=lane,
|
|
|
|
|
|
rt_phys_id=rt_phys_id,
|
|
|
|
|
|
rt_phys_lane=rt_phys_lane,
|
|
|
|
|
|
tmp_err_map=tmp_err_map
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
lane_data_list.append(lane_info)
|
|
|
|
|
|
if param == '':
|
|
|
|
|
|
logging.info(f"preset is empty, please set preset by param")
|
|
|
|
|
|
preset_list = [int(param)]
|
|
|
|
|
|
for preset in preset_list:
|
|
|
|
|
|
for ctle in tune_value_list:
|
|
|
|
|
|
for rtmr in retimers:
|
|
|
|
|
|
for rt_lane in range(16):
|
|
|
|
|
|
WriteRtmrCtle(host, exp_id, bmc, [rtmr], [rt_lane], ctle)
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
|
|
|
|
|
|
|
|
# if all_rtmr_lane_settings:
|
|
|
|
|
|
CommitRtmrCtle(exp_id, bmc, retimers)
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool.EnableTxPrbs(exp_id, retimers, preset)
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool.prbs_check(exp_id, retimers, True)
|
|
|
|
|
|
time.sleep(5)
|
|
|
|
|
|
prbs_results = prbs_tool.prbs_check(exp_id, retimers, False)
|
|
|
|
|
|
# logging.info(f'-------------- prbs_results: {prbs_results}')
|
|
|
|
|
|
|
|
|
|
|
|
for prbs in prbs_results:
|
|
|
|
|
|
logging.info(f'rtmr_id: {prbs.rtmr_id}, lane: {prbs.rtmr_lane}, route: {route_name}')
|
|
|
|
|
|
slot = topo_map.get_local_slot_by_retimer(prbs.rtmr_id, prbs.rtmr_lane, route_name)
|
|
|
|
|
|
|
|
|
|
|
|
if not slot:
|
|
|
|
|
|
logging.error(f'local slot is none!')
|
|
|
|
|
|
return False
|
|
|
|
|
|
slot_id, lane_id = slot
|
|
|
|
|
|
|
|
|
|
|
|
for info in lane_data_list:
|
|
|
|
|
|
if info.slot_id == slot_id and info.logic_lane == lane_id:
|
|
|
|
|
|
info.preset = preset
|
|
|
|
|
|
# logging.info(f'--------- start modify, value: {value}, prbs.locked: {prbs.locked}')
|
|
|
|
|
|
if prbs.locked:
|
|
|
|
|
|
info.tmp_err_map[ctle] = prbs.err_count
|
|
|
|
|
|
else:
|
|
|
|
|
|
info.tmp_err_map[ctle] = 69999
|
|
|
|
|
|
# logging.info(f'------prbs unlock, {value}: {info.tmp_err_map[value]}')
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f'info.tmp_err_map: {info.tmp_err_map}')
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
for rtmr in retimers:
|
|
|
|
|
|
bmc.CmdVendorCommand(exp_id, f'rtmr {rtmr} phy full')
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
rd_regs = ['mgc']
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
all_lane_reg_values: List[LaneRegInfo] = reg_access_tool.read_opt_regs(exp_id, slot_list, [0,1,2,3,4,5,6,7], rd_regs)
|
|
|
|
|
|
if not all_lane_reg_values:
|
|
|
|
|
|
print("No register data read.")
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 提取 slot 和 lane 顺序(只需一次)
|
|
|
|
|
|
slots = [item.slot_id for item in all_lane_reg_values]
|
|
|
|
|
|
lanes = [item.logic_lane for item in all_lane_reg_values]
|
|
|
|
|
|
|
|
|
|
|
|
# 对 rd_regs 中每个寄存器,单独打印
|
|
|
|
|
|
for reg_name in rd_regs:
|
|
|
|
|
|
values = [getattr(item, reg_name) for item in all_lane_reg_values]
|
|
|
|
|
|
logging.info(f"host: {host} exp: {exp_id} reg: {reg_name} slot: {slot_list} lane: {lane_list}")
|
|
|
|
|
|
logging.info(f"value: {values}\n")
|
|
|
|
|
|
|
|
|
|
|
|
print_general_err_matrix(host, exp_id, lane_data_list, tune_value_list)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == "rtmr-reset":
|
|
|
|
|
|
if remote_host != '':
|
|
|
|
|
|
host_list = f'{host},{remote_host}'
|
|
|
|
|
|
else:
|
|
|
|
|
|
host_list = host
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(param)
|
|
|
|
|
|
logging.info(param_list)
|
|
|
|
|
|
if param_list == ['']:
|
|
|
|
|
|
retimers = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
retimers = [int(x) for x in param_list]
|
|
|
|
|
|
|
|
|
|
|
|
if remote_bmc is None:
|
|
|
|
|
|
remote_bmc = bmc
|
|
|
|
|
|
remote_reg_access_tool = reg_access_tool
|
|
|
|
|
|
|
|
|
|
|
|
prbs_tool = PrbsTool(bmc, remote_bmc, reg_access_tool, remote_reg_access_tool, route_name)
|
|
|
|
|
|
logging.info('--------step 2')
|
|
|
|
|
|
logging.info(f"------slot_list: {slot_list}")
|
|
|
|
|
|
# prbs_tool.ResetRetimer(exp_id, retimers)
|
|
|
|
|
|
# logging.info(f'host: {host_list}')
|
|
|
|
|
|
# with ThreadPoolExecutor(max_workers=len(host_list)) as executor:
|
|
|
|
|
|
# executor.map(process_rtmr_waram_reset, host_list)
|
|
|
|
|
|
rtmr_reset_and_port_reset(bmc, exp_id)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == "vcmd":
|
|
|
|
|
|
bmc.CmdVendorCommand(exp_id, param)
|
|
|
|
|
|
elif cmd == "eq-auto-tune":
|
|
|
|
|
|
logging.info(f'------------ param: {param}')
|
|
|
|
|
|
AutoTuneEq(host, bmc, exp_id, slot_list, lane_list, remote_bmc, route_name, reg_access_tool, remote_reg_access_tool)
|
|
|
|
|
|
|
|
|
|
|
|
elif cmd == "calc-ctle-map":
|
|
|
|
|
|
logging.info(f'------------ param: {param}')
|
|
|
|
|
|
CalcCtleMap(host, bmc, exp_id, slot_list, lane_list, remote_bmc, route_name, reg_access_tool, remote_reg_access_tool)
|
|
|
|
|
|
elif cmd == "topo-config":
|
|
|
|
|
|
bmc.TopoConfig(exp_id, param)
|
|
|
|
|
|
elif cmd == "exp-stat":
|
|
|
|
|
|
bmc.GetExpStatus(exp_id)
|
|
|
|
|
|
elif cmd == 'reg-save':
|
|
|
|
|
|
regs = param_list
|
|
|
|
|
|
logging.info(f'--------param_list:{param_list}')
|
|
|
|
|
|
if regs == ['']:
|
|
|
|
|
|
regs = ['mgc', 'vpeak', 'tia_peak', 'ibias', 'ipcurrent', 'opcurrent',
|
|
|
|
|
|
'lowfreq_eq', 'highfreq_eq', 'vgc_set', 'drv_vpeak', 'rssi',
|
|
|
|
|
|
'swa_onoc_h', 'swa_onoc_m', 'swa_onoc_l', 'swa_onet_h', 'swa_onet_m', 'swa_onet_l',
|
|
|
|
|
|
'swb_oneta_h', 'swb_oneta_m', 'swb_oneta_l', 'swb_onetb_h', 'swb_onetb_m', 'swb_onetb_l']
|
|
|
|
|
|
SaveRegsToFile(reg_access_tool, host, exp_id, slot_list, route_name, lane_list, regs, sl_file)
|
|
|
|
|
|
elif cmd == 'reg-load':
|
|
|
|
|
|
regs = param_list
|
|
|
|
|
|
logging.info(f'--------param_list:{param_list}')
|
|
|
|
|
|
# if regs == ['']:
|
|
|
|
|
|
# logging.error('regs is empty')
|
|
|
|
|
|
# regs = ['mgc', 'tia_peak', 'ibias', 'ipcurrent', 'opcurrent',
|
|
|
|
|
|
# 'lowfreq_eq', 'highfreq_eq', 'vgc_set', 'drv_vpeak']
|
|
|
|
|
|
LoadRegsToFile(reg_access_tool, host, exp_id, slot_list, route_name, regs, sl_file)
|
|
|
|
|
|
elif cmd == 'tune-rd':
|
|
|
|
|
|
rtmr_id = int(param_list[0])
|
|
|
|
|
|
rtmr_lane = int(param_list[1])
|
|
|
|
|
|
TuneView(host, bmc, exp_id, slot_list, lane_list, remote_bmc,
|
|
|
|
|
|
route_name, reg_access_tool, remote_reg_access_tool,
|
|
|
|
|
|
rtmr_id, rtmr_lane)
|
|
|
|
|
|
elif cmd == 'tune-wt':
|
|
|
|
|
|
rtmr_id = int(param_list[0])
|
|
|
|
|
|
rtmr_lane = int(param_list[1])
|
|
|
|
|
|
reg_name_value = reg_wt_value.split('=')
|
|
|
|
|
|
TuneWrite(host, bmc, exp_id, slot_list, lane_list, remote_bmc,
|
|
|
|
|
|
route_name, reg_access_tool, remote_reg_access_tool,
|
|
|
|
|
|
rtmr_id, rtmr_lane, reg_name_value[0], int(reg_name_value[1]))
|
|
|
|
|
|
elif cmd == 'set-power':
|
|
|
|
|
|
SetPower(host, exp_id, bmc, param)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logging.error(f"Invalid command: {cmd}")
|
|
|
|
|
|
|
|
|
|
|
|
exp_util.unlock(exp_id)
|
|
|
|
|
|
logging.info(f'----------process_host {host} exp {exp_id} unlock')
|
|
|
|
|
|
|
|
|
|
|
|
if cmd in ['ibias-auto-tune', 'eq-auto-tune', 'tune-rd', 'tune-wt', 'rssi-check', 'err-check', 'rtmr-prbs', 'rtmr-prbs-test', 'ctle-auto-tune', 'mgc-auto-tune',
|
|
|
|
|
|
'mgc-auto-tune2', 'lowfreq-auto-tune', 'highfreq-auto-tune', 'opcurrent-auto-tune', 'opcurrent-auto-tune-test', 'tiapeak-auto-tune'] and remote_ip != '':
|
|
|
|
|
|
if remote_exp_util:
|
|
|
|
|
|
remote_exp_util.unlock(exp_id)
|
|
|
|
|
|
logging.info(f'----------process dst host {remote_host} exp {exp_id} unlock')
|
|
|
|
|
|
|
|
|
|
|
|
def expand_ip(ip: str) -> str:
|
|
|
|
|
|
if '.' in ip:
|
|
|
|
|
|
return ip # 已经是完整 IP,直接返回
|
|
|
|
|
|
try:
|
|
|
|
|
|
last_octet = int(ip)
|
|
|
|
|
|
if 0 <= last_octet <= 255:
|
|
|
|
|
|
return f"10.57.216.{last_octet}"
|
|
|
|
|
|
else:
|
|
|
|
|
|
raise ValueError(f"Invalid IP last octet: {last_octet}")
|
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
|
raise ValueError(f"Invalid IP format: {ip}, must be x.x.x.x or 0-255") from e
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
Logger.init_logging(log_folder='logs', level=logging.INFO)
|
|
|
|
|
|
parser = argparse.ArgumentParser(description="XZtech OCS Diag Tool (v0.2@20260106)")
|
|
|
|
|
|
parser.add_argument("--host", "-i", type=str, required=False, default='', help="")
|
|
|
|
|
|
parser.add_argument("--remote_host", "-r", type=str, required=False, default='', help="")
|
|
|
|
|
|
parser.add_argument("--os_host", "-o", type=str, required=False, default='', help="")
|
|
|
|
|
|
parser.add_argument("--exp", "-e", type=str, required=True, default='', help="")
|
|
|
|
|
|
parser.add_argument("--slot", "-s", type=str, default='0', help="")
|
|
|
|
|
|
parser.add_argument("--rtmr", "-rt", type=str, default='all', help="")
|
|
|
|
|
|
parser.add_argument("--lane", "-l", type=str, default='all', help="default all lane")
|
|
|
|
|
|
parser.add_argument("--cmd", "-c", required=True, type=str, default='',
|
|
|
|
|
|
help="" )
|
|
|
|
|
|
# parser.add_argument("--cmd", "-c", required=True, type=str, default='',
|
|
|
|
|
|
# help="exp-cold-reset, exp_stat, rtmr-prbs, rtmr-reset, reg-rd, reg-wt, vcmd, \
|
|
|
|
|
|
# topo-config, mgc-auto-tune, mgc-manual-tune, mgc-calc-target-vpeak, \
|
|
|
|
|
|
# ibias-auto-tune, reg-save, reg-load, lowfreq-auto-tune, highfreq-tune, tia-peak-tune, eq-auto-tune, tune-view" )
|
|
|
|
|
|
parser.add_argument("--param", "-p", type=str, default='', help="param for cmd")
|
|
|
|
|
|
parser.add_argument("--value", "-v", type=str, default='', help="value of reg-rd")
|
|
|
|
|
|
parser.add_argument("--reg_table", type=str, default='', help="")
|
|
|
|
|
|
parser.add_argument("--sl_file", type=str, default='',
|
|
|
|
|
|
help="default")
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
|
|
# config_file = args.rw_config
|
|
|
|
|
|
reg_table_file = args.reg_table
|
|
|
|
|
|
# logging.info(reg_table_file)
|
|
|
|
|
|
|
|
|
|
|
|
sl_file = args.sl_file
|
|
|
|
|
|
# logging.info(f'-------save load file: {sl_file}')
|
|
|
|
|
|
|
|
|
|
|
|
host_list = [expand_ip(h.strip()) for h in args.host.split(',') if h.strip()]
|
|
|
|
|
|
# logging.info(f'------ host_list: {host_list}')
|
|
|
|
|
|
|
|
|
|
|
|
os_host_list = [expand_ip(h.strip()) for h in args.os_host.split(',') if h.strip()]
|
|
|
|
|
|
# logging.info(f'------ os_host_list: {os_host_list}')
|
|
|
|
|
|
|
|
|
|
|
|
if hasattr(args, 'remote_host') and args.remote_host:
|
|
|
|
|
|
remote_ip = expand_ip(args.remote_host.strip())
|
|
|
|
|
|
logging.info(f'------ remote_ip: {remote_ip}')
|
|
|
|
|
|
else:
|
|
|
|
|
|
remote_ip = ''
|
|
|
|
|
|
|
|
|
|
|
|
exp_list = args.exp.split(',')
|
|
|
|
|
|
|
|
|
|
|
|
cmd = args.cmd
|
|
|
|
|
|
|
|
|
|
|
|
if args.slot == 'all':
|
|
|
|
|
|
slot_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
else:
|
|
|
|
|
|
slot_list = list(map(int, args.slot.split(',')))
|
|
|
|
|
|
|
|
|
|
|
|
if args.rtmr == 'all':
|
|
|
|
|
|
rtmr_list = [1,2,3,4]
|
|
|
|
|
|
else:
|
|
|
|
|
|
rtmr_list = list(map(int, args.rtmr.split(',')))
|
|
|
|
|
|
logging.info(rtmr_list)
|
|
|
|
|
|
|
|
|
|
|
|
if args.lane == 'all':
|
|
|
|
|
|
lane_list = [0,1,2,3,4,5,6,7]
|
|
|
|
|
|
if cmd == 'rtmr-ctle-wt':
|
|
|
|
|
|
lane_list = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
|
|
|
|
|
|
else:
|
|
|
|
|
|
lane_list = list(map(int, args.lane.split(',')))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# logging.info(f'------slot_list:{slot_list}')
|
|
|
|
|
|
|
|
|
|
|
|
param = ''
|
|
|
|
|
|
param_list = args.param.split(',')
|
|
|
|
|
|
if len(param_list) == 1:
|
|
|
|
|
|
param = args.param
|
|
|
|
|
|
|
|
|
|
|
|
reg_wt_value = args.value
|
|
|
|
|
|
|
|
|
|
|
|
if cmd == 'reg-wt' and reg_wt_value == '':
|
|
|
|
|
|
logging.error('reg write value is empty!')
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
# with ThreadPoolExecutor(max_workers=len(host_list)) as executor:
|
|
|
|
|
|
# executor.map(process_host, host_list)
|
|
|
|
|
|
|
|
|
|
|
|
if cmd == 'link-train':
|
|
|
|
|
|
if param == '':
|
|
|
|
|
|
logging.error('topo name is empty!')
|
|
|
|
|
|
sys.exit()
|
|
|
|
|
|
else:
|
|
|
|
|
|
link_train(host_list, os_host_list, exp_list, f'mesh_{param}.json')
|
|
|
|
|
|
sys.exit()
|
|
|
|
|
|
elif cmd == 'gpu-reset':
|
|
|
|
|
|
gpu_reset(os_host_list)
|
|
|
|
|
|
sys.exit()
|
|
|
|
|
|
elif cmd == 'gpu-cto-disable':
|
|
|
|
|
|
gpu_cto_disable(os_host_list)
|
|
|
|
|
|
sys.exit()
|
|
|
|
|
|
|
|
|
|
|
|
with ThreadPoolExecutor(max_workers=1) as executor:
|
|
|
|
|
|
func_with_params = partial(process_host, reg_table_file=reg_table_file, exp_list=exp_list,
|
|
|
|
|
|
slot_list=slot_list, rtmr_list=rtmr_list, lane_list=lane_list, cmd=cmd, param=param,
|
|
|
|
|
|
reg_wt_value=reg_wt_value, sl_file=sl_file)
|
|
|
|
|
|
executor.map(func_with_params, host_list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|