bead64508faa053501aa31a6bb182d133639a2d2
[fleet.git] / src / edu / berkeley / fleet / fpga / greg / ddr2_phy_io.v
1 //*****************************************************************************
2 // DISCLAIMER OF LIABILITY
3 //
4 // This text/file contains proprietary, confidential
5 // information of Xilinx, Inc., is distributed under license
6 // from Xilinx, Inc., and may be used, copied and/or
7 // disclosed only pursuant to the terms of a valid license
8 // agreement with Xilinx, Inc. Xilinx hereby grants you a
9 // license to use this text/file solely for design, simulation,
10 // implementation and creation of design files limited
11 // to Xilinx devices or technologies. Use with non-Xilinx
12 // devices or technologies is expressly prohibited and
13 // immediately terminates your license unless covered by
14 // a separate agreement.
15 //
16 // Xilinx is providing this design, code, or information
17 // "as-is" solely for use in developing programs and
18 // solutions for Xilinx devices, with no obligation on the
19 // part of Xilinx to provide support. By providing this design,
20 // code, or information as one possible implementation of
21 // this feature, application or standard, Xilinx is making no
22 // representation that this implementation is free from any
23 // claims of infringement. You are responsible for
24 // obtaining any rights you may require for your implementation.
25 // Xilinx expressly disclaims any warranty whatsoever with
26 // respect to the adequacy of the implementation, including
27 // but not limited to any warranties or representations that this
28 // implementation is free from claims of infringement, implied
29 // warranties of merchantability or fitness for a particular
30 // purpose.
31 //
32 // Xilinx products are not intended for use in life support
33 // appliances, devices, or systems. Use in such applications is
34 // expressly prohibited.
35 //
36 // Any modifications that are made to the Source Code are
37 // done at the user\92s sole risk and will be unsupported.
38 //
39 // Copyright (c) 2006-2007 Xilinx, Inc. All rights reserved.
40 //
41 // This copyright and support notice must be retained as part
42 // of this text at all times.
43 //*****************************************************************************
44 //   ____  ____
45 //  /   /\/   /
46 // /___/  \  /    Vendor: Xilinx
47 // \   \   \/     Version: 2.3
48 //  \   \         Application: MIG
49 //  /   /         Filename: ddr2_phy_io.v
50 // /___/   /\     Date Last Modified: $Date: 2008/07/29 15:24:03 $
51 // \   \  /  \    Date Created: Wed Aug 16 2006
52 //  \___\/\___\
53 //
54 //Device: Virtex-5
55 //Design Name: DDR2
56 //Purpose:
57 //   This module instantiates calibration logic, data, data strobe and the
58 //   data mask iobs.
59 //Reference:
60 //Revision History:
61 //   Rev 1.1 - DM_IOB instance made based on USE_DM_PORT value . PK. 25/6/08
62 //*****************************************************************************
63
64 `timescale 1ns/1ps
65
66 module ddr2_phy_io #
67   (
68    // Following parameters are for 72-bit RDIMM design (for ML561 Reference
69    // board design). Actual values may be different. Actual parameters values
70    // are passed from design top module ddr2_sdram module. Please refer to
71    // the ddr2_sdram module for actual values.
72    parameter CLK_WIDTH             = 1,
73    parameter USE_DM_PORT           = 1,
74    parameter DM_WIDTH              = 9,
75    parameter DQ_WIDTH              = 72,
76    parameter DQ_BITS               = 7,
77    parameter DQ_PER_DQS            = 8,
78    parameter DQS_BITS              = 4,
79    parameter DQS_WIDTH             = 9,
80    parameter HIGH_PERFORMANCE_MODE = "TRUE",
81    parameter ODT_WIDTH             = 1,
82    parameter ADDITIVE_LAT          = 0,
83    parameter CAS_LAT               = 5,
84    parameter REG_ENABLE            = 1,
85    parameter CLK_PERIOD            = 3000,
86    parameter DDR_TYPE              = 1,
87    parameter SIM_ONLY              = 0,
88    parameter DEBUG_EN              = 0,
89    parameter DQS_IO_COL            = 0,
90    parameter DQ_IO_MS              = 0
91    )
92   (
93    input                                clk0,
94    input                                clk90,
95    input                                clkdiv0,
96    input                                rst0,
97    input                                rst90,
98    input                                rstdiv0,
99    input                                dm_ce,
100    input [1:0]                          dq_oe_n,
101    input                                dqs_oe_n,
102    input                                dqs_rst_n,
103    input [3:0]                          calib_start,
104    input                                ctrl_rden,
105    input                                phy_init_rden,
106    input                                calib_ref_done,
107    output [3:0]                         calib_done,
108    output                               calib_ref_req,
109    output [DQS_WIDTH-1:0]               calib_rden,
110    output [DQS_WIDTH-1:0]               calib_rden_sel,
111    input [DQ_WIDTH-1:0]                 wr_data_rise,
112    input [DQ_WIDTH-1:0]                 wr_data_fall,
113    input [(DQ_WIDTH/8)-1:0]             mask_data_rise,
114    input [(DQ_WIDTH/8)-1:0]             mask_data_fall,
115    output [(DQ_WIDTH)-1:0]              rd_data_rise,
116    output [(DQ_WIDTH)-1:0]              rd_data_fall,
117    output [CLK_WIDTH-1:0]               ddr_ck,
118    output [CLK_WIDTH-1:0]               ddr_ck_n,
119    output [DM_WIDTH-1:0]                ddr_dm,
120    inout [DQS_WIDTH-1:0]                ddr_dqs,
121    inout [DQS_WIDTH-1:0]                ddr_dqs_n,
122    inout [DQ_WIDTH-1:0]                 ddr_dq,
123    // Debug signals (optional use)
124    input                                dbg_idel_up_all,
125    input                                dbg_idel_down_all,
126    input                                dbg_idel_up_dq,
127    input                                dbg_idel_down_dq,
128    input                                dbg_idel_up_dqs,
129    input                                dbg_idel_down_dqs,
130    input                                dbg_idel_up_gate,
131    input                                dbg_idel_down_gate,
132    input [DQ_BITS-1:0]                  dbg_sel_idel_dq,
133    input                                dbg_sel_all_idel_dq,
134    input [DQS_BITS:0]                   dbg_sel_idel_dqs,
135    input                                dbg_sel_all_idel_dqs,
136    input [DQS_BITS:0]                   dbg_sel_idel_gate,
137    input                                dbg_sel_all_idel_gate,
138    output [3:0]                         dbg_calib_done,
139    output [3:0]                         dbg_calib_err,
140    output [(6*DQ_WIDTH)-1:0]            dbg_calib_dq_tap_cnt,
141    output [(6*DQS_WIDTH)-1:0]           dbg_calib_dqs_tap_cnt,
142    output [(6*DQS_WIDTH)-1:0]           dbg_calib_gate_tap_cnt,
143    output [DQS_WIDTH-1:0]               dbg_calib_rd_data_sel,
144    output [(5*DQS_WIDTH)-1:0]           dbg_calib_rden_dly,
145    output [(5*DQS_WIDTH)-1:0]           dbg_calib_gate_dly
146    );
147
148   // ratio of # of physical DM outputs to bytes in data bus
149   // may be different - e.g. if using x4 components
150   localparam DM_TO_BYTE_RATIO = DM_WIDTH / (DQ_WIDTH/8);
151
152   wire [CLK_WIDTH-1:0]                     ddr_ck_q;
153   wire [DQS_WIDTH-1:0]                     delayed_dqs;
154   wire [DQ_WIDTH-1:0]                      dlyce_dq;
155   wire [DQS_WIDTH-1:0]                     dlyce_dqs;
156   wire [DQS_WIDTH-1:0]                     dlyce_gate;
157   wire [DQ_WIDTH-1:0]                      dlyinc_dq;
158   wire [DQS_WIDTH-1:0]                     dlyinc_dqs;
159   wire [DQS_WIDTH-1:0]                     dlyinc_gate;
160   wire                                     dlyrst_dq;
161   wire                                     dlyrst_dqs;
162   wire [DQS_WIDTH-1:0]                     dlyrst_gate;
163   wire [DQS_WIDTH-1:0]                     dq_ce;
164   (* KEEP = "TRUE" *) wire [DQS_WIDTH-1:0] en_dqs /* synthesis syn_keep = 1 */;
165   wire [DQS_WIDTH-1:0]                     rd_data_sel;
166
167   //***************************************************************************
168
169   ddr2_phy_calib #
170     (
171      .DQ_WIDTH      (DQ_WIDTH),
172      .DQ_BITS       (DQ_BITS),
173      .DQ_PER_DQS    (DQ_PER_DQS),
174      .DQS_BITS      (DQS_BITS),
175      .DQS_WIDTH     (DQS_WIDTH),
176      .ADDITIVE_LAT  (ADDITIVE_LAT),
177      .CAS_LAT       (CAS_LAT),
178      .REG_ENABLE    (REG_ENABLE),
179      .CLK_PERIOD    (CLK_PERIOD),
180      .SIM_ONLY      (SIM_ONLY),
181      .DEBUG_EN      (DEBUG_EN)
182      )
183     u_phy_calib
184       (
185        .clk                    (clk0),
186        .clkdiv                 (clkdiv0),
187        .rstdiv                 (rstdiv0),
188        .calib_start            (calib_start),
189        .ctrl_rden              (ctrl_rden),
190        .phy_init_rden          (phy_init_rden),
191        .rd_data_rise           (rd_data_rise),
192        .rd_data_fall           (rd_data_fall),
193        .calib_ref_done         (calib_ref_done),
194        .calib_done             (calib_done),
195        .calib_ref_req          (calib_ref_req),
196        .calib_rden             (calib_rden),
197        .calib_rden_sel         (calib_rden_sel),
198        .dlyrst_dq              (dlyrst_dq),
199        .dlyce_dq               (dlyce_dq),
200        .dlyinc_dq              (dlyinc_dq),
201        .dlyrst_dqs             (dlyrst_dqs),
202        .dlyce_dqs              (dlyce_dqs),
203        .dlyinc_dqs             (dlyinc_dqs),
204        .dlyrst_gate            (dlyrst_gate),
205        .dlyce_gate             (dlyce_gate),
206        .dlyinc_gate            (dlyinc_gate),
207        .en_dqs                 (en_dqs),
208        .rd_data_sel            (rd_data_sel),
209        .dbg_idel_up_all        (dbg_idel_up_all),
210        .dbg_idel_down_all      (dbg_idel_down_all),
211        .dbg_idel_up_dq         (dbg_idel_up_dq),
212        .dbg_idel_down_dq       (dbg_idel_down_dq),
213        .dbg_idel_up_dqs        (dbg_idel_up_dqs),
214        .dbg_idel_down_dqs      (dbg_idel_down_dqs),
215        .dbg_idel_up_gate       (dbg_idel_up_gate),
216        .dbg_idel_down_gate     (dbg_idel_down_gate),
217        .dbg_sel_idel_dq        (dbg_sel_idel_dq),
218        .dbg_sel_all_idel_dq    (dbg_sel_all_idel_dq),
219        .dbg_sel_idel_dqs       (dbg_sel_idel_dqs),
220        .dbg_sel_all_idel_dqs   (dbg_sel_all_idel_dqs),
221        .dbg_sel_idel_gate      (dbg_sel_idel_gate),
222        .dbg_sel_all_idel_gate  (dbg_sel_all_idel_gate),
223        .dbg_calib_done         (dbg_calib_done),
224        .dbg_calib_err          (dbg_calib_err),
225        .dbg_calib_dq_tap_cnt   (dbg_calib_dq_tap_cnt),
226        .dbg_calib_dqs_tap_cnt  (dbg_calib_dqs_tap_cnt),
227        .dbg_calib_gate_tap_cnt (dbg_calib_gate_tap_cnt),
228        .dbg_calib_rd_data_sel  (dbg_calib_rd_data_sel),
229        .dbg_calib_rden_dly     (dbg_calib_rden_dly),
230        .dbg_calib_gate_dly     (dbg_calib_gate_dly)
231        );
232
233   //***************************************************************************
234   // Memory clock generation
235   //***************************************************************************
236
237   genvar ck_i;
238   generate
239     for(ck_i = 0; ck_i < CLK_WIDTH; ck_i = ck_i+1) begin: gen_ck
240       ODDR #
241         (
242          .SRTYPE       ("SYNC"),
243          .DDR_CLK_EDGE ("OPPOSITE_EDGE")
244          )
245         u_oddr_ck_i
246           (
247            .Q   (ddr_ck_q[ck_i]),
248            .C   (clk0),
249            .CE  (1'b1),
250            .D1  (1'b0),
251            .D2  (1'b1),
252            .R   (1'b0),
253            .S   (1'b0)
254            );
255       // Can insert ODELAY here if required
256       OBUFDS u_obuf_ck_i
257         (
258          .I   (ddr_ck_q[ck_i]),
259          .O   (ddr_ck[ck_i]),
260          .OB  (ddr_ck_n[ck_i])
261          );
262     end
263   endgenerate
264
265   //***************************************************************************
266   // DQS instances
267   //***************************************************************************
268
269   genvar dqs_i;
270   generate
271     for(dqs_i = 0; dqs_i < DQS_WIDTH; dqs_i = dqs_i+1) begin: gen_dqs
272       ddr2_phy_dqs_iob #
273         (
274          .DDR_TYPE              (DDR_TYPE),
275          .HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE)
276          )
277         u_iob_dqs
278           (
279            .clk0           (clk0),
280            .clkdiv0        (clkdiv0),
281            .rst0           (rst0),
282            .dlyinc_dqs     (dlyinc_dqs[dqs_i]),
283            .dlyce_dqs      (dlyce_dqs[dqs_i]),
284            .dlyrst_dqs     (dlyrst_dqs),
285            .dlyinc_gate    (dlyinc_gate[dqs_i]),
286            .dlyce_gate     (dlyce_gate[dqs_i]),
287            .dlyrst_gate    (dlyrst_gate[dqs_i]),
288            .dqs_oe_n       (dqs_oe_n),
289            .dqs_rst_n      (dqs_rst_n),
290            .en_dqs         (en_dqs[dqs_i]),
291            .ddr_dqs        (ddr_dqs[dqs_i]),
292            .ddr_dqs_n      (ddr_dqs_n[dqs_i]),
293            .dq_ce          (dq_ce[dqs_i]),
294            .delayed_dqs    (delayed_dqs[dqs_i])
295            );
296     end
297   endgenerate
298
299   //***************************************************************************
300   // DM instances
301   //***************************************************************************
302
303   genvar dm_i;
304   generate
305     if (USE_DM_PORT) begin: gen_dm_inst
306       for(dm_i = 0; dm_i < DM_WIDTH; dm_i = dm_i+1) begin: gen_dm
307         ddr2_phy_dm_iob u_iob_dm
308           (
309            .clk90           (clk90),
310            .dm_ce           (dm_ce),
311            .mask_data_rise  (mask_data_rise[dm_i/DM_TO_BYTE_RATIO]),
312            .mask_data_fall  (mask_data_fall[dm_i/DM_TO_BYTE_RATIO]),
313            .ddr_dm          (ddr_dm[dm_i])
314            );
315       end
316     end
317   endgenerate
318
319   //***************************************************************************
320   // DQ IOB instances
321   //***************************************************************************
322
323   genvar dq_i;
324   generate
325     for(dq_i = 0; dq_i < DQ_WIDTH; dq_i = dq_i+1) begin: gen_dq
326       ddr2_phy_dq_iob #
327         (
328          .DQ_COL (DQS_IO_COL[2*(dq_i/DQ_PER_DQS)+1:2*(dq_i/DQ_PER_DQS)]),
329          .DQ_MS  (DQ_IO_MS[dq_i]),
330          .HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE)
331          )
332         u_iob_dq
333         (
334          .clk0         (clk0),
335          .clk90        (clk90),
336          .clkdiv0      (clkdiv0),
337          .rst90        (rst90),
338          .dlyinc       (dlyinc_dq[dq_i]),
339          .dlyce        (dlyce_dq[dq_i]),
340          .dlyrst       (dlyrst_dq),
341          .dq_oe_n      (dq_oe_n),
342          .dqs          (delayed_dqs[dq_i/DQ_PER_DQS]),
343          .ce           (dq_ce[dq_i/DQ_PER_DQS]),
344          .rd_data_sel  (rd_data_sel[dq_i/DQ_PER_DQS]),
345          .wr_data_rise (wr_data_rise[dq_i]),
346          .wr_data_fall (wr_data_fall[dq_i]),
347          .rd_data_rise (rd_data_rise[dq_i]),
348          .rd_data_fall (rd_data_fall[dq_i]),
349          .ddr_dq       (ddr_dq[dq_i])
350          );
351     end
352   endgenerate
353
354 endmodule