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
a0c1b572
Commit
a0c1b572
authored
May 14, 2014
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more code for ddr3 phy
parent
c73e99f3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
159 additions
and
5 deletions
+159
-5
phy_top.v
phy/phy_top.v
+159
-5
No files found.
phy/phy_top.v
View file @
a0c1b572
...
@@ -24,15 +24,36 @@ module phy_top #(
...
@@ -24,15 +24,36 @@ module phy_top #(
parameter
IOSTANDARD_DQ
=
"SSTL15_T_DCI"
,
parameter
IOSTANDARD_DQ
=
"SSTL15_T_DCI"
,
parameter
IOSTANDARD_DQS
=
"DIFF_SSTL15_T_DCI"
,
parameter
IOSTANDARD_DQS
=
"DIFF_SSTL15_T_DCI"
,
parameter
IOSTANDARD_CMDA
=
"SSTL15"
,
parameter
IOSTANDARD_CMDA
=
"SSTL15"
,
parameter
IOSTANDARD_CLK
=
"DIFF_SSTL15"
,
parameter
SLEW_DQ
=
"SLOW"
,
parameter
SLEW_DQ
=
"SLOW"
,
parameter
SLEW_DQS
=
"SLOW"
,
parameter
SLEW_DQS
=
"SLOW"
,
parameter
SLEW_CMDA
=
"SLOW"
,
parameter
SLEW_CMDA
=
"SLOW"
,
parameter
SLEW_CLK
=
"SLOW"
,
parameter
IBUF_LOW_PWR
=
"TRUE"
,
parameter
IBUF_LOW_PWR
=
"TRUE"
,
parameter
IODELAY_GRP
=
"IODELAY_MEMORY"
,
parameter
IODELAY_GRP
=
"IODELAY_MEMORY"
,
parameter
real
REFCLK_FREQUENCY
=
300.0
,
parameter
real
REFCLK_FREQUENCY
=
300.0
,
parameter
HIGH_PERFORMANCE_MODE
=
"FALSE"
,
parameter
HIGH_PERFORMANCE_MODE
=
"FALSE"
,
parameter
integer
ADDRESS_NUMBER
=
15
parameter
integer
ADDRESS_NUMBER
=
15
,
parameter
PHASE_WIDTH
=
8
,
parameter
BANDWIDTH
=
"OPTIMIZED"
,
// Assuming 100MHz input clock, 800MHz Fvco, 400MHz clk, 200MHz clk_div, 200MHz mclk
parameter
CLKIN_PERIOD
=
10
,
//ns >1.25, 600<Fvco<1200
parameter
CLKFBOUT_MULT
=
8
,
// Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter
CLKFBOUT_MULT_REF
=
9
,
// Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter
CLKFBOUT_DIV_REF
=
3
,
// To get 300MHz for the reference clock
parameter
DIVCLK_DIVIDE
=
1
,
parameter
CLKFBOUT_PHASE
=
0.000
,
parameter
CLKOUT0_PHASE
=
0.000
,
parameter
CLKOUT1_PHASE
=
0.000
,
parameter
CLKOUT2_PHASE
=
0.000
,
parameter
CLKOUT3_PHASE
=
0.000
,
parameter
REF_JITTER1
=
0.010
,
parameter
SS_EN
=
"FALSE"
,
parameter
SS_MODE
=
"CENTER_HIGH"
,
parameter
SS_MOD_PERIOD
=
10000
)(
)(
output
ddr3_clk
,
// DDR3 clock differential output, positive
output
ddr3_nclk
,
// DDR3 clock differential output, negative
output
[
ADDRESS_NUMBER
-
1
:
0
]
ddr3_a
,
// output address ports (14:0) for 4Gb device
output
[
ADDRESS_NUMBER
-
1
:
0
]
ddr3_a
,
// output address ports (14:0) for 4Gb device
output
[
2
:
0
]
ddr3_ba
,
// output bank address ports
output
[
2
:
0
]
ddr3_ba
,
// output bank address ports
output
ddr3_we
,
// output WE port
output
ddr3_we
,
// output WE port
...
@@ -49,8 +70,10 @@ module phy_top #(
...
@@ -49,8 +70,10 @@ module phy_top #(
inout
dqsu
,
// UDQS I/O pad
inout
dqsu
,
// UDQS I/O pad
inout
ndqsu
,
// ~UDQS I/O pad
inout
ndqsu
,
// ~UDQS I/O pad
input
clk
,
// free-running system clock, same frequency as iclk (shared for R/W)
input
clk_in
,
// master input clock, initially assuming 100MHz
input
clk_div
,
// free-running half clk frequency, front aligned to clk (shared for R/W)
output
clk
,
// free-running system clock, same frequency as iclk (shared for R/W), BUFR output
output
clk_div
,
// free-running half clk frequency, front aligned to clk (shared for R/W), BUFR output
output
mclk
,
// same as clk_div, through separate BUFG and static phase adjust
input
rst_in
,
// reset delays/serdes
input
rst_in
,
// reset delays/serdes
input
[
2
*
ADDRESS_NUMBER
-
1
:
0
]
in_a
,
// input address, 2 bits per signal (first, second) (29:0) for 4Gb device
input
[
2
*
ADDRESS_NUMBER
-
1
:
0
]
in_a
,
// input address, 2 bits per signal (first, second) (29:0) for 4Gb device
...
@@ -77,7 +100,10 @@ module phy_top #(
...
@@ -77,7 +100,10 @@ module phy_top #(
input
[
7
:
0
]
dly_data
,
// delay value (3 LSB - fine delay)
input
[
7
:
0
]
dly_data
,
// delay value (3 LSB - fine delay)
input
[
6
:
0
]
dly_addr
,
// select which delay to program
input
[
6
:
0
]
dly_addr
,
// select which delay to program
input
ld_delay
,
// load delay data to selected iodelayl (clk_iv synchronous)
input
ld_delay
,
// load delay data to selected iodelayl (clk_iv synchronous)
input
set
// clk_div synchronous set all delays from previously loaded values
input
set
,
// clk_div synchronous set all delays from previously loaded values
output
locked
,
output
ps_rdy
,
output
[
PHASE_WIDTH
-
1
:
0
]
ps_out
)
;
)
;
reg
rst
=
1'b0
;
reg
rst
=
1'b0
;
always
@
(
posedge
clk
or
posedge
rst_in
)
begin
always
@
(
posedge
clk
or
posedge
rst_in
)
begin
...
@@ -87,7 +113,11 @@ module phy_top #(
...
@@ -87,7 +113,11 @@ module phy_top #(
wire
ld_data_l
=
(
dly_addr
[
6
:
5
]
==
2'h0
)
&&
ld_delay
;
wire
ld_data_l
=
(
dly_addr
[
6
:
5
]
==
2'h0
)
&&
ld_delay
;
wire
ld_data_h
=
(
dly_addr
[
6
:
5
]
==
2'h1
)
&&
ld_delay
;
wire
ld_data_h
=
(
dly_addr
[
6
:
5
]
==
2'h1
)
&&
ld_delay
;
wire
ld_cmda
=
(
dly_addr
[
6
:
5
]
==
2'h2
)
&&
ld_delay
;
wire
ld_cmda
=
(
dly_addr
[
6
:
5
]
==
2'h2
)
&&
ld_delay
;
wire
ld_mmcm
=
(
dly_addr
[
6
:
0
]
==
7'h60
)
&&
ld_delay
;
wire
clkfb_ref
,
clk_ref_pre
;
wire
clk_ref
;
// 200MHz/300Mhz to calibrate I/O delays
wire
locked_mmcm
,
locked_pll
,
dly_ready
;
assign
locked
=
locked_mmcm
&&
locked_pll
&&
dly_ready
;
// both PLL ready, I/O delay calibrated
cmd_addr
#(
cmd_addr
#(
.
IODELAY_GRP
(
IODELAY_GRP
)
,
.
IODELAY_GRP
(
IODELAY_GRP
)
,
.
IOSTANDARD
(
IOSTANDARD_CMDA
)
,
.
IOSTANDARD
(
IOSTANDARD_CMDA
)
,
...
@@ -183,6 +213,130 @@ module phy_top #(
...
@@ -183,6 +213,130 @@ module phy_top #(
.
ld_delay
(
ld_data_h
)
,
// load delay data to selected iodelayl (clk_div synchronous)
.
ld_delay
(
ld_data_h
)
,
// load delay data to selected iodelayl (clk_div synchronous)
.
set
(
set
)
// clk_div synchronous set all delays from previously loaded values
.
set
(
set
)
// clk_div synchronous set all delays from previously loaded values
)
;
)
;
//ddr3_clk
wire
iclk
;
// BUFIO
oddr_ds
#(
.
IOSTANDARD
(
IOSTANDARD_CLK
)
,
.
SLEW
(
SLEW_CLK
)
)
oddr_ds_i
(
.
clk
(
iclk
)
,
// input
.
ce
(
1'b1
)
,
// input
.
rst
(
1'b0
)
,
// input
.
set
(
1'b0
)
,
// input
.
din
(
2'b01
)
,
// input[1:0]
.
dq
(
ddr3_clk
)
,
// output
.
ndq
(
ddr3_nclk
)
// output
)
;
// Clocks: MMCM is used to generate ddr3 differential clock (no dynamic phase shift),
// clk - write bit clock, phase dynamically adjusted, BUFR (initially 400MHz)
// clk_div half bit frequency clock, phase dynamically adjusted, BUFR. Used also for delay/phase control (200MHz)
// mclk - same frequency as clk_div (same dynamic phase adjust), but with BUFG to be used in other regions. Phase to be
// statically adjusted for clock boundary crossing
// Phase control included, allowing setting phase in +/- 127 steps, each 1/56 of 1/Fvco (~22ps for Fvco=800MHz)
wire
clk_pre
,
clk_div_pre
,
iclk_pre
,
mclk_pre
,
clk_fb
;
BUFR
clk_bufr_i
(
.
O
(
clk
)
,
.
CE
()
,
.
CLR
()
,
.
I
(
clk_pre
))
;
BUFR
clk_div_bufr_i
(
.
O
(
clk_div
)
,
.
CE
()
,
.
CLR
()
,
.
I
(
clk_div_pre
))
;
BUFIO
iclk_bufio_i
(
.
O
(
iclk
)
,
.
I
(
iclk_pre
)
)
;
BUFIO
clk_ref_i
(
.
O
(
clk_ref
)
,
.
I
(
clk_ref_pre
))
;
BUFG
mclk_i
(
.
O
(
mclk
)
,.
I
(
mclk_pre
)
)
;
/* Instance template for module mmcm_phase_cntr */
mmcm_phase_cntr
#(
.
PHASE_WIDTH
(
PHASE_WIDTH
)
,
.
CLKIN_PERIOD
(
CLKIN_PERIOD
)
,
.
BANDWIDTH
(
BANDWIDTH
)
,
.
CLKFBOUT_MULT_F
(
CLKFBOUT_MULT
)
,
.
DIVCLK_DIVIDE
(
DIVCLK_DIVIDE
)
,
.
CLKFBOUT_PHASE
(
CLKFBOUT_PHASE
)
,
.
CLKOUT0_PHASE
(
CLKOUT0_PHASE
)
,
.
CLKOUT1_PHASE
(
CLKOUT1_PHASE
)
,
.
CLKOUT2_PHASE
(
CLKOUT2_PHASE
)
,
.
CLKOUT3_PHASE
(
CLKOUT3_PHASE
)
,
// .CLKOUT4_PHASE (0.000),
// .CLKOUT5_PHASE (0.000),
// .CLKOUT6_PHASE (0.000),
.
CLKFBOUT_USE_FINE_PS
(
"FALSE"
)
,
.
CLKOUT0_USE_FINE_PS
(
"FALSE"
)
,
.
CLKOUT1_USE_FINE_PS
(
"TRUE"
)
,
.
CLKOUT2_USE_FINE_PS
(
"TRUE"
)
,
.
CLKOUT3_USE_FINE_PS
(
"TRUE"
)
,
// .CLKOUT4_USE_FINE_PS("FALSE"),
// .CLKOUT5_USE_FINE_PS("FALSE"),
// .CLKOUT6_USE_FINE_PS("FALSE"),
.
CLKOUT0_DIVIDE_F
(
2.000
)
,
.
CLKOUT1_DIVIDE
(
2
)
,
.
CLKOUT2_DIVIDE
(
4
)
,
.
CLKOUT3_DIVIDE
(
4
)
,
// .CLKOUT4_DIVIDE(1),
// .CLKOUT5_DIVIDE(1),
// .CLKOUT6_DIVIDE(1),
.
COMPENSATION
(
"ZHOLD"
)
,
.
REF_JITTER1
(
REF_JITTER1
)
,
// .REF_JITTER2(0.010),
.
SS_EN
(
SS_EN
)
,
.
SS_MODE
(
SS_MODE
)
,
.
SS_MOD_PERIOD
(
SS_MOD_PERIOD
)
,
.
STARTUP_WAIT
(
"FALSE"
)
)
mmcm_phase_cntr_i
(
.
clkin
(
clk_in
)
,
// input
.
clkfbin
(
clk_fb
)
,
// input
.
rst
(
rst
)
,
// input
.
pwrdwn
(
1'b0
)
,
// input
.
psclk
(
clk_div
)
,
// input
.
ps_we
(
ld_mmcm
)
,
// input
.
ps_din
(
dly_data
)
,
// input[7:0]
.
ps_ready
(
ps_rdy
)
,
// output
.
ps_dout
(
ps_out
)
,
// output[7:0] reg
.
clkout0
(
iclk_pre
)
,
// output
.
clkout1
(
clk_pre
)
,
// output
.
clkout2
(
clk_div_pre
)
,
// output
.
clkout3
(
mclk_pre
)
,
// output
.
clkout4
()
,
// output
.
clkout5
()
,
// output
.
clkout6
()
,
// output
.
clkout0b
()
,
// output
.
clkout1b
()
,
// output
.
clkout2b
()
,
// output
.
clkout3b
()
,
// output
.
clkfbout
(
clk_fb
)
,
// output
.
clkfboutb
()
,
// output
.
locked
(
locked_mmcm
)
// output
)
;
// Generate reference clock for the I/O delays
/*
parameter CLKFBOUT_MULT_REF = 9, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter CLKFBOUT_DIV_REF = 3, // To get 300MHz for the reference clock
Instance template for module pll_base */
pll_base
#(
.
CLKIN_PERIOD
(
CLKIN_PERIOD
)
,
.
BANDWIDTH
(
"OPTIMIZED"
)
,
.
CLKFBOUT_MULT
(
CLKFBOUT_MULT_REF
)
,
.
CLKOUT0_DIVIDE
(
CLKFBOUT_DIV_REF
)
,
.
REF_JITTER1
(
0.010
)
,
.
STARTUP_WAIT
(
"FALSE"
)
)
pll_base_i
(
.
clkin
(
clk_in
)
,
// input
.
clkfbin
(
clkfb_ref
)
,
// input
.
rst
(
rst
)
,
// input
.
pwrdwn
(
1'b0
)
,
// input
.
clkout0
(
clk_ref_pre
)
,
// output
.
clkout1
()
,
// output
.
clkout2
()
,
// output
.
clkout3
()
,
// output
.
clkout4
()
,
// output
.
clkout5
()
,
// output
.
clkfbout
(
clkfb_ref
)
,
// output
.
locked
(
locked_pll
)
// output
)
;
// Does it need to be re-calibrated periodically?
idelay_ctrl
#
(
.
IODELAY_GRP
(
"IODELAY_MEMORY"
)
)
idelay_ctrl_i
(
.
refclk
(
clk_ref
)
,
.
rst
(
rst
)
,
.
rdy
(
dly_ready
)
)
;
endmodule
endmodule
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