5cdf1d57f102c515dff28914f6369ea42e8fb720
[fleet.git] / src / edu / berkeley / fleet / fpga / ddr2 / ddr2_infrastructure.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 users 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_infrastructure.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 //   Clock generation/distribution and reset synchronization
58 //Reference:
59 //Revision History:
60 //   Rev 1.1 - Parameter CLK_TYPE added and logic for  DIFFERENTIAL and 
61 //             SINGLE_ENDED added. PK. 20/6/08
62 //*****************************************************************************
63
64 `timescale 1ns/1ps
65
66 module ddr2_infrastructure #
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_PERIOD    = 3000,
73    parameter CLK_TYPE      = "DIFFERENTIAL",
74    parameter DLL_FREQ_MODE = "HIGH",
75    parameter RST_ACT_LOW  = 1
76    )
77   (
78    input  sys_clk_p,
79    input  sys_clk_n,
80    input  sys_clk,
81    input  clk200_p,
82    input  clk200_n,
83    input  idly_clk_200,
84    output clk0,
85    output clk90,
86    output clk200,
87    output clkdiv0,
88    input  sys_rst_n,
89    input  idelay_ctrl_rdy,
90    output rst0,
91    output rst90,
92    output rst200,
93    output rstdiv0
94    );
95
96   // # of clock cycles to delay deassertion of reset. Needs to be a fairly
97   // high number not so much for metastability protection, but to give time
98   // for reset (i.e. stable clock cycles) to propagate through all state
99   // machines and to all control signals (i.e. not all control signals have
100   // resets, instead they rely on base state logic being reset, and the effect
101   // of that reset propagating through the logic). Need this because we may not
102   // be getting stable clock cycles while reset asserted (i.e. since reset
103   // depends on DCM lock status)
104   localparam RST_SYNC_NUM = 25;
105   localparam CLK_PERIOD_NS = CLK_PERIOD / 1000.0;
106
107   wire                       clk0_bufg;
108   wire                       clk90_bufg;
109   wire                       clk200_bufg;
110   wire                       clk200_ibufg;
111   wire                       clkdiv0_bufg;
112   wire                       dcm_clk0;
113   wire                       dcm_clk90;
114   wire                       dcm_clkdiv0;
115   wire                       dcm_lock;
116   reg [RST_SYNC_NUM-1:0]     rst0_sync_r    /* synthesis syn_maxfan = 10 */;
117   reg [RST_SYNC_NUM-1:0]     rst200_sync_r  /* synthesis syn_maxfan = 10 */;
118   reg [RST_SYNC_NUM-1:0]     rst90_sync_r   /* synthesis syn_maxfan = 10 */;
119   reg [(RST_SYNC_NUM/2)-1:0] rstdiv0_sync_r /* synthesis syn_maxfan = 10 */;
120   wire                       rst_tmp;
121   wire                       sys_clk_ibufg;
122   wire                       sys_rst;
123
124   assign sys_rst = RST_ACT_LOW ? ~sys_rst_n: sys_rst_n;
125
126   assign clk0    = clk0_bufg;
127   assign clk90   = clk90_bufg;
128   assign clk200  = clk200_bufg;
129   assign clkdiv0 = clkdiv0_bufg;
130
131   generate
132   if(CLK_TYPE == "DIFFERENTIAL") begin : DIFF_ENDED_CLKS_INST
133     //***************************************************************************
134     // Differential input clock input buffers
135     //***************************************************************************
136
137     IBUFGDS_LVPECL_25 SYS_CLK_INST
138       (
139        .I  (sys_clk_p),
140        .IB (sys_clk_n),
141        .O  (sys_clk_ibufg)
142        );
143
144     IBUFGDS_LVPECL_25 IDLY_CLK_INST
145       (
146        .I  (clk200_p),
147        .IB (clk200_n),
148        .O  (clk200_ibufg)
149        );
150
151   end else if(CLK_TYPE == "SINGLE_ENDED") begin : SINGLE_ENDED_CLKS_INST
152     //**************************************************************************
153     // Single ended input clock input buffers
154     //**************************************************************************
155
156     // AM -- edits: changed IBUFG to BUF
157
158     BUF SYS_CLK_INST
159       (
160        .I  (sys_clk),
161        .O  (sys_clk_ibufg)
162        );
163
164     BUF IDLY_CLK_INST
165       (
166        .I  (idly_clk_200),
167        .O  (clk200_ibufg)
168        );
169
170   end
171   endgenerate
172
173   BUFG CLK_200_BUFG
174     (
175      .O (clk200_bufg),
176      .I (clk200_ibufg)
177      );
178
179   //***************************************************************************
180   // Global clock generation and distribution
181   //***************************************************************************
182
183   DCM_BASE #
184     (
185      .CLKIN_PERIOD          (CLK_PERIOD_NS),
186      .CLKDV_DIVIDE          (2.0),
187      .DLL_FREQUENCY_MODE    (DLL_FREQ_MODE),
188      .DUTY_CYCLE_CORRECTION ("TRUE"),
189      .FACTORY_JF            (16'hF0F0)
190      )
191     u_dcm_base
192       (
193        .CLK0      (dcm_clk0),
194        .CLK180    (),
195        .CLK270    (),
196        .CLK2X     (),
197        .CLK2X180  (),
198        .CLK90     (dcm_clk90),
199        .CLKDV     (dcm_clkdiv0),
200        .CLKFX     (),
201        .CLKFX180  (),
202        .LOCKED    (dcm_lock),
203        .CLKFB     (clk0_bufg),
204        .CLKIN     (sys_clk_ibufg),
205        .RST       (sys_rst)
206        );
207
208   BUFG U_BUFG_CLK0
209     (
210      .O (clk0_bufg),
211      .I (dcm_clk0)
212      );
213
214   BUFG U_BUFG_CLK90
215     (
216      .O (clk90_bufg),
217      .I (dcm_clk90)
218      );
219
220    BUFG U_BUFG_CLKDIV0
221     (
222      .O (clkdiv0_bufg),
223      .I (dcm_clkdiv0)
224      );
225
226
227   //***************************************************************************
228   // Reset synchronization
229   // NOTES:
230   //   1. shut down the whole operation if the DCM hasn't yet locked (and by
231   //      inference, this means that external SYS_RST_IN has been asserted -
232   //      DCM deasserts DCM_LOCK as soon as SYS_RST_IN asserted)
233   //   2. In the case of all resets except rst200, also assert reset if the
234   //      IDELAY master controller is not yet ready
235   //   3. asynchronously assert reset. This was we can assert reset even if
236   //      there is no clock (needed for things like 3-stating output buffers).
237   //      reset deassertion is synchronous.
238   //***************************************************************************
239
240   assign rst_tmp = sys_rst | ~dcm_lock | ~idelay_ctrl_rdy;
241
242   // synthesis attribute max_fanout of rst0_sync_r is 10
243   always @(posedge clk0_bufg or posedge rst_tmp)
244     if (rst_tmp)
245       rst0_sync_r <= {RST_SYNC_NUM{1'b1}};
246     else
247       // logical left shift by one (pads with 0)
248       rst0_sync_r <= rst0_sync_r << 1;
249
250   // synthesis attribute max_fanout of rstdiv0_sync_r is 10
251   always @(posedge clkdiv0_bufg or posedge rst_tmp)
252     if (rst_tmp)
253       rstdiv0_sync_r <= {(RST_SYNC_NUM/2){1'b1}};
254     else
255       // logical left shift by one (pads with 0)
256       rstdiv0_sync_r <= rstdiv0_sync_r << 1;
257
258   // synthesis attribute max_fanout of rst90_sync_r is 10
259   always @(posedge clk90_bufg or posedge rst_tmp)
260     if (rst_tmp)
261       rst90_sync_r <= {RST_SYNC_NUM{1'b1}};
262     else
263       rst90_sync_r <= rst90_sync_r << 1;
264
265   // make sure CLK200 doesn't depend on IDELAY_CTRL_RDY, else chicken n' egg
266    // synthesis attribute max_fanout of rst200_sync_r is 10
267   always @(posedge clk200_bufg or negedge dcm_lock)
268     if (!dcm_lock)
269       rst200_sync_r <= {RST_SYNC_NUM{1'b1}};
270     else
271       rst200_sync_r <= rst200_sync_r << 1;
272
273
274   assign rst0    = rst0_sync_r[RST_SYNC_NUM-1];
275   assign rst90   = rst90_sync_r[RST_SYNC_NUM-1];
276   assign rst200  = rst200_sync_r[RST_SYNC_NUM-1];
277   assign rstdiv0 = rstdiv0_sync_r[(RST_SYNC_NUM/2)-1];
278
279 endmodule