Commit 5fc79880 authored by Andrey Filippov's avatar Andrey Filippov

desting, debugging, cleaning up

parent 4aaf6074
...@@ -444,7 +444,8 @@ class X393McntrlAdjust(object): ...@@ -444,7 +444,8 @@ class X393McntrlAdjust(object):
phaseData=delays[phase] phaseData=delays[phase]
phaseErrs=errors[phase] phaseErrs=errors[phase]
if quiet <1: if quiet <1:
print("phaseData=",phaseData) print(phase,"--phaseData=",phaseData," ... highDelay=",highDelay," lowDelay=",lowDelay," list_branches=",list_branches)
# print("phaseErrs=",phaseErrs) # print("phaseErrs=",phaseErrs)
else: else:
try: try:
...@@ -457,10 +458,13 @@ class X393McntrlAdjust(object): ...@@ -457,10 +458,13 @@ class X393McntrlAdjust(object):
return None return None
if quiet <1: if quiet <1:
print("phaseData=",phaseData) print(phase,"phaseData=",phaseData," ... highDelay=",highDelay," lowDelay=",lowDelay," list_branches=",list_branches)
if phaseData is None: if phaseData is None:
return None return None
# print ("target=",target," phaseData=",phaseData )
"""
periods=phaseData.keys() periods=phaseData.keys()
periods.sort() # can compare tuples (1-st is "more important") periods.sort() # can compare tuples (1-st is "more important")
...@@ -476,7 +480,24 @@ class X393McntrlAdjust(object): ...@@ -476,7 +480,24 @@ class X393McntrlAdjust(object):
for indx,branch in enumerate(periods): # if all elements are None for indx,branch in enumerate(periods): # if all elements are None
if all(v is None for v in phaseData[branch]): if all(v is None for v in phaseData[branch]):
periods.pop(indx) periods.pop(indx)
"""
periods=set(phaseData.keys())
if maxErrPS:
for period in periods.copy():
if phaseErrs[period] > maxErrPS:
periods.remove(period)
if allGood:
for period in periods.copy():
if None in phaseData[period]:
periods.remove(period)
for period in periods.copy(): # if all elements are None
if all(v is None for v in phaseData[period]):
periods.remove(period)
periods=list(periods)
periods.sort() # can compare tuples (1-st is "more important")
# useBranch # useBranch
# filter results # filter results
...@@ -500,7 +521,7 @@ class X393McntrlAdjust(object): ...@@ -500,7 +521,7 @@ class X393McntrlAdjust(object):
eff_errs=[phaseErrs[b]+(delay_cost*sum(d for d in phaseData[b] if not d is None)/sum(1 for d in phaseData[b] if not d is None)) for b in periods] eff_errs=[phaseErrs[b]+(delay_cost*sum(d for d in phaseData[b] if not d is None)/sum(1 for d in phaseData[b] if not d is None)) for b in periods]
periods=[periods[eff_errs.index(min(eff_errs))]] periods=[periods[eff_errs.index(min(eff_errs))]]
#Filter by low/high delays without minError mode #Filter by low/high delays without minError mode
if len(periods)>1: if len(periods)>1:
dl0_per=[phaseData[p][0] for p in periods] # only delay for line 0, but with same branch requirement this should be the same for all lines dl0_per=[phaseData[p][0] for p in periods] # only delay for line 0, but with same branch requirement this should be the same for all lines
if highDelay or lowDelay or not list_branches or return_error: # in list_branches mode - filter by low/high only if requested, for delays use low if not highDelay if highDelay or lowDelay or not list_branches or return_error: # in list_branches mode - filter by low/high only if requested, for delays use low if not highDelay
periods=[periods[dl0_per.index((min,max)[highDelay](dl0_per))]] periods=[periods[dl0_per.index((min,max)[highDelay](dl0_per))]]
...@@ -567,7 +588,7 @@ class X393McntrlAdjust(object): ...@@ -567,7 +588,7 @@ class X393McntrlAdjust(object):
try: try:
phase= self.adjustment_state['optimal_phase'] phase= self.adjustment_state['optimal_phase']
except: except:
raise Exception("Phase value is not provided and global;optimal phase is not defined") raise Exception("Phase value is not provided and global optimal phase is not defined")
num_addr=vrlg.ADDRESS_NUMBER num_addr=vrlg.ADDRESS_NUMBER
num_banks=3 num_banks=3
dly_steps=self.x393_mcntrl_timing.get_dly_steps() dly_steps=self.x393_mcntrl_timing.get_dly_steps()
...@@ -672,7 +693,7 @@ class X393McntrlAdjust(object): ...@@ -672,7 +693,7 @@ class X393McntrlAdjust(object):
if (k == CMDA_KEY) and ((not 'addr_odelay' in self.adjustment_state) or if (k == CMDA_KEY) and ((not 'addr_odelay' in self.adjustment_state) or
(isinstance (filter_cmda,str) and (len(filter_cmda)>1) and (filter_cmda.upper()[0]=='S'))): (isinstance (filter_cmda,str) and (len(filter_cmda)>1) and (filter_cmda.upper()[0]=='S'))):
if quiet < 3: if quiet < 3:
print ("\n===== processing '%s' using self.adjustment_state['cmda_bspe']"%(k)) print ("\n------ processing '%s' using self.adjustment_state['cmda_bspe'], filter= %s"%(k,str(filters[k])))
try: try:
cmda_bspe=self.adjustment_state['cmda_bspe'] cmda_bspe=self.adjustment_state['cmda_bspe']
except: except:
...@@ -692,7 +713,7 @@ class X393McntrlAdjust(object): ...@@ -692,7 +713,7 @@ class X393McntrlAdjust(object):
delays[k]=cmda_bspe[phase]['ldly'] delays[k]=cmda_bspe[phase]['ldly']
else: else:
if quiet < 3: if quiet < 3:
print ("\n===== processing '%s'"%(k)) print ("\n------ processing '%s', filter= %s"%(k,str(filters[k])))
if forgive_missing: if forgive_missing:
try: try:
delays[k]=self.get_delays_for_phase(phase = phase, delays[k]=self.get_delays_for_phase(phase = phase,
...@@ -732,6 +753,7 @@ class X393McntrlAdjust(object): ...@@ -732,6 +753,7 @@ class X393McntrlAdjust(object):
@param filter_dqo filter for DQS output delays, @param filter_dqo filter for DQS output delays,
@param quiet Reduce output @param quiet Reduce output
""" """
"""
required_keys=('addr_odelay', required_keys=('addr_odelay',
'dqi_phase_multi', 'dqi_phase_multi',
'dqi_phase_err', 'dqi_phase_err',
...@@ -741,35 +763,90 @@ class X393McntrlAdjust(object): ...@@ -741,35 +763,90 @@ class X393McntrlAdjust(object):
'dqsi_phase_err', 'dqsi_phase_err',
'dqso_phase_multi', 'dqso_phase_multi',
'dqso_phase_err') 'dqso_phase_err')
if not all (k in self.adjustment_state for k in required_keys): """
print ("Running in simulation mode, using hardcoded data") #temporarily:
self.load_hardcoded_data() self.load_mcntrl('dbg/x393_mcntrl.pickle')
self.proc_addr_odelay(True, 200.0, 4)
self.proc_dqsi_phase ('All', 50, 0, 0.0, 200, 3)
self.proc_dqso_phase ('All', 50, 0, 0.0, 200, 3) # if not all (k in self.adjustment_state for k in required_keys):
# print ("Running in simulation mode, using hardcoded data")
# self.load_hardcoded_data()
# self.proc_addr_odelay(True, 200.0, 4)
# self.proc_dqsi_phase ('All', 50, 0, 0.0, 200, 3)
# self.proc_dqso_phase ('All', 50, 0, 0.0, 200, 3)
#datasheet step per average delay per finedelay step #datasheet step per average delay per finedelay step
all_groups_valid_only=False
if (isinstance(filter_variants,str)) : # currently - any string means "keep only phases that have all groups valid)
all_groups_valid_only=True
filter_variants=None
tSDQS=1000.0*self.x393_mcntrl_timing.get_dly_steps()['DLY_STEP']/NUM_FINE_STEPS tSDQS=1000.0*self.x393_mcntrl_timing.get_dly_steps()['DLY_STEP']/NUM_FINE_STEPS
filters=dict(zip(SIG_LIST,[filter_cmda,filter_dqsi,filter_dqi,filter_dqso,filter_dqo])) filters=dict(zip(SIG_LIST,[filter_cmda,filter_dqsi,filter_dqi,filter_dqso,filter_dqo]))
# filters={CMDA_KEY:filter_cmda,DQSI_KEY:filter_dqsi,DQI_KEY:filter_dqi,DQSO_KEY:filter_dqso,DQO_KEY:filter_dqo} # filters={CMDA_KEY:filter_cmda,DQSI_KEY:filter_dqsi,DQI_KEY:filter_dqi,DQSO_KEY:filter_dqso,DQO_KEY:filter_dqo}
periods_phase={} periods_phase={}
periods_all={} periods_all={}
for k in SIG_LIST: for k in SIG_LIST:
if quiet < 3: if quiet < 2:
print ("\n===== processing '%s'"%(k)) print ("\n===== processing '%s', filter= %s"%(k,str(filters[k])))
periods_phase[k]=self.get_delays_for_phase(phase = None, periods_phase[k]=self.get_delays_for_phase(phase = None,
list_branches=True, list_branches=True,
target=k, target=k,
b_filter=filters[k], b_filter=filters[k],
#cost=NUM_FINE_STEPS, #cost=NUM_FINE_STEPS,
quiet = quiet+2) # quiet = quiet+2)
quiet = quiet+0)
numPhases=len(periods_phase[CMDA_KEY]) numPhases=len(periods_phase[CMDA_KEY])
#Remove DQI and DQO branches that are referenced to non-existing (filtered out) DQSI/DQI
for phase in range (numPhases):# ,cmda,dqso,dqo, in zip(range(numPhases),cmda_vars,dqso_vars,dqo_vars):
if (DQI_KEY in periods_phase) and (DQSI_KEY in periods_phase):
fl=[]
if periods_phase[DQI_KEY][phase] is not None:
for variant in periods_phase[DQI_KEY][phase]:
if (not periods_phase[DQSI_KEY][phase] is None) and (variant[0] in periods_phase[DQSI_KEY][phase]):
fl.append(variant)
if fl:
periods_phase[DQI_KEY][phase]=fl
else:
periods_phase[DQI_KEY][phase]=None
if (DQO_KEY in periods_phase) and (DQSO_KEY in periods_phase):
if periods_phase[DQO_KEY][phase] is not None:
fl=[]
for variant in periods_phase[DQO_KEY][phase]:
if (not periods_phase[DQSO_KEY][phase] is None) and (variant[0] in periods_phase[DQSO_KEY][phase]):
fl.append(variant)
if fl:
periods_phase[DQO_KEY][phase]=fl
else:
periods_phase[DQO_KEY][phase]=None
if quiet < 2:
print ("all_groups_valid_only=",all_groups_valid_only)
if all_groups_valid_only:
for phase in range (numPhases):
for k in periods_phase:
if periods_phase[k][phase] is None:
for k in periods_phase:
periods_phase[k][phase]=None
break
if quiet < 2:
print("===== Filtered periods: =====")
for phase in range (numPhases):
print ("phase=%d"%(phase),end=" ")
for k in periods_phase:
print ("'%s':%s"%(k,str(periods_phase[k][phase])),end=" ")
print()
if not filter_variants is None: if not filter_variants is None:
strict= not ('all' in filter_variants) strict= not ('all' in filter_variants)
if quiet < 3: if quiet < 3:
print ("filter_variants=",filter_variants) print ("filter_variants=",filter_variants)
for phase in range (numPhases):# ,cmda,dqso,dqo, in zip(range(numPhases),cmda_vars,dqso_vars,dqo_vars): for phase in range (numPhases):# ,cmda,dqso,dqo, in zip(range(numPhases),cmda_vars,dqso_vars,dqo_vars):
#build variants for each group that are used in at least one permitted combination of cmda, dqso, dqo, dqsi, dqi
# 'try' makes sure that all groups are not None (in that case just skip that phase value)
key_vars={} key_vars={}
for k in SIG_LIST: for k in SIG_LIST:
key_vars[k]=set() key_vars[k]=set()
...@@ -777,32 +854,39 @@ class X393McntrlAdjust(object): ...@@ -777,32 +854,39 @@ class X393McntrlAdjust(object):
for cmda in periods_phase[CMDA_KEY][phase]: for cmda in periods_phase[CMDA_KEY][phase]:
for dqo in periods_phase[DQO_KEY][phase]: for dqo in periods_phase[DQO_KEY][phase]:
for dqi in periods_phase[DQI_KEY][phase]: for dqi in periods_phase[DQI_KEY][phase]:
print("phase=%d, (cmda,dqo,dqi)=%s"%(phase,str((cmda,dqo,dqi)))) if quiet < 3:
print("phase=%d, (cmda,dqo,dqi)=%s"%(phase,str((cmda,dqo,dqi))))
if (((cmda,dqo,dqi) in filter_variants) and if (((cmda,dqo,dqi) in filter_variants) and
(dqo[0] in periods_phase[DQSO_KEY][phase]) and (dqo[0] in periods_phase[DQSO_KEY][phase]) and
(dqi[0] in periods_phase[DQSI_KEY][phase])): (dqi[0] in periods_phase[DQSI_KEY][phase])):
for i,k in enumerate(SIG_LIST): for i,k in enumerate(SIG_LIST):
key_vars[k].add((cmda,dqi[0],dqi,dqo[0],dqo)[i]) #careful with the order key_vars[k].add((cmda,dqi[0],dqi,dqo[0],dqo)[i]) #careful with the order
print("phase=%d, key_vars=%s"%(phase,str(key_vars))) # OK if quiet < 2:
print("phase=%d, key_vars=%s"%(phase,str(key_vars))) # OK
for k in SIG_LIST: for k in SIG_LIST:
for variant in periods_phase[k][phase]: for variant in periods_phase[k][phase]:
if not variant in key_vars[k]: if not variant in key_vars[k]:
print ("variant % s is not in %s for %s"%(variant,str(key_vars[k]), str(k))) if quiet < 3:
print ("phase=%d: variant %s is not in %s for %s, key_vars=%s . OK in when filtered by 'filter_variants'"%(phase,
variant,
str(key_vars[k]),
str(k),
str(key_vars)))
periods_phase[k][phase].pop(variant) # remove variants that do not fit in one of the combinations in filter_variants periods_phase[k][phase].pop(variant) # remove variants that do not fit in one of the combinations in filter_variants
print("periods_phase[%s][phase]=%s, strict=%s"%(str(k),str(periods_phase[k][phase]),str(strict))) if quiet <2:
if strict and (not periods_phase[k][phase]): print("periods_phase[%s][phase]=%s, strict=%s"%(str(k),str(periods_phase[k][phase]),str(strict)))
print("empty") assert (periods_phase[k][phase] or (not strict))
raise Exception('Just get to except')
except: except:
for k in SIG_LIST: for k in SIG_LIST:
print("except %s"%str(k)) if quiet <2:
print("except %s"%str(k))
periods_phase[k][phase]=None periods_phase[k][phase]=None
for phase in range (numPhases): if quiet <2:
print ("phase= %d"%(phase), end=" ") for phase in range (numPhases):
for k in SIG_LIST: print ("phase= %d"%(phase), end=" ")
print ("%s"%(periods_phase[k][phase]), end=" ") for k in SIG_LIST:
print() print ("%s"%(periods_phase[k][phase]), end=" ")
print()
for k in SIG_LIST: for k in SIG_LIST:
periods_all[k]=set() periods_all[k]=set()
for lp in periods_phase[k]: for lp in periods_phase[k]:
...@@ -858,7 +942,8 @@ class X393McntrlAdjust(object): ...@@ -858,7 +942,8 @@ class X393McntrlAdjust(object):
print ("%d"%(phase),end=" ") print ("%d"%(phase),end=" ")
for k in SIG_LIST: for k in SIG_LIST:
for period in periods_all[k]: for period in periods_all[k]:
if not periods_phase[k][phase] is None: if (not periods_phase[k][phase] is None) and (period in periods_phase[k][phase]):
# print("<<",k,"::",periods_phase[k][phase],":",period,">>>")
data_group=self.get_delays_for_phase(phase = phase, data_group=self.get_delays_for_phase(phase = phase,
list_branches=False, list_branches=False,
target=k, target=k,
...@@ -875,7 +960,7 @@ class X393McntrlAdjust(object): ...@@ -875,7 +960,7 @@ class X393McntrlAdjust(object):
for k in [CMDA_KEY,DQSI_KEY,DQSO_KEY]: for k in [CMDA_KEY,DQSI_KEY,DQSO_KEY]:
for period in periods_all[k]: for period in periods_all[k]:
if not periods_phase[k][phase] is None: if (not periods_phase[k][phase] is None) and (period in periods_phase[k][phase]):
err_ps=self.get_delays_for_phase(phase = phase, err_ps=self.get_delays_for_phase(phase = phase,
list_branches='Err', list_branches='Err',
target=k, target=k,
...@@ -3693,17 +3778,113 @@ class X393McntrlAdjust(object): ...@@ -3693,17 +3778,113 @@ class X393McntrlAdjust(object):
self.x393_pio_sequences.set_write_lev(16,False) # write leveling - 'good' mode (if it was not set so) self.x393_pio_sequences.set_write_lev(16,False) # write leveling - 'good' mode (if it was not set so)
return cmd_odelay return cmd_odelay
def _map_varinats(self, def _map_variants(self,
list_variants): list_variants,
var_template):
""" """
@param list_variants list of sets of variants - for each variant find the longest steak (rolls over the end of the list) @param list_variants list of sets of variants - for each variant find the longest steak (rolls over the end of the list)
Each item of a set should be a tuple of integers(cmda)/pairs of integers(dqi and dqo)
dqi/dqo tuple consists of reference dqsi/dqso branch (signed int) and a relative shift to it (negative - earlier,
positive - later)
@param var_template - a tuple of the same number of elements as each variant in a set, of boolean: True (cmda,dqso, dqo) - add 1 when crossing
from last to 0, False (dqi,dqsi) - subtract
@return dictionary with keys - variants, and values - tuples of starts and lengths of the longest streak @return dictionary with keys - variants, and values - tuples of starts and lengths of the longest streak
""" """
l=len(list_variants) map_all=self._map_variants_all(list_variants=list_variants,
streaks={} var_template=var_template)
prev_vars=list_variants[l-1] result={}
for k,v in map_all.items():
lengths=[sl[1] for sl in v]
result[k]= v[lengths.index(max(lengths))]
# print ("map_all=",map_all)
# print ("result=",result)
return result
def _map_variants_all(self,
list_variants,
var_template):
"""
@param list_variants list of sets of variants - for each variant find the longest steak (rolls over the end of the list)
Each item of a set should be a tuple of integers(cmda)/pairs of integers(dqi and dqo)
dqi/dqo tuple consists of reference dqsi/dqso branch (signed int) and a relative shift to it (negative - earlier,
positive - later)
@param var_template - a tuple of the same number of elements as each variant in a set, of boolean: True (cmda,dqso, dqo) - add 1 when crossing
from last to 0, False (dqi,dqsi) - subtract
@return dictionary with keys - variants, and values - list of tuples (usually just one element) of starts and lengths of the longest streak
"""
numPhases=len(list_variants)
falling_signs=tuple([(-1,1)[i] for i in var_template])
# for each variant (key) a list of (start,len,(this_start,this_end))
# start - start of this steak, possibly rolling through 0, len - length of this streak (rolling over
# this start - start of this streak not crossing 0, this_end - last+1 - not crossing len
streaks={}
prev_vars=set()
all_variants=set()
# First - process phase=0, all the rest will have starts
def check_extrapolated_var_to_phase(phase,variant):
extrapolated_variant=variant
periods = phase // numPhases
if periods != 0:
extrapolated_variant = []
for falling,item_var in zip(falling_signs,variant):
if isinstance(item_var,tuple):
extrapolated_variant.append((item_var[0]+falling*periods,item_var[1]))
else:
extrapolated_variant.append(item_var+falling*periods)
extrapolated_variant=tuple(extrapolated_variant)
try:
# print("check_extrapolated_var_to_phase(%d,%s ==> %s)"%(phase,str(variant),str(extrapolated_variant in list_variants[phase % numPhases])))
return extrapolated_variant in list_variants[phase % numPhases]
except:
# print("check_extrapolated_var_to_phase(%d,%s) - was None"%(phase,str(variant)))
return False # was None
# periods= phase // numPhases
# p_phase=phase % numPhases
for phase, variants in enumerate(list_variants):
if variants:
all_variants |= variants
new_vars = variants - prev_vars
for new_var in new_vars:
# First - process phase=0, all the rest will have starts
if phase==0:
s_phase = phase
while check_extrapolated_var_to_phase(s_phase-1,new_var):
s_phase -= 1
else:
s_phase=phase
# now s_phase >=0 for phase>0 or <= 0 for phase=0
# find the end of the streak
e_phase=phase+1
while check_extrapolated_var_to_phase(e_phase,new_var):
e_phase += 1
# print(".... phase=%d, s_phase=%d, e_phase=%d"%(phase, s_phase, e_phase))
if not new_var in streaks:
streaks[new_var]=[]
streaks[new_var].append((s_phase % numPhases, e_phase-s_phase))
"""
for streak_len in range(1,numPhases):
if (list_variants[(s_phase+streak_len) % numPhases] is None) or (not new_var in list_variants[(s_phase+streak_len) % numPhases]):
if (not new_var in streaks) or (streaks[new_var][1]<streak_len):
streaks[new_var]=(s_phase,streak_len)
break
"""
else:
variants=set()
prev_vars=variants
return streaks
"""
prev_vars=list_variants[numPhases-1]
all_variants=set() all_variants=set()
for s_phase, variants in enumerate(list_variants): for s_phase, variants in enumerate(list_variants):
if variants: if variants:
...@@ -3713,8 +3894,8 @@ class X393McntrlAdjust(object): ...@@ -3713,8 +3894,8 @@ class X393McntrlAdjust(object):
else: else:
new_vars = variants new_vars = variants
for new_var in new_vars: for new_var in new_vars:
for streak_len in range(1,l): for streak_len in range(1,numPhases):
if (list_variants[(s_phase+streak_len) % l] is None) or (not new_var in list_variants[(s_phase+streak_len) % l]): if (list_variants[(s_phase+streak_len) % numPhases] is None) or (not new_var in list_variants[(s_phase+streak_len) % numPhases]):
if (not new_var in streaks) or (streaks[new_var][1]<streak_len): if (not new_var in streaks) or (streaks[new_var][1]<streak_len):
streaks[new_var]=(s_phase,streak_len) streaks[new_var]=(s_phase,streak_len)
break break
...@@ -3723,9 +3904,9 @@ class X393McntrlAdjust(object): ...@@ -3723,9 +3904,9 @@ class X393McntrlAdjust(object):
# check if a variant is available everywher (should not be the case in this application) # check if a variant is available everywher (should not be the case in this application)
for v in all_variants: for v in all_variants:
if not v in streaks: if not v in streaks:
streaks[v]=(0,l) # all length, starting from 0 streaks[v]=(0,numPhases) # all length, starting from 0
return streaks return streaks
"""
def set_read_branch(self, def set_read_branch(self,
...@@ -3743,7 +3924,7 @@ class X393McntrlAdjust(object): ...@@ -3743,7 +3924,7 @@ class X393McntrlAdjust(object):
if the remaining number of errors is odd if the remaining number of errors is odd
""" """
#temporarily: #temporarily:
# self.load_mcntrl('dbg/proc_addr_odelay_0x55.pickle') # self.load_mcntrl('dbg/x393_mcntrl.pickle')
if wbuf_dly is None: if wbuf_dly is None:
wbuf_dly=vrlg.DFLT_WBUF_DELAY wbuf_dly=vrlg.DFLT_WBUF_DELAY
...@@ -3804,15 +3985,41 @@ class X393McntrlAdjust(object): ...@@ -3804,15 +3985,41 @@ class X393McntrlAdjust(object):
for phase, v in enumerate(read_phase_variants): for phase, v in enumerate(read_phase_variants):
print("%d: %s"%(phase,str(v))) print("%d: %s"%(phase,str(v)))
variants_map=self._map_varinats(read_phase_variants) variants_map=self._map_variants(list_variants=read_phase_variants,
var_template=(True,False))
centers={} centers={}
skipped_centers=set() # just for debugging
used_centers=set() # just for debugging
data_shifts={}
for k,v in variants_map.items(): for k,v in variants_map.items():
centers[k]=(v[0]+v[1]//2) % numPhases data_shifts[k]=k[1][1]-k[1][0]-k[0]
center_phase=(v[0]+v[1]//2) % numPhases
if k in read_phase_variants[center_phase]:
centers[k]=center_phase
used_centers.add(center_phase)
else:
skipped_centers.add(center_phase)
if quiet < 2:
print ("center phase = %d for variant %s is not in read_phase_variants[%d]=%s"%(center_phase,
str(k),
center_phase,
str(read_phase_variants[center_phase])))
print ("It should be listed for some other variant")
if quiet < 3: if quiet < 3:
print ("variants_map=",variants_map) print ("variants_map=",variants_map)
print ("centers=",centers) print ("centers=",centers)
print ("used_centers=",used_centers)
print ("skipped_centers=",skipped_centers)
print ('data_shifts=',data_shifts)
if skipped_centers - used_centers:
print ("Some skipped centers %s are not listed for other variants %s, variants_map=%s)"%(str(skipped_centers),
str(used_centers),
str(variants_map)))
raise Exception("BUG: Some skipped centers %s are not listed for other variants")
# print ("**** REMOVE THIS RETURN ****")
# return
# some different varinats are actually the same when they roll over phases TODO: merge them # some different varinats are actually the same when they roll over phases TODO: merge them
...@@ -3874,6 +4081,7 @@ class X393McntrlAdjust(object): ...@@ -3874,6 +4081,7 @@ class X393McntrlAdjust(object):
cost=None, cost=None,
refresh=True, refresh=True,
forgive_missing=False, forgive_missing=False,
# quiet=quiet+1)
quiet=quiet+1) quiet=quiet+1)
if used_delays is None: if used_delays is None:
raise Exception("set_read_branch(): failed to set phase = %d"%(phase)) raise Exception("set_read_branch(): failed to set phase = %d"%(phase))
...@@ -3885,12 +4093,13 @@ class X393McntrlAdjust(object): ...@@ -3885,12 +4093,13 @@ class X393McntrlAdjust(object):
read_problems=None read_problems=None
for _ in range(20): # limit numer of repetiotions - just in case for _ in range(20): # limit numer of repetiotions - just in case
self.x393_mcntrl_timing.axi_set_wbuf_delay(wdly) self.x393_mcntrl_timing.axi_set_wbuf_delay(wdly)
read_problems=self.x393_pio_sequences. set_and_read_inc(num8=8, # max 512 16-bit words read_results = self.x393_pio_sequences. set_and_read_inc(num8=8, # max 512 16-bit words
ca=ca+16, ca=ca+16,
ra=ra, ra=ra,
ba=ba, ba=ba,
sel=rsel, sel=rsel,
quiet=quiet+1) quiet=quiet+1)
read_problems=read_results[:2]
if (read_problems[0]>=4) or ((rsel==0) and (read_problems[0]>=2)): if (read_problems[0]>=4) or ((rsel==0) and (read_problems[0]>=2)):
if last_wstep < 0: if last_wstep < 0:
if quiet < 1: if quiet < 1:
...@@ -3931,12 +4140,32 @@ class X393McntrlAdjust(object): ...@@ -3931,12 +4140,32 @@ class X393McntrlAdjust(object):
if sum(read_problems_min) > 0: if sum(read_problems_min) > 0:
for dw,sel in ((-1,0),(-1,1),(0,0),(0,1),(1,0),(1,1)): for dw,sel in ((-1,0),(-1,1),(0,0),(0,1),(1,0),(1,1)):
self.x393_mcntrl_timing.axi_set_wbuf_delay(wdly+dw) self.x393_mcntrl_timing.axi_set_wbuf_delay(wdly+dw)
read_problems=self.x393_pio_sequences. set_and_read_inc(num8=8, # max 512 16-bit words read_results = self.x393_pio_sequences. set_and_read_inc(num8=8, # max 512 16-bit words
ca=ca+16, ca=ca+16,
ra=ra, ra=ra,
ba=ba, ba=ba,
sel=sel ^ rsel, sel=sel ^ rsel,
quiet=quiet+1) # quiet=quiet+1)
quiet=quiet+1)
read_problems=read_results[:2]
shft=(read_results[2] & 0x1ff)-16-read_results[3]
if quiet < 2:
print("=== Variant=%s, phase=%d sel=%d wbuf=%d : shift=%d, Read_problems=%s"%(str(variant),
phase,
sel ^ rsel,
wdly+dw,
str(read_problems)))
if quiet < 3:
measured_shift= 4*(wdly+dw) - shft - 2* (sel ^ rsel)
#variant=(-1, (0, 0)), calculated shift=1, measured shift=34, cal-meas=-32 shift=0 sel=1 wdly=9 sw=17
print ("variant=%s, calculated shift=%d (clocks), measured shift=%d(words), cal-meas=%d(words), problems=%s"%(
str(variant),
data_shifts[variant],
measured_shift,
2*data_shifts[variant]-measured_shift,
str(read_problems)))
if sum(read_problems) < sum(read_problems_min): if sum(read_problems) < sum(read_problems_min):
read_problems_min=read_problems read_problems_min=read_problems
best_dw,best_sel= dw,sel best_dw,best_sel= dw,sel
...@@ -3949,6 +4178,7 @@ class X393McntrlAdjust(object): ...@@ -3949,6 +4178,7 @@ class X393McntrlAdjust(object):
print("-wdly=",wdly) print("-wdly=",wdly)
print("-rsel=",rsel) print("-rsel=",rsel)
print("-sum(read_problems_min)=",sum(read_problems_min)) print("-sum(read_problems_min)=",sum(read_problems_min))
print(" shift = ", (read_results[2] & 0x1ff)-16-read_results[3])
if sum(read_problems_min) ==0: if sum(read_problems_min) ==0:
rslt[variant]={'wbuf_dly':wdly, 'sel':rsel} rslt[variant]={'wbuf_dly':wdly, 'sel':rsel}
...@@ -4002,7 +4232,7 @@ class X393McntrlAdjust(object): ...@@ -4002,7 +4232,7 @@ class X393McntrlAdjust(object):
if the remaining number of errors is odd if the remaining number of errors is odd
""" """
#temporarily: #temporarily:
#self.load_mcntrl('dbg/proc_addr_odelay_0x55.pickle') # self.load_mcntrl('dbg/x393_mcntrl.pickle')
#write/used block parameters #write/used block parameters
startValue=0 startValue=0
num8=8 # 8 bursts to read/write num8=8 # 8 bursts to read/write
...@@ -4041,7 +4271,8 @@ read_variants= {(-1, (0, 0)): {'sel': 1, 'wbuf_dly': 9}, ...@@ -4041,7 +4271,8 @@ read_variants= {(-1, (0, 0)): {'sel': 1, 'wbuf_dly': 9},
if not read_var_set: if not read_var_set:
raise Exception ("No valid read variant is found, can not proceed with write setup") raise Exception ("No valid read variant is found, can not proceed with write setup")
if quiet <2:
print ("read_var_set=",read_var_set)
cmda_vars= self.get_delays_for_phase(phase = None, cmda_vars= self.get_delays_for_phase(phase = None,
list_branches=True, list_branches=True,
target=CMDA_KEY, target=CMDA_KEY,
...@@ -4103,7 +4334,8 @@ read_variants= {(-1, (0, 0)): {'sel': 1, 'wbuf_dly': 9}, ...@@ -4103,7 +4334,8 @@ read_variants= {(-1, (0, 0)): {'sel': 1, 'wbuf_dly': 9},
print("%d: %s"%(phase,str(v))) print("%d: %s"%(phase,str(v)))
#variant - just for writing #variant - just for writing
write_only_map=self._map_varinats(write_phase_variants) write_only_map=self._map_variants(list_variants=write_phase_variants,
var_template=(True,True))
if quiet < 3: if quiet < 3:
print ("write_only_map=",write_only_map) print ("write_only_map=",write_only_map)
...@@ -4134,7 +4366,8 @@ read_variants= {(-1, (0, 0)): {'sel': 1, 'wbuf_dly': 9}, ...@@ -4134,7 +4366,8 @@ read_variants= {(-1, (0, 0)): {'sel': 1, 'wbuf_dly': 9},
print("%d: %s"%(phase,str(v))) print("%d: %s"%(phase,str(v)))
#read/write variants #read/write variants
read_write_map=self._map_varinats(read_write_variants) read_write_map=self._map_variants(list_variants=read_write_variants,
var_template=(True,True,False))
if quiet < 3: if quiet < 3:
print ("read_write_map=",read_write_map) print ("read_write_map=",read_write_map)
...@@ -4165,17 +4398,20 @@ read_variants= {(-1, (0, 0)): {'sel': 1, 'wbuf_dly': 9}, ...@@ -4165,17 +4398,20 @@ read_variants= {(-1, (0, 0)): {'sel': 1, 'wbuf_dly': 9},
'dqo': k_rw[1], 'dqo': k_rw[1],
'dqso': k_rw[1][0], 'dqso': k_rw[1][0],
'read_phase': phase, 'read_phase': phase,
'write_phase': phase} 'write_phase': phase,
'rel_sel':k_wo[0]+k_wo[1][1]-k_wo[1][0]}
break break
else: else:
raise Exception("failed") # just to get to "except" raise Exception("failed") # just assert
except: except:
phase=(write_only_map[k_wo][0]+read_write_map[k_wo][1]//2)% numPhases phase=(write_only_map[k_wo][0]+read_write_map[k_wo][1]//2)% numPhases
write_settings[k_wo]={'cmda_write': k_wo[0], write_settings[k_wo]={'cmda_write': k_wo[0],
'dqo': k_wo[1], 'dqo': k_wo[1],
'dqso': k_wo[1][0], 'dqso': k_wo[1][0],
'write_phase': phase} 'write_phase': phase,
'rel_sel':k_wo[0]+k_wo[1][1]-k_wo[1][0]}
write_settings[k_wo].update(default_read) write_settings[k_wo].update(default_read)
#rel_sel has a constant shift to wsel - this can be used to reduce number of measurements and/or verify consistency
if quiet < 3: if quiet < 3:
print ("write_settings=",write_settings) print ("write_settings=",write_settings)
""" """
...@@ -4218,6 +4454,8 @@ write_settings= { ...@@ -4218,6 +4454,8 @@ write_settings= {
'dqi': (0, 0)}} 'dqi': (0, 0)}}
""" """
# print ("**** REMOVE THIS RETURN ****")
# return
odd_list=[] odd_list=[]
for write_variant_key, variant in write_settings.items(): for write_variant_key, variant in write_settings.items():
...@@ -4267,12 +4505,13 @@ write_settings= { ...@@ -4267,12 +4505,13 @@ write_settings= {
raise Exception("set_write_branch(): failed to set phase = %d"%(phase)) raise Exception("set_write_branch(): failed to set phase = %d"%(phase))
#set wbuf delay #set wbuf delay
self.x393_mcntrl_timing.axi_set_wbuf_delay(readVars[(variant['cmda_read'],variant['dqi'])]['wbuf_dly']) self.x393_mcntrl_timing.axi_set_wbuf_delay(readVars[(variant['cmda_read'],variant['dqi'])]['wbuf_dly'])
problems=self.x393_pio_sequences. set_and_read_inc(num8=num8, # max 512 16-bit words read_results = self.x393_pio_sequences. set_and_read_inc(num8=num8, # max 512 16-bit words
ca=ca, ca=ca,
ra=ra, ra=ra,
ba=ba, ba=ba,
sel=readVars[(variant['cmda_read'],variant['dqi'])]['sel'], sel=readVars[(variant['cmda_read'],variant['dqi'])]['sel'],
quiet=quiet+1) quiet=quiet+1)
problems=read_results[:2]
if (problems_min is None) or (sum(problems) < sum(problems_min)): if (problems_min is None) or (sum(problems) < sum(problems_min)):
problems_min=problems problems_min=problems
best_wsel=wsel best_wsel=wsel
...@@ -4302,11 +4541,11 @@ write_settings= { ...@@ -4302,11 +4541,11 @@ write_settings= {
def get_phase_range(self, def get_phase_range(self,
rsel=None, # None (any) or 0/1 rsel=None, # None (any) or 0/1
wsel=None, # None (any) or 0/1 wsel=None, # None (any) or 0/1
cmda_filter=None, filter_cmda=None,
dqsi_filter=None, filter_dqsi=None,
dqi_filter= None, filter_dqi= None,
dqso_filter=None, filter_dqso=None,
dqo_filter= None, filter_dqo= None,
set_globals=True, set_globals=True,
quiet=1): quiet=1):
""" """
...@@ -4319,17 +4558,15 @@ write_settings= { ...@@ -4319,17 +4558,15 @@ write_settings= {
""" """
#temporarily: #temporarily:
# self.load_mcntrl('dbg/proc_addr_odelay_0x55.pickle') # self.load_mcntrl('dbg/proc_addr_odelay_0x55.pickle')
if cmda_filter is None: # self.load_mcntrl('dbg/x393_mcntrl.pickle')
cmda_filter = DFLT_DLY_FILT filters=dict(zip(SIG_LIST,[filter_cmda,filter_dqsi,filter_dqi,filter_dqso,filter_dqo]))
if dqsi_filter is None: for k,v in filters.items():
dqsi_filter = DFLT_DLY_FILT if v is None:
if dqi_filter is None: filters[k]=DFLT_DLY_FILT
dqi_filter = DFLT_DLY_FILT elif not isinstance (filters[k],(tuple,list)):
if dqso_filter is None: filters[k]=[filters[k]]
dqso_filter = DFLT_DLY_FILT elif isinstance (filters[k],tuple):
if dqo_filter is None: filters[k]=list(filters[k]) # tuple not OK as it will be merged
dqo_filter = DFLT_DLY_FILT
try: try:
read_variants=self.adjustment_state['read_variants'] read_variants=self.adjustment_state['read_variants']
...@@ -4339,6 +4576,7 @@ write_settings= { ...@@ -4339,6 +4576,7 @@ write_settings= {
write_variants=self.adjustment_state['write_variants'] write_variants=self.adjustment_state['write_variants']
except: except:
write_variants=None write_variants=None
try: try:
dqs_pattern=self.adjustment_state["dqs_pattern"] dqs_pattern=self.adjustment_state["dqs_pattern"]
except: except:
...@@ -4370,31 +4608,31 @@ write_settings= { ...@@ -4370,31 +4608,31 @@ write_settings= {
cmda_vars= self.get_delays_for_phase(phase = None, cmda_vars= self.get_delays_for_phase(phase = None,
list_branches=True, list_branches=True,
target=CMDA_KEY, target=CMDA_KEY,
b_filter=cmda_filter, b_filter=filters[CMDA_KEY],
cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it
quiet = quiet+2) quiet = quiet+2)
dqsi_vars= self.get_delays_for_phase(phase = None, dqsi_vars= self.get_delays_for_phase(phase = None,
list_branches=True, list_branches=True,
target=DQSI_KEY, target=DQSI_KEY,
b_filter=dqsi_filter, b_filter=filters[DQSI_KEY],
cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it
quiet = quiet+2) quiet = quiet+2)
dqi_vars= self.get_delays_for_phase(phase = None, dqi_vars= self.get_delays_for_phase(phase = None,
list_branches=True, list_branches=True,
target=DQI_KEY, target=DQI_KEY,
b_filter=dqi_filter, b_filter=filters[DQI_KEY],
cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it
quiet = quiet+2) quiet = quiet+2)
dqso_vars= self.get_delays_for_phase(phase = None, dqso_vars= self.get_delays_for_phase(phase = None,
list_branches=True, list_branches=True,
target=DQSO_KEY, target=DQSO_KEY,
b_filter=dqso_filter, b_filter=filters[DQSO_KEY],
cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it
quiet = quiet+2) quiet = quiet+2)
dqo_vars= self.get_delays_for_phase(phase = None, dqo_vars= self.get_delays_for_phase(phase = None,
list_branches=True, list_branches=True,
target=DQO_KEY, target=DQO_KEY,
b_filter=dqo_filter, b_filter=filters[DQO_KEY],
cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it cost=None, # if None - will default to NUM_FINE_STEPS, if 0 - will keep it
quiet = quiet+2) quiet = quiet+2)
numPhases=len(cmda_vars) numPhases=len(cmda_vars)
...@@ -4427,9 +4665,16 @@ write_settings= { ...@@ -4427,9 +4665,16 @@ write_settings= {
if quiet < 3: if quiet < 3:
print ("all_variants=",all_variants) print ("all_variants=",all_variants)
varints_map=self._map_varinats(all_variants) varints_map=self._map_variants(list_variants=all_variants,
var_template=(True,True,False))
if quiet < 3: if quiet < 3:
print ("varints_map=",varints_map) print ("varints_map=",varints_map)
# print ("**** REMOVE THIS RETURN ****")
# return
rslt=[] rslt=[]
for k,v in varints_map.items(): for k,v in varints_map.items():
rslt.append({ rslt.append({
...@@ -4461,7 +4706,7 @@ write_settings= { ...@@ -4461,7 +4706,7 @@ write_settings= {
print ("toSort=",toSort) print ("toSort=",toSort)
rslt=[i[1] for i in toSort] rslt=[i[1] for i in toSort]
if quiet < 3: if quiet < 4:
print ("sorted result=",rslt) print ("sorted result=",rslt)
optimal=rslt[0] optimal=rslt[0]
if set_globals: if set_globals:
...@@ -4477,19 +4722,19 @@ write_settings= { ...@@ -4477,19 +4722,19 @@ write_settings= {
cost = None, cost = None,
refresh = True, refresh = True,
forgive_missing = False, forgive_missing = False,
quiet = quiet) quiet = quiet+1)
if used_delays is None: if used_delays is None:
print ("sorted result=",rslt) print ("sorted result=",rslt)
raise Exception("get_phase_range(): failed to set phase = %d"%(optimal['phase'])) # raise Exception("get_phase_range(): failed to set phase = %d"%(optimal['phase'])) #
if quiet <5: if quiet <4:
self.show_all_delays(filter_variants = varints_map.keys(), self.show_all_delays(filter_variants = varints_map.keys(),
filter_cmda = 'A',#None, filter_cmda = filters[CMDA_KEY],
filter_dqsi = 'A',#None, filter_dqsi = filters[DQSI_KEY],
filter_dqi = 'A',#None, filter_dqi = filters[DQI_KEY],
filter_dqso = 'A',#None, filter_dqso = filters[DQSO_KEY],
filter_dqo = 'A',#None, filter_dqo = filters[DQO_KEY],
quiet = quiet+2) quiet = quiet+1)
return rslt # first in the list is the best return rslt # first in the list is the best
...@@ -5519,469 +5764,7 @@ write_settings= { ...@@ -5519,469 +5764,7 @@ write_settings= {
print ("parameters=",parameters) print ("parameters=",parameters)
self.adjustment_state['addr_odelay']= rslt self.adjustment_state['addr_odelay']= rslt
return rslt return rslt
'''
def get_delays_vs_phase(self,
filter_dqo=2,
filter_dqi=2,
filter_dqso=2,
filter_dqsi=2,
filter_cmda=2,
filter_read=0,
filter_write=0,
filter_rsel=None,
filter_wsel=None,
keep_all=False,
set_table=True,
quiet=2):
"""
Create list of valid "phases", after applying several filters. Each filter parameter can be
one of 3 values: 0 - do not apply filter, 1 - OK if each of multiple bits fit for at least one
early/nominal/late branch and 2 - all of the bits should fit the same branch
@param filter_dqo for DQ output delays
@param filter_dqi for DQ input delays
@param filter_dqso for DQS output delays
@param filter_dqsi for DQS input delays
@param filter_cmda for command and address output delays
if non-integer - special mode - try to keep cmda low, with setup violation to test marginal phase
@param filter_read remove phases that do not provide correct reads (data shifted by some periods/half periods)
@param filter_write remove phases that do not provide correct writes (data shifted by some periods/half periods)
@param filter_rsel filter by early/late read command (in two-clock command cycle - 'sel') Valid values: None, 0 or 1
@param filter_wsel filter by early/late write command (in two-clock command cycle - 'sel') Valid values: None, 0 or 1
@param keep_all Keep phases where some delays do not have valid values, just mark them as None
remove just items that do not have any non-None elements
@param set_table store results to the global table (used to simultaneously set all pahse-derived
delays in hardware
@param quiet reduce output
@return per-phase value list, each being none or a dictionary with optional fields "in" and "out"
having values early/nominal/late
"""
# self.load_hardcoded_data() # TODO: REMOVE LATER
num_addr=vrlg.ADDRESS_NUMBER
num_banks=3
# num_cmd=3 # (we,ras,cas,cke,odt)
rslt_names=("early","nominal","late")
timing=self.x393_mcntrl_timing.get_dly_steps()
numPhaseSteps= int(timing['SDCLK_PERIOD']/timing['PHASE_STEP']+0.5)
step180= int(NUM_FINE_STEPS*0.5* timing['SDCLK_PERIOD'] / timing['DLY_STEP'] +0.5)
halfDlyRange=min(NUM_DLY_STEPS//2, step180) # minimum of half adjustment range of the delay and half SDCLK period
# clk_period=1000.0*timing['SDCLK_PERIOD'] # in PS
if quiet <1:
print ("halfDlyRange=",halfDlyRange)
try:
read_variants=self.adjustment_state['read_variants']
except:
read_variants=None
try:
write_variants=self.adjustment_state['write_variants']
except:
write_variants=None
if filter_read or (not filter_rsel is None):
if not read_variants is None:
filter_read=1 # if filter_rsel is not None
if filter_dqsi==0:
filter_dqsi=2
if filter_dqi==0:
filter_dqi=2
else:
print ('Data for filter_read is not available (self.adjustment_state["read_variants"]')
filter_read=0
filter_rsel=None
if filter_write or (not filter_wsel is None):
if not write_variants is None:
filter_write=1 # if filter_wsel is not None
if filter_dqso==0:
filter_dqso=2
if filter_dqo==0:
filter_dqo=2
else:
print ('Data for filter_write is not available (self.adjustment_state["write_variants"]')
filter_write=0
filter_wsel=None
delays_phase=[]
if filter_dqo:
try:
DQOvDQSO=self.adjustment_state["dqo_dqso"]
except:
print ('Data for filter_dqo is not available (self.adjustment_state["dqo_dqso"]')
filter_dqo=0
try:
wlev_dqs_bspe=self.adjustment_state['wlev_dqs_bspe']
except:
print ('Data for filter_dqo requires data for filter_dqso and it is not available (self.adjustment_state["wlev_dqs_bspe"]')
filter_dqo=0
if filter_dqi:
try:
DQIvDQSI=self.adjustment_state["dqi_dqsi"]
except:
print ('Data for filter_dqi is not available (self.adjustment_state["dqi_dqsi"]')
filter_dqi=0
try:
dqsi_phase=self.adjustment_state['dqsi_phase']
except:
print ('Data for filter_dqi requires data for filter_dqsi and it is not available (self.adjustment_state["dqsi_phase"]')
filter_dqi=0
if filter_dqso:
try:
wlev_dqs_bspe=self.adjustment_state['wlev_dqs_bspe']
except:
print ('Data for filter_dqso is not available (self.adjustment_state["wlev_dqs_bspe"]')
filter_dqso=0
if filter_dqsi:
try:
dqsi_phase=self.adjustment_state['dqsi_phase']
except:
print ('Data for filter_dqsi is not available (self.adjustment_state["dqsi_phase"]')
filter_dqsi=0
if filter_cmda:
try:
addr_odelay= self.adjustment_state['addr_odelay']
except:
addr_odelay=None
#keep cmda_bspe even if addr_odelay is available?
try:
cmda_bspe=self.adjustment_state['cmda_bspe']
except:
if addr_odelay is None:
print ('Data for filter_cmda is not available (self.adjustment_state["cmda_bspe"]')
filter_cmda=0
if isinstance(filter_cmda,float):
if filter_cmda >=0.5:
print ("Invalid 'safe range' for filter_cmda. It is measured in clock cycles and should be < 0.5.Using strict cmda filter")
filter_cmda=2
num_cmda=0
for phase in range(numPhaseSteps):
delays_phase.append({})
if filter_cmda:
# for special case (float filter_cmda) use initial 'cmda_bspe', not 'addr_odelay'
if (not addr_odelay is None) and (not isinstance(filter_cmda,float)): #TODO: add zerr to addr_odelay (error as a fraction of clock period if delay is set to 0)
#special case to test address setup time - will never execute now
if isinstance(filter_cmda,float) and (not addr_odelay['err'][phase] is None) and (addr_odelay['err'][phase] < 0.5-filter_cmda):
delays_phase[phase][CMDA_KEY]=0
else:
if (addr_odelay['dlys'][phase] is None) and (not keep_all):
delays_phase[phase]=None
continue # next phase
else:
if not addr_odelay['dlys'][phase] is None:
delays_phase[phase][CMDA_KEY]=addr_odelay['dlys'][phase] # list, not single value!
num_cmda=len(addr_odelay['dlys'][phase])
else:
#special case to test address setup time
if isinstance(filter_cmda,float) and (not cmda_bspe[phase]['zerr'] is None) and (cmda_bspe[phase]['zerr']< 0.5-filter_cmda):
delays_phase[phase][CMDA_KEY]=0 # set to minimal delay (==0)
else:
if (cmda_bspe[phase]['ldly'] is None) and (not keep_all):
delays_phase[phase]=None
continue # next phase
else:
if not cmda_bspe[phase]['ldly'] is None:
delays_phase[phase][CMDA_KEY]=cmda_bspe[phase]['ldly']
#all(v is None for v in l)
if filter_dqsi:
dqsi=[dqsi_lane[phase] for dqsi_lane in dqsi_phase]
if None in dqsi:
if keep_all:
if not all(v is None for v in dqsi):
delays_phase[phase][DQSI_KEY]=dqsi
else:
delays_phase[phase]=None
continue # next phase
elif (filter_dqsi == 2) and ((max(dqsi) - min(dqsi)) > halfDlyRange):
delays_phase[phase]=None
continue # next phase
else:
delays_phase[phase][DQSI_KEY]=dqsi
if filter_dqso:
dqso=[None if wlev_lane[phase] is None else wlev_lane[phase]['ldly'] for wlev_lane in wlev_dqs_bspe]
if None in dqso:
if keep_all:
if not all(v is None for v in dqso):
delays_phase[phase][DQSO_KEY]=dqso
else:
delays_phase[phase]=None
continue # next phase
elif (filter_dqsi == 2) and ((max(dqso) - min(dqso)) > halfDlyRange):
delays_phase[phase]=None
continue # next phase
else:
delays_phase[phase][DQSO_KEY]=dqso
if filter_dqi:
dqsi=[dqsi_lane[phase] for dqsi_lane in dqsi_phase]
if (None in dqsi) and (not keep_all):
delays_phase[phase]=None # phase for at least one of the DQSI is invalid
continue # next phase
else:
dqi_options={}
for k in rslt_names:
if (k in DQIvDQSI) and (not DQIvDQSI[k] is None):
#sum (...,[]) makes it a concatenation of lists, not arithmetic sum
dqi= sum([[None]*8 if (dqs is None) or (DQIvDQSI[k][dqs] is None) else DQIvDQSI[k][dqs][8*lane:8*(lane+1)] for lane,dqs in enumerate(dqsi)], [])
if keep_all:
if not all(v is None for v in dqi):
dqi_options[k]=dqi
else:
if None in dqi:
continue # not this branch
elif filter_read and not k in read_variants:
continue # not this branch
elif (not filter_rsel is None) and (k in read_variants) and (read_variants[k]['sel'] != filter_rsel):
continue # not this branch
elif (filter_dqi == 2) and ((max(dqi) - min(dqi)) > halfDlyRange):
continue # failed filter, continue to the next branch
dqi_options[k]=dqi
if dqi_options:
delays_phase[phase][DQI_KEY]=dqi_options
elif not keep_all:
delays_phase[phase]=None
continue # next phase
if filter_dqo:
dqso=[None if wlev_lane[phase] is None else wlev_lane[phase]['ldly'] for wlev_lane in wlev_dqs_bspe]
if (None in dqso) and (not keep_all):
delays_phase[phase]=None # phase for at least one of the DQSI is invalid
continue # next phase
else:
dqo_options={}
for k in rslt_names:
if (k in DQOvDQSO) and (not DQOvDQSO[k] is None):
dqo= sum([[None]*8 if (dqs is None) or (DQOvDQSO[k][dqs] is None) else DQOvDQSO[k][dqs][8*lane:8*(lane+1)] for lane,dqs in enumerate(dqso)], [])
if keep_all:
if not all(v is None for v in dqo):
dqo_options[k]=dqo
else:
if None in dqo:
continue # not this branch
elif filter_write and not k in write_variants:
continue # not this branch
elif (not filter_wsel is None) and (k in write_variants) and (write_variants[k]['sel'] != filter_wsel):
continue # not this branch
elif (filter_dqi == 2) and ((max(dqo) - min(dqo)) > halfDlyRange):
continue # failed filter, continue to the next branch
dqo_options[k]=dqo
if dqo_options:
delays_phase[phase][DQO_KEY]=dqo_options
elif not keep_all:
delays_phase[phase]=None
continue # next phase
if quiet <1:
print("delays_phase=",delays_phase)
if quiet < 2:
print ("delays_phase=[")
prev_none=False
for phase_data in delays_phase:
if phase_data is None:
if not prev_none:
print("\n ",end="")
print ("None,",end=" ")
prev_none=True
else:
if prev_none:
print()
print(" {")
for k,v in phase_data.items():
if isinstance(v,str):
v="'"+v+"'"
print (" '%s':%s"%(k, str(v)))
print (" },")
prev_none=False
print("]")
if quiet < 3:
enl_list_in=[]
enl_list_out=[]
numBits=None
for k in rslt_names:
for phase_data in delays_phase:
try:
if k in phase_data["dqi"]:
enl_list_in.append(k)
break
except:
pass
for phase_data in delays_phase:
try:
if k in phase_data["dqo"]:
enl_list_out.append(k)
break
except:
pass
for phase_data in delays_phase:
try:
numBits=len(phase_data["dqi"].values()[0])
break
except:
pass
try:
numBits=len(phase_data["dqo"].values()[0])
break
except:
pass
if numBits is None:
print ("No phase has all delays valid")
return delays_phase
numLanes=numBits//8
try:
maxErrDqsi=self.adjustment_state["maxErrDqsi"]
except:
maxErrDqsi=None
try:
maxErrDqso=self.adjustment_state["maxErrDqso"]
except:
maxErrDqso=None
#print header
print("Phase",end=" ")
if num_cmda == 0:
print("CMDA",end=" ")
else:
for i in range(num_addr):
print("A%d"%(i),end=" ")
for i in range(num_banks):
print("BA%d"%(i),end=" ")
print ("WE RAS CAS AVG", end=" ") # AVG - average for address, banks, RCW
# print("RCW",end=" ") # TODO - modify when separate command line data will be available
# num_addr=vrlg.ADDRESS_NUMBER
# num_banks=3
for lane in range(numLanes):
print("DQS%di"%(lane),end=" ")
for k in enl_list_in:
for b in range(numBits):
print("%s-DQ%di"%(k.upper()[0], b),end=" ")
for lane in range(numLanes):
print("DQS%d0"%(lane),end=" ")
for k in enl_list_out:
for b in range(numBits):
print("%s-DQ%do"%(k.upper()[0], b),end=" ")
if not read_variants is None:
for k in enl_list_in:
print("%s-rsel"%(k.upper()[0]),end=" ")
if not write_variants is None:
for k in enl_list_out:
print("%s-wsel"%(k.upper()[0]),end=" ")
for k in enl_list_in:
print("%s-in-err"%(k.upper()[0]),end=" ")
for k in enl_list_out:
print("%s-out-err"%(k.upper()[0]),end=" ")
print()
#print table rows
for phase, phase_data in enumerate(delays_phase):
print ("%d"%(phase),end=" ")
if not phase_data is None:
if num_cmda ==0:
try:
print ("%d"%(phase_data[CMDA_KEY]),end=" ")
except:
print ("?",end=" ")
else:
for line in range (num_cmda):
try:
print ("%d"%(phase_data[CMDA_KEY][line]),end=" ")
except:
print ("?",end=" ")
for lane in range(numLanes):
try:
print ("%d"%(phase_data[DQSI_KEY][lane]),end=" ")
except:
print ("?",end=" ")
for k in enl_list_in:
for b in range(numBits):
try:
print ("%d"%(phase_data[DQI_KEY][k][b]),end=" ")
except:
print ("?",end=" ")
for lane in range(numLanes):
try:
print ("%d"%(phase_data[DQSO_KEY][lane]),end=" ")
except:
print ("?",end=" ")
for k in enl_list_out:
for b in range(numBits):
try:
print ("%d"%(phase_data[DQO_KEY][k][b]),end=" ")
except:
print ("?",end=" ")
if not read_variants is None:
for k in enl_list_in:
try:
if not None in phase_data[DQI_KEY][k]:
print ("%d"%(10*read_variants[k]['sel']),end=" ")# 10* - for graph visibility
else:
print ("?",end=" ")
except:
print ("?",end=" ")
if not write_variants is None:
for k in enl_list_out:
try:
# print ('k=',k,end=" ")
# print ("phase_data[DQO_KEY]=",phase_data[DQO_KEY])
if not None in phase_data[DQO_KEY][k]:
print ("%d"%(12*write_variants[k]['sel']),end=" ")# 12* - for graph visibility
else:
print ("?",end=" ")
except:
print ("?",end=" ")
for k in enl_list_in:
try:
if not None in phase_data[DQSI_KEY]:
max_err=max(maxErrDqsi[k][dly][lane] for lane,dly in enumerate(phase_data[DQSI_KEY]))
print("%.1f"%(max_err),end=" ")
else:
print ("X",end=" ")
except:
print ("?",end=" ")
for k in enl_list_out:
try:
if not None in phase_data[DQSO_KEY]:
max_err=max(maxErrDqso[k][dly][lane] for lane,dly in enumerate(phase_data[DQSO_KEY]))
print("%.1f"%(max_err),end=" ")
else:
print ("x",end=" ")
except:
print ("?",end=" ")
print()
if set_table:
self.adjustment_state['delays_phase'] = delays_phase
return delays_phase
'''
'''
def show_all_vs_phase(self,
keep_all=False,
load_hardcoded=False,
filter_rw=False,
filter_rsel=None,
filter_wsel=None):
"""
Show table (to be copied to a spreadsheet) with all delay settings for each
DDR3 memory clock phase value
@param keep_all - show incomplete data (some of the delays may not have valid values
for selected clock phase, false - show only data for valid phases
@param load_hardcoded - get hard-coded data (false - use current)
"""
if load_hardcoded:
self.load_hardcoded_data()
return self.get_delays_vs_phase(
filter_dqo=2,
filter_dqi=2,
filter_dqso=2,
filter_dqsi=2,
filter_cmda=2,
filter_read=(0,1)[filter_rw], #
filter_write=(0,1)[filter_rw],
filter_rsel=filter_rsel,
filter_wsel=filter_wsel,
keep_all=keep_all,
set_table=False,
quiet=2)
'''
def save_mcntrl(self, def save_mcntrl(self,
path=None, path=None,
......
...@@ -1117,9 +1117,10 @@ class X393PIOSequences(object): ...@@ -1117,9 +1117,10 @@ class X393PIOSequences(object):
break break
else: else:
last_bad= 0 last_bad= 0
rslt=(first_bad, last_bad, data16[mid_index],mid_index)
if quiet < 3: if quiet < 3:
print ("non_consecutive leading/trailing: %d /%d"%(first_bad, last_bad)) print ("non_consecutive leading/trailing: %d /%d, middle data=0x%x, index=0x%x"%rslt)
return (first_bad, last_bad) return rslt
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment