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
a7004146
Commit
a7004146
authored
Apr 04, 2015
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
some cleanup, added command that runs full set of measurement/adjustment functions
parent
4a9e4b55
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
805 additions
and
231 deletions
+805
-231
get_test_dq_dqs_data.py
py393/get_test_dq_dqs_data.py
+23
-1
x393_lma.py
py393/x393_lma.py
+38
-63
x393_mcntrl_adjust.py
py393/x393_mcntrl_adjust.py
+718
-157
x393_mcntrl_buffers.py
py393/x393_mcntrl_buffers.py
+11
-8
x393_mcntrl_timing.py
py393/x393_mcntrl_timing.py
+12
-0
x393_pio_sequences.py
py393/x393_pio_sequences.py
+3
-2
No files found.
py393/get_test_dq_dqs_data.py
View file @
a7004146
...
...
@@ -914,7 +914,8 @@ def get_wlev_data():
{
'ldly'
:
68
,
'period'
:
0
,
'err'
:
0.032233890055650249
},
{
'ldly'
:
67
,
'period'
:
0
,
'err'
:
0.45716638330499393
},
{
'ldly'
:
64
,
'period'
:
0
,
'err'
:
-
0.23339414538470038
},
{
'ldly'
:
63
,
'period'
:
0
,
'err'
:
-
0.42992632596594405
},
{
'ldly'
:
62
,
'period'
:
0
,
'err'
:
-
0.004993832716600366
},
{
'ldly'
:
59
,
'period'
:
0
,
'err'
:
-
0.69555436140630178
},
{
'ldly'
:
59
,
'period'
:
0
,
'err'
:
0.81705889991982161
},
{
'ldly'
:
56
,
'period'
:
0
,
'err'
:
-
0.030778077807781301
},
{
'ldly'
:
57
,
'period'
:
0
,
'err'
:
1.0454592125879216
},
{
'ldly'
:
54
,
'period'
:
0
,
'err'
:
0.35489868389822021
}],
[{
'ldly'
:
50
,
'period'
:
-
1
,
'err'
:
0.90683082593974973
},
{
'ldly'
:
49
,
'period'
:
-
1
,
'err'
:
0.52528052805281789
},
{
'ldly'
:
54
,
'period'
:
0
,
'err'
:
0.35489868389822021
}],
[{
'ldly'
:
50
,
'period'
:
-
1
,
'err'
:
0.90683082593974973
},
{
'ldly'
:
49
,
'period'
:
-
1
,
'err'
:
0.52528052805281789
},
{
'ldly'
:
46
,
'period'
:
-
1
,
'err'
:
-
0.10166902404525047
},
{
'ldly'
:
45
,
'period'
:
-
1
,
'err'
:
0.38526466932408709
},
{
'ldly'
:
44
,
'period'
:
-
1
,
'err'
:
0.0037143714371552505
},
{
'ldly'
:
42
,
'period'
:
-
1
,
'err'
:
0.1118091809181081
},
{
'ldly'
:
40
,
'period'
:
-
1
,
'err'
:
-
0.13630148729157554
},
{
'ldly'
:
39
,
'period'
:
-
1
,
'err'
:
-
0.51785178517850738
},
{
'ldly'
:
37
,
'period'
:
-
1
,
'err'
:
-
0.40975697569755454
},
{
'ldly'
:
36
,
'period'
:
-
1
,
'err'
:
0.34800994385153672
},
{
'ldly'
:
35
,
'period'
:
-
1
,
'err'
:
0.83494363722087428
},
...
...
@@ -1025,6 +1026,27 @@ def get_dqsi_vs_phase(variant):
[(
None
,
None
,
'e'
),
(
150
,
0.75
,
'e'
)],
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
[(
20
,
None
,
'n'
),
(
7
,
-
0.25
,
'n'
)],
[(
29
,
0.25
,
'n'
),
(
5
,
None
,
'n'
)],
[(
25
,
None
,
'n'
),
(
10
,
0.75
,
'n'
)],
[(
25
,
None
,
'n'
),
(
14
,
0.25
,
'n'
)],
[(
31
,
0.75
,
'n'
),
(
10
,
None
,
'n'
)],
[(
34
,
0.0
,
'n'
),
(
16
,
-
0.25
,
'n'
)],
[(
30
,
None
,
'n'
),
(
17
,
0.0
,
'n'
)],
[(
30
,
None
,
'n'
),
(
19
,
-
0.75
,
'n'
)]]
elif
variant
==
1
:
return
[[(
36
,
0.5
,
'n'
),
(
15
,
None
,
'n'
)],
[(
39
,
0.25
,
'n'
),
(
22
,
0.5
,
'n'
)],
[(
35
,
None
,
'n'
),
(
24
,
0.0
,
'n'
)],
[(
35
,
None
,
'n'
),
(
20
,
None
,
'n'
)],
[(
38
,
None
,
'n'
),
(
26
,
0.75
,
'n'
)],
[(
44
,
0.0
,
'n'
),
(
28
,
-
0.25
,
'n'
)],
[(
40
,
None
,
'n'
),
(
29
,
-
0.5
,
'n'
)],
[(
45
,
0.0
,
'n'
),
(
30
,
0.5
,
'n'
)],
[(
46
,
0.25
,
'n'
),
(
32
,
0.25
,
'n'
)],
[(
45
,
None
,
'n'
),
(
33
,
-
0.25
,
'n'
)],
[(
45
,
None
,
'n'
),
(
30
,
None
,
'n'
)],
[(
45
,
None
,
'n'
),
(
35
,
0.75
,
'n'
)],
[(
53
,
0.75
,
'n'
),
(
38
,
-
0.25
,
'n'
)],
[(
50
,
None
,
'n'
),
(
39
,
-
0.75
,
'n'
)],
[(
50
,
None
,
'n'
),
(
41
,
0.5
,
'n'
)],
[(
56
,
0.75
,
'n'
),
(
44
,
0.5
,
'n'
)],
[(
55
,
None
,
'n'
),
(
40
,
None
,
'n'
)],
[(
55
,
None
,
'n'
),
(
40
,
None
,
'n'
)],
[(
56
,
None
,
'n'
),
(
47
,
-
0.25
,
'n'
)],
[(
63
,
0.25
,
'n'
),
(
45
,
None
,
'n'
)],
[(
60
,
None
,
'n'
),
(
45
,
None
,
'n'
)],
[(
65
,
0.25
,
'n'
),
(
54
,
0.25
,
'n'
)],
[(
66
,
0.0
,
'n'
),
(
54
,
-
0.25
,
'n'
)],
[(
65
,
None
,
'n'
),
(
50
,
None
,
'n'
)],
[(
65
,
None
,
'n'
),
(
56
,
0.0
,
'n'
)],
[(
70
,
0.5
,
'n'
),
(
59
,
-
0.5
,
'n'
)],
[(
71
,
0.25
,
'n'
),
(
55
,
None
,
'n'
)],
[(
70
,
None
,
'n'
),
(
55
,
None
,
'n'
)],
[(
70
,
None
,
'n'
),
(
64
,
0.25
,
'n'
)],
[(
76
,
0.5
,
'n'
),
(
60
,
None
,
'n'
)],
[(
75
,
None
,
'n'
),
(
60
,
None
,
'n'
)],
[(
75
,
None
,
'n'
),
(
65
,
-
0.5
,
'n'
)],
None
,
[(
84
,
0.0
,
'n'
),
(
65
,
None
,
'n'
)],
[(
80
,
None
,
'n'
),
(
71
,
-
0.25
,
'n'
)],
[(
None
,
None
,
'n'
),
(
73
,
-
0.75
,
'n'
)],
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
[(
127
,
0.5
,
'e'
),
(
116
,
-
0.75
,
'e'
)],
[(
125
,
None
,
'e'
),
(
115
,
None
,
'e'
)],
[(
125
,
None
,
'e'
),
(
120
,
0.5
,
'e'
)],
[(
130
,
0.5
,
'e'
),
(
123
,
0.0
,
'e'
)],
[(
131
,
0.0
,
'e'
),
(
119
,
None
,
'e'
)],
[(
134
,
0.0
,
'e'
),
(
120
,
None
,
'e'
)],
[(
130
,
None
,
'e'
),
(
120
,
None
,
'e'
)],
[(
131
,
None
,
'e'
),
(
127
,
0.0
,
'e'
)],
[(
135
,
None
,
'e'
),
(
124
,
None
,
'e'
)],
[(
135
,
None
,
'e'
),
(
125
,
None
,
'e'
)],
[(
140
,
0.25
,
'e'
),
(
131
,
0.25
,
'e'
)],
[(
141
,
0.25
,
'e'
),
(
134
,
0.0
,
'e'
)],
[(
140
,
None
,
'e'
),
(
130
,
None
,
'e'
)],
[(
140
,
None
,
'e'
),
(
130
,
None
,
'e'
)],
[(
140
,
None
,
'e'
),
(
135
,
-
0.5
,
'e'
)],
[(
149
,
0.25
,
'e'
),
(
135
,
None
,
'e'
)],
[(
145
,
None
,
'e'
),
(
135
,
None
,
'e'
)],
[(
145
,
None
,
'e'
),
(
135
,
None
,
'e'
)],
[(
151
,
0.75
,
'e'
),
(
141
,
0.0
,
'e'
)],
[(
150
,
None
,
'e'
),
(
140
,
None
,
'e'
)],
[(
150
,
None
,
'e'
),
(
145
,
0.75
,
'e'
)],
[(
155
,
0.0
,
'e'
),
(
145
,
0.25
,
'e'
)],
[(
158
,
0.0
,
'e'
),
(
149
,
-
0.5
,
'e'
)],
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
None
,
[(
26
,
0.25
,
'n'
),
(
9
,
-
0.5
,
'n'
)],
[(
29
,
0.25
,
'n'
),
(
10
,
0.0
,
'n'
)],
[(
25
,
None
,
'n'
),
(
13
,
0.5
,
'n'
)],
[(
25
,
None
,
'n'
),
(
10
,
None
,
'n'
)],
[(
33
,
0.25
,
'n'
),
(
10
,
None
,
'n'
)],
[(
30
,
None
,
'n'
),
(
17
,
-
0.25
,
'n'
)],
[(
30
,
None
,
'n'
),
(
18
,
-
0.5
,
'n'
)]]
def
get_dqsi_vs_phase_prim_steps
(
variant
=
0
):
# 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)
...
...
py393/x393_lma.py
View file @
a7004146
...
...
@@ -311,9 +311,12 @@ class X393LMA(object):
except
:
pass
if
not
numBits
:
# print("showENLresults(): No no-None data provided")
# print("DQvDQS=",DQvDQS)
# return
raise
Exception
(
"showENLresults(): No no-None data provided"
)
numLanes
=
numBits
//
8
# print ("numBits=%d"%(numBits))
# print ("
****
numBits=%d"%(numBits))
enl_list
=
[]
for
k
in
rslt_names
:
if
DQvDQS
[
k
]:
...
...
@@ -1036,7 +1039,7 @@ class X393LMA(object):
if
quiet
<
2
:
print
(
"parameters=
%
s"
%
(
str
(
parameters
)))
self
.
normalizeParameters
(
parameters
)
#isMask=False)
if
quiet
<
4
:
if
quiet
<
3
:
print
(
"normalized parameters=
%
s"
%
(
str
(
parameters
)))
"""
both ways work:
...
...
@@ -1069,12 +1072,13 @@ class X393LMA(object):
print
(
"
\n
fx (filtered):"
)
self
.
showYOrVector
(
ywp
,
True
,
fx
)
if
quiet
<
4
:
if
quiet
<
5
:
arms
=
self
.
getParAvgRMS
(
parameters
,
ywp
,
primary_set
,
# prima
quiet
+
1
)
print
(
"average(fx)=
%
fps, rms(fx)=
%
fps"
%
(
arms
[
'avg'
],
arms
[
'rms'
]))
print
(
"Before LMA (DQ lane
%
d): average(fx)=
%
fps, rms(fx)=
%
fps"
%
(
lane
,
arms
[
'avg'
],
arms
[
'rms'
]))
if
quiet
<
3
:
jByJT
=
np
.
dot
(
fxj
[
'jacob'
],
np
.
transpose
(
fxj
[
'jacob'
]))
print
(
"
\n
jByJT:"
)
...
...
@@ -1092,7 +1096,7 @@ class X393LMA(object):
self
.
lambdas
,
self
.
finalDiffRMS
,
quiet
)
if
(
quiet
<
4
)
or
((
quiet
<
5
)
and
finished
):
if
(
quiet
<
5
)
or
((
quiet
<
6
)
and
finished
):
arms
=
self
.
getParAvgRMS
(
parameters
,
ywp
,
primary_set
,
# prima
...
...
@@ -1126,36 +1130,6 @@ class X393LMA(object):
DQvDQS
=
DQvDQS_withErr
[
'dqForDqs'
]
DQvDQS_ERR
=
DQvDQS_withErr
[
'maxErrDqs'
]
if
quiet
<
4
:
# print ("DQvDQS_ERR=",DQvDQS_ERR)
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
=
" "
)
for
enl
in
enl_list
:
print
(
"
%
s-Err"
%
((
'E'
,
'N'
,
'L'
)[
enl
]),
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
=
" "
)
for
enl
in
enl_list
:
if
DQvDQS_ERR
[
enl
][
dly
]
is
None
:
print
(
"? "
,
end
=
""
)
else
:
print
(
"
%
f"
%
(
DQvDQS_ERR
[
enl
][
dly
]),
end
=
" "
)
print
()
rslt
=
{}
rslt_names
=
(
"early"
,
"nominal"
,
"late"
)
for
i
,
d
in
enumerate
(
DQvDQS
):
...
...
@@ -1165,15 +1139,13 @@ class X393LMA(object):
rslt
[
'maxErrDqs'
]
=
{}
# {enl}[dly]
for
i
,
d
in
enumerate
(
DQvDQS_ERR
):
rslt
[
'maxErrDqs'
][
rslt_names
[
i
]]
=
d
if
quiet
<
4
:
if
quiet
<
3
:
self
.
showDQDQSValues
(
parameters
)
# print ("DQvDQS_ERR=",DQvDQS_ERR)
# print ("rslt['maxErrDqs']=",rslt['maxErrDqs'])
if
quiet
<
3
:
print
(
"*** quiet="
,
quiet
)
self
.
showENLresults
(
rslt
)
# here DQvDQS already contain the needed data
return
rslt
# return DQvDQS
# Returns 3-element dictionary of ('early','nominal','late'), each being None or a 160-element list,
# each element being either None, or a list of 3 best DQ delay values for the DQS delay (some mey be None too)
def
getBestDQforDQS
(
self
,
...
...
@@ -1204,7 +1176,8 @@ class X393LMA(object):
asym_err
=
[]
for
i
in
range
(
8
):
asym_err
.
append
(
0.25
*
(
abs
(
tDQSHL
)
+
abs
(
tDQHL
[
i
])))
print
(
"asym_err="
,
asym_err
)
if
quiet
<
3
:
print
(
"asym_err="
,
asym_err
)
dqForDqs
=
[]
maxErrDqs
=
[]
for
enl
in
(
0
,
1
,
2
):
...
...
@@ -1617,15 +1590,13 @@ class X393LMA(object):
lane
,
# byte lane
bin_size_ps
,
clk_period
,
# phase_step, # ~22ps
# dly_step_ds,
# primary_set,
dqsi_dqi_parameters
,
data_set
,
compare_prim_steps
,
scale_w
,
numPhaseSteps
,
quiet
=
1
):
dqsi_dqi_parameters
,
data_set
,
compare_prim_steps
,
scale_w
,
numPhaseSteps
,
quiet
=
1
):
# print("++++++lma_fit_dqsi_phase(), quiet=",quiet)
def
show_input_data
(
filtered
):
print
((
'unfiltered'
,
'filtered'
)[
filtered
])
for
phase
,
d
in
enumerate
(
data_set
):
...
...
@@ -1668,7 +1639,8 @@ class X393LMA(object):
SX
+=
binArr
[
i
]
*
i
if
S0
>
0
:
SX
/=
S0
print
(
"SX="
,
SX
)
if
quiet
<
3
:
print
(
"SX="
,
SX
)
return
minVal
+
bin_size_ps
*
(
SX
+
0.5
)
# ps
if
not
isinstance
(
lane
,(
int
,
long
)):
# ignore content, process both lanes
...
...
@@ -1686,7 +1658,7 @@ class X393LMA(object):
compare_prim_steps
,
scale_w
,
numPhaseSteps
,
quiet
=
1
)
quiet
)
for
name
in
rslt_names
:
rslt
[
name
]
.
append
(
rslt_lane
[
name
])
if
quiet
<
3
:
...
...
@@ -1713,8 +1685,9 @@ class X393LMA(object):
dbg_tSDQS
=
(
dqsi_dqi_parameters
[
0
][
'tSDQS'
],
dqsi_dqi_parameters
[
1
][
'tSDQS'
])
halfStep
=
0.5
*
(
1
,
compare_prim_steps
)[
compare_prim_steps
]
#phase_step/tSDQS
print
(
phase_step
,
dbg_tSDQS
)
# print("lma_fit_dqsi_phase(): quiet=",quiet
)
if
quiet
<
2
:
print
(
phase_step
,
dbg_tSDQS
)
for
filtered
in
range
(
2
):
show_input_data
(
filtered
)
...
...
@@ -1723,12 +1696,14 @@ class X393LMA(object):
minVal
=
-
clk_period
num_bins
=
int
((
maxVal
-
minVal
)
/
bin_size_ps
)
+
1
binArr
=
[
0
]
*
num_bins
print
(
"minVal="
,
minVal
)
print
(
"maxVal="
,
maxVal
)
print
(
"num_bins="
,
num_bins
)
if
quiet
<
2
:
print
(
"minVal="
,
minVal
)
print
(
"maxVal="
,
maxVal
)
print
(
"num_bins="
,
num_bins
)
#find main max
dly_max0
=
get_shift_by_hist
()
# delay in ps, corresponding to largest maximum
print
(
"max0=
%
f, (
%
f)"
%
(
dly_max0
,
dly_max0
/
tSDQS
))
if
quiet
<
2
:
print
(
"max0=
%
f, (
%
f)"
%
(
dly_max0
,
dly_max0
/
tSDQS
))
periods
=
[
None
]
*
len
(
data_set
)
for
phase
,
d
in
enumerate
(
data_set
):
if
not
d
is
None
:
...
...
@@ -1751,19 +1726,19 @@ class X393LMA(object):
dl
=
d
[
lane
]
if
(
not
dl
is
None
)
and
(
not
dl
[
0
]
is
None
):
dly
=
dl
[
0
]
w
[
i
]
=
1.0
w
[
phase
]
=
1.0
if
dl
[
1
]
is
None
:
dly
+=
halfStep
w
[
i
]
=
scale_w
w
[
phase
]
=
scale_w
d
=
dly
*
tSDQS
-
periods
[
phase
]
*
clk_period
-
tFDQS
[
dl
[
0
]
%
FINE_STEPS
]
y
=
d
-
phase
*
phase_step
S0
+=
w
[
i
]
SY
+=
w
[
i
]
*
y
S0
+=
w
[
phase
]
SY
+=
w
[
phase
]
*
y
if
S0
>
0.0
:
SY
/=
S0
print
(
"shift="
,
SY
,
" ps"
)
if
quiet
<
2
:
print
(
"shift="
,
SY
,
" ps"
)
for
phase
,
d
in
enumerate
(
data_set
):
print
(
"
%
d"
%
(
phase
),
end
=
" "
)
if
not
d
is
None
:
...
...
py393/x393_mcntrl_adjust.py
View file @
a7004146
...
...
@@ -48,7 +48,7 @@ from verilog_utils import checkIntArgs,smooth2d
import
get_test_dq_dqs_data
# temporary to test processing
import
x393_lma
import
time
#import vrlg
NUM_FINE_STEPS
=
5
NUM_DLY_STEPS
=
NUM_FINE_STEPS
*
32
# =160
...
...
@@ -211,7 +211,7 @@ class X393McntrlAdjust(object):
def
set_phase_with_refresh
(
self
,
# check result for not None
phase
,
quiet
=
2
):
quiet
=
1
):
"""
Set specified phase and matching cmda_odelay while temporarily turning off refresh
@param phase phase to set, signed short
...
...
@@ -231,7 +231,170 @@ class X393McntrlAdjust(object):
self
.
x393_mcntrl_timing
.
axi_set_cmda_odelay
(
self
.
combine_delay
(
cmda_odly_lin
),
quiet
=
quiet
)
self
.
x393_axi_tasks
.
enable_refresh
(
1
)
return
cmda_odly_lin
def
set_phase_delays
(
self
,
phase
,
inp_period
=
'A'
,
out_period
=
'A'
,
refresh
=
True
,
quiet
=
1
):
"""
Set clock phase and all I/O delays optimal for this phase
@param phase value to set
@param inp_period - period branch for DQ inputs: E<arly>, N<ominal>, L<ate> or A<ny>
@param out_period - period branch for DQ outputs: E<arly>, N<ominal>, L<ate> or A<ny>
@param refresh - turn refresh OFF before and ON after changing the delays and phase
@param quiet - reduce output
@return True on success, False on invalid phase
"""
rslt_names
=
(
"early"
,
"nominal"
,
"late"
)
enl_in
=
None
enl_out
=
None
enl_in_used
=
None
enl_out_used
=
None
try
:
inp
=
str
(
inp_period
)[
0
]
.
upper
()
except
:
print
(
"Invalid parameter <inp_period>=
%
s"
%
(
str
(
inp_period
)))
return
False
try
:
outp
=
str
(
out_period
)[
0
]
.
upper
()
except
:
print
(
"Invalid parameter <out_period>=
%
s"
%
(
str
(
out_period
)))
return
False
if
inp
==
'A'
:
enl_in
=
rslt_names
else
:
for
k
in
rslt_names
:
if
inp
==
k
[
0
]
.
upper
():
enl_in
=
(
k
,)
break
else
:
print
(
"Unrecognized parameter <inp_period>=
%
s"
%
(
str
(
inp_period
)))
return
False
if
outp
==
'A'
:
enl_out
=
rslt_names
else
:
for
k
in
rslt_names
:
if
outp
==
k
[
0
]
.
upper
():
enl_out
=
(
k
,)
break
else
:
print
(
"Unrecognized parameter <out_period>=
%
s"
%
(
str
(
out_period
)))
return
False
dly_steps
=
self
.
x393_mcntrl_timing
.
get_dly_steps
()
numPhaseSteps
=
int
(
dly_steps
[
'SDCLK_PERIOD'
]
/
dly_steps
[
'PHASE_STEP'
]
+
0.5
)
phase
=
phase
%
numPhaseSteps
# valid for negative also, numPhaseSteps should be <=128 (now it is 112)
try
:
delays_phase
=
self
.
adjustment_state
[
'delays_phase'
]
except
:
print
(
"Delays for phases (self.adjustment_state['delays_phase']) are not set, running 'get_delays_vs_phase' command "
)
try
:
delays_phase
=
self
.
get_delays_vs_phase
(
filter_dqo
=
2
,
filter_dqi
=
2
,
filter_dqso
=
2
,
filter_dqsi
=
2
,
filter_cmda
=
2
,
keep_all
=
False
,
set_table
=
True
,
quiet
=
quiet
+
2
)
self
.
adjustment_state
[
'delays_phase'
]
=
delays_phase
except
:
print
(
"Failed to execute get_'delays_vs_phase' command"
)
return
False
try
:
delays
=
delays_phase
[
phase
]
except
:
print
(
"No valid delay data for phase
%
d is available"
%
(
phase
))
return
False
try
:
cmda_odly
=
delays
[
'cmda'
]
except
:
print
(
"No valid CMDA output delay data for phase
%
d is available, it is required"
%
(
phase
))
return
False
try
:
dqs_idelays
=
delays
[
'dqsi'
]
except
:
dqs_idelays
=
None
if
quiet
<
2
:
print
(
"No valid DQS input delay data for phase
%
d is available, it will not be set"
%
(
phase
))
try
:
dqs_odelays
=
delays
[
'dqso'
]
except
:
dqs_odelays
=
None
if
quiet
<
2
:
print
(
"No valid DQS output delay data for phase
%
d is available, it will not be set"
%
(
phase
))
for
k
in
enl_in
:
try
:
dq_idelays
=
delays
[
'dqi'
][
k
]
enl_in_used
=
k
break
except
:
pass
else
:
dq_idelays
=
None
if
quiet
<
2
:
print
(
"No valid DQ input delay data for phase
%
d (period(s)=
%
s) is available, it will not be set"
%
(
phase
,
str
(
enl_in
)))
for
k
in
enl_out
:
try
:
dq_odelays
=
delays
[
'dqo'
][
k
]
enl_out_used
=
k
break
except
:
pass
else
:
dq_odelays
=
None
if
quiet
<
2
:
print
(
"No valid DQ output delay data for phase
%
d (period(s)=
%
s) is available, it will not be set"
%
(
phase
,
str
(
enl_out
)))
if
quiet
<
2
:
print
(
"Going to set:"
)
print
(
"phase="
,
phase
)
print
(
'cmda_odly='
,
cmda_odly
)
print
(
'dqs_idelays='
,
dqs_idelays
)
print
(
'dqs_odelays='
,
dqs_odelays
)
print
(
'dq_idelays='
,
dq_idelays
,
' ('
,
enl_in_used
,
')'
)
print
(
'dq_odelays='
,
dq_odelays
,
' ('
,
enl_out_used
,
')'
)
print
(
'Memory refresh will
%
sbe controlled'
%
((
'NOT '
,
''
)[
refresh
]))
if
refresh
:
self
.
x393_axi_tasks
.
enable_refresh
(
0
)
self
.
x393_mcntrl_timing
.
axi_set_phase
(
phase
,
quiet
=
quiet
)
self
.
x393_mcntrl_timing
.
axi_set_cmda_odelay
(
self
.
combine_delay
(
cmda_odly
),
quiet
=
quiet
)
if
refresh
:
self
.
x393_axi_tasks
.
enable_refresh
(
1
)
if
not
dqs_idelays
is
None
:
self
.
x393_mcntrl_timing
.
axi_set_dqs_idelay
(
self
.
combine_delay
(
dqs_idelays
),
quiet
=
quiet
)
if
not
dq_idelays
is
None
:
self
.
x393_mcntrl_timing
.
axi_set_dq_idelay
(
self
.
combine_delay
(
dq_idelays
),
quiet
=
quiet
)
if
not
dqs_odelays
is
None
:
self
.
x393_mcntrl_timing
.
axi_set_dqs_odelay
(
self
.
combine_delay
(
dqs_odelays
),
quiet
=
quiet
)
if
not
dq_odelays
is
None
:
self
.
x393_mcntrl_timing
.
axi_set_dq_odelay
(
self
.
combine_delay
(
dq_odelays
),
quiet
=
quiet
)
if
refresh
:
self
.
x393_axi_tasks
.
enable_refresh
(
1
)
return
True
"""
{
'dqsi':[110, 100]
'dqo':{'nominal': [95, 94, 99, 93, 99, 95, 94, 94, 93, 94, 100, 94, 93, 93, 90, 92]}
'dqi':{'early': [1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]}
'cmda':48
'dqso':[57, 52]
},
"""
pass
def
scan_dqs
(
self
,
low_delay
,
high_delay
,
...
...
@@ -1041,8 +1204,15 @@ class X393McntrlAdjust(object):
quiet
=
1
):
"""
<max_phase_err> maximal phase error for command and address line
as a fraction of SDCLK period to consider
Find CMDA output delay for each phase value using linear interpolation for available results
Use write levelling mode (refresh off) and A7 (that makes it write levelling or not).
Only A7 is subject to marginal timing, other signals are kept safe. But accidentally it still can hit
wrong timing - in that case memory is reset and re-initialized
Sets global parameters, including self.adjustment_state['cmda_bspe']
@param start_phase initial phase to start measuremts (non-0 only for debugging dependencies)
@param reinits higher the number - more re-inits are used (0 - only where absolutely necessary)
@param max_phase_err maximal phase error for command and address line as a fraction of SDCLK period to consider
@param quiet reduce output
"""
start_phase
&=
0xff
if
start_phase
>=
128
:
...
...
@@ -1131,6 +1301,9 @@ class X393McntrlAdjust(object):
if
quiet
<
3
:
print
(
"
%
d:"
%
(
phase
),
end
=
" "
)
sys
.
stdout
.
flush
()
elif
quiet
<
5
:
print
(
"."
,
end
=
""
)
sys
.
stdout
.
flush
()
phase_mod
=
phase
%
numPhaseSteps
dlys
=
phase_step
(
phase
,
cmda_dly
)
cmda_marg_dly
[
phase_mod
]
=
dlys
# [1] # Marginal delay or -1
...
...
@@ -1140,6 +1313,9 @@ class X393McntrlAdjust(object):
if
quiet
<
3
:
print
(
"X"
,
end
=
" "
)
sys
.
stdout
.
flush
()
elif
quiet
<
5
:
print
(
"."
,
end
=
""
)
sys
.
stdout
.
flush
()
if
reinits
>
1
:
#re-init each time failed to find delay
if
quiet
<
3
:
print
(
"
\n
Failed to find marginal odelay for A7 - re-initializing DDR3 with odelay=0x
%
x"
,
cmda_dly
)
...
...
@@ -1149,6 +1325,9 @@ class X393McntrlAdjust(object):
if
quiet
<
3
:
print
(
"
%
d"
%
dlys
[
1
],
end
=
" "
)
sys
.
stdout
.
flush
()
elif
quiet
<
5
:
print
(
"."
,
end
=
""
)
sys
.
stdout
.
flush
()
lin_dly
=
self
.
split_delay
(
cmda_dly
)
if
(
dlys
[
1
]
-
lin_dly
)
<
safe_early
:
if
(
lin_dly
>
0
):
...
...
@@ -1168,6 +1347,8 @@ class X393McntrlAdjust(object):
if
quiet
<
2
:
for
i
,
d
in
enumerate
(
cmda_marg_dly
):
print
(
"
%
d
%
d
%
d"
%
(
i
,
d
[
0
],
d
[
1
]))
elif
quiet
<
5
:
print
()
#find the largest positive step of cmda_marg_dly while cyclically increasing phase
numValid
=
0
for
i
,
d
in
enumerate
(
cmda_marg_dly
):
...
...
@@ -1469,12 +1650,18 @@ class X393McntrlAdjust(object):
if
quiet
<
3
:
print
(
"
%
d(
%
d):"
%
(
phase
,
phase_mod
),
end
=
" "
)
sys
.
stdout
.
flush
()
elif
quiet
<
5
:
print
(
"."
,
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
:
elif
quiet
<
5
:
print
(
"."
,
end
=
""
)
sys
.
stdout
.
flush
()
if
quiet
<
2
:
print
()
if
quiet
<
2
:
...
...
@@ -1483,6 +1670,8 @@ class X393McntrlAdjust(object):
print
(
"
%
d
%
d
%
d"
%
(
i
,
d
[
0
],
d
[
1
]))
else
:
print
(
"
%
d"
%
(
i
))
elif
quiet
<
5
:
print
()
#find the largest positive step of cmda_marg_dly while cyclically increasing phase
numValid
=
0
...
...
@@ -1700,6 +1889,8 @@ class X393McntrlAdjust(object):
then use them to find finedelay for each of the DQS and DQ,
linear coefficients (a,b) for each DQ vs DQS and asymmetry
(late 0->1, early 1->0) for each of the DQ and DQS
@param quiet reduce output
"""
nrep
=
8
max_lin_dly
=
NUM_DLY_STEPS
-
1
#159
...
...
@@ -1956,8 +2147,11 @@ class X393McntrlAdjust(object):
if
quiet
<
3
:
print
(
"
%
d(0x
%
x):"
%
(
ldly
,
self
.
combine_delay
(
ldly
)),
end
=
" "
)
sys
.
stdout
.
flush
()
elif
quiet
<
5
:
print
(
"."
,
end
=
""
)
sys
.
stdout
.
flush
()
meas_data
[
ldly
]
=
patt_dqs_step
(
ldly
)
if
quiet
<
3
:
if
quiet
<
5
:
print
()
if
quiet
<
3
:
...
...
@@ -2066,12 +2260,9 @@ class X393McntrlAdjust(object):
to system-synchronous one
cmda_odelay should be already calibrated, refresh will be turned on.
Uses random/previously written pattern in one memory block (should have some varying data
@param quiet reduce output
"""
"""
TODO: write block of data: 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff, ...(dqs_odelay set by wlev)
All bits will alternate, even if the DQ_ODELAY vs DQS_ODELAY will be wrong
"""
try
:
dqi_dqsi
=
self
.
adjustment_state
[
'dqi_dqsi'
]
except
:
...
...
@@ -2133,8 +2324,34 @@ class X393McntrlAdjust(object):
if
quiet
<
2
:
print
(
"timing)=
%
s, dly_step=
%
d step180=
%
d"
%
(
str
(
timing
),
dly_step
,
step180
))
self
.
x393_pio_sequences
.
set_read_block
(
*
(
brc
+
(
nrep
+
3
,
sel
)))
# set sequence once
# def read_blk(): #return array of 16-bit words to compare for bit diffs
# pass
#prepare writing block:
wdata16
=
(
0
,
0
,
0xffff
,
0xffff
)
*
(
2
*
(
nrep
+
3
))
# Data will have o/1 transitions in every bit, even if DQ_OPDELAY to DQS_OPDELAY is not yet adjusted
wdata32
=
self
.
convert_mem16_to_w32
(
wdata16
)
self
.
x393_mcntrl_buffers
.
write_block_buf_chn
(
0
,
0
,
wdata32
,
quiet
)
# fill block memory (channel, page, number)
self
.
x393_pio_sequences
.
set_write_block
(
*
(
brc
+
(
nrep
+
3
,
0
,
sel
)))
# set sequence once
cmda_bspe
=
self
.
adjustment_state
[
'cmda_bspe'
]
wlev_dqs_bspe
=
self
.
adjustment_state
[
'wlev_dqs_bspe'
]
for
phase
in
range
(
numPhaseSteps
):
try
:
dqs_odelay
=
[
wlev_dqs_bspe
[
lane
][
phase
][
'ldly'
]
for
lane
in
range
(
len
(
wlev_dqs_bspe
))]
cmda_odelay
=
cmda_bspe
[
phase
][
'ldly'
]
if
(
not
None
in
dqs_odelay
)
and
(
not
cmda_odelay
is
None
):
break
except
:
pass
else
:
raise
Exception
(
"BUG: could not find phase that has valid cmda_odelay and dqs_odelay"
)
phase_ok
=
self
.
set_phase_with_refresh
(
# check result for not None
phase
,
quiet
)
if
not
phase_ok
:
raise
Exception
(
"BUG: Failed set_phase_with_refresh(
%
s)"
%
(
str
(
phase
)))
self
.
x393_mcntrl_timing
.
axi_set_dqs_odelay
(
self
.
combine_delay
(
dqs_odelay
),
quiet
=
quiet
)
self
.
x393_pio_sequences
.
write_block
()
#page= 0, wait_complete=1)
def
dqsi_phase_step
(
phase
):
dqsi_cache
=
[
None
]
*
NUM_DLY_STEPS
# cache for holding already measured delays. None - not measured, 0 - no data, [[]..[]]
...
...
@@ -2304,15 +2521,18 @@ class X393McntrlAdjust(object):
# body of the measure_dqs_idly_phase()
dqsi_vs_phase
=
[]
for
phase
in
range
(
numPhaseSteps
):
if
quiet
<
3
:
if
quiet
<
2
:
print
(
"====== PHASE=
%
d ======"
%
(
phase
))
elif
quiet
<
4
:
elif
quiet
<
3
:
print
(
"
%
d:"
%
(
phase
),
end
=
" "
)
sys
.
stdout
.
flush
()
elif
quiet
<
5
:
print
(
"."
,
end
=
""
)
sys
.
stdout
.
flush
()
dqsi_vs_phase
.
append
(
dqsi_phase_step
(
phase
))
if
quiet
<
4
:
if
quiet
<
3
:
print
(
"dqsi_vs_phase=
%
s"
%
(
str
(
dqsi_vs_phase
)))
print
(
"Phase DQSI0 DQSI1 diff0 diff1 branch0 branch1"
)
for
phase
,
v
in
enumerate
(
dqsi_vs_phase
):
...
...
@@ -2321,6 +2541,8 @@ class X393McntrlAdjust(object):
print
(
"
%
s
%
s
%
s
%
s
%
s
%
s"
%
(
str
(
v
[
0
][
0
]),
str
(
v
[
1
][
0
]),
str
(
v
[
0
][
1
]),
str
(
v
[
1
][
1
]),
v
[
0
][
2
],
v
[
1
][
2
]))
else
:
print
()
elif
quiet
<
5
:
print
()
self
.
adjustment_state
[
'dqsi_vs_phase'
]
=
dqsi_vs_phase
self
.
adjustment_state
[
'dqsi_vs_phase_steps'
]
=
compare_prim_steps
return
dqsi_vs_phase
...
...
@@ -2340,8 +2562,9 @@ class X393McntrlAdjust(object):
Measure 4 different transitions for each data bit (rising DQS/rising DQ, falling DQS/falling DQ,
rising DQS/falling DQ and falling DQS/rising DQ (that allows to measure duty cycles fro both
DQS and DQ lines
@param quiet reduce output
"""
self
.
load_hardcoded_data
()
# TODO: REMOVE LATER
#
self.load_hardcoded_data() # TODO: REMOVE LATER
try
:
dqi_dqsi
=
self
.
adjustment_state
[
'dqi_dqsi'
]
except
:
...
...
@@ -2361,32 +2584,6 @@ class X393McntrlAdjust(object):
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
)
"""
dqsi_valid={} #[None]*NUM_DLY_STEPS
for k,v in dqi_dqsi.items():
if v:
dqsi_valid[k]=[False]*NUM_DLY_STEPS
for dly in range(NUM_DLY_STEPS):
if v[dly]:
for d in v[dly]:
if d is None:
break
else: # All values are not None
dqsi_valid[k][dly]=True
if not dqsi_valid:
print ("No Valid DQ IDELAY vs. DQS IDELAY data is available, exiting")
return
if quiet <1:
print ('dqi_dqsi=
%
s'
%
(str(dqi_dqsi)))
print("
\n\n
")
if quiet <2:
print ('dqsi_valid=
%
s'
%
(str(dqsi_valid)))
"""
#Calculate phase for the best match for the DQS output delay (for both lanes - use average). If
# solution for different lanes point to the opposite ends of the phase range - keep previous
...
...
@@ -2781,7 +2978,7 @@ class X393McntrlAdjust(object):
if
self
.
DRY_MODE
:
return
self
.
x393_mcntrl_buffers
.
write_block_buf_chn
(
0
,
0
,
wdata32
);
# fill block memory (channel, page, number)
self
.
x393_mcntrl_buffers
.
write_block_buf_chn
(
0
,
0
,
wdata32
,
quiet
);
# fill block memory (channel, page, number)
self
.
x393_pio_sequences
.
set_write_block
(
*
(
brc
+
(
nrep
+
3
,
extraTgl
,
sel
)))
# set sequence once
self
.
x393_pio_sequences
.
set_read_block
(
*
(
brc
+
(
nrep
+
3
,
sel
)))
# set sequence once
#With the data to write being the same as pattern data, try using the same measurements as for the pattern
...
...
@@ -2794,8 +2991,11 @@ class X393McntrlAdjust(object):
if
quiet
<
3
:
print
(
"
%
d(0x
%
x):"
%
(
ldly
,
self
.
combine_delay
(
ldly
)),
end
=
" "
)
sys
.
stdout
.
flush
()
elif
quiet
<
5
:
print
(
"."
,
end
=
""
)
sys
.
stdout
.
flush
()
meas_data
[
ldly
]
=
dqs_step
(
ldly
)
if
quiet
<
3
:
if
quiet
<
5
:
print
()
if
quiet
<
3
:
...
...
@@ -2899,6 +3099,131 @@ class X393McntrlAdjust(object):
adjust_write_levelling 0 1 0 .1 3
adjust_pattern 0.125 0.1 1
'''
def
measure_all
(
self
,
tasks
=
"CWRPOZ"
,
prim_steps
=
1
,
primary_set_in
=
2
,
primary_set_out
=
2
,
quiet
=
3
):
"""
@param tasks - "C" cmda, "W' - write levelling, "R" - read levelling (DQI-DQSI), "P" - dqs input phase (DQSI-PHASE),
"O" - output timing (DQ odelay vs DQS odelay) "Z" - print results
@param prim_steps - compare measurement with current delay with one lower by 1 primary step (5 fine delay steps), 0 -
compare with one fine step lower
@param quiet reduce output
"""
max_phase_err
=
0.1
frac_step
=
0.125
# read_sel=1 # set DDR3 command in the second cycle of two (0 - during the first omne)
read_bin_size
=
5
# dealy counts
write_bin_size
=
5
# dealy counts
read_scale_w
=
0.0
# weight of the "binary" results relative to "analog"
write_scale_w
=
0.0
# weight of the "binary" results relative to "analog"
idly_phase_sel
=
1
bin_size_ps
=
50.0
read_phase_scale_w
=
0.0
prim_steps_in
=
prim_steps
prim_steps_out
=
prim_steps
# primary_set_in=2
# primary_set_out=2
write_sel
=
1
# set DDR3 command in the second cycle of two (0 - during the first omne)
task_data
=
[{
'key'
:
'C'
,
'func'
:
self
.
adjust_cmda_odelay
,
'comment'
:
'Measuring CMDA output delay for each clock phase'
,
'params'
:{
'start_phase'
:
0
,
'reinits'
:
1
,
'max_phase_err'
:
max_phase_err
,
'quiet'
:
quiet
+
1
}},
{
'key'
:
'W'
,
'func'
:
self
.
adjust_write_levelling
,
'comment'
:
'Write levelling - measuring optimal DQS output delay for each phase'
,
'params'
:{
'start_phase'
:
0
,
'reinits'
:
1
,
'invert'
:
0
,
'max_phase_err'
:
max_phase_err
,
'quiet'
:
quiet
+
1
}},
{
'key'
:
'R'
,
'func'
:
self
.
measure_pattern
,
'comment'
:
'Read levelling - measuring predefined pattern to determine DQ input delays relative to DQS ones'
,
'params'
:{
'compare_prim_steps'
:
prim_steps_in
,
'limit_step'
:
frac_step
,
'max_phase_err'
:
max_phase_err
,
'quiet'
:
quiet
+
1
}},
{
'key'
:
'R'
,
'func'
:
self
.
proc_dqi_dqsi
,
'comment'
:
'Processing read levelling results using Levenberg-Marquardt algorithm to determine delay model parameters and optimal delay values'
,
'params'
:{
'lane'
:
'All'
,
'bin_size'
:
read_bin_size
,
'primary_set'
:
primary_set_in
,
'data_set_number'
:
-
1
,
# use measured data
'scale_w'
:
read_scale_w
,
'quiet'
:
quiet
+
1
}},
{
'key'
:
'P'
,
'func'
:
self
.
measure_dqs_idly_phase
,
'comment'
:
'Measure optimal DQS input delays for clock phases (clock boundary crossing from DQS in to internal)'
,
'params'
:{
'compare_prim_steps'
:
prim_steps_in
,
'frac_step'
:
frac_step
,
'sel'
:
idly_phase_sel
,
'quiet'
:
quiet
+
1
}},
{
'key'
:
'P'
,
'func'
:
self
.
proc_dqsi_phase
,
# compare_prim_steps???
'comment'
:
'Calculate optimal DQS input delays vs. clock phase'
,
'params'
:{
'lane'
:
'All'
,
'bin_size_ps'
:
bin_size_ps
,
'data_set_number'
:
-
1
,
# use measured data
'scale_w'
:
read_phase_scale_w
,
'quiet'
:
quiet
+
1
}},
{
'key'
:
'O'
,
'func'
:
self
.
measure_dqo_dqso
,
'comment'
:
'Measure write mode output delays on DQ lines relative to DQS output delays'
,
'params'
:{
'compare_prim_steps'
:
prim_steps_out
,
'frac_step'
:
frac_step
,
'sel'
:
write_sel
,
'quiet'
:
quiet
+
1
}},
{
'key'
:
'O'
,
'func'
:
self
.
proc_dqo_dqso
,
'comment'
:
'Processing DQ output delays to DQS output data results using Levenberg-Marquardt algorithm to determine optimal delays'
,
'params'
:{
'lane'
:
'All'
,
'bin_size'
:
write_bin_size
,
'primary_set'
:
primary_set_out
,
'data_set_number'
:
-
1
,
# use measured data
'scale_w'
:
write_scale_w
,
'quiet'
:
quiet
+
1
}},
{
'key'
:
'Z'
,
'func'
:
self
.
show_all_vs_phase
,
'comment'
:
'Printing results table (delays and errors vs. phase)- all, including invalid phases'
,
'params'
:{
'keep_all'
:
True
,
'load_hardcoded'
:
False
}},
{
'key'
:
'Z'
,
'func'
:
self
.
show_all_vs_phase
,
'comment'
:
'Printing results table (delays and errors vs. phase)- only for valid clock phase values'
,
'params'
:{
'keep_all'
:
False
,
'load_hardcoded'
:
False
}},
]
start_time
=
time
.
time
()
last_task_start_time
=
start_time
for
task_item
in
task_data
:
# execute tasks in predefined sequence, if their keys are enabled through arguments (several tasks may be needed for 1 key)
if
task_item
[
'key'
]
in
tasks
.
upper
():
tim
=
time
.
time
()
if
quiet
<
5
:
print
(
"[
%.3
f/+
%.3
f]
%
s"
%
(
tim
-
start_time
,
tim
-
last_task_start_time
,
task_item
[
'comment'
]))
print
(
"
%
s("
%
(
task_item
[
'func'
]
.
__name__
),
end
=
""
)
# print ("task_item=",task_item)
# print ("task_item['params']=",task_item['params'])
for
k
,
v
in
task_item
[
'params'
]
.
items
():
print
(
"
%
s=
%
s, "
%
(
k
,
str
(
v
)),
end
=
""
)
print
(
")"
)
# TODO: print function name and used arguments
task_item
[
'func'
](
**
task_item
[
'params'
])
last_task_start_time
=
tim
tim
=
time
.
time
()
if
quiet
<
5
:
print
(
"[
%.3
f/+
%.3
f]
%
s"
%
(
tim
-
start_time
,
tim
-
last_task_start_time
,
"All Done"
))
def
load_hardcoded_data
(
self
):
"""
Debug feature - load hard-coded previously acquired/processed data
...
...
@@ -2933,6 +3258,7 @@ class X393McntrlAdjust(object):
set #2 (default) used measurement with previous primary step measurement (will not suffer from
fine range wider than on primary step)
If not number or <0 - use measured data
@param quiet reduce output
@param scale_w weight for "uncertain" values (where samples change from all 0 to all 1 in one step)
For sufficient data 0.0 is OK (and seems to work better)- only "analog" samples are considered
@return 3-element dictionary of ('early','nominal','late'), each being None or a 160-element list,
...
...
@@ -2979,18 +3305,13 @@ class X393McntrlAdjust(object):
compare_prim_steps
,
scale_w
,
quiet
)
if
quiet
<
5
:
if
quiet
<
4
:
lma
.
showENLresults
(
rslt
)
if
quiet
<
5
:
print
(
"dqi_dqsi={"
)
for
k
,
v
in
rslt
.
items
():
print
(
"'
%
s':
%
s,"
%
(
k
,
str
(
v
)))
print
(
"}"
)
self
.
adjustment_state
[
"dqi_dqsi_parameters"
]
=
rslt
.
pop
(
'parameters'
)
try
:
self
.
adjustment_state
[
"maxErrDqsi"
]
=
rslt
.
pop
(
'maxErrDqs'
)
if
quiet
<
5
:
if
quiet
<
4
:
print
(
"maxErrDqsi={"
)
for
k
,
v
in
self
.
adjustment_state
[
"maxErrDqsi"
]
.
items
():
print
(
"'
%
s':
%
s,"
%
(
k
,
str
(
v
)))
...
...
@@ -2998,6 +3319,12 @@ class X393McntrlAdjust(object):
except
:
print
(
"maxErrDqs does not exist"
)
if
quiet
<
4
:
print
(
"dqi_dqsi={"
)
for
k
,
v
in
rslt
.
items
():
print
(
"'
%
s':
%
s,"
%
(
k
,
str
(
v
)))
print
(
"}"
)
self
.
adjustment_state
[
"dqi_dqsi"
]
=
rslt
return
rslt
...
...
@@ -3006,7 +3333,6 @@ class X393McntrlAdjust(object):
bin_size_ps
=
50
,
data_set_number
=
0
,
# not number - use measured data
scale_w
=
0.1
,
# weight for "uncertain" values (where samples chane from all 0 to all 1 in one step)
quiet
=
1
):
"""
Run DQSI vs PHASE fitting for one data lane (0 or 1) using earlier acquired hard-coded data
...
...
@@ -3018,6 +3344,7 @@ class X393McntrlAdjust(object):
If not number or <0 - use measured data
@param scale_w weight for "uncertain" values (where samples change from all 0 to all 1 in one step)
For sufficient data 0.0 is OK (and seems to work better)- only "analog" samples are considered
@param quiet reduce output
@return 3-element dictionary of ('early','nominal','late'), each being None or a 160-element list,
each element being either None, or a list of 3 best DQ delay values for the DQS delay (some mey be None too)
"""
...
...
@@ -3043,19 +3370,18 @@ class X393McntrlAdjust(object):
timing
=
self
.
x393_mcntrl_timing
.
get_dly_steps
()
numPhaseSteps
=
int
(
timing
[
'SDCLK_PERIOD'
]
/
timing
[
'PHASE_STEP'
]
+
0.5
)
lma
=
x393_lma
.
X393LMA
()
# use persistent one?
# print("++++++proc_dqsi_phase(), quiet=",quiet)
dqsi_phase
=
lma
.
lma_fit_dqsi_phase
(
lane
,
# byte lane
bin_size_ps
,
1000.0
*
self
.
x393_mcntrl_timing
.
get_dly_steps
()[
'SDCLK_PERIOD'
],
# 2500.0, # clk_period,
# 1000.0*self.x393_mcntrl_timing.get_dly_steps()['PHASE_STEP'],# phase_step,
# dly_step_ds,
# primary_set,
dqsi_dqi_parameters
,
dqsi_phase_data
,
# data_set,
compare_prim_steps
,
scale_w
,
numPhaseSteps
,
quiet
=
1
)
quiet
)
self
.
adjustment_state
.
update
(
dqsi_phase
)
return
dqsi_phase
...
...
@@ -3080,6 +3406,7 @@ class X393McntrlAdjust(object):
If not number or <0 - use measured data
@param scale_w weight for "uncertain" values (where samples change from all 0 to all 1 in one step)
For sufficient data 0.0 is OK (and seems to work better)- only "analog" samples are considered
@param quiet reduce output
@return 3-element dictionary of ('early','nominal','late'), each being None or a 160-element list,
each element being either None, or a list of 3 best DQ delay values for the DQS delay (some mey be None too)
"""
...
...
@@ -3094,7 +3421,7 @@ class X393McntrlAdjust(object):
if
quiet
<
4
:
print
(
"Using measured data set"
)
try
:
compare_prim_steps
=
self
.
adjustment_state
[
"w
t
ite_prim_steps"
]
compare_prim_steps
=
self
.
adjustment_state
[
"w
r
ite_prim_steps"
]
meas_data
=
self
.
adjustment_state
[
"write_meas_data"
]
except
:
print
(
"Pattern-measured data is not available, exiting"
)
...
...
@@ -3124,18 +3451,13 @@ class X393McntrlAdjust(object):
compare_prim_steps
,
scale_w
,
quiet
)
if
quiet
<
5
:
if
quiet
<
4
:
lma
.
showENLresults
(
rslt
)
if
quiet
<
5
:
print
(
"dqi_dqsi={"
)
for
k
,
v
in
rslt
.
items
():
print
(
"'
%
s':
%
s,"
%
(
k
,
str
(
v
)))
print
(
"}"
)
self
.
adjustment_state
[
"dqi_dqsi_parameters"
]
=
rslt
.
pop
(
'parameters'
)
try
:
self
.
adjustment_state
[
"maxErrDqso"
]
=
rslt
.
pop
(
'maxErrDqs'
)
if
quiet
<
5
:
if
quiet
<
4
:
print
(
"maxErrDqso={"
)
for
k
,
v
in
self
.
adjustment_state
[
"maxErrDqso"
]
.
items
():
print
(
"'
%
s':
%
s,"
%
(
k
,
str
(
v
)))
...
...
@@ -3143,114 +3465,353 @@ class X393McntrlAdjust(object):
except
:
print
(
"maxErrDqs does not exist"
)
if
quiet
<
4
:
print
(
"dqi_dqsi={"
)
for
k
,
v
in
rslt
.
items
():
print
(
"'
%
s':
%
s,"
%
(
k
,
str
(
v
)))
print
(
"}"
)
self
.
adjustment_state
[
"dqo_dqso"
]
=
rslt
return
rslt
def
show_all_vs_phase
(
self
,
load_hardcoded
=
False
):
if
load_hardcoded
:
self
.
load_hardcoded_data
()
def
get_delays_vs_phase
(
self
,
filter_dqo
=
2
,
filter_dqi
=
2
,
filter_dqso
=
2
,
filter_dqsi
=
2
,
filter_cmda
=
2
,
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
@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
rslt_names
=
(
"early"
,
"nominal"
,
"late"
)
DQIvDQSI
=
self
.
adjustment_state
[
"dqi_dqsi"
]
DQOvDQSO
=
self
.
adjustment_state
[
"dqo_dqso"
]
cmda_bspe
=
self
.
adjustment_state
[
'cmda_bspe'
]
dqsi_phase
=
self
.
adjustment_state
[
'dqsi_phase'
]
wlev_dqs_bspe
=
self
.
adjustment_state
[
'wlev_dqs_bspe'
]
numBits
=
0
for
n
in
DQIvDQSI
:
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
if
quiet
<
1
:
print
(
"halfDlyRange="
,
halfDlyRange
)
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
:
for
d
in
DQIvDQSI
[
n
]:
cmda_bspe
=
self
.
adjustment_state
[
'cmda_bspe'
]
except
:
print
(
'Data for filter_cmda is not available (self.adjustment_state["cmda_bspe"]'
)
filter_cmda
=
0
for
phase
in
range
(
numPhaseSteps
):
delays_phase
.
append
({})
if
filter_cmda
:
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'
]
=
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'
]
=
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'
]
=
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'
]
=
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'
]
=
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
):
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_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'
]
=
dqi_options
elif
not
keep_all
:
delays_phase
[
phase
]
=
None
continue
# next phase
"""
delays_phase[phase]['in']=k # found solution
delays_phase[phase]['dqi']=dqi
break
else:
delays_phase[phase]=None # phase for at least one of the DQSI is invalid
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_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'
]
=
dqo_options
elif
not
keep_all
:
delays_phase
[
phase
]
=
None
continue
# next phase
"""
delays_phase[phase]['out']=k # found solution
delays_phase[phase]['dqo']=dqo
break
else:
delays_phase[phase]=None # phase for at least one of the DQSI is invalid
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
(
d
)
numBits
=
len
(
phase_data
[
"dqo"
]
.
values
()[
0
]
)
break
except
:
pass
break
numLanes
=
numBits
//
8
try
:
maxErrDqsi
=
self
.
adjustment_state
[
"maxErrDqsi"
]
except
:
pass
if
not
numBits
:
raise
Exception
(
"showENLresults(): No no-None data provided"
)
numLanes
=
numBits
//
8
enl_list_in
=
[]
for
k
in
rslt_names
:
if
DQIvDQSI
[
k
]:
enl_list_in
.
append
(
k
)
enl_list_out
=
[]
for
k
in
rslt_names
:
if
DQOvDQSO
[
k
]:
enl_list_out
.
append
(
k
)
timing
=
self
.
x393_mcntrl_timing
.
get_dly_steps
()
numPhaseSteps
=
int
(
timing
[
'SDCLK_PERIOD'
]
/
timing
[
'PHASE_STEP'
]
+
0.5
)
print
(
"Phase CMDA"
,
end
=
" "
)
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
=
" "
)
#TODO: add DQ%do
for
k
in
enl_list_out
:
for
b
in
range
(
numBits
):
print
(
"
%
s-DQ
%
do"
%
(
k
.
upper
()[
0
],
b
),
end
=
" "
)
print
()
for
phase
in
range
(
numPhaseSteps
):
print
(
"
%
d"
%
(
phase
),
end
=
" "
)
#CMDA_ODEALY
if
not
cmda_bspe
[
phase
][
'ldly'
]
is
None
:
print
(
"
%
d"
%
(
cmda_bspe
[
phase
][
'ldly'
]),
end
=
" "
)
else
:
print
(
"?"
,
end
=
" "
)
#DQS_IDEALY
# print ('\n\ndqsi_phase=',dqsi_phase)
maxErrDqsi
=
None
try
:
maxErrDqso
=
self
.
adjustment_state
[
"maxErrDqso"
]
except
:
maxErrDqso
=
None
#print header
print
(
"Phase CMDA"
,
end
=
" "
)
for
lane
in
range
(
numLanes
):
if
not
dqsi_phase
[
lane
][
phase
]
is
None
:
print
(
"
%
d"
%
(
dqsi_phase
[
lane
][
phase
]),
end
=
" "
)
else
:
print
(
"?"
,
end
=
" "
)
#DQ_IDELAY, with half/clock variants
print
(
"DQS
%
di"
%
(
lane
),
end
=
" "
)
for
k
in
enl_list_in
:
for
b
in
range
(
numBits
):
lane
=
b
//
8
dqs_dly
=
dqsi_phase
[
lane
][
phase
]
valid
=
not
dqs_dly
is
None
valid
=
valid
and
not
DQIvDQSI
[
k
]
is
None
valid
=
valid
and
not
DQIvDQSI
[
k
][
dqs_dly
]
is
None
valid
=
valid
and
not
DQIvDQSI
[
k
][
dqs_dly
][
b
]
is
None
if
valid
:
print
(
"
%
d"
%
(
DQIvDQSI
[
k
][
dqs_dly
][
b
]),
end
=
" "
)
else
:
print
(
"?"
,
end
=
" "
)
#DQS_ODELAY
print
(
"
%
s-DQ
%
di"
%
(
k
.
upper
()[
0
],
b
),
end
=
" "
)
for
lane
in
range
(
numLanes
):
if
(
not
wlev_dqs_bspe
[
lane
][
phase
]
is
None
)
and
(
not
wlev_dqs_bspe
[
lane
][
phase
][
'ldly'
]
is
None
):
print
(
"
%
d"
%
(
wlev_dqs_bspe
[
lane
][
phase
][
'ldly'
]),
end
=
" "
)
else
:
print
(
"?"
,
end
=
" "
)
#DQ_IDELAY, with half/clock variants
print
(
"DQS
%
d0"
%
(
lane
),
end
=
" "
)
#TODO: add DQ%do
for
k
in
enl_list_out
:
for
b
in
range
(
numBits
):
lane
=
b
//
8
if
(
not
wlev_dqs_bspe
[
lane
][
phase
]
is
None
):
dqs_dly
=
wlev_dqs_bspe
[
lane
][
phase
][
'ldly'
]
else
:
dqs_dly
=
None
valid
=
not
dqs_dly
is
None
valid
=
valid
and
not
DQOvDQSO
[
k
]
is
None
valid
=
valid
and
not
DQOvDQSO
[
k
][
dqs_dly
]
is
None
valid
=
valid
and
not
DQOvDQSO
[
k
][
dqs_dly
][
b
]
is
None
if
valid
:
print
(
"
%
d"
%
(
DQOvDQSO
[
k
][
dqs_dly
][
b
]),
end
=
" "
)
else
:
print
(
"
%
s-DQ
%
do"
%
(
k
.
upper
()[
0
],
b
),
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
:
try
:
print
(
"
%
d"
%
(
phase_data
[
'cmda'
]),
end
=
" "
)
except
:
print
(
"?"
,
end
=
" "
)
print
()
for
lane
in
range
(
numLanes
):
try
:
print
(
"
%
d"
%
(
phase_data
[
'dqsi'
][
lane
]),
end
=
" "
)
except
:
print
(
"?"
,
end
=
" "
)
for
k
in
enl_list_in
:
for
b
in
range
(
numBits
):
try
:
print
(
"
%
d"
%
(
phase_data
[
'dqi'
][
k
][
b
]),
end
=
" "
)
except
:
print
(
"?"
,
end
=
" "
)
for
lane
in
range
(
numLanes
):
try
:
print
(
"
%
d"
%
(
phase_data
[
'dqso'
][
lane
]),
end
=
" "
)
except
:
print
(
"?"
,
end
=
" "
)
for
k
in
enl_list_out
:
for
b
in
range
(
numBits
):
try
:
print
(
"
%
d"
%
(
phase_data
[
'dqo'
][
k
][
b
]),
end
=
" "
)
except
:
print
(
"?"
,
end
=
" "
)
for
k
in
enl_list_in
:
try
:
if
not
None
in
phase_data
[
'dqsi'
]:
max_err
=
max
(
maxErrDqsi
[
k
][
dly
][
lane
]
for
lane
,
dly
in
enumerate
(
phase_data
[
'dqsi'
]))
# for dly in phase_data['dqsi']:
# err=maxErrDqsi[k][dly]
# print("%.1f"%(err),end=" ")
print
(
"
%.1
f"
%
(
max_err
),
end
=
" "
)
else
:
print
(
"X"
,
end
=
" "
)
except
:
print
(
"?"
,
end
=
" "
)
for
k
in
enl_list_out
:
try
:
if
not
None
in
phase_data
[
'dqso'
]:
max_err
=
max
(
maxErrDqso
[
k
][
dly
][
lane
]
for
lane
,
dly
in
enumerate
(
phase_data
[
'dqso'
]))
print
(
"
%.1
f"
%
(
max_err
),
end
=
" "
)
else
:
print
(
"x"
,
end
=
" "
)
except
:
print
(
"?"
,
end
=
" "
)
print
()
\ No newline at end of file
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
):
'''
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
()
self
.
get_delays_vs_phase
(
filter_dqo
=
2
,
filter_dqi
=
2
,
filter_dqso
=
2
,
filter_dqsi
=
2
,
filter_cmda
=
2
,
keep_all
=
keep_all
,
set_table
=
False
,
quiet
=
2
)
py393/x393_mcntrl_buffers.py
View file @
a7004146
...
...
@@ -132,20 +132,23 @@ class X393McntrlBuffers(object):
def
write_block_buf_chn
(
self
,
#
chn
,
# input integer chn; # buffer channel
page
,
# input [1:0] page;
num_words_or_data_list
):
# input integer num_words; # number of words to write (will be rounded up to multiple of 16)
num_words_or_data_list
,
# input integer num_words; # number of words to write (will be rounded up to multiple of 16)
quiet
=
1
):
"""
Fill specified buffer with the pattern data
@param chn 4-bit buffer channel (0..4) to write data to
@param page 2-bit buffer page to write to
@param num_words_or_data_list> number of 32-bit words to generate/write or a list with integer data
@param quiet reduce output
"""
print
(
"===write_block_buf_chn() chn=0x
%
x, page=0x
%
x"
%
(
chn
,
page
),
end
=
" "
)
if
isinstance
(
num_words_or_data_list
,
list
):
try
:
print
(
"=== [0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,...]"
%
tuple
(
num_words_or_data_list
[:
8
]),
end
=
""
)
except
:
print
(
"=== [
%
s]"
%
str
(
num_words_or_data_list
))
print
(
"==="
)
if
quiet
<
2
:
print
(
"===write_block_buf_chn() chn=0x
%
x, page=0x
%
x"
%
(
chn
,
page
),
end
=
" "
)
if
isinstance
(
num_words_or_data_list
,
list
):
try
:
print
(
"=== [0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,...]"
%
tuple
(
num_words_or_data_list
[:
8
]),
end
=
""
)
except
:
print
(
"=== [
%
s]"
%
str
(
num_words_or_data_list
))
print
(
"==="
)
start_addr
=-
1
if
chn
==
0
:
start_addr
=
vrlg
.
MCONTR_BUF0_WR_ADDR
+
(
page
<<
8
)
elif
chn
==
1
:
start_addr
=
vrlg
.
MCONTR_BUF1_WR_ADDR
+
(
page
<<
8
)
...
...
py393/x393_mcntrl_timing.py
View file @
a7004146
...
...
@@ -185,6 +185,7 @@ class X393McntrlTiming(object):
@param delay 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
Each of the two elements in the delay tuple/list may be a a common integer or a list/tuple itself
if delay is None will restore default values
Alternatively it can be a one-level list/tuple covering all (16) delays
@param quiet reduce output
"""
# print("====axi_set_dq_idelay %s"%str(delay))
...
...
@@ -196,6 +197,11 @@ class X393McntrlTiming(object):
delay
[
1
]
.
append
(
vrlg
.
get_default_field
(
"DLY_LANE1_IDELAY"
,
i
))
if
isinstance
(
delay
,(
int
,
long
)):
delay
=
(
delay
,
delay
)
elif
len
(
delay
)
%
8
==
0
:
delay2
=
[]
for
lane
in
range
(
len
(
delay
)
//
8
):
delay2
.
append
(
delay
[
8
*
lane
:
8
*
(
lane
+
1
)])
delay
=
delay2
if
quiet
<
2
:
print
(
"SET DQ IDELAY="
+
hexMultiple
(
delay
))
# hexMultiple
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE0_IDELAY
,
0
,
8
,
delay
[
0
],
"DLY_LANE0_IDELAY"
)
...
...
@@ -211,6 +217,7 @@ class X393McntrlTiming(object):
@param delay 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
Each of the two elements in the delay tuple/list may be a a common integer or a list/tuple itself
if delay is None will restore default values
Alternatively it can be a one-level list/tuple covering all (16) delays
@param quiet reduce output
"""
if
delay
is
None
:
...
...
@@ -220,6 +227,11 @@ class X393McntrlTiming(object):
delay
[
1
]
.
append
(
vrlg
.
get_default_field
(
"DLY_LANE1_ODELAY"
,
i
))
if
isinstance
(
delay
,(
int
,
long
)):
delay
=
(
delay
,
delay
)
elif
len
(
delay
)
%
8
==
0
:
delay2
=
[]
for
lane
in
range
(
len
(
delay
)
//
8
):
delay2
.
append
(
delay
[
8
*
lane
:
8
*
(
lane
+
1
)])
delay
=
delay2
if
quiet
<
2
:
print
(
"SET DQ ODELAY="
+
hexMultiple
(
delay
))
# hexMultiple
self
.
axi_set_multiple_delays
(
vrlg
.
LD_DLY_LANE0_ODELAY
,
0
,
8
,
delay
[
0
],
"DLY_LANE0_ODELAY"
);
...
...
py393/x393_pio_sequences.py
View file @
a7004146
...
...
@@ -532,7 +532,8 @@ class X393PIOSequences(object):
@sel - 0 - early, 1 - late read command
@verbose print data being written (default: False)
"""
print
(
"===set_write_block ba=0x
%
x, ra=0x
%
x, ca=0x
%
x, num8=
%
d extraTgl=
%
d, sel=
%
d, verbose=
%
d"
%
(
ba
,
ra
,
ca
,
num8
,
extraTgl
,
sel
,
verbose
))
if
verbose
>
0
:
print
(
"===set_write_block ba=0x
%
x, ra=0x
%
x, ca=0x
%
x, num8=
%
d extraTgl=
%
d, sel=
%
d, verbose=
%
d"
%
(
ba
,
ra
,
ca
,
num8
,
extraTgl
,
sel
,
verbose
))
cmd_addr
=
vrlg
.
MCONTR_CMD_WR_ADDR
+
vrlg
.
WRITE_BLOCK_OFFSET
# activate
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
...
...
@@ -790,7 +791,7 @@ class X393PIOSequences(object):
<en_refresh> enable refresh immediately
<verbose> print data being written (default: False)
"""
print
(
"SET REFRESH: tRFC=
%
d, tREFI=
%
d"
%
(
t_rfc
,
t_refi
))
print
(
"
****
SET REFRESH: tRFC=
%
d, tREFI=
%
d"
%
(
t_rfc
,
t_refi
))
cmd_addr
=
vrlg
.
MCONTR_CMD_WR_ADDR
+
vrlg
.
REFRESH_OFFSET
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data
=
self
.
func_encode_cmd
(
0
,
0
,
6
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
)
...
...
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