Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
eddr3
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
eddr3
Commits
e00b15e3
Commit
e00b15e3
authored
Jun 14, 2014
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code to align bit delays on random data
parent
2ac46e21
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
417 additions
and
130 deletions
+417
-130
ddrc_test01_testbench.sav
ddrc_test01_testbench.sav
+34
-22
ddrc_test01_testbench.tf
ddrc_test01_testbench.tf
+6
-6
ddrtests.py
python/ddrtests.py
+377
-102
No files found.
ddrc_test01_testbench.sav
View file @
e00b15e3
[*]
[*]
[*] GTKWave Analyzer v3.3.49 (w)1999-2013 BSI
[*] GTKWave Analyzer v3.3.49 (w)1999-2013 BSI
[*]
Wed Jun 11 02:38:51
2014
[*]
Sat Jun 14 07:10:23
2014
[*]
[*]
[dumpfile] "/data/vdt/vdt-projects/eddr3/simulation/ddrc_test01_testbench-20140610175433027.lxt"
[dumpfile] "/data/vdt/vdt-projects/eddr3/simulation/ddrc_test01_testbench-20140610175433027.lxt"
[dumpfile_mtime] "Tue Jun 10 23:58:40 2014"
[dumpfile_mtime] "Tue Jun 10 23:58:40 2014"
[dumpfile_size] 75451369
[dumpfile_size] 75451369
[savefile] "/data/vdt/vdt-projects/eddr3/ddrc_test01_testbench.sav"
[savefile] "/data/vdt/vdt-projects/eddr3/ddrc_test01_testbench.sav"
[timestart] 13
862811
0
[timestart] 13
750787
0
[size] 1920 1180
[size] 1920 1180
[pos] -1 -1
[pos] -1 -1
*-12.
445735 138646045
134765625 134912600 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-12.
527021 137532500
134765625 134912600 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] ddrc_test01_testbench.
[treeopen] ddrc_test01_testbench.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.axibram_read_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.axibram_read_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.axibram_write_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.axibram_write_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_control_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_control_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].
[treeopen] ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].
...
@@ -1530,54 +1529,67 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.set[0]
...
@@ -1530,54 +1529,67 @@ ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.set[0]
-ddrc_sequencer
-ddrc_sequencer
@800200
@800200
-ddr_sequencer_i_selected
-ddr_sequencer_i_selected
@800201
-ddr_read_data
-ddr_read_data
@2
9
@2
8
ddrc_test01_testbench.DQSL[0]
ddrc_test01_testbench.DQSL[0]
@2
3
@2
2
ddrc_test01_testbench.SDD[15:0]
ddrc_test01_testbench.SDD[15:0]
@2
9
@2
8
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dq_di[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dq_di[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dq_dly[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dq_dly[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.iclk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.iclk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.clk_div[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.clk_div[0]
@2
3
@2
2
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dout[31:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.dout[31:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.dout[63:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.dout[63:0]
@1000201
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.mclk[0]
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.buf_wdata[63:0]
@200
-ddrc_sequencer
@22
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_wdata[63:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_wdata_negedge[63:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_waddr_negedge[8:0]
@28
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_wr[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_wr_ndly[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.buf_wr_negedge[0]
@1000200
-ddr_read_data
-ddr_read_data
@200
@200
-
-
@
c00200
@
800201
-tristate_control
-tristate_control
@2
8
@2
9
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDODT[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.SDODT[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dci_disable_dqs[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dci_disable_dqs[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dci_disable_dq[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dci_disable_dq[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dci_in[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dci_in[0]
@2
2
@2
3
ddrc_test01_testbench.ddrc_test01_i.ddrc_control_i.dqs_tri_pattern_r[15:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_control_i.dqs_tri_pattern_r[15:0]
@2
8
@2
9
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.clk[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.clk[0]
@2
2
@2
3
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dqs_tri_off_pattern[3:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dqs_tri_off_pattern[3:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dqs_tri_on_pattern[3:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dqs_tri_on_pattern[3:0]
@2
8
@2
9
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dqs_tri_prev[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dqs_tri_prev[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dqs_tri_in[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dqs_tri_in[0]
@2
2
@2
3
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dqs_tri[7:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dqs_tri[7:0]
@2
8
@2
9
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dqs_i.iobufs_dqs_i.T[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dqs_i.iobufs_dqs_i.T[0]
@2
2
@2
3
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dq_tri_off_pattern[3:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dq_tri_off_pattern[3:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dq_tri_on_pattern[3:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dq_tri_on_pattern[3:0]
@2
8
@2
9
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dq_tri_prev[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.dq_tri_prev[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dq_tri_in[0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dq_tri_in[0]
@2
2
@2
3
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dq_tri[7:0]
ddrc_test01_testbench.ddrc_test01_i.ddrc_sequencer_i.phy_cmd_i.phy_dq_tri[7:0]
@1
401200
@1
000201
-tristate_control
-tristate_control
@28
@28
ddrc_test01_testbench.ddrc_test01_i.refresh_need[0]
ddrc_test01_testbench.ddrc_test01_i.refresh_need[0]
...
...
ddrc_test01_testbench.tf
View file @
e00b15e3
...
@@ -173,12 +173,12 @@ module ddrc_test01_testbench #(
...
@@ -173,12 +173,12 @@ module ddrc_test01_testbench #(
localparam DLY_LANE1_IDELAY= 72'ha0636261605c5b5a59; // idelay dqs, idelay dq[7:0
localparam DLY_LANE1_IDELAY= 72'ha0636261605c5b5a59; // idelay dqs, idelay dq[7:0
localparam DLY_CMDA= 256'h3c3c3c3c3b3a39383434343433323130002c2c2c2b2a29282424242423222120; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
localparam DLY_CMDA= 256'h3c3c3c3c3b3a39383434343433323130002c2c2c2b2a29282424242423222120; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// alternative to set same type delays to the same value
// alternative to set same type delays to the same value
localparam DLY_DQ_IDELAY = 'h60;
localparam DLY_DQ_IDELAY = 'h
20 ;// 'h
60;
localparam DLY_DQ_ODELAY = 'h48;
localparam DLY_DQ_ODELAY = 'h
a0; // 'h
48;
localparam DLY_DQS_IDELAY = 'ha0;
localparam DLY_DQS_IDELAY = 'h
40; // 'h
a0;
localparam DLY_DQS_ODELAY = 'h4c; //
b0 for WLV
localparam DLY_DQS_ODELAY = 'h4c; //
localparam DLY_DM_ODELAY = 'h48;
localparam DLY_DM_ODELAY = 'h
a0; // 'h
48;
localparam DLY_CMDA_ODELAY ='h30;
localparam DLY_CMDA_ODELAY ='h
50; // 'h
30;
`else
`else
localparam DLY_LANE0_DQS_WLV_IDELAY = 8'he8; // idelay dqs
localparam DLY_LANE0_DQS_WLV_IDELAY = 8'he8; // idelay dqs
...
...
python/ddrtests.py
View file @
e00b15e3
...
@@ -29,6 +29,7 @@ import struct
...
@@ -29,6 +29,7 @@ import struct
import
random
import
random
DRY_MODE
=
False
# True
DRY_MODE
=
False
# True
MONITOR_EMIO
=
False
#True
MONITOR_EMIO
=
False
#True
def
write_mem
(
addr
,
data
):
def
write_mem
(
addr
,
data
):
global
DEBUG_MODE
;
global
DEBUG_MODE
;
if
DRY_MODE
:
if
DRY_MODE
:
...
@@ -166,19 +167,22 @@ STATUS_SEQ_BUSY_MASK = 0x400;
...
@@ -166,19 +167,22 @@ STATUS_SEQ_BUSY_MASK = 0x400;
if
use200Mhz
:
if
use200Mhz
:
DLY_LANE0_DQS_WLV_IDELAY
=
0xb0
# idelay dqs
DLY_LANE0_DQS_WLV_IDELAY
=
0xb0
# idelay dqs
DLY_LANE1_DQS_WLV_IDELAY
=
0xb0
# idelay dqs
DLY_LANE1_DQS_WLV_IDELAY
=
0xb0
# idelay dqs
DLY_LANE0_ODELAY
=
[
0x4c
,
0x4c
,
0x4b
,
0x4a
,
0x49
,
0x48
,
0x44
,
0x43
,
0x42
,
0x41
]
# odelay dqm, odelay ddqs, odelay dq[7:0]
DLY_LANE0_ODELAY
=
[
0x98
,
0x4c
,
0x94
,
0x94
,
0x98
,
0x9c
,
0x92
,
0x99
,
0x98
,
0x94
]
# odelay dqm, odelay ddqs, odelay dq[7:0]
DLY_LANE0_IDELAY
=
[
0xa0
,
0x63
,
0x62
,
0x61
,
0x60
,
0x5c
,
0x5b
,
0x5a
,
0x59
]
# idelay dqs, idelay dq[7:0
DLY_LANE1_ODELAY
=
[
0x4c
,
0x4c
,
0x4b
,
0x4a
,
0x49
,
0x48
,
0x44
,
0x43
,
0x42
,
0x41
]
# odelay dqm, odelay ddqs, odelay dq[7:0]
DLY_LANE0_IDELAY
=
[
0x40
,
0x13
,
0x14
,
0x14
,
0x1c
,
0x13
,
0x14
,
0x13
,
0x1a
]
# idelay dqs, idelay dq[7:0
DLY_LANE1_IDELAY
=
[
0xa0
,
0x63
,
0x62
,
0x61
,
0x60
,
0x5c
,
0x5b
,
0x5a
,
0x59
]
# idelay dqs, idelay dq[7:0
DLY_LANE1_ODELAY
=
[
0x98
,
0x4c
,
0x98
,
0x98
,
0x98
,
0x9b
,
0x99
,
0xa8
,
0x9c
,
0x98
]
# odelay dqm, odelay ddqs, odelay dq[7:0]
DLY_LANE1_IDELAY
=
[
0x40
,
0x2c
,
0x2b
,
0x2c
,
0x2c
,
0x34
,
0x30
,
0x33
,
0x30
]
# idelay dqs, idelay dq[7:0
DLY_CMDA
=
[
0x3c
,
0x3c
,
0x3c
,
0x3c
,
0x3b
,
0x3a
,
0x39
,
0x38
,
0x34
,
0x34
,
0x34
,
0x34
,
0x33
,
0x32
,
0x31
,
0x30
,
DLY_CMDA
=
[
0x3c
,
0x3c
,
0x3c
,
0x3c
,
0x3b
,
0x3a
,
0x39
,
0x38
,
0x34
,
0x34
,
0x34
,
0x34
,
0x33
,
0x32
,
0x31
,
0x30
,
0x00
,
0x2c
,
0x2c
,
0x2c
,
0x2b
,
0x2a
,
0x29
,
0x28
,
0x24
,
0x24
,
0x24
,
0x24
,
0x23
,
0x22
,
0x21
,
0x20
]
# odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
0x00
,
0x2c
,
0x2c
,
0x2c
,
0x2b
,
0x2a
,
0x29
,
0x28
,
0x24
,
0x24
,
0x24
,
0x24
,
0x23
,
0x22
,
0x21
,
0x20
]
# odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
# alternative to set same type delays to the same value
# alternative to set same type delays to the same value
DLY_DQ_IDELAY
=
0x
70
# 0x6
0
DLY_DQ_IDELAY
=
0x
2
0
DLY_DQ_ODELAY
=
0x
f0
# 0x48
DLY_DQ_ODELAY
=
0x
a0
DLY_DQS_IDELAY
=
0x
20
# 0xa
0
DLY_DQS_IDELAY
=
0x
4
0
DLY_DQS_ODELAY
=
0x4c
#
b0 for WLV
DLY_DQS_ODELAY
=
0x4c
#
should match with phase write leveling
DLY_DM_ODELAY
=
0x
48
# 0x48
DLY_DM_ODELAY
=
0x
a0
DLY_CMDA_ODELAY
=
0x
20
# 0x3
0
DLY_CMDA_ODELAY
=
0x
5
0
else
:
else
:
DLY_LANE0_DQS_WLV_IDELAY
=
0xe8
# idelay dqs
DLY_LANE0_DQS_WLV_IDELAY
=
0xe8
# idelay dqs
...
@@ -190,18 +194,18 @@ else:
...
@@ -190,18 +194,18 @@ else:
DLY_CMDA
=
[
0x5c
,
0x5c
,
0x5c
,
0x5c
,
0x5b
,
0x5a
,
0x59
,
0x58
,
0x54
,
0x54
,
0x54
,
0x54
,
0x53
,
0x52
,
0x51
,
0x50
,
DLY_CMDA
=
[
0x5c
,
0x5c
,
0x5c
,
0x5c
,
0x5b
,
0x5a
,
0x59
,
0x58
,
0x54
,
0x54
,
0x54
,
0x54
,
0x53
,
0x52
,
0x51
,
0x50
,
0x00
,
0x4c
,
0x4c
,
0x4c
,
0x4b
,
0x4a
,
0x49
,
0x48
,
0x44
,
0x44
,
0x44
,
0x44
,
0x43
,
0x42
,
0x41
,
0x40
]
# odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
0x00
,
0x4c
,
0x4c
,
0x4c
,
0x4b
,
0x4a
,
0x49
,
0x48
,
0x44
,
0x44
,
0x44
,
0x44
,
0x43
,
0x42
,
0x41
,
0x40
]
# odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
# alternative to set same type delays to the same value
# alternative to set same type delays to the same value
DLY_DQ_IDELAY
=
0x
7
0
DLY_DQ_IDELAY
=
0x
2
0
DLY_DQ_ODELAY
=
0x
68
DLY_DQ_ODELAY
=
0x
a0
DLY_DQS_IDELAY
=
0x
d8
DLY_DQS_IDELAY
=
0x
40
DLY_DQS_ODELAY
=
0x
74
# different for WLV
DLY_DQS_ODELAY
=
0x
4c
#should match with phase write leveling
DLY_DM_ODELAY
=
0x
74
DLY_DM_ODELAY
=
0x
a0
DLY_CMDA_ODELAY
=
0x50
DLY_CMDA_ODELAY
=
0x50
NUM_FINE_STEPS
=
5
NUM_FINE_STEPS
=
5
#`endif
#`endif
DLY_PHASE
=
0x
39
# 0x1c # mmcm fine phase shift, 1/4 tCK
DLY_PHASE
=
0x
2c
# 0x1c # mmcm fine phase shift, 1/4 tCK
DQSTRI_FIRST
=
0x3
# DQS tri-state control word, first when enabling output
DQSTRI_FIRST
=
0x3
# DQS tri-state control word, first when enabling output
DQSTRI_LAST
=
0xc
# DQS tri-state control word, first after disabling output
DQSTRI_LAST
=
0xc
# DQS tri-state control word, first after disabling output
...
@@ -810,14 +814,16 @@ def set_write_block(
...
@@ -810,14 +814,16 @@ def set_write_block(
((
1
&
0x1
)
<<
10
)
|
# phy_odt_in
((
1
&
0x1
)
<<
10
)
|
# phy_odt_in
((
0
&
0x1
)
<<
9
)
|
# phy_cke_inv # invert CKE
((
0
&
0x1
)
<<
9
)
|
# phy_cke_inv # invert CKE
# (( 1 & 0x1) << 8) | # phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
# (( 1 & 0x1) << 8) | # phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
((
0
&
0x1
)
<<
8
)
|
# phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
# ((0 & 0x1) << 8) | # phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
((
1
&
0x1
)
<<
8
)
|
# phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
((
0
&
0x1
)
<<
7
)
|
# phy_dq_en_in #phy_dq_tri_in, # tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
((
0
&
0x1
)
<<
7
)
|
# phy_dq_en_in #phy_dq_tri_in, # tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
((
0
&
0x1
)
<<
6
)
|
# phy_dqs_en_in #phy_dqs_tri_in, # tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
((
0
&
0x1
)
<<
6
)
|
# phy_dqs_en_in #phy_dqs_tri_in, # tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
((
0
&
0x1
)
<<
5
)
|
# phy_dqs_toggle_en #enable toggle DQS according to the pattern
((
0
&
0x1
)
<<
5
)
|
# phy_dqs_toggle_en #enable toggle DQS according to the pattern
((
0
&
0x1
)
<<
4
)
|
# phy_dci_en_in #phy_dci_in, # DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
((
0
&
0x1
)
<<
4
)
|
# phy_dci_en_in #phy_dci_in, # DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
((
0
&
0x1
)
<<
3
)
|
# phy_buf_wr # connect to external buffer (but only if not paused)
((
0
&
0x1
)
<<
3
)
|
# phy_buf_wr # connect to external buffer (but only if not paused)
# ((0 & 0x1) << 2) | # phy_buf_rd # connect to external buffer (but only if not paused)
# ((0 & 0x1) << 2) | # phy_buf_rd # connect to external buffer (but only if not paused)
((
1
&
0x1
)
<<
2
)
|
# phy_buf_rd # connect to external buffer (but only if not paused)
# (( 1 & 0x1) << 2) | # phy_buf_rd # connect to external buffer (but only if not paused)
((
0
&
0x1
)
<<
2
)
|
# phy_buf_rd # connect to external buffer (but only if not paused)
((
0
&
0x1
)
<<
1
))
# add_nop # add NOP after the current command, keep other data
((
0
&
0x1
)
<<
1
))
# add_nop # add NOP after the current command, keep other data
axi_write_single
(
cmd_addr
,
data
)
axi_write_single
(
cmd_addr
,
data
)
cmd_addr
=
cmd_addr
+
4
cmd_addr
=
cmd_addr
+
4
...
@@ -849,7 +855,8 @@ def set_write_block(
...
@@ -849,7 +855,8 @@ def set_write_block(
((
1
&
0x1
)
<<
10
)
|
# phy_odt_in
((
1
&
0x1
)
<<
10
)
|
# phy_odt_in
((
0
&
0x1
)
<<
9
)
|
# phy_cke_inv # invert CKE
((
0
&
0x1
)
<<
9
)
|
# phy_cke_inv # invert CKE
# (( 1 & 0x1) << 8) | # phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
# (( 1 & 0x1) << 8) | # phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
((
0
&
0x1
)
<<
8
)
|
# phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
# (( 0 & 0x1) << 8) | # phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
((
1
&
0x1
)
<<
8
)
|
# phy_sel_in # first/second half-cycle, other will be nop (cke+odt applicable to both)
((
1
&
0x1
)
<<
7
)
|
# phy_dq_en_in #phy_dq_tri_in, # tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
((
1
&
0x1
)
<<
7
)
|
# phy_dq_en_in #phy_dq_tri_in, # tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
((
1
&
0x1
)
<<
6
)
|
# phy_dqs_en_in #phy_dqs_tri_in, # tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
((
1
&
0x1
)
<<
6
)
|
# phy_dqs_en_in #phy_dqs_tri_in, # tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
((
1
&
0x1
)
<<
5
)
|
# phy_dqs_toggle_en #enable toggle DQS according to the pattern
((
1
&
0x1
)
<<
5
)
|
# phy_dqs_toggle_en #enable toggle DQS according to the pattern
...
@@ -890,7 +897,9 @@ def set_write_block(
...
@@ -890,7 +897,9 @@ def set_write_block(
((
0
&
0x1
)
<<
4
)
|
# phy_dci_en_in #phy_dci_in, # DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
((
0
&
0x1
)
<<
4
)
|
# phy_dci_en_in #phy_dci_in, # DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
((
0
&
0x1
)
<<
3
)
|
# phy_buf_wr # connect to external buffer (but only if not paused)
((
0
&
0x1
)
<<
3
)
|
# phy_buf_wr # connect to external buffer (but only if not paused)
# (( 1 & 0x1) << 2) | # phy_buf_rd # connect to external buffer (but only if not paused)
# (( 1 & 0x1) << 2) | # phy_buf_rd # connect to external buffer (but only if not paused)
((
0
&
0x1
)
<<
2
)
|
# phy_buf_rd # connect to external buffer (but only if not paused)
# (( 0 & 0x1) << 2) | # phy_buf_rd # connect to external buffer (but only if not paused)
#this is one extra read, needed because of BRAM latency
((
1
&
0x1
)
<<
2
)
|
# phy_buf_rd # connect to external buffer (but only if not paused)
((
0
&
0x1
)
<<
1
))
# add_nop # add NOP after the current command, keep other data
((
0
&
0x1
)
<<
1
))
# add_nop # add NOP after the current command, keep other data
axi_write_single
(
cmd_addr
,
data
)
axi_write_single
(
cmd_addr
,
data
)
cmd_addr
=
cmd_addr
+
4
cmd_addr
=
cmd_addr
+
4
...
@@ -1380,10 +1389,11 @@ def axi_set_tristate_patterns(): # task axi_set_tristate_patterns;
...
@@ -1380,10 +1389,11 @@ def axi_set_tristate_patterns(): # task axi_set_tristate_patterns;
if
(
VERBOSE
):
print
(
"SET TRISTATE PATTERNS"
)
if
(
VERBOSE
):
print
(
"SET TRISTATE PATTERNS"
)
def
axi_set_dqs_dqm_patterns
():
# task axi_set_dqs_dqm_patterns;
def
axi_set_dqs_dqm_patterns
(
data
):
# task axi_set_dqs_dqm_patterns; 0x0055
global
BASEADDR_PATTERNS
,
VERBOSE
global
BASEADDR_PATTERNS
,
VERBOSE
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
axi_write_single
(
BASEADDR_PATTERNS
,
0x0055
)
axi_write_single
(
BASEADDR_PATTERNS
,
data
)
#
0x0055)
if
(
VERBOSE
):
print
(
"SET DQS+DQM PATTERNS"
)
if
(
VERBOSE
):
print
(
"SET DQS+DQM PATTERNS"
)
...
@@ -1434,6 +1444,7 @@ def axi_set_dqs_idelay_wlv(): # task axi_set_dqs_idelay_wlv;
...
@@ -1434,6 +1444,7 @@ def axi_set_dqs_idelay_wlv(): # task axi_set_dqs_idelay_wlv;
def
axi_set_dly_single
(
# task axi_set_dly_single;
def
axi_set_dly_single
(
# task axi_set_dly_single;
group
,
# input [2:0] group; # 0 - lane 0 odelay, 1 - lane0 idelay, 2 - lane 1 odelay, 3 - lane1 idelay, 4 - cmda odelay
group
,
# input [2:0] group; # 0 - lane 0 odelay, 1 - lane0 idelay, 2 - lane 1 odelay, 3 - lane1 idelay, 4 - cmda odelay
index
,
# input [4:0] index; # 0..7 - DQ, 8 - DQS, 9 DQM (for byte lanes)
index
,
# input [4:0] index; # 0..7 - DQ, 8 - DQS, 9 DQM (for byte lanes)
delay
):
# input [7:0] delay;
delay
):
# input [7:0] delay;
...
@@ -1444,6 +1455,8 @@ def axi_set_dly_single( # task axi_set_dly_single;
...
@@ -1444,6 +1455,8 @@ def axi_set_dly_single( # task axi_set_dly_single;
global
BASEADDRESS_LANE1_ODELAY
global
BASEADDRESS_LANE1_ODELAY
global
BASEADDRESS_LANE1_IDELAY
global
BASEADDRESS_LANE1_IDELAY
global
BASEADDRESS_CMDA
global
BASEADDRESS_CMDA
global
BASEADDRESS_LANE0_IDELAY
,
BASEADDRESS_LANE1_IDELAY
,
VERBOSE
if
(
VERBOSE
):
print
(
"SET DELAY (0x
%
x, 0x
%0
x, 0x
%0
x)"
%
(
group
,
index
,
delay
))
i
=
index
i
=
index
dly
=
delay
dly
=
delay
if
group
==
0
:
if
group
==
0
:
...
@@ -1582,16 +1595,19 @@ def set_up(): # task set_up;
...
@@ -1582,16 +1595,19 @@ def set_up(): # task set_up;
# set dq /dqs tristate on/off patterns
# set dq /dqs tristate on/off patterns
axi_set_tristate_patterns
()
axi_set_tristate_patterns
()
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
axi_set_dqs_dqm_patterns
()
axi_set_dqs_dqm_patterns
(
0x0055
)
# axi_set_dqs_dqm_patterns(0x00aa)
# prepare all sequences
# prepare all sequences
set_all_sequences
()
set_all_sequences
()
# prepare write buffer
# prepare write buffer
write_block_buf
()
# fill block memory
write_block_buf
()
# fill block memory
# set all delays
# set all delays
#./ddrtests.py axi_set_same_delays (1a...34) (94...a8) 40 4c 70 30
axi_set_same_delays
(
DLY_DQ_IDELAY
,
DLY_DQ_ODELAY
,
DLY_DQS_IDELAY
,
DLY_DQS_ODELAY
,
DLY_DM_ODELAY
,
DLY_CMDA_ODELAY
)
axi_set_same_delays
(
DLY_DQ_IDELAY
,
DLY_DQ_ODELAY
,
DLY_DQS_IDELAY
,
DLY_DQS_ODELAY
,
DLY_DM_ODELAY
,
DLY_CMDA_ODELAY
)
#axi_set_delays;
#axi_set_delays;
# set clock phase relative to DDR clk
# set clock phase relative to DDR clk
axi_set_phase
(
DLY_PHASE
)
axi_set_phase
(
DLY_PHASE
)
#0x2c
axi_set_wbuf_delay
(
WBUF_DLY_DFLT
)
axi_set_wbuf_delay
(
WBUF_DLY_DFLT
)
def
split_delay
(
dly
):
def
split_delay
(
dly
):
...
@@ -1800,6 +1816,166 @@ def convert_w32_to_mem16(w32):
...
@@ -1800,6 +1816,166 @@ def convert_w32_to_mem16(w32):
# calibratin finedelay dealy steps using everaged "eye" data, assuming that most error
# calibratin finedelay dealy steps using everaged "eye" data, assuming that most error
# is in finedelay stage
# is in finedelay stage
def
corr_delays
(
low
,
# absolute delay value of start scan
avg_types
,
# weights of weach of the 8 bit sequences
res_bits
,
#individual per-bit results
res_avg
,
# averaged eye data tablle, each line has 8 elements, or [] for bad measurements
corr_fine
,
# fine delay correction
ends_dist
,
# do not process if one of the primary interval ends is within this from 0.0 or 1.0
verbose
):
# coarse adjustmenty - decimate arrays to use the same (0) value of the fine delay
usable_types
=
[]
for
i
,
w
in
enumerate
(
avg_types
):
if
(
w
>
0
)
and
not
i
in
(
0
,
7
)
:
usable_types
.
append
(
i
)
if
(
verbose
):
print
(
"usable_types="
,
usable_types
)
def
thr_sign
(
bit
,
type
,
limit
,
data
):
lim_l
=
limit
lim_u
=
1.0
-
limit
if
data
[
bit
][
type
]
<=
limit
:
return
-
1
if
data
[
bit
][
type
]
>=
(
1.0
-
limit
):
return
1
return
0
def
thr_signs
(
type
,
limit
,
data
):
signs
=
""
for
bit
in
range
(
15
,
-
1
,
-
1
):
signs
+=
(
"-"
,
"0"
,
"+"
)[
thr_sign
(
bit
,
type
,
limit
,
data
)
+
1
]
def
full_state
(
types
,
limit
,
data
):
#will NOT return None if any is undefined
state
=
""
for
t
in
types
:
for
bit
in
range
(
15
,
-
1
,
-
1
):
state
+=
(
"-"
,
"0"
,
"+"
)[
thr_sign
(
bit
,
t
,
limit
,
data
)
+
1
]
return
state
def
full_same_state
(
types
,
limit
,
data
):
#will return None if any is undefined
state
=
""
for
t
in
types
:
s0
=
thr_sign
(
15
,
t
,
limit
,
data
)
state
+=
(
"-"
,
"0"
,
"+"
)[
s0
+
1
]
for
bit
in
range
(
15
,
-
1
,
-
1
):
s
=
thr_sign
(
bit
,
t
,
limit
,
data
)
if
(
not
s
)
or
(
s
!=
s0
)
:
return
None
return
state
def
diff_state
(
state1
,
state2
):
for
i
,
s
in
enumerate
(
state1
):
if
s
!=
state2
[
i
]:
return
True
return
False
global
NUM_FINE_STEPS
start_index
=
0
;
if
(
low
%
NUM_FINE_STEPS
)
!=
0
:
start_index
=
NUM_FINE_STEPS
-
(
low
%
NUM_FINE_STEPS
)
#find the first index where all bits are either above 1.0 -ends_dist or below ends_dist
for
index
in
range
(
len
(
res_avg
)):
print
(
" index=
%
d:
%
s"
%
(
index
,
full_state
(
usable_types
,
ends_dist
,
res_bits
[
index
])))
initial_state
=
full_same_state
(
usable_types
,
ends_dist
,
res_bits
[
index
])
if
initial_state
:
break
else
:
print
(
"Could not find delay value where all bits/types are outside of undefined area (
%
f thershold)"
%
ends_dist
)
return
None
if
(
verbose
):
print
(
"start index=
%
d, start state=
%
s"
%
(
index
,
initial_state
))
#find end of that state
for
index
in
range
(
index
+
1
,
len
(
res_avg
)):
state
=
full_same_state
(
usable_types
,
ends_dist
,
res_bits
[
index
])
if
state
!=
initial_state
:
break
else
:
print
(
"Could not find delay value where initial state changes (
%
f thershold)"
%
ends_dist
)
return
None
last_initial_index
=
index
-
1
if
(
verbose
):
print
(
"last start state index=
%
d, new state=
%
s"
%
(
last_initial_index
,
state
))
#find new defined state for all bits
for
index
in
range
(
last_initial_index
+
1
,
len
(
res_avg
)):
#here repeat last delay
new_state
=
full_same_state
(
usable_types
,
ends_dist
,
res_bits
[
index
])
if
new_state
and
(
new_state
!=
initial_state
):
break
else
:
print
(
"Could not find delay value whith the new defined state (
%
f thershold)"
%
ends_dist
)
return
None
new_state_index
=
index
if
(
verbose
):
print
(
"new defined state index=
%
d, new state=
%
s"
%
(
new_state_index
,
new_state
))
# remove states that do not have a transition
filtered_types
=
[]
for
i
,
t
in
enumerate
(
usable_types
):
if
(
new_state
[
i
]
!=
initial_state
[
i
]):
filtered_types
.
append
(
t
)
if
(
verbose
):
print
(
"filtered_types="
,
filtered_types
)
second_trans
=
1
in
filtered_types
# use second transition, false - use first transition
if
(
verbose
):
print
(
"second_trans="
,
second_trans
)
# signs=((1,1,-1,-1),(1,-1,1,-1))[1 in filtered_types]
signs
=
((
0
,
0
,
1
,
1
,
-
1
,
-
1
,
0
,
0
),(
0
,
1
,
-
1
,
0
,
0
,
1
,
-
1
,
0
))[
1
in
filtered_types
]
if
(
verbose
):
print
(
"signs="
,
signs
)
for
index
in
range
(
last_initial_index
,
new_state_index
+
1
):
if
(
verbose
):
print
(
"index=
%3
d, delay=
%3
d, state=
%
s"
%
(
index
,
index
+
low
,
full_state
(
filtered_types
,
ends_dist
,
res_bits
[
index
])))
#extend range, combine each bit and averages
ext_low_index
=
last_initial_index
-
(
new_state_index
-
last_initial_index
)
if
ext_low_index
<
0
:
ext_low_index
=
0
ext_high_index
=
new_state_index
+
(
new_state_index
-
last_initial_index
)
if
ext_high_index
>=
len
(
res_bits
):
ext_high_index
=
res_bits
-
1
if
(
verbose
):
print
(
"ext_low_index=
%
d ext_high_index=
%
d"
%
(
ext_low_index
,
ext_high_index
))
bit_data
=
[]
for
i
in
range
(
16
):
bit_data
.
append
([])
# [[]]*16 does not work! (shallow copy)
avg_data
=
[]
for
index0
in
range
(
ext_high_index
-
ext_low_index
+
1
):
index
=
index0
+
ext_low_index
# if (verbose): print(res_bits[index])
bit_samples
=
[
0.0
]
*
16
avg_sample
=
0.0
weight
=
0.0
for
t
in
filtered_types
:
w
=
avg_types
[
t
]
weight
+=
w
sw
=
signs
[
t
]
*
w
avg_sample
+=
sw
*
(
2.0
*
res_avg
[
index
][
t
]
-
1.0
)
# if (verbose): print ("%3d %d:"%(index,t),end=" ")
for
bit
in
range
(
16
):
bit_samples
[
bit
]
+=
sw
*
(
2.0
*
res_bits
[
index
][
bit
][
t
]
-
1.0
)
# if (verbose): print ("%.3f"%(res_bits[index][bit][t]),end=" ")
# if (verbose): print()
avg_sample
/=
weight
avg_data
.
append
(
avg_sample
)
for
bit
in
range
(
16
):
bit_samples
[
bit
]
/=
weight
# if (verbose): print ("bit_samples[%d]=%f"%(bit,bit_samples[bit]))
bit_data
[
bit
]
.
append
(
bit_samples
[
bit
])
# if (verbose): print ("bit_samples=",bit_samples)
# if index0 <3:
# if (verbose): print ("bit_data=",bit_data)
# if (verbose): print ("\n\nbit_data=",bit_data)
period_fine
=
len
(
corr_fine
)
for
index
in
range
(
ext_high_index
-
ext_low_index
+
1
):
dly
=
low
+
index
+
ext_low_index
corr_dly
=
dly
+
corr_fine
[
dly
%
period_fine
]
if
(
verbose
):
print
(
"
%
d
%
d
%.2
f
%.3
f"
%
(
index
,
dly
,
corr_dly
,
avg_data
[
index
]),
end
=
" "
)
for
bit
in
range
(
16
):
if
(
verbose
):
print
(
"
%.3
f"
%
(
bit_data
[
bit
][
index
]),
end
=
" "
)
if
(
verbose
):
print
()
# Seems all above was an overkill, just find bit delays that result in most close to 0
delays
=
[]
for
bit
in
range
(
16
):
best_dist
=
1.0
best_index
=
None
for
index
in
range
(
ext_high_index
-
ext_low_index
+
1
):
if
(
abs
(
bit_data
[
bit
][
index
])
<
best_dist
):
best_dist
=
abs
(
bit_data
[
bit
][
index
])
best_index
=
index
delays
.
append
(
best_index
+
low
+
ext_low_index
)
if
(
verbose
):
print
(
delays
)
return
delays
def
calibrate_finedelay
(
def
calibrate_finedelay
(
low
,
# absolute delay value of start scan
low
,
# absolute delay value of start scan
avg_types
,
# weights of weach of the 8 bit sequences
avg_types
,
# weights of weach of the 8 bit sequences
...
@@ -1808,10 +1984,10 @@ def calibrate_finedelay(
...
@@ -1808,10 +1984,10 @@ def calibrate_finedelay(
min_diff
):
# minimal difference between primary delay steps to process
min_diff
):
# minimal difference between primary delay steps to process
global
NUM_FINE_STEPS
global
NUM_FINE_STEPS
start_index
=
0
;
start_index
=
0
;
weights
=
[
0.0
]
*
(
NUM_FINE_STEPS
-
1
)
corr
=
[
0.0
]
*
(
NUM_FINE_STEPS
-
1
)
if
(
low
%
NUM_FINE_STEPS
)
!=
0
:
if
(
low
%
NUM_FINE_STEPS
)
!=
0
:
start_index
=
NUM_FINE_STEPS
-
(
low
%
NUM_FINE_STEPS
)
start_index
=
NUM_FINE_STEPS
-
(
low
%
NUM_FINE_STEPS
)
weights
=
[
0.0
]
*
(
NUM_FINE_STEPS
)
corr
=
[
0.0
]
*
(
NUM_FINE_STEPS
)
#[0] will stay 0
for
index
in
range
(
start_index
,
len
(
res_avg
)
-
NUM_FINE_STEPS
,
NUM_FINE_STEPS
):
for
index
in
range
(
start_index
,
len
(
res_avg
)
-
NUM_FINE_STEPS
,
NUM_FINE_STEPS
):
if
(
len
(
res_avg
[
index
])
>
0
)
and
(
len
(
res_avg
[
index
+
NUM_FINE_STEPS
])
>
0
):
if
(
len
(
res_avg
[
index
])
>
0
)
and
(
len
(
res_avg
[
index
+
NUM_FINE_STEPS
])
>
0
):
for
t
,
w
in
enumerate
(
avg_types
):
for
t
,
w
in
enumerate
(
avg_types
):
...
@@ -1830,33 +2006,35 @@ def calibrate_finedelay(
...
@@ -1830,33 +2006,35 @@ def calibrate_finedelay(
#correction to the initila step==1
#correction to the initila step==1
d
=
(
v
-
f
)
/
(
s
-
f
)
*
NUM_FINE_STEPS
-
j
d
=
(
v
-
f
)
/
(
s
-
f
)
*
NUM_FINE_STEPS
-
j
#average
#average
corr
[
j
-
1
]
+=
wd
*
d
corr
[
j
]
+=
wd
*
d
weights
[
j
-
1
]
+=
wd
weights
[
j
]
+=
wd
# print ("\n weights:")
# print ("\n weights:")
# print(weights)
# print(weights)
# print ("\n corr:")
# print ("\n corr:")
# print(corr)
# print(corr)
for
i
,
w
in
enumerate
(
weights
):
for
i
,
w
in
enumerate
(
weights
):
if
(
w
>
0
)
:
corr
[
i
]
/=
w
if
(
w
>
0
)
:
corr
[
i
]
/=
w
# will skip 0
print
(
"
\n
corr:"
)
print
(
"
\n
corr:"
)
print
(
"
%
f"
%
0.0
)
# print(corr)
# print(corr)
for
c
in
corr
:
for
i
,
c
in
enumerate
(
corr
)
:
print
(
"
%
f"
%
c
)
print
(
"
%
i
%
f"
%
(
i
,
c
)
)
return
corr
return
corr
def
scan_
dq_i
delay_random
(
def
scan_
or_adjust_
delay_random
(
low_delay
,
low_delay
,
high_delay
,
high_delay
,
use_dq
,
# 0 - scan dqs, 1 - scan dq (common valuwe, post-adjustment)
use_dq
,
# 0 - scan dqs, 1 - scan dq (common valuwe, post-adjustment)
use_odelay
,
ends_dist
,
# do not process if one of the primary interval ends is within this from 0.0 or 1.0
ends_dist
,
# do not process if one of the primary interval ends is within this from 0.0 or 1.0
min_diff
):
# minimal difference between primary delay steps to process
min_diff
,
adjust
,
verbose
):
# minimal difference between primary delay steps to process
global
BASEADDR_PORT1_WR
,
VERBOSE
;
global
BASEADDR_PORT1_WR
,
VERBOSE
;
saved_verbose
=
VERBOSE
;
saved_verbose
=
VERBOSE
;
...
@@ -1868,36 +2046,36 @@ def scan_dq_idelay_random(
...
@@ -1868,36 +2046,36 @@ def scan_dq_idelay_random(
for
i
in
range
(
512
):
for
i
in
range
(
512
):
rand16
.
append
(
random
.
randint
(
0
,
65535
))
rand16
.
append
(
random
.
randint
(
0
,
65535
))
wdata
=
convert_mem16_to_w32
(
rand16
)
wdata
=
convert_mem16_to_w32
(
rand16
)
print
(
"rand16:"
)
if
(
verbose
and
not
adjust
):
print
(
"rand16:"
)
for
i
in
range
(
len
(
rand16
)):
for
i
in
range
(
len
(
rand16
)):
if
(
i
&
0x1f
)
==
0
:
if
(
i
&
0x1f
)
==
0
:
print
(
"
\n
%03
x:"
%
i
,
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
%03
x:"
%
i
,
end
=
" "
)
print
(
"
%04
x"
%
rand16
[
i
],
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
%04
x"
%
rand16
[
i
],
end
=
" "
)
print
(
"
\n
"
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
"
)
print
(
"wdata:"
)
if
(
verbose
and
not
adjust
):
print
(
"wdata:"
)
for
i
in
range
(
len
(
wdata
)):
for
i
in
range
(
len
(
wdata
)):
if
(
i
&
0xf
)
==
0
:
if
(
i
&
0xf
)
==
0
:
print
(
"
\n
%03
x:"
%
i
,
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
%03
x:"
%
i
,
end
=
" "
)
print
(
"
%08
x"
%
wdata
[
i
],
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
%08
x"
%
wdata
[
i
],
end
=
" "
)
print
(
"
\n
"
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
"
)
bit_type
=
[]
# does not include first and last elements
bit_type
=
[]
# does not include first and last elements
for
i
in
range
(
1
,
511
):
for
i
in
range
(
1
,
511
):
types
=
[]
types
=
[]
for
j
in
range
(
16
):
for
j
in
range
(
16
):
types
.
append
((((
rand16
[
i
-
1
]
>>
j
)
&
1
)
<<
2
)
|
(((
rand16
[
i
]
>>
j
)
&
1
)
<<
1
)
|
(((
rand16
[
i
+
1
]
>>
j
)
&
1
)))
types
.
append
((((
rand16
[
i
-
1
]
>>
j
)
&
1
)
<<
2
)
|
(((
rand16
[
i
]
>>
j
)
&
1
)
<<
1
)
|
(((
rand16
[
i
+
1
]
>>
j
)
&
1
)))
bit_type
.
append
(
types
)
bit_type
.
append
(
types
)
# print ("i=%d",i)
#
if (verbose and not adjust):
print ("i=%d",i)
# print(types)
#
if (verbose and not adjust):
print(types)
# total_types=[[0]*8]*16 # number of times each type occured in the block for each DQ bit (separate for DG up/down?)
# total_types=[[0]*8]*16 # number of times each type occured in the block for each DQ bit (separate for DG up/down?)
total_types
=
[]
# number of times each type occured in the block for each DQ bit (separate for DG up/down?)
total_types
=
[]
# number of times each type occured in the block for each DQ bit (separate for DG up/down?)
for
i
in
range
(
16
):
total_types
.
append
([
0
]
*
8
)
for
i
in
range
(
16
):
total_types
.
append
([
0
]
*
8
)
for
type
in
bit_type
:
for
type
in
bit_type
:
# print(type)
#
if (verbose and not adjust):
print(type)
for
j
in
range
(
16
):
for
j
in
range
(
16
):
# total_types[j][type[j]]+=1
# total_types[j][type[j]]+=1
total_types
[
j
][
type
[
j
]]
=
total_types
[
j
][
type
[
j
]]
+
1
total_types
[
j
][
type
[
j
]]
=
total_types
[
j
][
type
[
j
]]
+
1
print
(
"
\n
total_types:"
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
total_types:"
)
print
(
total_types
)
if
(
verbose
and
not
adjust
):
print
(
total_types
)
avg_types
=
[
0.0
]
*
8
avg_types
=
[
0.0
]
*
8
N
=
0
N
=
0
...
@@ -1907,8 +2085,8 @@ def scan_dq_idelay_random(
...
@@ -1907,8 +2085,8 @@ def scan_dq_idelay_random(
N
+=
n
N
+=
n
for
i
in
range
(
len
(
avg_types
)):
for
i
in
range
(
len
(
avg_types
)):
avg_types
[
i
]
/=
N
avg_types
[
i
]
/=
N
print
(
"
\a
vg_types:"
)
if
(
verbose
and
not
adjust
):
print
(
"
\a
vg_types:"
)
print
(
avg_types
)
if
(
verbose
and
not
adjust
):
print
(
avg_types
)
#write blobk buffer with 256x32bit data
#write blobk buffer with 256x32bit data
for
i
in
range
(
256
):
for
i
in
range
(
256
):
...
@@ -1918,17 +2096,38 @@ def scan_dq_idelay_random(
...
@@ -1918,17 +2096,38 @@ def scan_dq_idelay_random(
0x1234
,
# 15'h1234, # row address
0x1234
,
# 15'h1234, # row address
0x100
# 10'h100 # column address
0x100
# 10'h100 # column address
)
)
run_write_block
()
if
(
use_odelay
==
0
)
:
wait_sequencer_ready
()
run_write_block
()
wait_sequencer_ready
()
if
VERBOSE
:
print
(
"++++++++ block written once"
)
#now scanning - first DQS, then try with DQ (post-adjustment - best fit)
#now scanning - first DQS, then try with DQ (post-adjustment - best fit)
results
=
[]
results
=
[]
if
VERBOSE
:
print
(
"******** use_odelay=
%
d use_dq=
%
d"
%
(
use_odelay
,
use_dq
))
for
dly
in
range
(
low
,
high
+
1
):
for
dly
in
range
(
low
,
high
+
1
):
enc_dly
=
combine_delay
(
dly
)
enc_dly
=
combine_delay
(
dly
)
if
(
use_dq
!=
0
):
if
(
use_odelay
!=
0
)
:
axi_set_dq_idelay
(
enc_dly
)
if
(
use_dq
!=
0
):
if
VERBOSE
:
print
(
"******** axi_set_dq_odelay(0x
%
x)"
%
enc_dly
)
axi_set_dq_odelay
(
enc_dly
)
# set the same odelay for all DQ bits
else
:
if
VERBOSE
:
print
(
"******** axi_set_dqs_odelay(0x
%
x)"
%
enc_dly
)
axi_set_dqs_odelay
(
enc_dly
)
run_write_block
()
wait_sequencer_ready
()
if
VERBOSE
:
print
(
"-------- block written AGAIN"
)
else
:
else
:
axi_set_dqs_idelay_individual
(
enc_dly
,
enc_dly
)
if
(
use_dq
!=
0
):
if
VERBOSE
:
print
(
"******** axi_set_dq_idelay(0x
%
x)"
%
enc_dly
)
axi_set_dq_idelay
(
enc_dly
)
# set the same idelay for all DQ bits
else
:
if
VERBOSE
:
print
(
"******** axi_set_dqs_idelay(0x
%
x)"
%
enc_dly
)
axi_set_dqs_idelay
(
enc_dly
)
run_read_block
()
run_read_block
()
wait_sequencer_ready
()
wait_sequencer_ready
()
buf32
=
read_buf
(
256
)
buf32
=
read_buf
(
256
)
...
@@ -1937,20 +2136,20 @@ def scan_dq_idelay_random(
...
@@ -1937,20 +2136,20 @@ def scan_dq_idelay_random(
else
:
else
:
read16
=
convert_w32_to_mem16
(
buf32
)
# 512x16 bit, same as DDR3 DQ over time
read16
=
convert_w32_to_mem16
(
buf32
)
# 512x16 bit, same as DDR3 DQ over time
if
VERBOSE
and
(
dly
==
low
):
if
VERBOSE
and
(
dly
==
low
):
print
(
"buf32:"
)
if
(
verbose
and
not
adjust
):
print
(
"buf32:"
)
for
i
in
range
(
len
(
buf32
)):
for
i
in
range
(
len
(
buf32
)):
if
(
i
&
0xf
)
==
0
:
if
(
i
&
0xf
)
==
0
:
print
(
"
\n
%03
x:"
%
i
,
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
%03
x:"
%
i
,
end
=
" "
)
print
(
"
%08
x"
%
buf32
[
i
],
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
%08
x"
%
buf32
[
i
],
end
=
" "
)
print
(
"
\n
"
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
"
)
print
(
"read16:"
)
if
(
verbose
and
not
adjust
):
print
(
"read16:"
)
for
i
in
range
(
len
(
read16
)):
for
i
in
range
(
len
(
read16
)):
if
(
i
&
0x1f
)
==
0
:
if
(
i
&
0x1f
)
==
0
:
print
(
"
\n
%03
x:"
%
i
,
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
%03
x:"
%
i
,
end
=
" "
)
print
(
"
%04
x"
%
read16
[
i
],
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
%04
x"
%
read16
[
i
],
end
=
" "
)
print
(
"
\n
"
)
if
(
verbose
and
not
adjust
):
print
(
"
\n
"
)
# exit (0)
# exit (0)
# data=[[0]*8]*16 # for each bit - 8 types
# data=[[0]*8]*16 # for each bit - 8 types
...
@@ -1969,30 +2168,19 @@ def scan_dq_idelay_random(
...
@@ -1969,30 +2168,19 @@ def scan_dq_idelay_random(
if
(
total_types
[
i
][
t
]
>
0
):
if
(
total_types
[
i
][
t
]
>
0
):
data
[
i
][
t
]
*=
1.0
/
total_types
[
i
][
t
]
data
[
i
][
t
]
*=
1.0
/
total_types
[
i
][
t
]
results
.
append
(
data
)
results
.
append
(
data
)
print
(
"
%3
d (0x
%02
x): "
%
(
dly
,
enc_dly
),
end
=
""
)
if
(
verbose
and
not
adjust
):
print
(
"
%3
d (0x
%02
x): "
%
(
dly
,
enc_dly
),
end
=
""
)
for
i
in
range
(
16
):
for
i
in
range
(
16
):
print
(
"["
,
end
=
""
)
if
(
verbose
and
not
adjust
):
print
(
"["
,
end
=
""
)
for
j
in
range
(
8
):
for
j
in
range
(
8
):
print
(
"
%3
d"
%
(
round
(
100.0
*
data
[
i
][
j
])),
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"
%3
d"
%
(
round
(
100.0
*
data
[
i
][
j
])),
end
=
" "
)
print
(
"]"
,
end
=
" "
)
if
(
verbose
and
not
adjust
):
print
(
"]"
,
end
=
" "
)
print
()
if
(
verbose
and
not
adjust
):
print
()
titles
=
[
"'000"
,
"'001"
,
"'010"
,
"'011"
,
"'100"
,
"'101"
,
"'110"
,
"'111"
]
titles
=
[
"'000"
,
"'001"
,
"'010"
,
"'011"
,
"'100"
,
"'101"
,
"'110"
,
"'111"
]
print
(
"delay"
,
end
=
" "
)
for
t
in
range
(
8
):
for
i
in
range
(
16
):
print
(
"
%02
d:
%
s"
%
(
i
,
titles
[
t
]),
end
=
" "
)
print
()
for
dly
in
range
(
len
(
results
)):
if
(
len
(
results
[
dly
])
>
0
):
print
(
"
%
d"
%
(
dly
+
low
),
end
=
" "
)
for
t
in
range
(
8
):
for
i
in
range
(
16
):
print
(
"
%.4
f"
%
(
results
[
dly
][
i
][
t
]),
end
=
" "
)
print
()
#calculate weighted averages
#calculate weighted averages
#TODO: for DQ scan shift individula bits for the best match
#TODO: for DQ scan shift individula bits for the best match
if
use_dq
:
if
use_dq
:
print
(
"TODO: shift individual bits for the best match before averaging"
)
if
(
verbose
and
not
adjust
):
print
(
"TODO: shift individual bits for the best match before averaging"
)
res_avg
=
[]
res_avg
=
[]
for
dly
in
range
(
len
(
results
)):
for
dly
in
range
(
len
(
results
)):
if
(
len
(
results
[
dly
])
>
0
):
if
(
len
(
results
[
dly
])
>
0
):
...
@@ -2010,29 +2198,111 @@ def scan_dq_idelay_random(
...
@@ -2010,29 +2198,111 @@ def scan_dq_idelay_random(
res_avg
.
append
(
avg
)
res_avg
.
append
(
avg
)
else
:
else
:
res_avg
.
append
([])
res_avg
.
append
([])
print
(
"delay"
,
end
=
" "
)
for
t
in
range
(
8
):
print
(
titles
[
t
],
end
=
" "
)
print
()
for
dly
in
range
(
len
(
res_avg
)):
if
(
len
(
res_avg
[
dly
])
>
0
):
print
(
"
%
d"
%
(
dly
+
low
),
end
=
" "
)
for
t
in
range
(
8
):
print
(
"
%.4
f"
%
(
res_avg
[
dly
][
t
]),
end
=
" "
)
print
()
corr_fine
=
calibrate_finedelay
(
corr_fine
=
calibrate_finedelay
(
low
,
# absolute delay value of start scan
low
,
# absolute delay value of start scan
avg_types
,
# weights of weach of the 8 bit sequences
avg_types
,
# weights of weach of the 8 bit sequences
res_avg
,
# averaged eye data tablle, each line has 8 elements, or [] for bad measurements
res_avg
,
# averaged eye data tablle, each line has 8 elements, or [] for bad measurements
ends_dist
/
256.0
,
# ends_dist, # do not process if one of the primary interval ends is within this from 0.0 or 1.0
ends_dist
/
256.0
,
# ends_dist, # do not process if one of the primary interval ends is within this from 0.0 or 1.0
min_diff
/
256.0
)
#min_diff): # minimal difference between primary delay steps to process
min_diff
/
256.0
)
#min_diff): # minimal difference between primary delay steps to process
period
=
len
(
corr_fine
)
VEBOSE
=
saved_verbose
if
(
not
adjust
):
print
(
"
\n\n\n
========== Copy below to the spreadsheet, use columns from corr_delay =========="
)
print
(
"========== First are individual results for each bit, then averaged eye pattern =========="
)
print
(
"delay corr_delay"
,
end
=
" "
)
for
t
in
range
(
8
):
for
i
in
range
(
16
):
if
(
not
adjust
):
print
(
"
%02
d:
%
s"
%
(
i
,
titles
[
t
]),
end
=
" "
)
print
()
for
index
in
range
(
len
(
results
)):
if
(
len
(
results
[
index
])
>
0
):
dly
=
index
+
low
corr_dly
=
dly
+
corr_fine
[
dly
%
period
]
print
(
"
%
d
%.2
f"
%
(
dly
,
corr_dly
),
end
=
" "
)
for
t
in
range
(
8
):
for
i
in
range
(
16
):
print
(
"
%.4
f"
%
(
results
[
dly
][
i
][
t
]),
end
=
" "
)
print
()
print
(
"
\n\n\n
========== Copy below to the spreadsheet, use columns from corr_delay =========="
)
print
(
"========== data above can be used for the individual bits eye patterns =========="
)
print
(
"delay corr_delay"
,
end
=
" "
)
for
t
in
range
(
8
):
print
(
titles
[
t
],
end
=
" "
)
print
()
for
index
in
range
(
len
(
res_avg
)):
if
(
len
(
res_avg
[
index
])
>
0
):
dly
=
index
+
low
corr_dly
=
dly
+
corr_fine
[
dly
%
period
]
print
(
"
%
d
%.2
f"
%
(
dly
,
corr_dly
),
end
=
" "
)
for
t
in
range
(
8
):
print
(
"
%.4
f"
%
(
res_avg
[
dly
][
t
]),
end
=
" "
)
print
()
dly_corr
=
None
if
adjust
:
dly_corr
=
corr_delays
(
low
,
# absolute delay value of start scan
avg_types
,
# weights of weach of the 8 bit sequences
results
,
#individual per-bit results
res_avg
,
# averaged eye data tablle, each line has 8 elements, or [] for bad measurements
corr_fine
,
# fine delay correction
ends_dist
/
256.0
,
# find where all bits are above/below that distance from 0.0/1.0margin
verbose
)
VERBOSE
=
verbose
print
(
"VERBOSE="
,
VERBOSE
)
print
(
"dly_corr="
,
dly_corr
)
print
(
"use_dq="
,
use_dq
)
if
dly_corr
and
use_dq
:
# only adjusting DQ delays, not DQS
if
use_odelay
:
for
i
in
range
(
8
):
axi_set_dly_single
(
0
,
i
,
combine_delay
(
dly_corr
[
i
]))
for
i
in
range
(
8
):
axi_set_dly_single
(
2
,
i
,
combine_delay
(
dly_corr
[
i
+
8
]))
else
:
for
i
in
range
(
8
):
axi_set_dly_single
(
1
,
i
,
combine_delay
(
dly_corr
[
i
]))
for
i
in
range
(
8
):
axi_set_dly_single
(
3
,
i
,
combine_delay
(
dly_corr
[
i
+
8
]))
# use_dq, # 0 - scan dqs, 1 - scan dq (common valuwe, post-adjustment)
# use_odelay,
VEBOSE
=
saved_verbose
return
dly_corr
def
scan_delay_random
(
low_delay
,
high_delay
,
use_dq
,
# 0 - scan dqs, 1 - scan dq (common valuwe, post-adjustment)
use_odelay
,
# 0 - idelay, 1 - odelay
ends_dist
,
# do not process if one of the primary interval ends is within this from 0.0 or 1.0
min_diff
,
verbose
):
# minimal difference between primary delay steps to process
scan_or_adjust_delay_random
(
low_delay
,
high_delay
,
use_dq
,
# 0 - scan dqs, 1 - scan dq (common valuwe, post-adjustment)
use_odelay
,
ends_dist
,
# do not process if one of the primary interval ends is within this from 0.0 or 1.0
min_diff
,
False
,
#scan, not adjust
verbose
)
# minimal difference between primary delay steps to process
def
adjust_dq_delay_random
(
low_delay
,
high_delay
,
#use_dq, # 0 - scan dqs, 1 - scan dq (common valuwe, post-adjustment)
use_odelay
,
ends_dist
,
# do not process if one of the primary interval ends is within this from 0.0 or 1.0
min_diff
,
verbose
):
# minimal difference between primary delay steps to process
scan_or_adjust_delay_random
(
low_delay
,
high_delay
,
1
,
#use_dq, # 0 - scan dqs, 1 - scan dq (common valuwe, post-adjustment)
use_odelay
,
ends_dist
,
# do not process if one of the primary interval ends is within this from 0.0 or 1.0
min_diff
,
True
,
#adjust, not scan
verbose
)
# minimal difference between primary delay steps to process
# main
# main
if
len
(
sys
.
argv
)
<
2
:
if
len
(
sys
.
argv
)
<
2
:
print
(
"Usage:
%
s command [hex_parameter, ...]"
%
sys
.
argv
[
0
])
print
(
"Usage:
%
s command [hex_parameter, ...]"
%
sys
.
argv
[
0
])
...
@@ -2213,9 +2483,9 @@ elif command=="axi_set_tristate_patterns":
...
@@ -2213,9 +2483,9 @@ elif command=="axi_set_tristate_patterns":
axi_set_tristate_patterns
()
axi_set_tristate_patterns
()
print
(
"axi_set_tristate_patterns() OK"
)
print
(
"axi_set_tristate_patterns() OK"
)
elif
command
==
"axi_set_dqs_dqm_patterns"
:
elif
command
==
"axi_set_dqs_dqm_patterns"
:
check_args
(
0
,
command
,
args
)
check_args
(
1
,
command
,
args
)
axi_set_dqs_dqm_patterns
()
axi_set_dqs_dqm_patterns
(
args
[
0
]
)
print
(
"axi_set_dqs_dqm_patterns(
) OK"
)
print
(
"axi_set_dqs_dqm_patterns(
0x
%
x) OK"
%
(
args
[
0
])
)
elif
command
==
"set_all_sequences"
:
elif
command
==
"set_all_sequences"
:
check_args
(
0
,
command
,
args
)
check_args
(
0
,
command
,
args
)
...
@@ -2237,10 +2507,15 @@ elif command=="scan_dq_idelay":
...
@@ -2237,10 +2507,15 @@ elif command=="scan_dq_idelay":
scan_dq_idelay
(
args
[
0
],
args
[
1
],
args
[
2
])
scan_dq_idelay
(
args
[
0
],
args
[
1
],
args
[
2
])
print
(
"scan_dq_idelay(0x
%
x,0x
%
x,0x
%
x) OK"
%
(
args
[
0
],
args
[
1
],
args
[
2
]))
print
(
"scan_dq_idelay(0x
%
x,0x
%
x,0x
%
x) OK"
%
(
args
[
0
],
args
[
1
],
args
[
2
]))
elif
command
==
"scan_dq_idelay_random"
:
elif
command
==
"scan_delay_random"
:
check_args
(
5
,
command
,
args
)
check_args
(
7
,
command
,
args
)
scan_dq_idelay_random
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
])
scan_delay_random
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
])
print
(
"scan_dq_idelay_random(0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x) OK"
%
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
]))
print
(
"scan_delay_random(0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x) OK"
%
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
]))
elif
command
==
"adjust_dq_delay_random"
:
check_args
(
6
,
command
,
args
)
adjust_dq_delay_random
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
])
print
(
"adjust_dq_delay_random(0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x,0x
%
x) OK"
%
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
]))
elif
command
==
"adjust_dq_idelay"
:
elif
command
==
"adjust_dq_idelay"
:
check_args
(
4
,
command
,
args
)
check_args
(
4
,
command
,
args
)
...
...
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