OpenCores
URL https://opencores.org/ocsvn/openarty/openarty/trunk

Subversion Repositories openarty

[/] [openarty/] [trunk/] [rtl/] [ddr3insert.v] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    ddr3insert.v
4
//
5
// Project:     A wishbone controlled DDR3 SDRAM memory controller.
6
//
7
// Purpose:     Since the DDR3 RAM requires I/O resources not available
8
//              in Verilog alone, this insert (i.e. include file) is designed
9
//      to be included from a top-level block that would otherwise use the
10
//      DDR3 SDRAM.  It is meant to encapsulate the I/O resource requirements
11
//      and connections required to make the DDR3 SDRAM work.
12
//
13
//
14
//      This file is not a module in its own right, but rather a file
15
//      included in a larger module.
16
//
17
//
18
// Creator:     Dan Gisselquist, Ph.D.
19
//              Gisselquist Technology, LLC
20
//
21
////////////////////////////////////////////////////////////////////////////////
22
//
23
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
24
//
25
// This program is free software (firmware): you can redistribute it and/or
26
// modify it under the terms of  the GNU General Public License as published
27
// by the Free Software Foundation, either version 3 of the License, or (at
28
// your option) any later version.
29
//
30
// This program is distributed in the hope that it will be useful, but WITHOUT
31
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
32
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
33
// for more details.
34
//
35
// You should have received a copy of the GNU General Public License along
36
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
37
// target there if the PDF file isn't present.)  If not, see
38
// <http://www.gnu.org/licenses/> for a copy.
39
//
40
// License:     GPL, v3, as defined and found on www.gnu.org,
41
//              http://www.gnu.org/licenses/gpl.html
42
//
43
//
44
////////////////////////////////////////////////////////////////////////////////
45
//
46
//
47
 
48
//      EXTERNAL PINS (BOTH INPUT AND OUTPUT):
49
//              o_ddr_reset_n, o_ddr_cke, o_ddr_ck_p, o_ddr_ck_n
50
//              o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
51
//              io_ddr_dqs_p, io_ddr_dqs_n,
52
//              o_ddr_addr, o_ddr_ba,
53
//              io_ddr_data, o_ddr_dm, o_ddr_odt
54
//
55
//      INPUTS: (from elsewhere in the toplevel module)
56
//              pwr_reset               True for one clock at power on
57
//              i_clk                   200 MHz clock used in fabric
58
//              clk_for_ddr             800 MHz clock to send to memory clk pins
59
//              mem_serial_clk          800 MHz clock to drive serdes's
60
//              mem_serial_clk_inv      The inverse of the 800 MHz clock ...
61
//      
62
//
63
//      LOCAL VARIABLES PROVIDED:
64
//              (These come from the controller)
65
//      [3:0]   w_ddr_cs_n, w_ddr_ras_n, w_ddr_cas_n, w_ddr_we_n
66
//      [11:0]  w_ddr_ba, divided into
67
//              { w_ddr_ba[11:9], w_ddr_ba[8:6], w_ddr[5:3], w_ddr_ba[2:0] }
68
//      [55:0]  w_ddr_addr
69
//              { w_ddr_addr[55:42], w_ddr_addr[41:28], w_ddr_addr[27:14],
70
//                      w_ddr_addr[13:0] }
71
//      [7:0]   w_ddr_odt       // On-die termination
72
//      [7:0]   w_ddr_odt       // On-die termination
73
//      [15:0]  w_ddr_dm        // Data mask, headed to memory
74
//      [127:0] wo_ddr_data     // Data going to the memory
75
//      [127:0] wi_ddr_data     // The data returned by the memory
76
//
77
//              
78
 
79
        //
80
        wire            w_ddr_reset_n, w_ddr_cke, w_ddr_bus_oe;
81
        wire    [26:0]   w_ddr_cmd_a, w_ddr_cmd_b;
82
        wire    [63:0]   wi_ddr_data, wo_ddr_data;
83
        wire    [127:0]  wide_ddr_data;
84
 
85
        //
86
        //
87
        // Wires for setting up the DDR3 memory
88
        //
89
        //
90
 
91
        // First, let's set up the clock(s)
92
        xoddrserdesb ddrclk(mem_serial_clk, i_clk, pwr_reset, 8'h66,
93
                o_ddr_ck_p, o_ddr_ck_n);
94
 
95
        wire    [7:0]    w_udqs_in, w_ldqs_in;
96
 
97
        xioddrserdesb ddrudqs(mem_serial_clk, mem_serial_clk_inv, i_clk,
98
                        ~w_ddr_reset_n, w_ddr_cmd_a[0],
99
                        (w_ddr_cmd_b[0])? 8'h66 : 8'h06,
100
                        w_udqs_in,
101
                        io_ddr_dqs_p[1], io_ddr_dqs_n[1]);
102
 
103
        xioddrserdesb ddrldqs(mem_serial_clk, mem_serial_clk_inv, i_clk,
104
                        ~w_ddr_reset_n, w_ddr_cmd_a[0],
105
                        (w_ddr_cmd_b[0])? 8'h66 : 8'h06,
106
                        w_ldqs_in,
107
                        io_ddr_dqs_p[0], io_ddr_dqs_n[0]);
108
 
109
        // The command wires: CS_N, RAS_N, CAS_N, and WE_N
110
        xoddrserdes ddrcsn(mem_serial_clk, i_clk, ~w_ddr_reset_n,
111
                { w_ddr_cmd_a[26], w_ddr_cmd_a[26],
112
                  w_ddr_cmd_a[26], w_ddr_cmd_a[26],
113
                  w_ddr_cmd_b[26], w_ddr_cmd_b[26],
114
                  w_ddr_cmd_b[26], w_ddr_cmd_b[26] }, o_ddr_cs_n);
115
 
116
        xoddrserdes ddrrasn(mem_serial_clk, i_clk, ~w_ddr_reset_n,
117
                { w_ddr_cmd_a[25], w_ddr_cmd_a[25],
118
                  w_ddr_cmd_a[25], w_ddr_cmd_a[25],
119
                  w_ddr_cmd_b[25], w_ddr_cmd_b[25],
120
                  w_ddr_cmd_b[25], w_ddr_cmd_b[25] }, o_ddr_ras_n);
121
 
122
        xoddrserdes ddrcasn(mem_serial_clk, i_clk, ~w_ddr_reset_n,
123
                { w_ddr_cmd_a[24], w_ddr_cmd_a[24],
124
                  w_ddr_cmd_a[24], w_ddr_cmd_a[24],
125
                  w_ddr_cmd_b[24], w_ddr_cmd_b[24],
126
                  w_ddr_cmd_b[24], w_ddr_cmd_b[24] }, o_ddr_cas_n);
127
 
128
        xoddrserdes ddrwen(mem_serial_clk, i_clk, ~w_ddr_reset_n,
129
                { w_ddr_cmd_a[23], w_ddr_cmd_a[23],
130
                  w_ddr_cmd_a[23], w_ddr_cmd_a[23],
131
                  w_ddr_cmd_b[23], w_ddr_cmd_b[23],
132
                  w_ddr_cmd_b[23], w_ddr_cmd_b[23] }, o_ddr_we_n);
133
 
134
        // Data mask wires, first the upper byte
135
        xoddrserdes ddrudm(mem_serial_clk, i_clk, ~w_ddr_reset_n,
136
                { w_ddr_cmd_a[4], w_ddr_cmd_a[4],
137
                  w_ddr_cmd_a[2], w_ddr_cmd_a[2],
138
                  w_ddr_cmd_b[4], w_ddr_cmd_b[4],
139
                  w_ddr_cmd_b[2], w_ddr_cmd_b[2] }, o_ddr_dm[1]);
140
        // then the lower byte
141
        xoddrserdes ddrldm(mem_serial_clk, i_clk, ~w_ddr_reset_n,
142
                { w_ddr_cmd_a[3], w_ddr_cmd_a[3],
143
                  w_ddr_cmd_a[1], w_ddr_cmd_a[1],
144
                  w_ddr_cmd_b[3], w_ddr_cmd_b[3],
145
                  w_ddr_cmd_b[1], w_ddr_cmd_b[1] }, o_ddr_dm[0]);
146
 
147
        // and the On-Die termination wire
148
        xoddrserdes ddrodt(mem_serial_clk, i_clk, ~w_ddr_reset_n,
149
                { w_ddr_cmd_a[0], w_ddr_cmd_a[0],
150
                  w_ddr_cmd_a[0], w_ddr_cmd_a[0],
151
                  w_ddr_cmd_b[0], w_ddr_cmd_b[0],
152
                  w_ddr_cmd_b[0], w_ddr_cmd_b[0] }, o_ddr_odt);
153
 
154
        //
155
        // Now for the data, bank, and address wires
156
        //
157
        genvar  k;
158
        generate begin
159
        //
160
        for(k=0; k<16; k=k+1)
161
                xioddrserdes ddrdata(mem_serial_clk, mem_serial_clk_inv, i_clk, ~w_ddr_reset_n,
162
                                w_ddr_bus_oe,
163
                        { wo_ddr_data[48+k], wo_ddr_data[48+k],
164
                          wo_ddr_data[32+k], wo_ddr_data[32+k],
165
                          wo_ddr_data[16+k], wo_ddr_data[16+k],
166
                          wo_ddr_data[   k], wo_ddr_data[   k] },
167
                        { wide_ddr_data[112+k], wide_ddr_data[96+k],
168
                          wide_ddr_data[ 80+k], wide_ddr_data[64+k],
169
                          wide_ddr_data[ 48+k], wide_ddr_data[32+k],
170
                          wide_ddr_data[ 16+k], wide_ddr_data[   k] },
171
                        io_ddr_data[k]);
172
        //
173
        for(k=0; k<3; k=k+1)
174
                xoddrserdes ddrbank(mem_serial_clk, i_clk, ~w_ddr_reset_n,
175
                        { w_ddr_cmd_a[20+k], w_ddr_cmd_a[20+k],
176
                          w_ddr_cmd_a[20+k], w_ddr_cmd_a[20+k],
177
                          w_ddr_cmd_b[20+k], w_ddr_cmd_b[20+k],
178
                          w_ddr_cmd_b[20+k], w_ddr_cmd_b[20+k] },
179
                        o_ddr_ba[k]);
180
        //
181
        for(k=0; k<14; k=k+1)
182
                xoddrserdes ddraddr(mem_serial_clk, i_clk, ~w_ddr_reset_n,
183
                        { w_ddr_cmd_a[ 6+k], w_ddr_cmd_a[ 6+k],
184
                          w_ddr_cmd_a[ 6+k], w_ddr_cmd_a[ 6+k],
185
                          w_ddr_cmd_b[ 6+k], w_ddr_cmd_b[ 6+k],
186
                          w_ddr_cmd_b[ 6+k], w_ddr_cmd_b[ 6+k] },
187
                        o_ddr_addr[k]);
188
        //
189
 
190
        for(k=0; k<64; k=k+1)
191
                assign wi_ddr_data[k] = (w_ddr_bus_oe) ? wide_ddr_data[2*k+1]
192
                                        : wide_ddr_data[2*k];
193
        end endgenerate
194
 
195
        assign  o_ddr_reset_n = w_ddr_reset_n;
196
        assign  o_ddr_cke = w_ddr_cke;
197
 
198
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.