df1dc70d2af2953a9003bbf35ac189c976e495bf
[fleet.git] / src / edu / berkeley / fleet / fpga / greg / ddr2_phy_ctl_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_ctl_io.v
50 // /___/   /\     Date Last Modified: $Date: 2008/07/29 15:24:03 $
51 // \   \  /  \    Date Created: Thu Aug 24 2006
52 //  \___\/\___\
53 //
54 //Device: Virtex-5
55 //Design Name: DDR2
56 //Purpose:
57 //   This module puts the memory control signals like address, bank address,
58 //   row address strobe, column address strobe, write enable and clock enable
59 //   in the IOBs.
60 //Reference:
61 //Revision History:
62 //*****************************************************************************
63
64 `timescale 1ns/1ps
65
66 module ddr2_phy_ctl_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 BANK_WIDTH    = 2,
73    parameter CKE_WIDTH     = 1,
74    parameter COL_WIDTH     = 10,
75    parameter CS_NUM        = 1,
76    parameter TWO_T_TIME_EN = 0,
77    parameter CS_WIDTH      = 1,
78    parameter ODT_WIDTH     = 1,
79    parameter ROW_WIDTH     = 14,
80    parameter DDR_TYPE      = 1
81    )
82   (
83    input                   clk0,
84    input                   clk90,
85    input                   rst0,
86    input                   rst90,
87    input [ROW_WIDTH-1:0]   ctrl_addr,
88    input [BANK_WIDTH-1:0]  ctrl_ba,
89    input                   ctrl_ras_n,
90    input                   ctrl_cas_n,
91    input                   ctrl_we_n,
92    input [CS_NUM-1:0]      ctrl_cs_n,
93    input [ROW_WIDTH-1:0]   phy_init_addr,
94    input [BANK_WIDTH-1:0]  phy_init_ba,
95    input                   phy_init_ras_n,
96    input                   phy_init_cas_n,
97    input                   phy_init_we_n,
98    input [CS_NUM-1:0]      phy_init_cs_n,
99    input [CKE_WIDTH-1:0]   phy_init_cke,
100    input                   phy_init_data_sel,
101    input [CS_NUM-1:0]      odt,
102    output [ROW_WIDTH-1:0]  ddr_addr,
103    output [BANK_WIDTH-1:0] ddr_ba,
104    output                  ddr_ras_n,
105    output                  ddr_cas_n,
106    output                  ddr_we_n,
107    output [CKE_WIDTH-1:0]  ddr_cke,
108    output [CS_WIDTH-1:0]   ddr_cs_n,
109    output [ODT_WIDTH-1:0]  ddr_odt
110    );
111
112   reg [ROW_WIDTH-1:0]     addr_mux;
113   reg [BANK_WIDTH-1:0]    ba_mux;
114   reg                     cas_n_mux;
115   reg [CS_NUM-1:0]        cs_n_mux;
116   reg                     ras_n_mux;
117   reg                     we_n_mux;
118
119
120
121   //***************************************************************************
122
123
124
125
126   // MUX to choose from either PHY or controller for SDRAM control
127
128   generate // in 2t timing mode the extra register stage cannot be used.
129     if(TWO_T_TIME_EN) begin // the control signals are asserted for two cycles
130       always @(*)begin
131         if (phy_init_data_sel) begin
132           addr_mux  = ctrl_addr;
133           ba_mux    = ctrl_ba;
134           cas_n_mux = ctrl_cas_n;
135           cs_n_mux  = ctrl_cs_n;
136           ras_n_mux = ctrl_ras_n;
137           we_n_mux  = ctrl_we_n;
138         end else begin
139           addr_mux  = phy_init_addr;
140           ba_mux    = phy_init_ba;
141           cas_n_mux = phy_init_cas_n;
142           cs_n_mux  = phy_init_cs_n;
143           ras_n_mux = phy_init_ras_n;
144           we_n_mux  = phy_init_we_n;
145         end
146       end
147     end else begin
148       always @(posedge clk0)begin // register the signals in non 2t mode
149         if (phy_init_data_sel) begin
150           addr_mux <= ctrl_addr;
151           ba_mux <= ctrl_ba;
152           cas_n_mux <= ctrl_cas_n;
153           cs_n_mux <= ctrl_cs_n;
154           ras_n_mux <= ctrl_ras_n;
155           we_n_mux <= ctrl_we_n;
156         end else begin
157           addr_mux <= phy_init_addr;
158           ba_mux <= phy_init_ba;
159           cas_n_mux <= phy_init_cas_n;
160           cs_n_mux <= phy_init_cs_n;
161           ras_n_mux <= phy_init_ras_n;
162           we_n_mux <= phy_init_we_n;
163         end
164       end
165     end
166   endgenerate
167
168   //***************************************************************************
169   // Output flop instantiation
170   // NOTE: Make sure all control/address flops are placed in IOBs
171   //***************************************************************************
172
173   // RAS: = 1 at reset
174   (* IOB = "TRUE" *) FDCPE u_ff_ras_n
175     (
176      .Q   (ddr_ras_n),
177      .C   (clk0),
178      .CE  (1'b1),
179      .CLR (1'b0),
180      .D   (ras_n_mux),
181      .PRE (rst0)
182      ) /* synthesis syn_useioff = 1 */;
183
184   // CAS: = 1 at reset
185   (* IOB = "TRUE" *) FDCPE u_ff_cas_n
186     (
187      .Q   (ddr_cas_n),
188      .C   (clk0),
189      .CE  (1'b1),
190      .CLR (1'b0),
191      .D   (cas_n_mux),
192      .PRE (rst0)
193      ) /* synthesis syn_useioff = 1 */;
194
195   // WE: = 1 at reset
196   (* IOB = "TRUE" *) FDCPE u_ff_we_n
197     (
198      .Q   (ddr_we_n),
199      .C   (clk0),
200      .CE  (1'b1),
201      .CLR (1'b0),
202      .D   (we_n_mux),
203      .PRE (rst0)
204      ) /* synthesis syn_useioff = 1 */;
205
206   // CKE: = 0 at reset
207   genvar cke_i;
208   generate
209     for (cke_i = 0; cke_i < CKE_WIDTH; cke_i = cke_i + 1) begin: gen_cke
210       (* IOB = "TRUE" *) FDCPE u_ff_cke
211         (
212          .Q   (ddr_cke[cke_i]),
213          .C   (clk0),
214          .CE  (1'b1),
215          .CLR (rst0),
216          .D   (phy_init_cke[cke_i]),
217          .PRE (1'b0)
218          ) /* synthesis syn_useioff = 1 */;
219     end
220   endgenerate
221
222   // chip select: = 1 at reset
223   // For unbuffered dimms the loading will be high. The chip select
224   // can be asserted early if the loading is very high. The
225   // code as is uses clock 0. If needed clock 270 can be used to
226   // toggle chip select 1/4 clock cycle early. The code has
227   // the clock 90 input for the early assertion of chip select.
228
229   genvar cs_i;
230   generate
231     for(cs_i = 0; cs_i < CS_WIDTH; cs_i = cs_i + 1) begin: gen_cs_n
232       if(TWO_T_TIME_EN) begin
233          (* IOB = "TRUE" *) FDCPE u_ff_cs_n
234            (
235             .Q   (ddr_cs_n[cs_i]),
236             .C   (clk0),
237             .CE  (1'b1),
238             .CLR (1'b0),
239             .D   (cs_n_mux[(cs_i*CS_NUM)/CS_WIDTH]),
240             .PRE (rst0)
241             ) /* synthesis syn_useioff = 1 */;
242       end else begin // if (TWO_T_TIME_EN)
243          (* IOB = "TRUE" *) FDCPE u_ff_cs_n
244            (
245             .Q   (ddr_cs_n[cs_i]),
246             .C   (clk0),
247             .CE  (1'b1),
248             .CLR (1'b0),
249             .D   (cs_n_mux[(cs_i*CS_NUM)/CS_WIDTH]),
250             .PRE (rst0)
251             ) /* synthesis syn_useioff = 1 */;
252       end // else: !if(TWO_T_TIME_EN)
253     end
254   endgenerate
255
256   // address: = X at reset
257   genvar addr_i;
258   generate
259     for (addr_i = 0; addr_i < ROW_WIDTH; addr_i = addr_i + 1) begin: gen_addr
260       (* IOB = "TRUE" *) FDCPE u_ff_addr
261         (
262          .Q   (ddr_addr[addr_i]),
263          .C   (clk0),
264          .CE  (1'b1),
265          .CLR (1'b0),
266          .D   (addr_mux[addr_i]),
267          .PRE (1'b0)
268          ) /* synthesis syn_useioff = 1 */;
269     end
270   endgenerate
271
272   // bank address = X at reset
273   genvar ba_i;
274   generate
275     for (ba_i = 0; ba_i < BANK_WIDTH; ba_i = ba_i + 1) begin: gen_ba
276       (* IOB = "TRUE" *) FDCPE u_ff_ba
277         (
278          .Q   (ddr_ba[ba_i]),
279          .C   (clk0),
280          .CE  (1'b1),
281          .CLR (1'b0),
282          .D   (ba_mux[ba_i]),
283          .PRE (1'b0)
284          ) /* synthesis syn_useioff = 1 */;
285     end
286   endgenerate
287
288   // ODT control = 0 at reset
289   genvar odt_i;
290   generate
291     if (DDR_TYPE > 0) begin: gen_odt_ddr2
292       for (odt_i = 0; odt_i < ODT_WIDTH; odt_i = odt_i + 1) begin: gen_odt
293         (* IOB = "TRUE" *) FDCPE u_ff_odt
294           (
295            .Q   (ddr_odt[odt_i]),
296            .C   (clk0),
297            .CE  (1'b1),
298            .CLR (rst0),
299            .D   (odt[(odt_i*CS_NUM)/ODT_WIDTH]),
300            .PRE (1'b0)
301            ) /* synthesis syn_useioff = 1 */;
302       end
303     end
304   endgenerate
305
306 endmodule