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
d6733779
Commit
d6733779
authored
May 17, 2014
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
just a snapshot
parent
c7b65d94
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
861 additions
and
17 deletions
+861
-17
byte_lane.v
phy/byte_lane.v
+4
-2
cmd_addr.v
phy/cmd_addr.v
+5
-5
ddr3c16.v
phy/ddr3c16.v
+193
-0
phy_cmd.v
phy/phy_cmd.v
+317
-0
phy_top.v
phy/phy_top.v
+3
-3
test_phy_top_01.v
phy/test_phy_top_01.v
+1
-1
ram_1kx32_1kx32.v
wrap/ram_1kx32_1kx32.v
+6
-6
ram_1kx32w_512x64r.v
wrap/ram_1kx32w_512x64r.v
+166
-0
ram_512x64w_1kx32r.v
wrap/ram_512x64w_1kx32r.v
+166
-0
No files found.
phy/byte_lane.v
View file @
d6733779
...
...
@@ -111,10 +111,12 @@ generate
.
rst
(
rst
)
,
.
dci_disable
(
dci_disable_dq_r
)
,
// disable DCI termination during writes and idle
.
dly_data
(
dly_data_r
)
,
// delay value (3 LSB - fine delay)
.
din
(
din_r
[
4
*
i
+
3
:
4
*
i
])
,
// parallel data to be sent out
.
din
(
{
din_r
[
i
+
24
]
,
din_r
[
i
+
16
]
,
din_r
[
i
+
8
]
,
din_r
[
i
]
}
)
,
// parallel data to be sent out
// .din(din_r[4*i+3:4*i]) , // parallel data to be sent out
// .din(din_r[4*i+3-:4]) , // parallel data to be sent out
.
tin
(
tin_dq_r
)
,
// tristate for data out (sent out earlier than data!)
.
dout
(
dout
[
4
*
i
+
3
:
4
*
i
])
,
// parallel data received from DDR3 memory
.
dout
(
{
dout
[
i
+
24
]
,
dout
[
i
+
16
]
,
dout
[
i
+
8
]
,
dout
[
i
]
}
)
,
// parallel data received from DDR3 memory
// .dout(dout[4*i+3:4*i]), // parallel data received from DDR3 memory
.
set_odelay
(
set_r
)
,
// clk_div synchronous load odelay value from dly_data
.
ld_odelay
(
ld_odly
[
i
])
,
// clk_div synchronous set odealy value from loaded
.
set_idelay
(
set_r
)
,
// clk_div synchronous load idelay value from dly_data
...
...
phy/cmd_addr.v
View file @
d6733779
...
...
@@ -49,7 +49,7 @@ module cmd_addr #(
input
in_tri
,
// tristate command/address outputs - same timing, but no odelay
input
[
7
:
0
]
dly_data
,
// delay value (3 LSB - fine delay)
input
[
4
:
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_
d
iv synchronous)
input
set
// clk_div synchronous set all delays from previously loaded values
)
;
reg
[
2
*
ADDRESS_NUMBER
-
1
:
0
]
in_a_r
=
0
;
...
...
@@ -110,7 +110,7 @@ generate
.
clk_div
(
clk_div
)
,
// free-running half clk frequency, front aligned to clk (shared for R/W)
.
rst
(
rst
)
,
.
dly_data
(
dly_data_r
[
7
:
0
])
,
// delay value (3 LSB - fine delay)
.
din
(
in_a_r
[
2
*
i
+
1
:
2
*
i
]
)
,
// parallel data to be sent out
.
din
(
{
in_a_r
[
ADDRESS_NUMBER
+
i
]
,
in_a_r
[
i
]
}
)
,
// parallel data to be sent out
// .tin(in_tri_r[1:0]), // tristate for data out (sent out earlier than data!)
.
tin
(
in_tri_r
)
,
// tristate for data out (sent out earlier than data!)
.
set_delay
(
set_r
)
,
// clk_div synchronous load odelay value from dly_data
...
...
@@ -132,7 +132,7 @@ endgenerate
.
clk_div
(
clk_div
)
,
.
rst
(
rst
)
,
.
dly_data
(
dly_data_r
[
7
:
0
])
,
.
din
(
in_ba_r
[
1
:
0
]
)
,
.
din
(
{
in_ba_r
[
3
]
,
in_ba_r
[
0
]
}
)
,
// .tin(in_tri_r[1:0]),
.
tin
(
in_tri_r
)
,
.
set_delay
(
set_r
)
,
...
...
@@ -150,7 +150,7 @@ endgenerate
.
clk_div
(
clk_div
)
,
.
rst
(
rst
)
,
.
dly_data
(
dly_data_r
[
7
:
0
])
,
.
din
(
in_ba_r
[
3
:
2
]
)
,
.
din
(
{
in_ba_r
[
4
]
,
in_ba_r
[
1
]
}
)
,
// .tin(in_tri_r[1:0]),
.
tin
(
in_tri_r
)
,
.
set_delay
(
set_r
)
,
...
...
@@ -168,7 +168,7 @@ endgenerate
.
clk_div
(
clk_div
)
,
.
rst
(
rst
)
,
.
dly_data
(
dly_data_r
[
7
:
0
])
,
.
din
(
in_ba_r
[
5
:
4
]
)
,
.
din
(
{
in_ba_r
[
5
]
,
in_ba_r
[
2
]
}
)
,
// .tin(in_tri_r[1:0]),
.
tin
(
in_tri_r
)
,
.
set_delay
(
set_r
)
,
...
...
phy/ddr3c16.v
0 → 100644
View file @
d6733779
/*******************************************************************************
* Module: ddr3c16
* Date:2014-05-16
* Author: Andrey Filippov
* Description: ddr3 controller, 16 channel
*
* Copyright (c) 2014 Elphel, Inc.
* ddr3c16.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ddr3c16.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale
1
ns
/
1
ps
module
ddr3c16
#(
parameter
PHASE_WIDTH
=
8
,
parameter
SLEW_DQ
=
"SLOW"
,
parameter
SLEW_DQS
=
"SLOW"
,
parameter
SLEW_CMDA
=
"SLOW"
,
parameter
SLEW_CLK
=
"SLOW"
,
parameter
IBUF_LOW_PWR
=
"TRUE"
,
parameter
real
REFCLK_FREQUENCY
=
300.0
,
parameter
HIGH_PERFORMANCE_MODE
=
"FALSE"
,
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
ICLK_PHASE
=
0.000
,
parameter
CLK_PHASE
=
0.000
,
parameter
CLK_DIV_PHASE
=
0.000
,
parameter
MCLK_PHASE
=
90.000
,
parameter
REF_JITTER1
=
0.010
,
parameter
SS_EN
=
"FALSE"
,
parameter
SS_MODE
=
"CENTER_HIGH"
,
parameter
SS_MOD_PERIOD
=
10000
,
parameter
DQSTRI_FIRST
=
4'h3
,
// DQS tri-state control word, first when enabling output
parameter
DQSTRI_LAST
=
4'hc
,
// DQS tri-state control word, first after disabling output
parameter
DQTRI_FIRST
=
4'h7
,
// DQ tri-state control word, first when enabling output
parameter
DQTRI_LAST
=
4'he
// DQ tri-state control word, first after disabling output
)(
// DDR3 interface
output
SDCLK
,
// DDR3 clock differential output, positive
output
SDNCLK
,
// DDR3 clock differential output, negative
output
[
ADDRESS_NUMBER
-
1
:
0
]
SDA
,
// output address ports (14:0) for 4Gb device
output
[
2
:
0
]
SDBA
,
// output bank address ports
output
SDWE
,
// output WE port
output
SDRAS
,
// output RAS port
output
SDCAS
,
// output CAS port
output
SDCKE
,
// output Clock Enable port
output
SDODT
,
// output ODT port
inout
[
15
:
0
]
SDD
,
// DQ I/O pads
inout
SDDML
,
// LDM I/O pad (actually only output)
inout
DQSL
,
// LDQS I/O pad
inout
NDQSL
,
// ~LDQS I/O pad
inout
SDDMU
,
// UDM I/O pad (actually only output)
inout
DQSU
,
// UDQS I/O pad
inout
NDQSU
,
// ~UDQS I/O pad
// clocks, reset
input
clk_in
,
input
rst_in
,
output
mclk
,
// global clock, half DDR3 clock, synchronizes all I/O thorough the command port
// command port 0 (filled by software - 32w->64r) - used for mode set, refresh, write levelling, ...
input
cmd0_we
,
input
[
9
:
0
]
cmd0_addr
,
input
[
31
:
0
]
cmd0_data
,
// TODO: add automatic command port1 , filled by the PL, 36w 36r, used for actual page R/W
input
cmd1_we
,
input
[
9
:
0
]
cmd1_addr
,
input
[
35
:
0
]
cmd1_data
,
// Controller run interface, posedge mclk
input
[
10
:
0
]
run_addr
,
// controller sequencer start address (0..11'h1ff - cmd0, 11'h400..11'h7ff - cmd1)
input
[
3
:
0
]
run_chn
,
// data channel to use
input
run_seq
,
// start controller sequence
output
run_done
,
// controller sequence finished
// inteface to control I/O delays and mmcm
input
[
7
:
0
]
dly_data
,
// delay value (3 LSB - fine delay)
input
[
6
:
0
]
dly_addr
,
// select which delay to program
input
ld_delay
,
// load delay data to selected iodelayl (clk_div synchronous)
input
set
,
// clk_div synchronous set all delays from previously loaded values
output
locked
,
output
ps_rdy
,
output
[
PHASE_WIDTH
-
1
:
0
]
ps_out
,
// read port 0
input
port0_clk
,
input
port0_re
,
input
port0_regen
,
input
[
1
:
0
]
port0_page
,
input
[
1
:
0
]
port0_int_page
,
input
[
7
:
0
]
port0_addr
,
output
[
31
:
0
]
port0_data
,
// write port 1
input
port1_clk
,
input
port1_we
,
input
[
1
:
0
]
port1_page
,
input
[
1
:
0
]
port1_int_page
,
input
[
7
:
0
]
port1_addr
,
input
[
31
:
0
]
port1_data
,
// extras
input
cmda_tri
,
// tristate command and address lines // not likely to be used
input
inv_clk_div
,
input
[
7
:
0
]
dqs_pattern
,
// 8'h55
input
[
7
:
0
]
dqm_pattern
// 8'h00
)
;
localparam
ADDRESS_NUMBER
=
15
;
wire
[
35
:
0
]
phy_cmd
;
// input[35:0]
wire
[
6
:
0
]
buf_addr
;
// output[6:0]
wire
[
63
:
0
]
buf_wdata
;
// output[63:0]
wire
[
63
:
0
]
buf_rdata
;
// input[63:0]
wire
buf_wr
;
// output
wire
buf_rd
;
// output
phy_cmd
#(
.
ADDRESS_NUMBER
(
ADDRESS_NUMBER
)
,
.
PHASE_WIDTH
(
PHASE_WIDTH
)
,
.
SLEW_DQ
(
SLEW_DQ
)
,
.
SLEW_DQS
(
SLEW_DQS
)
,
.
SLEW_CMDA
(
SLEW_CMDA
)
,
.
SLEW_CLK
(
SLEW_CLK
)
,
.
IBUF_LOW_PWR
(
IBUF_LOW_PWR
)
,
.
REFCLK_FREQUENCY
(
REFCLK_FREQUENCY
)
,
.
HIGH_PERFORMANCE_MODE
(
HIGH_PERFORMANCE_MODE
)
,
.
CLKIN_PERIOD
(
CLKIN_PERIOD
)
,
.
CLKFBOUT_MULT
(
CLKFBOUT_MULT
)
,
.
CLKFBOUT_MULT_REF
(
CLKFBOUT_MULT_REF
)
,
.
CLKFBOUT_DIV_REF
(
CLKFBOUT_DIV_REF
)
,
.
DIVCLK_DIVIDE
(
DIVCLK_DIVIDE
)
,
.
CLKFBOUT_PHASE
(
CLKFBOUT_PHASE
)
,
.
ICLK_PHASE
(
ICLK_PHASE
)
,
.
CLK_PHASE
(
CLK_PHASE
)
,
.
CLK_DIV_PHASE
(
CLK_DIV_PHASE
)
,
.
MCLK_PHASE
(
MCLK_PHASE
)
,
.
REF_JITTER1
(
REF_JITTER1
)
,
.
SS_EN
(
SS_EN
)
,
.
SS_MODE
(
SS_MODE
)
,
.
SS_MOD_PERIOD
(
SS_MOD_PERIOD
)
)
phy_cmd_i
(
.
SDCLK
(
SDCLK
)
,
// output
.
SDNCLK
(
SDNCLK
)
,
// output
.
SDA
(
SDA
[
ADDRESS_NUMBER
-
1
:
0
])
,
// output[14:0]
.
SDBA
(
SDBA
[
2
:
0
])
,
// output[2:0]
.
SDWE
(
SDWE
)
,
// output
.
SDRAS
(
SDRAS
)
,
// output
.
SDCAS
(
SDCAS
)
,
// output
.
SDCKE
(
SDCKE
)
,
// output
.
SDODT
(
SDODT
)
,
// output
.
SDD
(
SDD
[
15
:
0
])
,
// inout[15:0]
.
SDDML
(
SDDML
)
,
// inout
.
DQSL
(
DQSL
)
,
// inout
.
NDQSL
(
NDQSL
)
,
// inout
.
SDDMU
(
SDDMU
)
,
// inout
.
DQSU
(
DQSU
)
,
// inout
.
NDQSU
(
NDQSU
)
,
// inout
.
clk_in
(
clk_in
)
,
// input
.
rst_in
(
rst_in
)
,
// input
.
mclk
(
mclk
)
,
// output
.
dly_data
(
dly_data
[
7
:
0
])
,
// input[7:0]
.
dly_addr
(
dly_addr
[
6
:
0
])
,
// input[6:0]
.
ld_delay
(
ld_delay
)
,
// input
.
set
(
set
)
,
// input
.
locked
(
locked
)
,
// output
.
ps_rdy
(
ps_rdy
)
,
// output
.
ps_out
(
ps_out
[
7
:
0
])
,
// output[7:0]
.
phy_cmd
(
phy_cmd
[
35
:
0
])
,
// input[35:0]
.
buf_addr
(
buf_addr
[
6
:
0
])
,
// output[6:0]
.
buf_wdata
(
buf_wdata
[
63
:
0
])
,
// output[63:0]
.
buf_rdata
(
buf_rdata
[
63
:
0
])
,
// input[63:0]
.
buf_wr
(
buf_wr
)
,
// output
.
buf_rd
(
buf_rd
)
,
// output
.
cmda_tri
(
cmda_tri
)
,
// input
.
inv_clk_div
(
inv_clk_div
)
,
// input
.
dqs_pattern
(
dqs_pattern
)
,
// input[7:0]
.
dqm_pattern
(
dqm_pattern
)
// input[7:0]
)
;
endmodule
phy/phy_cmd.v
0 → 100644
View file @
d6733779
/*******************************************************************************
* Module: phy_cmd
* Date:2014-05-15
* Author: Andrey Filippov
* Description: Executes a stream of commands to DDR3 phy at 1/2 ddr3 clock, global
* (also proveides r/w interface to the x64 external buffer)
*
* Copyright (c) 2014 Elphel, Inc.
* phy_cmd.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* phy_cmd.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale
1
ns
/
1
ps
module
phy_cmd
#(
parameter
ADDRESS_NUMBER
=
15
,
parameter
PHASE_WIDTH
=
8
,
parameter
SLEW_DQ
=
"SLOW"
,
parameter
SLEW_DQS
=
"SLOW"
,
parameter
SLEW_CMDA
=
"SLOW"
,
parameter
SLEW_CLK
=
"SLOW"
,
parameter
IBUF_LOW_PWR
=
"TRUE"
,
parameter
real
REFCLK_FREQUENCY
=
300.0
,
parameter
HIGH_PERFORMANCE_MODE
=
"FALSE"
,
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
ICLK_PHASE
=
0.000
,
parameter
CLK_PHASE
=
0.000
,
parameter
CLK_DIV_PHASE
=
0.000
,
parameter
MCLK_PHASE
=
90.000
,
parameter
REF_JITTER1
=
0.010
,
parameter
SS_EN
=
"FALSE"
,
parameter
SS_MODE
=
"CENTER_HIGH"
,
parameter
SS_MOD_PERIOD
=
10000
)(
// DDR3 interface
output
SDCLK
,
// DDR3 clock differential output, positive
output
SDNCLK
,
// DDR3 clock differential output, negative
output
[
ADDRESS_NUMBER
-
1
:
0
]
SDA
,
// output address ports (14:0) for 4Gb device
output
[
2
:
0
]
SDBA
,
// output bank address ports
output
SDWE
,
// output WE port
output
SDRAS
,
// output RAS port
output
SDCAS
,
// output CAS port
output
SDCKE
,
// output Clock Enable port
output
SDODT
,
// output ODT port
inout
[
15
:
0
]
SDD
,
// DQ I/O pads
inout
SDDML
,
// LDM I/O pad (actually only output)
inout
DQSL
,
// LDQS I/O pad
inout
NDQSL
,
// ~LDQS I/O pad
inout
SDDMU
,
// UDM I/O pad (actually only output)
inout
DQSU
,
// UDQS I/O pad
inout
NDQSU
,
// ~UDQS I/O pad
// clocks, reset
input
clk_in
,
input
rst_in
,
output
mclk
,
// global clock, half DDR3 clock, synchronizes all I/O thorough the command port
// inteface to control I/O delays and mmcm
input
[
7
:
0
]
dly_data
,
// delay value (3 LSB - fine delay)
input
[
6
:
0
]
dly_addr
,
// select which delay to program
input
ld_delay
,
// load delay data to selected iodelayl (clk_div synchronous)
input
set
,
// clk_div synchronous set all delays from previously loaded values
output
locked
,
output
ps_rdy
,
output
[
PHASE_WIDTH
-
1
:
0
]
ps_out
,
// command port
input
[
35
:
0
]
phy_cmd
,
// external memory buffer (cs- channel select, high addresses- page addresses are decoded externally)
output
[
6
:
0
]
buf_addr
,
output
[
63
:
0
]
buf_wdata
,
// data to be written to the buffer (from DDR3), valid @ negedge mclk
input
[
63
:
0
]
buf_rdata
,
// data read from the buffer (to DDR3)
output
buf_wr
,
// write buffer (next cycle!)
output
buf_rd
,
// read buffer (ready next cycle)
// extras
input
cmda_tri
,
// tristate command and address lines // not likely to be used
input
inv_clk_div
,
input
[
7
:
0
]
dqs_pattern
,
// 8'h55
input
[
7
:
0
]
dqm_pattern
// 8'h00
)
;
localparam
DQSTRI_FIRST
=
4'h3
;
// DQS tri-state control word, first when enabling output
localparam
DQSTRI_LAST
=
4'hc
;
// DQS tri-state control word, first after disabling output
localparam
DQTRI_FIRST
=
4'h7
;
// DQ tri-state control word, first when enabling output
localparam
DQTRI_LAST
=
4'he
;
// DQ tri-state control word, first after disabling output
// Decoding phy_cmd[35:0] into individual fields;
wire
[
ADDRESS_NUMBER
-
1
:
0
]
phy_addr_in
;
// also provides pause length when the command is NOP
wire
[
2
:
0
]
phy_bank_in
;
wire
[
2
:
0
]
phy_rcw_in
;
// {ras,cas,we}
wire
phy_odt_in
;
// may be optimized?
wire
phy_cke_in
;
// may be optimized?
wire
phy_sel_in
;
// fitst/second half-cycle, oter will be nop (cke+odt applicable to both)
wire
phy_dq_tri_in
;
// tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
wire
phy_dqs_tri_in
;
// tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
wire
phy_dci_in
;
// DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
wire
[
6
:
0
]
phy_buf_addr
;
// connect to extrenal buffer
wire
phy_buf_wr
;
// connect to extrenal buffer
wire
phy_buf_rd
;
// connect to extrenal buffer
// wire clk;
wire
clk_div
;
reg
[
7
:
0
]
dly_data_r
;
// delay value (3 LSB - fine delay)
reg
[
6
:
0
]
dly_addr_r
;
// select which delay to program
reg
ld_delay_r
;
// load delay data to selected iodelayl (clk_div synchronous)
reg
set_r
;
// clk_div synchronous set all delays from previously loaded values
wire
[
2
*
ADDRESS_NUMBER
-
1
:
0
]
phy_addr
;
// also provides pause length when the command is NOP
wire
[
5
:
0
]
phy_bank
;
wire
[
5
:
0
]
phy_rcw
;
// {ras,cas,we}
wire
[
1
:
0
]
phy_odt
;
// may be optimized?
wire
[
1
:
0
]
phy_cke
;
// may be optimized?
wire
[
7
:
0
]
phy_dq_tri
;
// tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
wire
[
7
:
0
]
phy_dqs_tri
;
// tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
wire
phy_dci_dis_dq
;
wire
phy_dci_dis_dqs
;
reg
dqs_tri_prev
,
dq_tri_prev
;
wire
phy_locked
;
wire
phy_ps_rdy
;
wire
[
PHASE_WIDTH
-
1
:
0
]
phy_ps_out
;
reg
locked_r1
,
locked_r2
;
reg
ps_rdy_r1
,
ps_rdy_r2
;
reg
[
PHASE_WIDTH
-
1
:
0
]
ps_out_r1
,
ps_out_r2
;
wire
[
63
:
0
]
phy_rdata
;
// data read from ddr3 iserdese2 at posedge clk_div
reg
[
63
:
0
]
phy_rdata_r
;
// registered @ posedge mclk
// output [63:0] buf_wdata, // data to be written to the buffer (from DDR3)
assign
{
phy_addr_in
,
phy_bank_in
,
phy_rcw_in
,
// {ras,cas,we}
phy_odt_in
,
// may be optimized?
phy_cke_in
,
// may be optimized?
phy_sel_in
,
// fitst/second half-cycle, oter will be nop (cke+odt applicable to both)
phy_dq_tri_in
,
// tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
phy_dqs_tri_in
,
// tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
phy_dci_in
,
// DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
phy_buf_addr
,
// connect to extrenal buffer
phy_buf_wr
,
// connect to extrenal buffer
phy_buf_rd
// connect to extrenal buffer
}
=
phy_cmd
;
assign
buf_addr
=
phy_buf_addr
;
assign
buf_wr
=
phy_buf_wr
;
assign
buf_rd
=
phy_buf_rd
;
assign
phy_addr
=
{
phy_addr_in
,
phy_addr_in
};
// also provides pause length when the command is NOP
assign
phy_bank
=
{
phy_bank_in
,
phy_bank_in
};
assign
phy_rcw
=
{
phy_sel_in
?
phy_rcw_in
:
3'h0
,
phy_sel_in
?
3'h0
:
phy_rcw_in
};
// {ras,cas,we}
assign
phy_odt
=
{
phy_odt_in
,
phy_odt_in
};
// may be optimized?
assign
phy_cke
=
{
phy_cke_in
,
phy_cke_in
};
// may be optimized?
// tristate DQ lines (internal timing sequencer for 0->1 and 1->0)
assign
phy_dq_tri
=
(
dq_tri_prev
==
phy_dq_tri_in
)
?{{
8
{
phy_dq_tri_in
}}}:
(
dq_tri_prev
?{
DQTRI_FIRST
,
DQTRI_FIRST
}:{
DQTRI_LAST
,
DQTRI_LAST
}
)
;
// tristate DQS lines (internal timing sequencer for 0->1 and 1->0)
assign
phy_dqs_tri
=
(
dqs_tri_prev
==
phy_dqs_tri_in
)
?{{
8
{
phy_dqs_tri_in
}}}:
(
dqs_tri_prev
?{
DQSTRI_FIRST
,
DQSTRI_FIRST
}:{
DQSTRI_LAST
,
DQSTRI_LAST
}
)
;
assign
phy_dci_dis_dq
=
phy_dci_in
;
// DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
assign
phy_dci_dis_dqs
=
phy_dci_in
;
// DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
assign
locked
=
locked_r2
;
assign
ps_rdy
=
ps_rdy_r2
;
assign
ps_out
=
ps_out_r2
;
assign
buf_wdata
[
63
:
0
]
=
phy_rdata_r
[
63
:
0
]
;
always
@
(
posedge
mclk
)
begin
dqs_tri_prev
<=
phy_dqs_tri_in
;
dq_tri_prev
<=
phy_dq_tri_in
;
end
// cross clock boundary posedge mclk -> posedge clk_div (mclk is later than clk_div)
always
@
(
posedge
clk_div
or
posedge
rst_in
)
begin
if
(
rst_in
)
begin
dly_data_r
<=
0
;
dly_addr_r
<=
0
;
ld_delay_r
<=
0
;
set_r
<=
0
;
end
else
begin
dly_data_r
<=
dly_data
;
dly_addr_r
<=
dly_addr
;
ld_delay_r
<=
ld_delay
;
set_r
<=
set
;
end
end
// cross clock boundary posedge posedge clk_div->negedge clk_div -> posedge mclk (mclk is later than clk_div)
always
@
(
negedge
clk_div
)
begin
locked_r1
<=
phy_locked
;
ps_rdy_r1
<=
phy_ps_rdy
;
ps_out_r1
<=
phy_ps_out
;
end
always
@
(
posedge
mclk
)
begin
locked_r2
<=
locked_r1
;
ps_rdy_r2
<=
ps_rdy_r1
;
ps_out_r2
<=
ps_out_r1
;
end
always
@
(
negedge
mclk
)
begin
phy_rdata_r
[
63
:
0
]
<=
phy_rdata
[
63
:
0
]
;
end
/*
phy_rdata
wire phy_locked;
wire phy_ps_rdy;
wire [PHASE_WIDTH-1:0] phy_ps_out;
output locked,
output ps_rdy,
output [PHASE_WIDTH-1:0] ps_out,
*/
phy_top
#(
.
IOSTANDARD_DQ
(
"SSTL15_T_DCI"
)
,
.
IOSTANDARD_DQS
(
"DIFF_SSTL15_T_DCI"
)
,
.
IOSTANDARD_CMDA
(
"SSTL15"
)
,
.
IOSTANDARD_CLK
(
"DIFF_SSTL15"
)
,
.
SLEW_DQ
(
SLEW_DQ
)
,
.
SLEW_DQS
(
SLEW_DQS
)
,
.
SLEW_CMDA
(
SLEW_CMDA
)
,
.
SLEW_CLK
(
SLEW_CLK
)
,
.
IBUF_LOW_PWR
(
IBUF_LOW_PWR
)
,
.
IODELAY_GRP
(
"IODELAY_MEMORY"
)
,
.
REFCLK_FREQUENCY
(
REFCLK_FREQUENCY
)
,
.
HIGH_PERFORMANCE_MODE
(
HIGH_PERFORMANCE_MODE
)
,
.
ADDRESS_NUMBER
(
ADDRESS_NUMBER
)
,
.
PHASE_WIDTH
(
8
)
,
.
BANDWIDTH
(
"OPTIMIZED"
)
,
.
CLKIN_PERIOD
(
CLKIN_PERIOD
)
,
.
CLKFBOUT_MULT
(
CLKFBOUT_MULT
)
,
.
CLKFBOUT_MULT_REF
(
CLKFBOUT_MULT_REF
)
,
.
CLKFBOUT_DIV_REF
(
CLKFBOUT_DIV_REF
)
,
.
DIVCLK_DIVIDE
(
DIVCLK_DIVIDE
)
,
.
CLKFBOUT_PHASE
(
CLKFBOUT_PHASE
)
,
.
ICLK_PHASE
(
ICLK_PHASE
)
,
.
CLK_PHASE
(
CLK_PHASE
)
,
.
CLK_DIV_PHASE
(
CLK_DIV_PHASE
)
,
.
MCLK_PHASE
(
MCLK_PHASE
)
,
.
REF_JITTER1
(
REF_JITTER1
)
,
.
SS_EN
(
SS_EN
)
,
.
SS_MODE
(
SS_MODE
)
,
.
SS_MOD_PERIOD
(
SS_MOD_PERIOD
)
)
phy_top_i
(
.
ddr3_clk
(
SDCLK
)
,
// output
.
ddr3_nclk
(
SDNCLK
)
,
// output
.
ddr3_a
(
SDA
[
ADDRESS_NUMBER
-
1
:
0
])
,
// output[14:0]
.
ddr3_ba
(
SDBA
[
2
:
0
])
,
// output[2:0]
.
ddr3_we
(
SDWE
)
,
// output
.
ddr3_ras
(
SDRAS
)
,
// output
.
ddr3_cas
(
SDCAS
)
,
// output
.
ddr3_cke
(
SDCKE
)
,
// output
.
ddr3_odt
(
SDODT
)
,
// output
.
dq
(
SDD
[
15
:
0
])
,
// inout[15:0]
.
dml
(
SDDML
)
,
// inout
.
dqsl
(
DQSL
)
,
// inout
.
ndqsl
(
NDQSL
)
,
// inout
.
dmu
(
SDDMU
)
,
// inout
.
dqsu
(
DQSU
)
,
// inout
.
ndqsu
(
NDQSU
)
,
// inout
.
clk_in
(
clk_in
)
,
// input
// .clk (clk), // output
.
clk
()
,
// output
.
clk_div
(
clk_div
)
,
// output
.
mclk
(
mclk
)
,
// output
.
rst_in
(
rst_in
)
,
// input
.
in_a
(
phy_addr
[
2
*
ADDRESS_NUMBER
-
1
:
0
])
,
// input[29:0]
.
in_ba
(
phy_bank
[
5
:
0
])
,
// input[5:0]
.
in_we
(
{
phy_rcw
[
3
]
,
phy_rcw
[
0
]
}
)
,
// input[1:0]
.
in_ras
(
{
phy_rcw
[
5
]
,
phy_rcw
[
2
]
}
)
,
// input[1:0]
.
in_cas
(
{
phy_rcw
[
4
]
,
phy_rcw
[
1
]
}
)
,
// input[1:0]
.
in_cke
(
phy_cke
)
,
// input[1:0]
.
in_odt
(
phy_odt
)
,
// input[1:0]
.
in_tri
(
cmda_tri
)
,
// input
.
din
(
buf_rdata
[
63
:
0
])
,
// input[63:0]
.
din_dm
(
dqm_pattern
[
7
:
0
])
,
// input[7:0]
.
tin_dq
(
phy_dq_tri
[
7
:
0
])
,
// input[7:0]
.
din_dqs
(
dqs_pattern
[
7
:
0
])
,
// input[7:0]
.
tin_dqs
(
phy_dqs_tri
[
7
:
0
])
,
// input[7:0]
.
dout
(
phy_rdata
[
63
:
0
])
,
// output[63:0] @posedge clk_div
.
inv_clk_div
(
inv_clk_div
)
,
// input
.
dci_disable_dqs
(
phy_dci_dis_dqs
)
,
// input
.
dci_disable_dq
(
phy_dci_dis_dq
)
,
// input
.
dly_data
(
dly_data_r
)
,
// input[7:0]
.
dly_addr
(
dly_addr_r
)
,
// input[6:0]
.
ld_delay
(
ld_delay_r
)
,
// input
.
set
(
set_r
)
,
// input
.
locked
(
phy_locked
)
,
// output
.
ps_rdy
(
phy_ps_rdy
)
,
// output
.
ps_out
(
phy_ps_out
)
// output[7:0]
)
;
endmodule
phy/phy_top.v
View file @
d6733779
...
...
@@ -46,7 +46,7 @@ module phy_top #(
parameter
ICLK_PHASE
=
0.000
,
parameter
CLK_PHASE
=
0.000
,
parameter
CLK_DIV_PHASE
=
0.000
,
parameter
MCLK_PHASE
=
0.000
,
parameter
MCLK_PHASE
=
9
0.000
,
parameter
REF_JITTER1
=
0.010
,
parameter
SS_EN
=
"FALSE"
,
parameter
SS_MODE
=
"CENTER_HIGH"
,
...
...
@@ -100,7 +100,7 @@ module phy_top #(
input
[
7
:
0
]
dly_data
,
// delay value (3 LSB - fine delay)
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_
d
iv synchronous)
input
set
,
// clk_div synchronous set all delays from previously loaded values
output
locked
,
output
ps_rdy
,
...
...
@@ -148,7 +148,7 @@ module phy_top #(
.
in_tri
(
in_tri
)
,
// tristate command/address outputs - same timing, but no odelay
.
dly_data
(
dly_data
[
7
:
0
])
,
// delay value (3 LSB - fine delay)
.
dly_addr
(
dly_addr
[
4
:
0
])
,
// select which delay to program
.
ld_delay
(
ld_cmda
)
,
// load delay data to selected iodelayl (clk_iv synchronous)
.
ld_delay
(
ld_cmda
)
,
// load delay data to selected iodelayl (clk_
d
iv synchronous)
.
set
(
set
)
// clk_div synchronous set all delays from previously loaded values
)
;
...
...
phy/test_phy_top_01.v
View file @
d6733779
...
...
@@ -105,7 +105,7 @@ module test_phy_top_01#(
reg
dci_disable_dq
;
// disable DCI termination during writes and idle for dq and dm signals
reg
[
7
:
0
]
dly_data
;
// delay value (3 LSB - fine delay)
reg
[
6
:
0
]
dly_addr
;
// select which delay to program
reg
ld_delay
;
// load delay data to selected iodelayl (clk_iv synchronous)
reg
ld_delay
;
// load delay data to selected iodelayl (clk_
d
iv synchronous)
reg
set
;
// clk_div synchronous set all delays from previously loaded values
reg
[
63
:
0
]
dout_r
;
...
...
wrap/ram_1kx32_1kx32.v
View file @
d6733779
...
...
@@ -142,12 +142,12 @@ module ram_1kx32_1kx32
.
DIBDI
(
data_in
[
31
:
0
])
,
// Port B data/MSB data[31:0], input
.
DIPBDIP
(
4'b0
)
,
// Port B parity/MSB parity[3:0], input
.
ADDRBWRADDR
(
{
1'b1
,
waddr
[
9
:
0
]
,
5'b11111
}
)
,
// Port B (write port in SDP) address [15:0]. used from [14] down, unused should be high, input
.
CLKBWRCLK
(
wclk
)
,
// Port B (
read
port in SDP) clock, input
.
ENBWREN
(
we
)
,
// Port B (
read
port in SDP) Enable, input
.
REGCEB
(
1'b0
)
,
// Port B (
read
port in SDP) register enable, input
.
RSTRAMB
(
1'b0
)
,
// Port B (
read
port in SDP) set/reset, input
.
RSTREGB
(
1'b0
)
,
// Port B (
read
port in SDP) register set/reset, input
.
WEBWE
(
{
4'b0
,
web
[
3
:
0
]
}
)
,
// Port B (
read
port in SDP) Write Enable[7:0], input
.
CLKBWRCLK
(
wclk
)
,
// Port B (
write
port in SDP) clock, input
.
ENBWREN
(
we
)
,
// Port B (
write
port in SDP) Enable, input
.
REGCEB
(
1'b0
)
,
// Port B (
write
port in SDP) register enable, input
.
RSTRAMB
(
1'b0
)
,
// Port B (
write
port in SDP) set/reset, input
.
RSTREGB
(
1'b0
)
,
// Port B (
write
port in SDP) register set/reset, input
.
WEBWE
(
{
4'b0
,
web
[
3
:
0
]
}
)
,
// Port B (
write
port in SDP) Write Enable[7:0], input
// Error correction circuitry
.
SBITERR
()
,
// Single bit error status, output
.
DBITERR
()
,
// Double bit error status, output
...
...
wrap/ram_1kx32w_512x64r.v
0 → 100644
View file @
d6733779
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* ram_1kx32w_512x64r.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ram_1kx32w_512x64r.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
/*
Address/data widths
Connect unused data to 1b0, unused addresses - to 1'b1
RAMB18E1 in True Dual Port (TDP) Mode - each port individually
+-----------+---------+---------+---------+
|Data Width | Address | Data | Parity |
+-----------+---------+---------+---------+
| 1 | A[13:0] | D[0] | --- |
| 2 | A[13:1] | D[1:0] | --- |
| 4 | A[13:2] | D[3:0[ | --- |
| 9 | A[13:3] | D[7:0] | DP[0] |
| 18 | A[13:4] | D[15:0] | DP[1:0] |
+-----------+---------+---------+---------+
RAMB18E1 in Simple Dual Port (SDP) Mode
one of the ports (r or w) - 32/36 bits, other - variable
+------------+---------+---------+---------+
|Data Widths | Address | Data | Parity |
+------------+---------+---------+---------+
| 32/ 1 | A[13:0] | D[0] | --- |
| 32/ 2 | A[13:1] | D[1:0] | --- |
| 32/ 4 | A[13:2] | D[3:0[ | --- |
| 36/ 9 | A[13:3] | D[7:0] | DP[0] |
| 36/ 18 | A[13:4] | D[15:0] | DP[1:0] |
| 36/ 36 | A[13:5] | D[31:0] | DP[3:0] |
+------------+---------+---------+---------+
RAMB36E1 in True Dual Port (TDP) Mode - each port individually
+-----------+---------+---------+---------+
|Data Width | Address | Data | Parity |
+-----------+---------+---------+---------+
| 1 | A[14:0] | D[0] | --- |
| 2 | A[14:1] | D[1:0] | --- |
| 4 | A[14:2] | D[3:0[ | --- |
| 9 | A[14:3] | D[7:0] | DP[0] |
| 18 | A[14:4] | D[15:0] | DP[1:0] |
| 36 | A[14:5] | D[31:0] | DP[3:0] |
|1(Cascade) | A[15:0] | D[0] | --- |
+-----------+---------+---------+---------+
RAMB36E1 in Simple Dual Port (SDP) Mode
one of the ports (r or w) - 64/72 bits, other - variable
+------------+---------+---------+---------+
|Data Widths | Address | Data | Parity |
+------------+---------+---------+---------+
| 64/ 1 | A[14:0] | D[0] | --- |
| 64/ 2 | A[14:1] | D[1:0] | --- |
| 64/ 4 | A[14:2] | D[3:0[ | --- |
| 64/ 9 | A[14:3] | D[7:0] | DP[0] |
| 64/ 18 | A[14:4] | D[15:0] | DP[1:0] |
| 64/ 36 | A[14:5] | D[31:0] | DP[3:0] |
| 64/ 72 | A[14:6] | D[63:0] | DP[7:0] |
+------------+---------+---------+---------+
*/
module
ram_1kx32w_512x64r
#(
parameter
integer
registers
=
0
// 1 - registered output
)
(
input
rclk
,
// clock for read port
input
[
8
:
0
]
raddr
,
// read address
input
ren
,
// read port enable
input
regen
,
// output register enable
output
[
63
:
0
]
data_out
,
// data out
input
wclk
,
// clock for read port
input
[
9
:
0
]
waddr
,
// write address
input
we
,
// write port enable
input
[
3
:
0
]
web
,
// write byte enable
input
[
31
:
0
]
data_in
// data out
)
;
RAMB36E1
#(
.
RSTREG_PRIORITY_A
(
"RSTREG"
)
,
// Valid: "RSTREG" or "REGCE"
.
RSTREG_PRIORITY_B
(
"RSTREG"
)
,
// Valid: "RSTREG" or "REGCE"
.
DOA_REG
(
registers
)
,
// Valid: 0 (no output registers) and 1 - one output register (in SDP - to lower 36)
.
DOB_REG
(
registers
)
,
// Valid: 0 (no output registers) and 1 - one output register (in SDP - to lower 36)
.
RAM_EXTENSION_A
(
"NONE"
)
,
// Cascading, valid: "NONE","UPPER", LOWER"
.
RAM_EXTENSION_B
(
"NONE"
)
,
// Cascading, valid: "NONE","UPPER", LOWER"
.
READ_WIDTH_A
(
72
)
,
// Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used)
.
READ_WIDTH_B
(
0
)
,
// Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used)
.
WRITE_WIDTH_A
(
0
)
,
// Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used)
.
WRITE_WIDTH_B
(
36
)
,
// Valid: 0,1,2,4,9,18,36 and in SDP mode - 72 (should be 0 if port is not used)
.
RAM_MODE
(
"SDP"
)
,
// Valid "TDP" (true dual-port) and "SDP" - simple dual-port