Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393
Commits
4cf7bd61
Commit
4cf7bd61
authored
Mar 23, 2015
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
debugging write levelling measuring/results approximation
parent
e4dae58e
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
345 additions
and
70 deletions
+345
-70
test_mcntrl.py
py393/test_mcntrl.py
+4
-4
x393_mcntrl_adjust.py
py393/x393_mcntrl_adjust.py
+328
-60
x393_mcntrl_timing.py
py393/x393_mcntrl_timing.py
+13
-6
No files found.
py393/test_mcntrl.py
View file @
4cf7bd61
...
@@ -225,10 +225,10 @@ USAGE
...
@@ -225,10 +225,10 @@ USAGE
verbose
=
args
.
verbose
verbose
=
args
.
verbose
if
not
verbose
:
if
not
verbose
:
verbose
=
0
verbose
=
0
print
(
"args=
%
s"
%
(
str
(
args
)))
#
print("args=%s"%(str(args)))
print
(
"sys.argv=
%
s"
%
(
str
(
sys
.
argv
)))
#
print("sys.argv=%s"%(str(sys.argv)))
print
(
"DEBUG=
%
s"
%
(
str
(
DEBUG
)))
#
print("DEBUG=%s"%(str(DEBUG)))
print
(
"verbose=
%
d"
%
verbose
)
#
print ("verbose=%d"%verbose)
paths
=
[]
paths
=
[]
...
...
py393/x393_mcntrl_adjust.py
View file @
4cf7bd61
...
@@ -57,6 +57,7 @@ class X393McntrlAdjust(object):
...
@@ -57,6 +57,7 @@ class X393McntrlAdjust(object):
x393_mcntrl_timing
=
None
x393_mcntrl_timing
=
None
x393_mcntrl_buffers
=
None
x393_mcntrl_buffers
=
None
verbose
=
1
verbose
=
1
adjustment_state
=
{}
def
__init__
(
self
,
debug_mode
=
1
,
dry_mode
=
True
):
def
__init__
(
self
,
debug_mode
=
1
,
dry_mode
=
True
):
self
.
DEBUG_MODE
=
debug_mode
self
.
DEBUG_MODE
=
debug_mode
self
.
DRY_MODE
=
dry_mode
self
.
DRY_MODE
=
dry_mode
...
@@ -657,7 +658,7 @@ class X393McntrlAdjust(object):
...
@@ -657,7 +658,7 @@ class X393McntrlAdjust(object):
for
j
in
range
(
1
,
NUM_FINE_STEPS
):
for
j
in
range
(
1
,
NUM_FINE_STEPS
):
if
(
(
len
(
res_avg
[
index
+
j
])
>
0
)):
if
(
(
len
(
res_avg
[
index
+
j
])
>
0
)):
v
=
res_avg
[
index
+
j
][
t
];
v
=
res_avg
[
index
+
j
][
t
];
#correction to the initi
la
step==1
#correction to the initi
al
step==1
d
=
(
v
-
f
)
/
(
s
-
f
)
*
NUM_FINE_STEPS
-
j
d
=
(
v
-
f
)
/
(
s
-
f
)
*
NUM_FINE_STEPS
-
j
#average
#average
corr
[
j
]
+=
wd
*
d
corr
[
j
]
+=
wd
*
d
...
@@ -1141,7 +1142,7 @@ class X393McntrlAdjust(object):
...
@@ -1141,7 +1142,7 @@ class X393McntrlAdjust(object):
if
d
[
1
]
>
0
:
if
d
[
1
]
>
0
:
numValid
+=
1
numValid
+=
1
if
numValid
<
2
:
if
numValid
<
2
:
raise
Exception
(
"Too few points wi
o
th measured marginal CMDA odelay:
%
d"
%
numValid
)
raise
Exception
(
"Too few points with measured marginal CMDA odelay:
%
d"
%
numValid
)
maxPosSep
=
0
maxPosSep
=
0
firstIndex
=
None
firstIndex
=
None
for
i
,
d
in
enumerate
(
cmda_marg_dly
):
for
i
,
d
in
enumerate
(
cmda_marg_dly
):
...
@@ -1192,6 +1193,7 @@ class X393McntrlAdjust(object):
...
@@ -1192,6 +1193,7 @@ class X393McntrlAdjust(object):
fineCorr
[
i
]
/=
fineCorrN
[
i
]
fineCorr
[
i
]
/=
fineCorrN
[
i
]
if
(
quiet
<
2
):
if
(
quiet
<
2
):
print
(
"fineCorr =
%
s"
%
str
(
fineCorr
))
print
(
"fineCorr =
%
s"
%
str
(
fineCorr
))
variantStep
=-
a
*
numPhaseSteps
#how much b changes when moving over the full SDCLK period
variantStep
=-
a
*
numPhaseSteps
#how much b changes when moving over the full SDCLK period
if
(
quiet
<
2
):
if
(
quiet
<
2
):
print
(
"Delay matching the full SDCLK period =
%
f"
%
(
variantStep
))
print
(
"Delay matching the full SDCLK period =
%
f"
%
(
variantStep
))
...
@@ -1208,6 +1210,7 @@ class X393McntrlAdjust(object):
...
@@ -1208,6 +1210,7 @@ class X393McntrlAdjust(object):
b_period
+=
1
b_period
+=
1
if
(
quiet
<
2
):
if
(
quiet
<
2
):
print
(
"a=
%
f, b=
%
f, b_period=
%
d"
%
(
a
,
b
,
b_period
))
print
(
"a=
%
f, b=
%
f, b_period=
%
d"
%
(
a
,
b
,
b_period
))
# Find best minimal delay (with higher SDCLK frequency delay range can exceed the period and there could
# Find best minimal delay (with higher SDCLK frequency delay range can exceed the period and there could
# be more than one solution
# be more than one solution
bestSolPerErr
=
[]
#list ot tuples, each containing(best cmda_odelay,number of added periods,error)
bestSolPerErr
=
[]
#list ot tuples, each containing(best cmda_odelay,number of added periods,error)
...
@@ -1304,75 +1307,340 @@ class X393McntrlAdjust(object):
...
@@ -1304,75 +1307,340 @@ class X393McntrlAdjust(object):
else
:
else
:
print
()
print
()
#TODO: Add 180 shift to get center, not marginal cmda_odelay
#TODO: Add 180 shift to get center, not marginal cmda_odelay
self
.
adjustment_state
.
update
(
rdict
)
return
rdict
return
rdict
def
adjust_write_levelling
(
self
,
start_phase
=
0
,
reinits
=
1
,
#higher the number - more re-inits are used (0 - only where absolutely necessary
invert
=
0
,
# anti-align DQS (should be 180 degrees off from the normal one)
max_phase_err
=
0.1
,
quiet
=
1
):
"""
"""
With 400MHz range of dealys approximately matches the full period, but with higher
Find DQS odelay for each phase value
frequency it may be possible to use several cmda delays for the same phase shift
Depends on adjust_cmda_odelay results
So we'll create a list for all the phase shifts (of the period), each having one or
several best pairs - cmda (integer 0..159) delays and error (in ns) that this delay
setting will cause for command/data setup/hold to SDCLK.
Actual optimal delays are shifted by numPhaseSteps/2 (180 degrees of SDCLK)
"""
"""
"""
#max_phase_err=0.1
if
not
self
.
adjustment_state
[
'cmda_bspe'
]:
max_dly_err=a*max_phase_err*numPhaseSteps # maximal allowed delay error (in 160-step scale)
raise
Exception
(
"Command/Address delay calibration data is not found - please run 'adjust_cmda_odelay' command first"
)
valid_cmda_delays=[[]]*numPhaseSteps
start_phase
&=
0xff
variantStep=a*numPhaseSteps # delay step to get the same phase (in normalized 160 step scale)
if
start_phase
>=
128
:
minBranchIndex=None
start_phase
-=
256
# -128..+127
maxBranchIndex=None
max_lin_dly
=
159
for phase in range(numPhaseSteps):
wlev_max_bad
=
0.01
# <= OK, > bad
x=phase-firstIndex
numPhaseSteps
=
len
(
self
.
adjustment_state
[
'cmda_bspe'
])
y0=a*x+b
if
quiet
<
2
:
print
(
"cmda_bspe =
%
s"
%
str
(
self
.
adjustment_state
[
'cmda_bspe'
]))
print
(
"numPhaseSteps=
%
d"
%
(
numPhaseSteps
))
def
wlev_phase_step
(
phase
):
def
norm_wlev
(
wlev
):
#change results to invert wlev data
if
invert
:
return
[
1.0
-
wlev
[
0
],
1.0
-
wlev
[
1
],
wlev
[
2
]]
else
:
return
wlev
dly90
=
int
(
0.25
*
numPhaseSteps
*
abs
(
self
.
adjustment_state
[
'cmda_odly_a'
])
+
0.5
)
# linear delay step ~ SDCLK period/4
cmda_odly_data
=
self
.
adjustment_state
[
'cmda_bspe'
][
phase
%
numPhaseSteps
]
if
(
not
cmda_odly_data
):
# phase is invalid for CMDA
return
None
cmda_odly_lin
=
cmda_odly_data
[
'ldly'
]
self
.
x393_mcntrl_timing
.
axi_set_phase
(
phase
,
quiet
=
quiet
)
self
.
x393_mcntrl_timing
.
axi_set_cmda_odelay
(
self
.
combine_delay
(
cmda_odly_lin
),
quiet
=
quiet
)
d_low
=
0
while
d_low
<=
max_lin_dly
:
self
.
x393_mcntrl_timing
.
axi_set_dqs_odelay
(
self
.
combine_delay
(
d_low
),
quiet
=
quiet
)
wlev_rslt
=
norm_wlev
(
self
.
x393_pio_sequences
.
write_levelling
(
1
,
quiet
+
1
))
if
wlev_rslt
[
2
]
>
wlev_max_bad
:
# should be 0 - otherwise wlev did not work (CMDA?)
raise
Exception
(
"Write levelling gave unespected data, aborting (may be wrong command/address delay, incorrectly initializaed"
)
if
(
wlev_rslt
[
0
]
<=
wlev_max_bad
)
and
(
wlev_rslt
[
1
]
<=
wlev_max_bad
):
break
d_low
+=
dly90
else
:
if
quiet
<
3
:
print
(
"Failed to find d_low during initial quadrant search for phase=
%
d (0x
%
x)"
%
(
phase
,
phase
))
return
None
# Now find d_high>d_low to get both bytes result above
d_high
=
d_low
+
dly90
while
d_high
<=
max_lin_dly
:
self
.
x393_mcntrl_timing
.
axi_set_dqs_odelay
(
self
.
combine_delay
(
d_high
),
quiet
=
quiet
)
wlev_rslt
=
norm_wlev
(
self
.
x393_pio_sequences
.
write_levelling
(
1
,
quiet
+
1
))
if
wlev_rslt
[
2
]
>
wlev_max_bad
:
# should be 0 - otherwise wlev did not work (CMDA?)
raise
Exception
(
"Write levelling gave unespected data, aborting (may be wrong command/address delay, incorrectly initializaed"
)
if
(
wlev_rslt
[
0
]
>=
(
1.0
-
wlev_max_bad
))
and
(
wlev_rslt
[
1
]
>=
(
1.0
-
wlev_max_bad
)):
break
d_high
+=
dly90
else
:
if
quiet
<
3
:
print
(
"Failed to find d_high during initial quadrant search for phase=
%
d (0x
%
x)"
%
(
phase
,
phase
))
return
None
# Narrow range while both bytes fit
if
quiet
<
2
:
print
(
"After quadrant adjust d_low=
%
d, d_high=
%
d"
%
(
d_low
,
d_high
))
while
d_high
>
d_low
:
dly
=
(
d_high
+
d_low
)
//
2
self
.
x393_mcntrl_timing
.
axi_set_dqs_odelay
(
self
.
combine_delay
(
dly
),
quiet
=
quiet
)
wlev_rslt
=
norm_wlev
(
self
.
x393_pio_sequences
.
write_levelling
(
1
,
quiet
+
1
))
if
wlev_rslt
[
2
]
>
wlev_max_bad
:
# should be 0 - otherwise wlev did not work (CMDA?)
raise
Exception
(
"Write levelling gave unespected data, aborting (may be wrong command/address delay, incorrectly initializaed"
)
if
(
wlev_rslt
[
0
]
<=
wlev_max_bad
)
and
(
wlev_rslt
[
1
]
<=
wlev_max_bad
):
if
d_low
==
dly
:
break
d_low
=
dly
elif
(
wlev_rslt
[
0
]
>=
(
1.0
-
wlev_max_bad
))
and
(
wlev_rslt
[
1
]
>=
(
1.0
-
wlev_max_bad
)):
d_high
=
dly
else
:
break
#mixed results
# Now process each byte separately
if
quiet
<
2
:
print
(
"After common adjust d_low=
%
d, d_high=
%
d"
%
(
d_low
,
d_high
))
d_low
=
[
d_low
,
d_low
]
d_high
=
[
d_high
,
d_high
]
for
i
in
range
(
2
):
while
d_high
[
i
]
>
d_low
[
i
]:
dly
=
(
d_high
[
i
]
+
d_low
[
i
])
//
2
if
quiet
<
1
:
print
(
"i=
%
d, d_low=
%
d, d_high=
%
d, dly=
%
d"
%
(
i
,
d_low
[
i
],
d_high
[
i
],
dly
))
dly01
=
[
d_low
[
0
],
d_low
[
1
]]
dly01
[
i
]
=
dly
self
.
x393_mcntrl_timing
.
axi_set_dqs_odelay
(
self
.
combine_delay
(
dly01
),
quiet
=
quiet
)
wlev_rslt
=
norm_wlev
(
self
.
x393_pio_sequences
.
write_levelling
(
1
,
quiet
+
1
))
if
wlev_rslt
[
2
]
>
wlev_max_bad
:
# should be 0 - otherwise wlev did not work (CMDA?)
raise
Exception
(
"Write levelling gave unespected data, aborting (may be wrong command/address delay, incorrectly initializaed"
)
if
wlev_rslt
[
i
]
<=
wlev_max_bad
:
if
d_low
[
i
]
==
dly
:
break
d_low
[
i
]
=
dly
else
:
d_high
[
i
]
=
dly
return
d_low
if
(
start_phase
+
numPhaseSteps
)
>
128
:
old_start_phase
=
start_phase
while
(
start_phase
+
numPhaseSteps
)
>
128
:
start_phase
-=
numPhaseSteps
print
(
"Selected scan phase range (
%
d..
%
d) does not fit into -128..+127, changing it to
%
d..
%
d)"
%
(
old_start_phase
,
old_start_phase
+
numPhaseSteps
-
1
,
start_phase
,
start_phase
+
numPhaseSteps
-
1
))
#start_phase
if
reinits
>
1
:
# Normally not needed (When started after adjust_cmda_odelay, but refresh should be off (init will do that)
self
.
x393_pio_sequences
.
restart_ddr3
()
wlev_dqs_delays
=
[
None
]
*
numPhaseSteps
for
phase
in
range
(
start_phase
,
start_phase
+
numPhaseSteps
):
phase_mod
=
phase
%
numPhaseSteps
if
quiet
<
3
:
print
(
"
%
d(
%
d):"
%
(
phase
,
phase_mod
),
end
=
" "
)
sys
.
stdout
.
flush
()
dlys
=
wlev_phase_step
(
phase
)
wlev_dqs_delays
[
phase_mod
]
=
dlys
if
quiet
<
3
:
print
(
"
%
s"
%
str
(
dlys
),
end
=
" "
)
sys
.
stdout
.
flush
()
if
quiet
<
2
:
print
()
if
quiet
<
2
:
for
i
,
d
in
enumerate
(
wlev_dqs_delays
):
if
d
:
print
(
"
%
d
%
d
%
d"
%
(
i
,
d
[
0
],
d
[
1
]))
else
:
print
(
"
%
d"
%
(
i
))
#find the largest positive step of cmda_marg_dly while cyclically increasing phase
numValid
=
0
for
i
,
d
in
enumerate
(
wlev_dqs_delays
):
if
d
:
numValid
+=
1
if
numValid
<
2
:
raise
Exception
(
"Too few points with DQS output delay in write levelling mode:
%
d"
%
numValid
)
firstIndex
=
[
None
]
*
2
for
lane
in
range
(
2
):
maxPosSep
=
0
for
i
,
d
in
enumerate
(
wlev_dqs_delays
):
if
d
>
0
:
for
j
in
range
(
1
,
numPhaseSteps
):
d1
=
wlev_dqs_delays
[(
i
+
j
)
%
numPhaseSteps
]
if
d1
:
# valid data
if
(
d1
[
lane
]
-
d
[
lane
])
>
maxPosSep
:
maxPosSep
=
d1
[
lane
]
-
d
[
lane
]
firstIndex
[
lane
]
=
(
i
+
j
)
%
numPhaseSteps
break
;
#now data from firstIndex to (firstIndex+numPhaseSteps)%numPhaseSteps is ~monotonic - apply linear approximation
if
quiet
<
2
:
print
(
"firstIndices=[
%
d,
%
d]"
%
(
firstIndex
[
0
],
firstIndex
[
1
]))
#Linear approximate each lane
a
=
[
None
]
*
2
b
=
[
None
]
*
2
for
lane
in
range
(
2
):
S0
=
0
SX
=
0
SY
=
0
SX2
=
0
SXY
=
0
for
x
in
range
(
numPhaseSteps
):
dlys
=
wlev_dqs_delays
[(
x
+
firstIndex
[
lane
])
%
numPhaseSteps
]
if
dlys
:
y
=
dlys
[
lane
]
+
0.5
S0
+=
1
SX
+=
x
SY
+=
y
SX2
+=
x
*
x
SXY
+=
x
*
y
# print("x=%f, index=%d, y=%f, S0=%f, SX=%f, SY=%f, SX2=%f, SXY=%f"%(x, (x+firstIndex) % numPhaseSteps, y, S0, SX, SY, SX2, SXY))
a
[
lane
]
=
(
SXY
*
S0
-
SY
*
SX
)
/
(
SX2
*
S0
-
SX
*
SX
)
b
[
lane
]
=
(
SY
*
SX2
-
SXY
*
SX
)
/
(
SX2
*
S0
-
SX
*
SX
)
if
quiet
<
2
:
print
(
"a=[
%
f,
%
f], b=[
%
f,
%
f]"
%
(
a
[
0
],
a
[
1
],
b
[
0
],
b
[
1
]))
# fine delay corrections
fineCorr
=
[[
0.0
]
*
5
,[
0.0
]
*
5
]
# not [[0.0]*5]*2 ! - they will poin to the same top element
fineCorrN
=
[[
0
]
*
5
,[
0
]
*
5
]
# not [[0]*5]*2 !
for
lane
in
range
(
2
):
for
x
in
range
(
numPhaseSteps
):
dlys
=
wlev_dqs_delays
[(
x
+
firstIndex
[
lane
])
%
numPhaseSteps
]
if
dlys
:
y
=
dlys
[
lane
]
i
=
y
%
5
y
+=
0.5
diff
=
y
-
(
a
[
lane
]
*
x
+
b
[
lane
])
fineCorr
[
lane
][
i
]
+=
diff
fineCorrN
[
lane
][
i
]
+=
1
# print("lane,x,y,i,diff,fc,fcn= %d, %d, %f, %d, %f, %f, %d"%(lane,x,y,i,diff,fineCorr[lane][i],fineCorrN[lane][i]))
# print ("lane=%d, fineCorr=%s, fineCorrN=%s"%(lane, fineCorr[lane], fineCorrN[lane]))
for
i
in
range
(
5
):
if
fineCorrN
[
lane
][
i
]
>
0
:
fineCorr
[
lane
][
i
]
/=
fineCorrN
[
lane
][
i
]
# print ("lane=%d, fineCorr=%s, fineCorrN=%s"%(lane, fineCorr[lane], fineCorrN[lane]))
if
(
quiet
<
2
):
print
(
"fineCorr lane0 =
%
s"
%
str
(
fineCorr
[
0
]))
# Why ar they both the same?
print
(
"fineCorr lane1 =
%
s"
%
str
(
fineCorr
[
1
]))
variantStep
=
[
-
a
[
0
]
*
numPhaseSteps
,
-
a
[
1
]
*
numPhaseSteps
]
#how much b changes when moving over the full SDCLK period
if
(
quiet
<
2
):
print
(
"Delay matching the full SDCLK period = [
%
f,
%
f]"
%
(
variantStep
[
0
],
variantStep
[
1
]))
b_period
=
[
None
]
*
2
for
lane
in
range
(
2
):
b
[
lane
]
-=
a
[
lane
]
*
firstIndex
[
lane
]
# recalculate b for phase=0
b_period
[
lane
]
=
0
if
(
quiet
<
2
):
print
(
"a[
%
d]=
%
f, b[
%
d]=
%
f"
%
(
lane
,
a
[
lane
],
lane
,
b
[
lane
]))
#Make b fit into 0..max_lin_dly range
while
(
b
[
lane
]
>
max_lin_dly
):
b
[
lane
]
-=
variantStep
[
lane
]
b_period
[
lane
]
-=
1
while
(
b
[
lane
]
<
0
):
b
[
lane
]
+=
variantStep
[
lane
]
# can end up having b>max_lin_dly - if the phase adjust by delay is lower than full period
b_period
[
lane
]
+=
1
if
(
quiet
<
2
):
print
(
"a[0]=
%
f, b[0]=
%
f, b_period[0]=
%
d"
%
(
a
[
0
],
b
[
0
],
b_period
[
0
]))
print
(
"a[1]=
%
f, b[1]=
%
f, b_period[1]=
%
d"
%
(
a
[
1
],
b
[
1
],
b_period
[
1
]))
# Find best minimal delay (with higher SDCLK frequency delay range can exceed the period and there could
# be more than one solution
bestSolPerErr
=
[[],[]]
# pair (for two lanes) of lists ot tuples, each containing(best cmda_odelay,number of added periods,error)
max_dly_err
=
[
abs
(
a
[
0
])
*
max_phase_err
*
numPhaseSteps
,
# maximal allowed delay error (in 160-step scale)
abs
(
a
[
1
])
*
max_phase_err
*
numPhaseSteps
]
if
(
quiet
<
2
):
print
(
"Max dly error=
%
s"
%
(
str
(
max_dly_err
)))
for
lane
in
range
(
2
):
for
phase
in
range
(
numPhaseSteps
):
periods
=
0
# b_period[lane]
y
=
a
[
lane
]
*
phase
+
b
[
lane
]
y0
=
y
#find the lowest approximate solution to consider
#find the lowest approximate solution to consider
if y0 > (-max_dly_err):
if
y0
>
(
-
max_dly_err
[
lane
]):
while (y0 >= (variantStep-max_dly_err)):
while
(
y0
>=
(
variantStep
[
lane
]
-
max_dly_err
[
lane
])):
y0 -= variantStep
y0
-=
variantStep
[
lane
]
periods
-=
1
else
:
else
:
while (y0<(-max_dly_err)):
while
(
y0
<
(
-
max_dly_err
[
lane
])):
y0 += variantStep
y0
+=
variantStep
[
lane
]
while y0 <= (159+max_dly_err): #May be never when using higher delay reference clock (300MHz) with the same SDCLK
periods
+=
1
#try delays in the range of +/- 5 steps from "ideal" and find the lowest error
dly_min
=
max
(
0
,
int
(
y0
-
4.5
))
dly_min
=
max
(
0
,
int
(
y0
-
4.5
))
dly_max= max(159,int(y0+5.5))
dly_max
=
min
(
max_lin_dly
,
int
(
y0
+
5.5
))
dly_to_try
=
[]
for
d
in
range
(
dly_min
,
dly_max
+
1
):
dly_to_try
.
append
((
d
,
periods
))
if
(
y0
<
0
):
# add a second range to try (higher delay values
y0
+=
variantStep
[
lane
]
periods
+=
1
dly_min
=
max
(
0
,
int
(
y0
-
4.5
))
dly_max
=
min
(
max_lin_dly
,
int
(
y0
+
5.5
))
for
d
in
range
(
dly_min
,
dly_max
+
1
):
dly_to_try
.
append
((
d
,
periods
))
bestDly
=
None
bestDly
=
None
bestDiff
=
None
bestDiff
=
None
for dly in range(dly_min,dly_max+1):
bestPeriods
=
None
actualDelay=dly-fineCorr[dly
% 5
] # delay corrected for the non-uniform 160-scale
for
dp
in
dly_to_try
:
diff=actualDelay-y0
actualDelay
=
dp
[
0
]
-
fineCorr
[
lane
][
dp
[
0
]
%
5
]
# delay corrected for the non-uniform 160-scale
diff
=
actualDelay
-
(
y
+
variantStep
[
lane
]
*
dp
[
1
])
# dp[1] - number of added/removed full periods
if
(
bestDiff
is
None
)
or
(
abs
(
bestDiff
)
>
abs
(
diff
)):
if
(
bestDiff
is
None
)
or
(
abs
(
bestDiff
)
>
abs
(
diff
)):
bestDiff
=
diff
bestDiff
=
diff
bestDly = dly
bestDly
=
dp
[
0
]
bestPeriods
=
dp
[
1
]
phase_rslt
=
()
#Default, if nothing was found
if
not
bestDiff
is
None
:
if
not
bestDiff
is
None
:
branchIndex=int(((y0-(a*x+b))/variantStep) + 0.5)
phase_rslt
=
(
bestDly
,
bestPeriods
,
bestDiff
)
valid_cmda_delays[phase].append((bestDly,bestDiff,branchIndex))
if
(
quiet
<
2
):
if (minBranchIndex is None) or (branchIndex < minBranchIndex):
print
(
"
%
d:
%
d:
%
s
%
s"
%
(
lane
,
phase
,
str
(
dly_to_try
),
str
(
phase_rslt
))
)
minBranchIndex = branchIndex
if (maxBranchIndex is None) or (branchIndex > maxBranchIndex):
bestSolPerErr
[
lane
]
.
append
(
phase_rslt
)
maxBranchIndex = branchIndex
if
(
quiet
<
2
):
y0+=variantStep
for
i
in
range
(
numPhaseSteps
):
# enumerate(cmda_marg_dly):
#print for plotting - find min/max for
d
=
wlev_dqs_delays
[
i
]
for phase in range(numPhaseSteps):
if
d
:
x=phase-firstIndex
print
(
"
%
d
%
d
%
d"
%
(
i
,
d
[
0
],
d
[
1
]),
end
=
" "
)
y0=a*x+b
dlys={}
diffs={}
for i,v in enumerate(valid_cmda_delays[phase]):
dlys[v[2]]= v[0]
diffs[v[2]]=v[1]
print ("
%3
d:
%3
d"
%
(phase,cmda_marg_dly[phase][1]),end=" ")
for branch in range(minBranchIndex, maxBranchIndex+1):
if branch in dlys:
print("
%
d"
%
dlys[branch],end=" ")
else
:
else
:
print("",end=" ")
print
(
"
%
d X X"
%
(
i
),
end
=
" "
)
for branch in range(minBranchIndex, maxBranchIndex+1):
for
lane
in
range
(
2
):
if branch in diffs:
bspe
=
bestSolPerErr
[
lane
][
i
]
print("
%
f"
%
diffs[branch],end=" ")
if
bspe
:
print
(
"
%
d
%
d
%
f"
%
(
bspe
[
0
],
bspe
[
1
],
bspe
[
2
]),
end
=
" "
)
else
:
else
:
print("",end=" ")
print
(
"X X X"
,
end
=
" "
)
print
()
wlev_bspe
=
[[],[]]
for
lane
in
range
(
2
):
for
phase
in
range
(
numPhaseSteps
):
bspe
=
bestSolPerErr
[
lane
][
phase
]
if
bspe
:
wlev_bspe
[
lane
]
.
append
({
'ldly'
:
bspe
[
0
],
'period'
:
bspe
[
1
]
+
b_period
[
lane
],
# b_period - shift from the branch
# where phase starts from the longest cmda_odelay and goes down
'err'
:
bspe
[
2
]})
else
:
wlev_bspe
[
lane
]
.
append
({})
rdict
=
{
"wlev_dqs_odly_a"
:
a
,
#[,]
"wlev_dqs_odly_b"
:
b
,
#[,]
"wlev_dqs_period"
:
b_period
,
#
"wlev_dqs_fine_corr"
:
fineCorr
,
"wlev_dqs_bspe"
:
wlev_bspe
}
if
(
quiet
<
3
):
print
(
"
\n
write levelling DQS output delay adjustmet results:"
)
print
(
'wlev_dqs0_odly_a:
%
f'
%
(
rdict
[
'wlev_dqs_odly_a'
][
0
]))
print
(
'wlev_dqs1_odly_a:
%
f'
%
(
rdict
[
'wlev_dqs_odly_a'
][
1
]))
print
(
'wlev_dqs0_odly_b:
%
f'
%
(
rdict
[
'wlev_dqs_odly_b'
][
0
]))
print
(
'wlev_dqs1_odly_b:
%
f'
%
(
rdict
[
'wlev_dqs_odly_b'
][
1
]))
print
(
'wlev_dqs0_period:
%
d'
%
(
rdict
[
'wlev_dqs_period'
][
0
]))
print
(
'wlev_dqs1_period:
%
d'
%
(
rdict
[
'wlev_dqs_period'
][
1
]))
print
(
'wlev_dqs0_fine_corr:
%
s'
%
(
rdict
[
'wlev_dqs_fine_corr'
][
0
]))
print
(
'wlev_dqs1_fine_corr:
%
s'
%
(
rdict
[
'wlev_dqs_fine_corr'
][
1
]))
print
(
"
\n
Phase Measured_DQS0 Measured_DQS1 DQS0 PERIODS0*10 ERR0*10 DQS1 PERIODS1*10 ERR1*10"
)
for
i
in
range
(
numPhaseSteps
):
# enumerate(cmda_marg_dly):
d
=
wlev_dqs_delays
[
i
]
if
d
:
print
(
"
%
d
%
d
%
d"
%
(
i
,
d
[
0
],
d
[
1
]),
end
=
" "
)
else
:
print
(
"
%
d X X"
%
(
i
),
end
=
" "
)
for
lane
in
range
(
2
):
bspe
=
rdict
[
'wlev_dqs_bspe'
][
lane
][
i
]
# bestSolPerErr[lane][i]
if
bspe
:
print
(
"
%
d
%
d
%
f"
%
(
bspe
[
'ldly'
],
10
*
bspe
[
'period'
],
10
*
bspe
[
'err'
]),
end
=
" "
)
else
:
print
(
"X X X"
,
end
=
" "
)
print
()
self
.
adjustment_state
.
update
(
rdict
)
# print (self.adjustment_state)
return
rdict
## TODO: add 0.5 to result, split low/high bits (as done in adjust_random
"""
\ No newline at end of file
py393/x393_mcntrl_timing.py
View file @
4cf7bd61
...
@@ -222,51 +222,58 @@ class X393McntrlTiming(object):
...
@@ -222,51 +222,58 @@ class X393McntrlTiming(object):
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
DLY_SET
,
0
);
# set all delays
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
DLY_SET
,
0
);
# set all delays
def
axi_set_dqs_idelay
(
self
,
def
axi_set_dqs_idelay
(
self
,
delay
=
None
):
# input [7:0] delay;
delay
=
None
,
# input [7:0] delay;
quiet
=
1
):
"""
"""
Set all DQs input delays to the same value
Set all DQs input delays to the same value
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
if delay is None will restore default values
<quiet> reduce output
"""
"""
if
delay
is
None
:
if
delay
is
None
:
delay
=
(
vrlg
.
get_default_field
(
"DLY_LANE0_IDELAY"
,
8
),
vrlg
.
get_default_field
(
"DLY_LANE1_IDELAY"
,
8
))
delay
=
(
vrlg
.
get_default_field
(
"DLY_LANE0_IDELAY"
,
8
),
vrlg
.
get_default_field
(
"DLY_LANE1_IDELAY"
,
8
))
if
isinstance
(
delay
,(
int
,
long
)):
if
isinstance
(
delay
,(
int
,
long
)):
delay
=
(
delay
,
delay
)
delay
=
(
delay
,
delay
)
if
self
.
DEBUG_MODE
>
1
:
if
quiet
<
2
:
print
(
"SET DQS IDELAY="
+
hexMultiple
(
delay
))
# hexMultiple
print
(
"SET DQS IDELAY="
+
hexMultiple
(
delay
))
# hexMultiple
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE0_IDELAY
,
8
,
1
,
delay
[
0
],
"DLY_LANE0_IDELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE0_IDELAY
,
8
,
1
,
delay
[
0
],
"DLY_LANE0_IDELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE1_IDELAY
,
8
,
1
,
delay
[
1
],
"DLY_LANE1_IDELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE1_IDELAY
,
8
,
1
,
delay
[
1
],
"DLY_LANE1_IDELAY"
)
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
DLY_SET
,
0
);
# set all delays
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
DLY_SET
,
0
);
# set all delays
def
axi_set_dqs_odelay
(
self
,
def
axi_set_dqs_odelay
(
self
,
delay
=
None
):
# input [7:0] delay;
delay
=
None
,
# input [7:0] delay;
quiet
=
1
):
"""
"""
Set all DQs OUTput delays to the same value
Set all DQs OUTput delays to the same value
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
if delay is None will restore default values
<quiet> reduce output
"""
"""
if
delay
is
None
:
if
delay
is
None
:
delay
=
(
vrlg
.
get_default_field
(
"DLY_LANE0_ODELAY"
,
8
),
vrlg
.
get_default_field
(
"DLY_LANE1_ODELAY"
,
8
))
delay
=
(
vrlg
.
get_default_field
(
"DLY_LANE0_ODELAY"
,
8
),
vrlg
.
get_default_field
(
"DLY_LANE1_ODELAY"
,
8
))
if
isinstance
(
delay
,(
int
,
long
)):
if
isinstance
(
delay
,(
int
,
long
)):
delay
=
(
delay
,
delay
)
delay
=
(
delay
,
delay
)
if
self
.
DEBUG_MODE
>
1
:
if
quiet
<
2
:
print
(
"SET DQS ODELAY="
+
hexMultiple
(
delay
))
# hexMultiple
print
(
"SET DQS ODELAY="
+
hexMultiple
(
delay
))
# hexMultiple
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE0_ODELAY
,
8
,
1
,
delay
[
0
],
"DLY_LANE0_ODELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE0_ODELAY
,
8
,
1
,
delay
[
0
],
"DLY_LANE0_ODELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE1_ODELAY
,
8
,
1
,
delay
[
1
],
"DLY_LANE1_ODELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE1_ODELAY
,
8
,
1
,
delay
[
1
],
"DLY_LANE1_ODELAY"
)
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
DLY_SET
,
0
);
# set all delays
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
DLY_SET
,
0
);
# set all delays
def
axi_set_dm_odelay
(
self
,
def
axi_set_dm_odelay
(
self
,
delay
=
None
):
# input [7:0] delay;
delay
=
None
,
# input [7:0] delay;
quiet
=
1
):
"""
"""
Set all DM output delays to the same value
Set all DM output delays to the same value
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
if delay is None will restore default values
<quiet> reduce output
"""
"""
if
delay
is
None
:
if
delay
is
None
:
delay
=
(
vrlg
.
get_default_field
(
"DLY_LANE0_ODELAY"
,
9
),
vrlg
.
get_default_field
(
"DLY_LANE1_ODELAY"
,
9
))
delay
=
(
vrlg
.
get_default_field
(
"DLY_LANE0_ODELAY"
,
9
),
vrlg
.
get_default_field
(
"DLY_LANE1_ODELAY"
,
9
))
if
isinstance
(
delay
,(
int
,
long
)):
if
isinstance
(
delay
,(
int
,
long
)):
delay
=
(
delay
,
delay
)
delay
=
(
delay
,
delay
)
if
self
.
DEBUG_MODE
>
1
:
if
quiet
<
2
:
print
(
"SET DQM IDELAY="
+
hexMultiple
(
delay
))
# hexMultiple
print
(
"SET DQM IDELAY="
+
hexMultiple
(
delay
))
# hexMultiple
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE0_ODELAY
,
9
,
1
,
delay
[
0
],
"DLY_LANE0_ODELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE0_ODELAY
,
9
,
1
,
delay
[
0
],
"DLY_LANE0_ODELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE1_ODELAY
,
9
,
1
,
delay
[
1
],
"DLY_LANE1_ODELAY"
)
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE1_ODELAY
,
9
,
1
,
delay
[
1
],
"DLY_LANE1_ODELAY"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment