Commit b7eab69e authored by Andrey Filippov's avatar Andrey Filippov

debugging, adding more parameters to fit

parent 50aca841
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -42,7 +42,7 @@ import re
from argparse import ArgumentParser
#import argparse
from argparse import RawDescriptionHelpFormatter
import time
from import_verilog_parameters import ImportVerilogParameters
#from import_verilog_parameters import VerilogParameters
from verilog_utils import hx
......@@ -158,6 +158,7 @@ def getFuncArgsString(name):
#dflts
def main(argv=None): # IGNORE:C0111
tim=time.time()
'''Command line options.'''
global QUIET
if argv is None:
......@@ -361,7 +362,8 @@ USAGE
if (args.interactive):
line =""
while True:
line=raw_input('x393%s--> '%('','(simulated)')[args.simulated]).strip()
line=raw_input('x393%s +%3.3fs--> '%(('','(simulated)')[args.simulated],(time.time()-tim))).strip()
tim=time.time()
#remove comment from the input line
if line.find("#") > 0:
line=line[:line.find("#")]
......
......@@ -44,14 +44,35 @@ tFDQi - array of 5 fine delay steps (here in ps) for each bit - 5*8=40
error**2 here (y-tFDQi-fXi)**2
"""
PARAMETER_TYPES=(
{"name":"tSDQS", "size":1, "units":"ps","description":"DQS input delay per step (1/5 of the datasheet value)","en":1},
{"name":"tSDQ", "size":8, "units":"ps","description":"DQ input delay per step (1/5 of the datasheet value)","en":1},
{"name":"tDQSHL", "size":1, "units":"ps","description":"DQS HIGH minus LOW difference","en":1},
{"name":"tDQHL", "size":8, "units":"ps","description":"DQi HIGH minus LOW difference","en":1},
{"name":"tDQS", "size":1, "units":"ps","description":"DQS delay (not adjusted)","en":0},
{"name":"tDQ", "size":8, "units":"ps","description":"DQi delay","en":1},
{"name":"tFDQS", "size":4, "units":"ps","description":"DQS fine delays (mod 5)","en":1}, #only 4 are independent, 5-th is -sum of 4
{"name":"tFDQ", "size":32, "units":"ps","description":"DQ fine delays (mod 5)","en":1},
{"name":"anaScale","size":1, "dflt":20, "units":"ps","description":"Scale for non-binary measured results","en":1},
{"name":"tCDQS", "size":30, "units":"ps","description":"DQS primary dealays (all but 8 and 24","en":1}, #only 4 are independent, 5-th is -sum of 4
)
FINE_STEPS=5
DLY_STEPS =FINE_STEPS * 32 # =160
def test_data(meas_delays,
compare_prim_steps,
quiet=1):
halfStep=0.5
if compare_prim_steps:
halfStep*=FINE_STEPS
if quiet < 2:
print ("DQS",end=" ")
for f in ('ir','if','or','of'):
for b in range (16):
print ("%s_%d"%(f,b),end=" ")
print()
print()
for ldly, data in enumerate(meas_delays):
print("%d"%ldly,end=" ")
if data:
......@@ -66,24 +87,14 @@ def test_data(meas_delays,
for typ in range(4):
for pData in data: # 16 DQs, each None nor a pair of lists for inPhase in (0,1), each a pair of edges, each a pair of (dly,diff)
if pData and (not pData[typ] is None):
print ("%d"%pData[typ],end=" ")
if pData[typ][1] is None:
print ("%d"%(pData[typ]+halfStep),end=" ")
else:
print ("%d"%(pData[typ]),end=" ")
else:
print ("x",end=" ")
print()
PARAMETER_TYPES=(
{"name":"tSDQS", "size":1, "units":"ps","description":"DQS input delay per step (1/5 of the datasheet value)","en":1},
{"name":"tSDQ", "size":8, "units":"ps","description":"DQ input delay per step (1/5 of the datasheet value)","en":1},
{"name":"tDQSHL", "size":1, "units":"ps","description":"DQS HIGH minus LOW difference","en":1},
{"name":"tDQHL", "size":8, "units":"ps","description":"DQi HIGH minus LOW difference","en":1},
{"name":"tDQS", "size":1, "units":"ps","description":"DQS delay (not adjusted)","en":0},
{"name":"tDQ", "size":8, "units":"ps","description":"DQi delay","en":1},
{"name":"tFDQS", "size":4, "units":"ps","description":"DQS fine delays (mod 5)","en":1}, #only 4 are independent, 5-th is -sum of 4
{"name":"tFDQ", "size":32, "units":"ps","description":"DQ fine delays (mod 5)","en":1},
{"name":"anaScale","size":1, "dflt":20, "units":"ps","description":"Scale for non-binary measured results","en":0},
)
FINE_STEPS=5
DLY_STEPS =FINE_STEPS * 32 # =160
def make_repeat(value,nRep):
if isinstance(value,(list,tuple)):
return value
......@@ -93,18 +104,19 @@ def make_repeat(value,nRep):
class X393LMA(object):
lambdas={"initial":0.1,"current":0.1,"max":100.0}
maxNumSteps=25
finalDiffRMS=0.0001
finalDiffRMS=0.001
parameters=None
# parameterMask={}
parameterMask={'tSDQS': True,
'tSDQ': [True, True, True, True, True, True, True, True],
'tDQSHL': True,
'tDQHL': [True, True, True, True, True, True, True, True],
'tDQHL': [True, True, True, True, True, True, True, True],# 23.523465ps -> 23.315524 - too little difference?
'tDQS': False,
'tDQ': [True, True, True, True, True, True, True, True],
'tFDQS': [True, True, True, True],
'tFDQ': [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True],
'anaScale': False
'anaScale': False,# True, # False # Broke?
'tCDQS': True #False #True # list of 30
}
"""
parameterMask={'tSDQS': True,
......@@ -130,16 +142,35 @@ class X393LMA(object):
def createYandWvectors(self,
lane,
data_set,
compare_prim_steps,
scale_w=0.2, # multiply weight by this if fractions are undefined
periods=None):
print ("createYandWvectors(): scale_w=%f"%(scale_w))
def pythIsNone(obj):
return obj is None
isNone=pythIsNone
if isinstance(data_set,np.ndarray):
isNone=np.isnan
n=len(data_set)*32
# fx=np.zeros((DLY_STEPS*32,))
"""
use np.nan instead of the None data
np.isnan() test
, dtype=np.float
"""
@compare_prim_steps while scanning, compare this delay with 1 less by primary(not fine) step,
save None for fraction in unknown (previous -0.5, next +0.5)
"""
halfStep=0.5
if compare_prim_steps:
halfStep*=FINE_STEPS
# extra_Y=(0.0,halfStep)
y=np.zeros((n,), dtype=np.int) #[0]*n
w=np.zeros((n,)) #[0]*n
f=np.full((n,),np.nan) # fractions
yf=np.zeros((n,)) # y with added fractions
if not periods is None:
p=np.zeros((n), dtype=np.int)#[0]*n
for dly,data in enumerate(data_set):
......@@ -152,40 +183,102 @@ class X393LMA(object):
for t,tData in enumerate(bData):
if not tData is None: #[dly],[b],[t] tData - int value
i=32*dly+8*t+b
y[i]=tData
w[i]=1
y[i]=tData[0]
if not isNone(tData[1]):
f[i] = tData[1]
yf[i]=tData[0]
w[i]=1
else:
w[i]=scale_w
yf[i]=tData[0]+halfStep
if not periods is None:
p[i]=periods[dly][b][t]
vectors={'y':y,'w':w}
vectors={'y':y,'yf':yf,'w':w,'f':f} # yf - use for actual float value, y - integer
if not periods is None:
vectors['p']=p
return vectors
def showYOrVector(self,
ywp,
vector=None):
pass
filtered=False,
vector=None,
showMode="IA"):
def pythIsNone(obj):
return obj is None
isNone=pythIsNone
# If vector is None - print y vector (skipping zero mask),
# otherwise print vector (should be the same length, using the same 'w' weight mask
v=vector
if v is None:
v= ywp['y']
v= ywp['yf']
w=ywp['w']
try:
f=ywp['f']
noF=False
except:
f=None
noF=True
if not noF:
if isinstance(f,np.ndarray):
isNone=np.isnan
# print ("using np.isnan")
# print("filtered=",filtered)
n=len(v)/32
if 'A' in showMode.upper():
av=[]
for dly in range(n):
avd=[]
SAX=0.0
SA0=0.0
for t in range(4):
SX=0.0
S0=0.0
for b in range(8):
i=32*dly+8*t+b
if w[i] and ((not filtered) or noF or (not isNone(f[i]))):
SX+=w[i]*v[i]
S0+=w[i]
SAX+=SX
SA0+=S0
if S0>0:
SX/=S0
else:
SX=None
avd.append(SX)
if SA0>0:
SAX/=SA0
else:
SAX=None
avd.append(SAX)
av.append(avd)
print("DQS_dly", end= " ")
for f in ('ir','if','or','of'):
for b in range (8):
print ("%s_%d"%(f,b),end=" ")
if "I" in showMode.upper():
for ft in ('ir','if','or','of'):
for b in range (8):
print ("%s_%d"%(ft,b),end=" ")
if "A" in showMode.upper():
for ft in ('ir','if','or','of','all'):
print ("%s"%(ft),end=" ")
print()
n=len(v)/32
for dly in range(n):
print("%d"%dly,end=" ")
for t in range(4):
for b in range(8):
i=32*dly+8*t+b
if w[i]:
print("%s"%(str(v[i])),end=" ")
if "I" in showMode.upper():
for t in range(4):
for b in range(8):
i=32*dly+8*t+b
if w[i] and ((not filtered) or noF or (not isNone(f[i]))):
print("%s"%(str(v[i])),end=" ")
else:
print("?",end=" ")
if "A" in showMode.upper():
for a in av[dly]:
if not a is None:
print("%f"%(a),end=" ")
else:
print("?",end=" ")
print("?",end=" ")
print()
def normalizeParameters(self,
......@@ -356,6 +449,7 @@ class X393LMA(object):
dly_step_ds,
primary_set,
data_set,
compare_prim_steps,
quiet=1):
"""
Prepare data by building and processing histograms to find
......@@ -376,14 +470,18 @@ class X393LMA(object):
@dly_step_ds IDELAY step (from the datasheet)
@primary_set which of the data edge series to use as leading (other will be trailing by 180)
@data_set measured data set
@compare_prim_steps while scanning, compare this delay with 1 less by primary(not fine) step,
save None for fraction in unknown (previous -0.5, next +0.5)
@quiet reduce output
"""
num_hist_steps=2*((DLY_STEPS+bin_size-1)//bin_size)
est_step_period=(clk_period/dly_step_ds)*FINE_STEPS
est_bin_period=est_step_period/bin_size
halfStep=0.5
if compare_prim_steps:
halfStep*=FINE_STEPS
extra_Y=(0.0,halfStep)
hist=[0.0]* num_hist_steps
hist4=[]
for _ in range(4):
......@@ -401,10 +499,11 @@ class X393LMA(object):
if bData:
for t,tData in enumerate(bData):
if not tData is None:
binNum=(tData-dly+DLY_STEPS+1) // bin_size
binNum=int((tData[0]+extra_Y[tData[1] is None]-dly+DLY_STEPS+1) / bin_size)
hist8x4[b][t][binNum] += 1 # lowest bin will be 1 count shy
if binNum == 0:
hist8x4[b][t][binNum] += 1.0/(bin_size-1.0)
for t in range(4):
for i in range(num_hist_steps):
for b in range(8):
......@@ -571,9 +670,19 @@ class X393LMA(object):
def get_periods_map(self,
lane,
data_set,
compare_prim_steps,
hist_estimated,
quiet=1):
quiet=1):
"""
@compare_prim_steps while scanning, compare this delay with 1 less by primary(not fine) step,
save None for fraction in unknown (previous -0.5, next +0.5)
"""
#assign most likely period shift for each data sample
halfStep=0.5
if compare_prim_steps:
halfStep*=FINE_STEPS
extra_Y=(0.0,halfStep)
period=hist_estimated['period']
data_periods_map=[]
for dly,data in enumerate(data_set):
......@@ -587,7 +696,7 @@ class X393LMA(object):
if not tData is None: #[dly],[b],[t] tData - int value
he=hist_estimated['b_indiv'][b][t] # tuple (b, periods)
#find most likely period shift
pm[b][t]=int(round((tData-dly-he[0])/period))+he[1]
pm[b][t]=int(round((tData[0]+extra_Y[tData[1] is None]-dly-he[0])/period))+he[1]
data_periods_map.append(pm)
else:
data_periods_map.append(None)
......@@ -606,7 +715,8 @@ class X393LMA(object):
for typ in range(4):
for b, bData in enumerate(data_lane): # 8 DQs, each ...
if bData and (not bData[typ] is None):
print ("%d"%(bData[typ]),end=" ")
d=bData[typ][0]+extra_Y[bData[typ][1] is None]
print ("%d"%(d),end=" ")
else:
print ("x",end=" ")
print()
......@@ -645,7 +755,8 @@ class X393LMA(object):
for typ in range(4):
for b, bData in enumerate(data_lane): # 8 DQs, each ...
if bData and (not bData[typ] is None):
print ("%f"%(bData[typ]-period*data_periods_map[dly][b][typ]),end=" ")
d=bData[typ][0]+extra_Y[bData[typ][1] is None]
print ("%f"%(d-period*data_periods_map[dly][b][typ]),end=" ")
else:
print ("x",end=" ")
print()
......@@ -658,6 +769,8 @@ class X393LMA(object):
dly_step_ds,
primary_set,
data_set,
compare_prim_steps,
scale_w,
quiet=1):
"""
Initialize parameters and y-vector
......@@ -672,8 +785,12 @@ class X393LMA(object):
@dly_step_ds IDELAY step (from the datasheet)
@primary_set which of the data edge series to use as leading (other will be trailing by 180)
@data_set measured data set
@compare_prim_steps while scanning, compare this delay with 1 less by primary(not fine) step,
save None for fraction in unknown (previous -0.5, next +0.5)
@scale_w weight for "uncertain" values (where samples chane from all 0 to all 1 in one step)
@quiet reduce output
"""
print ("init_parameters(): scale_w=%f"%(scale_w))
self.clk_period=clk_period
hist_estimated=self.estimate_from_histograms(lane, # byte lane
......@@ -682,24 +799,33 @@ class X393LMA(object):
dly_step_ds,
primary_set,
data_set,
compare_prim_steps,
quiet)
if quiet < 3:
print ("hist_estimated=%s"%(str(hist_estimated)))
data_periods_map=self.get_periods_map(lane,
data_set,
compare_prim_steps,
hist_estimated,
quiet) #+1)
ywp= self.createYandWvectors(lane,
data_set,
compare_prim_steps,
scale_w,
data_periods_map)
# print("ywp=%s"%(str(ywp)))
if quiet < 2:
print("\nY-vector:")
self.showYOrVector(ywp)
self.showYOrVector(ywp,False,None)
print("\nY-vector(filtered):")
self.showYOrVector(ywp,True,None)
if quiet < 2:
print("\nperiods map:")
self.showYOrVector(ywp,ywp['p'])
print("\nperiods_map:")
self.showYOrVector(ywp,False,ywp['p'])
if quiet < 2:
print("\nweights_map:")
self.showYOrVector(ywp,False,ywp['w'])
......@@ -722,12 +848,13 @@ class X393LMA(object):
parameters={
"tSDQS": step_ps,
"tSDQ": (step_ps,)*8,
"tDQSHL": tDQSHL, # 0.0, # improve
"tDQSHL": tDQSHL, # 0.0, # improve Seems that initial value does not match final by sign!
"tDQHL": tDQHL, # (0.0)*8, # improve
"tDQS": 0.0,
"tDQ": tDQ,
"tFDQS": (0.0,)*4,
"tFDQ": (0.0,)*32#,
"tFDQ": (0.0,)*32,
"tCDQS": (0.0,)*30
# "anaScale":self.analog_scale
}
print ("parameters=%s"%(str(parameters)))
......@@ -759,7 +886,11 @@ class X393LMA(object):
if quiet < 2:
print("\nfx:")
self.showYOrVector(ywp,fx)
self.showYOrVector(ywp,False,fx)
print("\nfx (filtered):")
self.showYOrVector(ywp,True,fx)
SX=0.0
SX2=0.0
S0=0.0
......@@ -771,9 +902,9 @@ class X393LMA(object):
avg= SX/S0
rms= math.sqrt(SX2/S0)
print ("average(fx)= %fps, rms(fx)=%fps"%(avg,rms))
jByJT=np.dot(fxj['jacob'],np.transpose(fxj['jacob']))
if quiet < 3:
jByJT=np.dot(fxj['jacob'],np.transpose(fxj['jacob']))
print("\njByJT:")
for i,l in enumerate(jByJT):
print ("%d"%(i),end=" ")
......@@ -781,7 +912,7 @@ class X393LMA(object):
print ("%f"%(d),end=" ")
print()
self.lambdas ['current']=self.lambdas ['initial']
for _ in range(self.maxNumSteps):
for n_iter in range(self.maxNumSteps):
OK,finished=self.LMA_step(parameters,
ywp, # keep in self.variable?
primary_set, # prima
......@@ -789,9 +920,18 @@ class X393LMA(object):
self.lambdas,
self.finalDiffRMS,
quiet)
if OK:
print ("parameters=%s"%(str(parameters)))
if quiet < 4:
arms = self.getParAvgRMS(parameters,
ywp,
primary_set, # prima
quiet+1)
print ("%d: LMA_step %s average(fx)= %fps, rms(fx)=%fps"%(n_iter,("FAILURE","SUCCESS")[OK],arms['avg'],arms['rms']))
if OK and quiet < 2:
print ("updated parameters=%s"%(str(parameters)))
if finished:
if quiet < 4:
print ("final parameters=%s"%(str(parameters)))
break
fx= self.createFxAndJacobian(parameters,
......@@ -802,16 +942,121 @@ class X393LMA(object):
quiet=1)
if quiet < 3:
print("\nfx:")
self.showYOrVector(ywp,fx)
# print("delta=%s"%(str(delta)))
# for i,d in enumerate(delta):
# print ("%d %f"%(i,d))
print("\nfx-postLMA:")
self.showYOrVector(ywp,False,fx)
print("\nfx-postLMA (filtered):")
self.showYOrVector(ywp,True,fx)
# calculate DQ[i] vs. DQS for -1, 0 and +1 period
DQvDQS=self.getBestDQforDQS(parameters,
primary_set,
quiet)
if quiet < 4:
enl_list=[]
for i in range(3):
if not DQvDQS[i] is None:
enl_list.append(i)
print("DQS", end=" ")
for enl in enl_list:
for b in range(8):
print("%s%d"%(('E','N','L')[enl],b),end=" ")
print()
for dly in range(DLY_STEPS):
print ("%d"%(dly),end=" ")
for enl in enl_list:
if DQvDQS[enl][dly] is None:
print ("? "*8,end="")
else:
for b in range(8):
if DQvDQS[enl][dly][b] is None:
print("?",end=" ")
else:
print("%d"%(DQvDQS[enl][dly][b]),end=" ")
print()
def getBestDQforDQS(self,
parameters,
primary_set, # prima
quiet=1):
period=self.clk_period
tFDQS5=list(parameters['tFDQS'])
tFDQS5.append(-tFDQS5[0]-tFDQS5[1]-tFDQS5[2]-tFDQS5[3])
tSDQS=parameters['tSDQS']
tSDQ= parameters['tSDQ'] # list
tDQS =parameters['tDQS']#single value
tDQ= parameters['tDQ'] # list
tCDQS32=list(parameters['tCDQS'][0:8])+[0]+list(parameters['tCDQS'][8:23])+[0]+list(parameters['tCDQS'][23:30])
# tDQSHL =parameters['tDQSHL']#single value
# tDQHL= parameters['tDQHL'] # list
tFDQs=[]
for b in range(8):
tFDQi=list(parameters['tFDQ'][4*b:4*(b+1)])
tFDQi.append(-tFDQi[0]-tFDQi[1]-tFDQi[2]-tFDQi[3])
for i in range(5):
tFDQi[i]/=tSDQ[b]
tFDQs.append(tFDQi)
dqForDqs=[]
for enl in (0,1,2):
vDQ=[]
someData=False
for dly in range(DLY_STEPS):
tdqs=dly * tSDQS - tDQS - tFDQS5[dly % FINE_STEPS] # t - time from DQS pad to internal DQS clock with zero setup/hold times to DQ FFs
tdqs-=tCDQS32[dly // FINE_STEPS]
tdq3=tdqs +(-0.75+enl)*period # (early, nominal, late)
bDQ=[]
for b in range(8): # use all 4 variants
tdq=(tdq3+tDQ[b])/tSDQ[b]
itdq=int(round(tdq)) # in delay steps
bestDQ=None
if (itdq >= 0) and (itdq < DLY_STEPS):
bestDiff=None
for idq in range (max(itdq-FINE_STEPS,0),min(itdq+FINE_STEPS,DLY_STEPS-1)+1):
diff=idq-tFDQs[b][idq % FINE_STEPS]
if (bestDQ is None) or (abs(diff) < bestDiff):
bestDQ=idq
bestDiff=abs(diff)
if bestDQ is None:
bDQ=None
break
bDQ.append(bestDQ)
someData=True
vDQ.append(bDQ)
if someData:
dqForDqs.append(vDQ)
else:
dqForDqs.append(None)
return dqForDqs
"""
for dly in range(DLY_STEPS):
tdqs=dly * tSDQS - tDQS - tFDQS5[dly % FINE_STEPS] # t - time from DQS pad to internal DQS clock with zero setup/hold times to DQ FFs
tdq3=(tdqs-0.75*period, tdqs + 0.25*period,tdqs + 1.25*period) # (early, nominal, late)
bDQ=[]
allBits=[True,True,True]
for b in range(8): # use all 4 variants
vDQ=[]
for enl in (0,1,2):
tdq=(tdq3[enl]+tDQ[b])/tSDQ[b]
itdq=int(round(tdq)) # in delay steps
bestDQ=None
if (itdq >= 0) and (itdq < DLY_STEPS):
bestDiff=None
for idq in range (max(itdq-FINE_STEPS,0),min(itdq+FINE_STEPS,DLY_STEPS-1)+1):
diff=idq-tFDQs[b][idq % FINE_STEPS]
if (bestDQ is None) or (abs(diff) < bestDiff):
bestDQ=idq
bestDiff=abs(diff)
if bestDQ is None:
allBits[enl] = False
vDQ.append(bestDQ)
bDQ.append(vDQ)
dqForDqs.append(bDQ)
"""
"""
......@@ -835,6 +1080,7 @@ class X393LMA(object):
return obj is None
isNone=pythIsNone # swithch to np.isnan
y_vector = y_data['y']
yf_vector = y_data['yf'] # when no fractions available - half interval (0.5 or 2.5) is added, if available - nothing is added
periods_vector=y_data['p']
period=self.clk_period
try:
......@@ -856,6 +1102,9 @@ class X393LMA(object):
#self.clk_period
tFDQS5=list(parameters['tFDQS'])
tFDQS5.append(-tFDQS5[0]-tFDQS5[1]-tFDQS5[2]-tFDQS5[3])
tCDQS32=list(parameters['tCDQS'][0:8])+[0]+list(parameters['tCDQS'][8:23])+[0]+list(parameters['tCDQS'][23:30])
print("*****tCDQS32=",tCDQS32)
tFDQ=[]
for b in range(8):
tFDQi=list(parameters['tFDQ'][4*b:4*(b+1)])
......@@ -871,15 +1120,16 @@ class X393LMA(object):
tDQHL= parameters['tDQHL'] # list
for dly in range(DLY_STEPS):
tdqs=dly * tSDQS - tDQS - tFDQS5[dly % FINE_STEPS] # t - time from DQS pad to internal DQS clock with zero setup/hold times to DQ FFs
tdqs_r = tdqs + 0.25 * tDQSHL # sign opposite from: ir = ir0 - s/4 + d/4; or = or0 - s/4 - d/4
tdqs_f = tdqs - 0.25 * tDQSHL # sign opposite from: if = if0 + s/4 - d/4; of = of0 + s/4 + d/4
tdqs-=tCDQS32[dly // FINE_STEPS]
tdqs_r = tdqs - 0.25 * tDQSHL # sign opposite from: ir = ir0 - s/4 + d/4; or = or0 - s/4 - d/4 - NOT, but maybe other is wrong
tdqs_f = tdqs + 0.25 * tDQSHL # sign opposite from: if = if0 + s/4 - d/4; of = of0 + s/4 + d/4
tdqs_rf=(tdqs_r, tdqs_f)
#correct for DQS edge type
for b in range(8): # use all 4 variants
for t in range(4):
indx=32*dly+t*8+b
if (w_vector is None) or (w_vector[indx] > 0):
tdq=y_vector[indx] * tSDQ[b] - tDQ[b] - tFDQ[b][y_vector[indx] % FINE_STEPS]
tdq=yf_vector[indx] * tSDQ[b] - tDQ[b] - tFDQ[b][y_vector[indx] % FINE_STEPS]
# correct for periods
tdq -= period*periods_vector[indx] # or should it be minus here?
# correct for edge types
......@@ -888,11 +1138,8 @@ class X393LMA(object):
else:
tdq += 0.25*tDQHL[b]
if anaScale:
# if y_fractions[indx] is None:
if isNone(y_fractions[indx]):
tdq+=2.5
else:
tdq+=anaScale*y_fractions[indx]
if not isNone(y_fractions[indx]):
tdq-=anaScale*y_fractions[indx] # negative values mean that actual zero-point is not yet reached
if (t ^ primary_set) & 2:
tdq -= 0.5*period
fx[indx] = tdq - tdqs_rf[t & 1] # odd are falling DQS, even are rising DQS
......@@ -904,19 +1151,43 @@ class X393LMA(object):
# numPars=len(pv)
# print("pv=%s"%(str(pv)))
parInd=self.createParameterIndex(parameters,parMask)
print("parInd=%s"%(str(parInd)))
if quiet <2:
print("parInd=%s"%(str(parInd)))
numPars=parInd['numPars']
jacob=np.zeros((numPars,DLY_STEPS*32))
"""
fineM5=((1.0, 0.0, 0.0, 0.0, -0.25),
(0.0, 1.0, 0.0, 0.0, -0.25),
(0.0, 0.0, 1.0, 0.0, -0.25),
(0.0, 0.0, 0.0, 1.0, -0.25))
"""
fineM5=((1.0, 0.0, 0.0, 0.0, -1.0),
(0.0, 1.0, 0.0, 0.0, -1.0),
(0.0, 0.0, 1.0, 0.0, -1.0),
(0.0, 0.0, 0.0, 1.0, -1.0))
dqs_finedelay_en=parInd['tFDQS']
for e in dqs_finedelay_en:
if e>=0:
break
else:
dqs_finedelay_en=None
dqs_delay32_en=parInd['tCDQS']
for e in dqs_delay32_en:
if e>=0:
break
else:
dqs_delay32_en=None
# tCDQS32=list(parameters['tCDQS'][0:8])+[0]+list(parameters['tCDQS'][8:23])+[0]+list(parameters['tCDQS'][23:30])
if not dqs_delay32_en is None:
dqs_delay32_index=range(0,8)+[-1]+range(8,23)+[-1]+range(23,30)
for i,d in enumerate(dqs_delay32_index):
if d >= 0:
dqs_delay32_index[i] = dqs_delay32_en[d]
print("*****dqs_delay32_index=",dqs_delay32_index)
dq_finedelay_en=[None]*8
for b in range(8):
dq_finedelay_en[b]=parInd['tFDQ'][4*b:4*(b+1)]
......@@ -928,10 +1199,11 @@ class X393LMA(object):
for dly in range(DLY_STEPS):
dlyMod5=dly % FINE_STEPS
dlyDiv5=dly // FINE_STEPS
dtdqs_dtSDQS = dly
dtdqs_dtDQS = -1.0
dtdqs_dtFDQS = (-fineM5[0][dlyMod5],-fineM5[1][dlyMod5],-fineM5[2][dlyMod5],-fineM5[3][dlyMod5])
dtdqs_dtDQSHL_rf=(0.25,-0.25)
dtdqs_dtDQSHL_rf=(-0.25,+0.25) # ign opposite from: ir = ir0 - s/4 + d/4; or = or0 - s/4 - d/4, ... - NOT, but maybe other is wrong
#correct for DQS edge type
for b in range(8): # use all 4 variants
for t in range(4):
......@@ -946,6 +1218,12 @@ class X393LMA(object):
for i,pIndx in enumerate (dqs_finedelay_en):
if pIndx >= 0:
jacob[pIndx,indx]=-dtdqs_dtFDQS[i]
if dqs_delay32_en:
for i,pIndx in enumerate (dqs_delay32_en):
if pIndx >= 0:
jacob[pIndx,indx]=(0,1.0)[i==dlyDiv5]
if parInd['tDQSHL'] >= 0:
jacob[parInd['tDQSHL'],indx]=-dtdqs_dtDQSHL_rf[t & 1]
#dependencies of DQ delays
......@@ -981,6 +1259,7 @@ class X393LMA(object):
False, # jacobian
None,
quiet)
"""
SX=0.0
SX2=0.0
S0=0.0
......@@ -989,6 +1268,10 @@ class X393LMA(object):
S0+=w
SX+=w*d
SX2+=w*d*d
"""
S0=np.sum(ywp['w'])
SX=np.sum(fx*ywp['w'])
SX2=np.sum(fx*fx*ywp['w'])
avg= SX/S0
rms= math.sqrt(SX2/S0)
return {"avg":avg,"rms":rms}
......@@ -1008,7 +1291,7 @@ class X393LMA(object):
ywp,
primary_set, # prima
quiet+1)
if quiet < 3:
if quiet < 2:
print ("LMA_step <start>: average(fx)= %fps, rms(fx)=%fps"%(arms0['avg'],arms0['rms']))
delta=self.LMA_solve(parameters,
......@@ -1032,13 +1315,13 @@ class X393LMA(object):
newPars) # parameters=None):# if not None, will be updated
if quiet < 2:
print ("\n2: newPars=%s"%(str(newPars)))
print ("\nparameters=%s"%(str(parameters)))
# print ("\nparameters=%s"%(str(parameters)))
arms1 = self.getParAvgRMS(newPars,
ywp,
primary_set, # prima
quiet+1)
finished=False
if arms1['rms'] < arms0['rms']:
if arms1['rms'] <= arms0['rms']:
parameters.update(newPars)
lambdas["current"]*=.5
success=True
......@@ -1049,7 +1332,7 @@ class X393LMA(object):
success=False
if lambdas["current"] > lambdas["max"]:
finished=True
if quiet < 3:
if (quiet < 2) or ((quiet < 4) and (not success)):
print ("LMA_step %s: average(fx)= %fps, rms(fx)=%fps, lambda=%f"%(('FAILURE','SUCCESS')[success],arms1['avg'],arms1['rms'],lambdas["current"]))
return (success,finished)
......@@ -1069,12 +1352,26 @@ class X393LMA(object):
True, # jacobian
parMask,
quiet)
try:
w_vector = ywp['w']
except:
w_vector = np.full((len(fxj['fx']),),1.0)
# print("w_vector=",w_vector)
# print("fxj['jacob']=",fxj['jacob'])
# JT=np.transpose(fxj['jacob'])
# print("JT=",JT)
wJ=fxj['jacob'] *w_vector
# JT=np.transpose(wJ) # fxj['jacob'])
JT=np.transpose(fxj['jacob'])
jByJT=np.dot(fxj['jacob'],JT)
# print("wJ=",wJ)
jByJT=np.dot(wJ,JT)
# print("jByJT=",jByJT)
for i,_ in enumerate(jByJT):
jByJT[i,i] += lmbda*jByJT[i,i]
jByDiff= -np.dot(fxj['jacob'],fxj['fx'])
jByDiff= -np.dot(wJ,fxj['fx'])
delta=np.linalg.solve(jByJT,jByDiff)
# print("*****delta=",delta)
return delta
"""
......
......@@ -1655,7 +1655,9 @@ class X393McntrlAdjust(object):
return rdict
def adjust_pattern(self,
limit_step=0.125, # initial delay step as a fraction of the period
compare_prim_steps=True, # while scanning, compare this delay with 1 less by primary(not fine) step,
# save None for fraction in unknown (previous -0.5, next +0.5)
limit_step=0.125, # initial delay step as a fraction of the period
max_phase_err=0.1,
quiet=1,
start_dly=0): #just to check dependence
......@@ -1849,31 +1851,61 @@ class X393McntrlAdjust(object):
# scan ranges, find closest solutions
#compare_prim_steps
best_dly= [[],[]]
best_diff=[[],[]]
for inPhase in range(2):
if not d_high[inPhase] is None:
patt=None
for dly in range(d_low[inPhase],d_high[inPhase]+1):
patt_prev=patt
patt=measure_patt(dly) # ,force_meas=False) - will be stored in cache
if patt_prev is None: #first run
best_dly[inPhase]=[d_low[inPhase]]*32
for p in patt:
best_diff[inPhase].append(p-0.5)
else: # all the rest
for b in range(32):
positiveJump=((not inPhase) and (b<16)) or (inPhase and (b >= 16)) # may be 0, False, True
signs=((-1,1)[patt_prev[b]>0.5],(-1,1)[patt[b]>0.5])
if (positiveJump and (signs==(-1,1))) or (not positiveJump and (signs==(1,-1))):
if abs(patt_prev[b]-0.5) < abs(patt[b]-0.5): # store previos sample
best_dly[inPhase][b]=dly-1
best_diff[inPhase][b]=patt_prev[b]-0.5
else:
best_dly[inPhase][b]=dly
best_diff[inPhase][b]=patt[b]-0.5
if not positiveJump:
best_diff[inPhase][b] *= -1 # inver sign, so sign always means <0 - delay too low, >0 - too high
# patt=None
best_dly[inPhase]=[d_low[inPhase]]*32
best_diff[inPhase]=[None]*32
# for b,p in enumerate(patt):
# positiveJump=((not inPhase) and (b<16)) or (inPhase and (b >= 16)) # may be 0, False, True
# if positiveJump:
# best_diff[inPhase].append(p-0.5)
# else:
# best_diff[inPhase].append(0.5-p)
for dly in range(d_low[inPhase]+1,d_high[inPhase]+1):
# patt_prev=patt
#as measured data is cached, there is no need to specially maintain patt_prev from earlier measurement
dly_prev= max(0,dly-(1,NUM_FINE_STEPS)[compare_prim_steps])
patt_prev=measure_patt(dly_prev) # ,force_meas=False) - will be stored in cache
patt= measure_patt(dly) # ,force_meas=False) - will be stored in cache
for b in range(32):
positiveJump=((not inPhase) and (b<16)) or (inPhase and (b >= 16)) # may be 0, False, True
signs=((-1,1)[patt_prev[b]>0.5],(-1,1)[patt[b]>0.5])
if (positiveJump and (signs==(-1,1))) or (not positiveJump and (signs==(1,-1))):
if positiveJump:
diffs_prev_this=(patt_prev[b]-0.5,patt[b]-0.5)
else:
diffs_prev_this=(0.5-patt_prev[b],0.5-patt[b])
"""
if abs(patt_prev[b]-0.5) < abs(patt[b]-0.5): # store previos sample
best_dly[inPhase][b]=dly_prev # dly-1
best_diff[inPhase][b]=patt_prev[b]-0.5
else:
best_dly[inPhase][b]=dly
best_diff[inPhase][b]=patt[b]-0.5
if not positiveJump:
best_diff[inPhase][b] *= -1 # invert sign, so sign always means <0 - delay too low, >0 - too high
"""
if abs(diffs_prev_this[0]) <= abs(diffs_prev_this[1]): # store previos sample
if (best_diff[inPhase][b] is None) or (abs (diffs_prev_this[0])<abs(best_diff[inPhase][b])):
best_dly[inPhase][b]=dly_prev # dly-1
best_diff[inPhase][b]=diffs_prev_this[0]
if quiet < 1:
print ("*%d:%0.3f:%0.3f%s"%(b,diffs_prev_this[0],diffs_prev_this[1],str(signs)),end="")
else:
if (best_diff[inPhase][b] is None) or (abs (diffs_prev_this[1])<abs(best_diff[inPhase][b])):
best_dly[inPhase][b]=dly # dly-1
best_diff[inPhase][b]=diffs_prev_this[1]
if quiet < 1:
print ("?%d:%0.3f:%0.3f%s"%(b,diffs_prev_this[0],diffs_prev_this[1],str(signs)),end="")
if quiet < 1:
print("\n dly=%d dly_prev=%d:"%(dly,dly_prev),end=" ")
for b in range(32):
if best_diff[inPhase][b] == -0.5:
best_diff[inPhase][b] = None # will have to add half-interval (0.5 or 2.5)
# rslt=[None]*16 # each bit will have [inphase][dqs_falling], each - a pair of (delay,diff)
for b in range(16):
rslt[b]=[[None]*2,[None]*2] # [inphase][dqs_falling]
......@@ -1904,6 +1936,7 @@ class X393McntrlAdjust(object):
print ()
if quiet < 3:
print("\n\nMeasured data, integer portion, measured with %s steps"%(("fine","primary")[compare_prim_steps]))
print ("DQS",end=" ")
for f in ('ir','if','or','of'):
for b in range (16):
......@@ -1929,6 +1962,32 @@ class X393McntrlAdjust(object):
print ("x",end=" ")
print()
if quiet < 2:
print("\n\nMasked measured data, integer portion, measured with %s steps"%(("fine","primary")[compare_prim_steps]))
for f in ('ir','if','or','of'):
for b in range (16):
print ("%s_%d"%(f,b),end=" ")
print()
for ldly, data in enumerate(meas_data):
print("%d"%ldly,end=" ")
if data:
for typ in ((0,0),(0,1),(1,0),(1,1)):
for pData in data: # 16 DQs, each None nor a pair of lists for inPhase in (0,1), each a pair of edges, each a pair of (dly,diff)
if pData:
if pData[typ[0]] and pData[typ[0]][typ[1]] and (not pData[typ[0]][typ[1]][1] is None):
print ("%d"%pData[typ[0]][typ[1]][0],end=" ")
'''
try:
print ("%d"%pData[typ[0]][typ[1]][0],end=" ")
except:
print (".", end=" ")
'''
else:
print ("?", end=" ")
else:
print ("x",end=" ")
print()
if quiet < 2:
print ("\nDifferences from 0.5:")
......@@ -1944,7 +2003,7 @@ class X393McntrlAdjust(object):
for typ in ((0,0),(0,1),(1,0),(1,1)):
for pData in data: # 16 DQs, each None nor a pair of lists for inPhase in (0,1), each a pair of edges, each a pair of (dly,diff)
if pData:
if pData[typ[0]] and pData[typ[0]][typ[1]]:
if pData[typ[0]] and pData[typ[0]][typ[1]] and (not pData[typ[0]][typ[1]][1] is None):
print ("%.2f"%pData[typ[0]][typ[1]][1],end=" ")
'''
try:
......@@ -1958,8 +2017,10 @@ class X393McntrlAdjust(object):
print ("x",end=" ")
print()
print("\n\n")
# print ("meas_data=%s"%str(meas_data))
if quiet < 3:
print("\n\nMeasured data, comparing current data with the earlier by one %s step"%(("fine","primary")[compare_prim_steps]))
print("When the fractional (second in the tuple) data is exactly -0.5, the actual result is in the range %s from the integer delay"%
(("+0.0..+1.0","+0.0..+%d"%NUM_FINE_STEPS)[compare_prim_steps]))
print ("meas_data=[")
for d in meas_data:
print("%s,"%(str(d)))
......@@ -1974,8 +2035,19 @@ class X393McntrlAdjust(object):
lane=0,
bin_size=5,
primary_set=2,
# compare_prim_steps=True, # while scanning, compare this delay with 1 less by primary(not fine) step,
# # save None for fraction in unknown (previous -0.5, next +0.5)
data_set_number=2,
scale_w=0.2, # weight for "uncertain" values (where samples chane from all 0 to all 1 in one step)
quiet=1):
meas_data=get_test_dq_dqs_data.get_data()
"""
@scale_w weight for "uncertain" values (where samples chane from all 0 to all 1 in one step)
"""
print ("proc_test_data(): scale_w=%f"%(scale_w))
compare_prim_steps=get_test_dq_dqs_data.get_compare_prim_steps(data_set_number)
meas_data=get_test_dq_dqs_data.get_data(data_set_number)
meas_delays=[]
for data in meas_data:
if data:
......@@ -1995,10 +2067,10 @@ class X393McntrlAdjust(object):
if pData[inPhase]:
for e in (0,1):
if pData[inPhase][e]:
bits[b][inPhase*2+e]=pData[inPhase][e][0]
bits[b][inPhase*2+e]=pData[inPhase][e]# [0]
meas_delays.append(bits)
if quiet<1:
x393_lma.test_data(meas_delays,quiet)
x393_lma.test_data(meas_delays,compare_prim_steps,quiet)
lma=x393_lma.X393LMA()
lma.init_parameters(
lane,
......@@ -2007,5 +2079,7 @@ class X393McntrlAdjust(object):
78.0, # dly_step_ds,
primary_set,
meas_delays,
compare_prim_steps,
scale_w,
quiet)
\ No newline at end of file
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