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

Subversion Repositories usb_fpga_2_14

[/] [usb_fpga_2_14/] [trunk/] [examples/] [memfifo/] [fpga-2.13/] [memfifo.srcs/] [sources_1/] [ip/] [mig_7series_0/] [mig_7series_0/] [user_design/] [rtl/] [phy/] [mig_7series_v2_3_ddr_mc_phy_wrapper.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
//*****************************************************************************
2
// (c) Copyright 2008 - 2014 Xilinx, Inc. All rights reserved.
3
//
4
// This file contains confidential and proprietary information
5
// of Xilinx, Inc. and is protected under U.S. and
6
// international copyright and other intellectual property
7
// laws.
8
//
9
// DISCLAIMER
10
// This disclaimer is not a license and does not grant any
11
// rights to the materials distributed herewith. Except as
12
// otherwise provided in a valid license issued to you by
13
// Xilinx, and to the maximum extent permitted by applicable
14
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
15
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
16
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
17
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
18
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
19
// (2) Xilinx shall not be liable (whether in contract or tort,
20
// including negligence, or under any other theory of
21
// liability) for any loss or damage of any kind or nature
22
// related to, arising under or in connection with these
23
// materials, including for any direct, or any indirect,
24
// special, incidental, or consequential loss or damage
25
// (including loss of data, profits, goodwill, or any type of
26
// loss or damage suffered as a result of any action brought
27
// by a third party) even if such damage or loss was
28
// reasonably foreseeable or Xilinx had been advised of the
29
// possibility of the same.
30
//
31
// CRITICAL APPLICATIONS
32
// Xilinx products are not designed or intended to be fail-
33
// safe, or for use in any application requiring fail-safe
34
// performance, such as life-support or safety devices or
35
// systems, Class III medical devices, nuclear facilities,
36
// applications related to the deployment of airbags, or any
37
// other applications that could lead to death, personal
38
// injury, or severe property or environmental damage
39
// (individually and collectively, "Critical
40
// Applications"). Customer assumes the sole risk and
41
// liability of any use of Xilinx products in Critical
42
// Applications, subject only to applicable laws and
43
// regulations governing limitations on product liability.
44
//
45
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
46
// PART OF THIS FILE AT ALL TIMES.
47
//
48
//*****************************************************************************
49
//   ____  ____
50
//  /   /\/   /
51
// /___/  \  /    Vendor                : Xilinx
52
// \   \   \/     Version               : %version
53
//  \   \         Application           : MIG
54
//  /   /         Filename              : ddr_mc_phy_wrapper.v
55
// /___/   /\     Date Last Modified    : $date$
56
// \   \  /  \    Date Created          : Oct 10 2010
57
//  \___\/\___\
58
//
59
//Device            : 7 Series
60
//Design Name       : DDR3 SDRAM
61
//Purpose           : Wrapper file that encompasses the MC_PHY module
62
//                    instantiation and handles the vector remapping between
63
//                    the MC_PHY ports and the user's DDR3 ports. Vector
64
//                    remapping affects DDR3 control, address, and DQ/DQS/DM. 
65
//Reference         :
66
//Revision History  :
67
//*****************************************************************************
68
 
69
`timescale 1 ps / 1 ps
70
 
71
module mig_7series_v2_3_ddr_mc_phy_wrapper #
72
  (
73
   parameter TCQ              = 100,    // Register delay (simulation only)
74
   parameter tCK              = 2500,   // ps
75
   parameter BANK_TYPE        = "HP_IO", // # = "HP_IO", "HPL_IO", "HR_IO", "HRL_IO"
76
   parameter DATA_IO_PRIM_TYPE = "DEFAULT", // # = "HP_LP", "HR_LP", "DEFAULT"
77
   parameter DATA_IO_IDLE_PWRDWN = "ON",  // "ON" or "OFF"
78
   parameter IODELAY_GRP      = "IODELAY_MIG",
79
   parameter FPGA_SPEED_GRADE = 1,
80
   parameter nCK_PER_CLK      = 4,      // Memory:Logic clock ratio
81
   parameter nCS_PER_RANK     = 1,      // # of unique CS outputs per rank
82
   parameter BANK_WIDTH       = 3,      // # of bank address
83
   parameter CKE_WIDTH        = 1,      // # of clock enable outputs 
84
   parameter CS_WIDTH         = 1,      // # of chip select
85
   parameter CK_WIDTH         = 1,      // # of CK
86
   parameter CWL              = 5,      // CAS Write latency
87
   parameter DDR2_DQSN_ENABLE = "YES",  // Enable differential DQS for DDR2
88
   parameter DM_WIDTH         = 8,      // # of data mask
89
   parameter DQ_WIDTH         = 16,     // # of data bits
90
   parameter DQS_CNT_WIDTH    = 3,      // ceil(log2(DQS_WIDTH))
91
   parameter DQS_WIDTH        = 8,      // # of strobe pairs
92
   parameter DRAM_TYPE        = "DDR3", // DRAM type (DDR2, DDR3)
93
   parameter RANKS            = 4,      // # of ranks
94
   parameter ODT_WIDTH        = 1,      // # of ODT outputs
95
   parameter POC_USE_METASTABLE_SAMP = "FALSE",
96
   parameter REG_CTRL         = "OFF",  // "ON" for registered DIMM
97
   parameter ROW_WIDTH        = 16,     // # of row/column address
98
   parameter USE_CS_PORT      = 1,      // Support chip select output 
99
   parameter USE_DM_PORT      = 1,      // Support data mask output
100
   parameter USE_ODT_PORT     = 1,      // Support ODT output
101
   parameter IBUF_LPWR_MODE   = "OFF",  // input buffer low power option
102
   parameter LP_DDR_CK_WIDTH  = 2,
103
 
104
   // Hard PHY parameters
105
   parameter PHYCTL_CMD_FIFO = "FALSE",
106
   parameter DATA_CTL_B0     = 4'hc,
107
   parameter DATA_CTL_B1     = 4'hf,
108
   parameter DATA_CTL_B2     = 4'hf,
109
   parameter DATA_CTL_B3     = 4'hf,
110
   parameter DATA_CTL_B4     = 4'hf,
111
   parameter BYTE_LANES_B0   = 4'b1111,
112
   parameter BYTE_LANES_B1   = 4'b0000,
113
   parameter BYTE_LANES_B2   = 4'b0000,
114
   parameter BYTE_LANES_B3   = 4'b0000,
115
   parameter BYTE_LANES_B4   = 4'b0000,
116
   parameter PHY_0_BITLANES  = 48'h0000_0000_0000,
117
   parameter PHY_1_BITLANES  = 48'h0000_0000_0000,
118
   parameter PHY_2_BITLANES  = 48'h0000_0000_0000,
119
   // Parameters calculated outside of this block
120
   parameter HIGHEST_BANK    = 3,        // Highest I/O bank index
121
   parameter HIGHEST_LANE    = 12,       // Highest byte lane index
122
   // ** Pin mapping parameters
123
   // Parameters for mapping between hard PHY and physical DDR3 signals
124
   // There are 2 classes of parameters:
125
   //   - DQS_BYTE_MAP, CK_BYTE_MAP, CKE_ODT_BYTE_MAP: These consist of 
126
   //      8-bit elements. Each element indicates the bank and byte lane 
127
   //      location of that particular signal. The bit lane in this case 
128
   //      doesn't need to be specified, either because there's only one 
129
   //      pin pair in each byte lane that the DQS or CK pair can be 
130
   //      located at, or in the case of CKE_ODT_BYTE_MAP, only the byte
131
   //      lane needs to be specified in order to determine which byte
132
   //      lane generates the RCLK (Note that CKE, and ODT must be located
133
   //      in the same bank, thus only one element in CKE_ODT_BYTE_MAP)
134
   //        [7:4] = bank # (0-4)
135
   //        [3:0] = byte lane # (0-3)
136
   //   - All other MAP parameters: These consist of 12-bit elements. Each
137
   //      element indicates the bank, byte lane, and bit lane location of
138
   //      that particular signal:
139
   //        [11:8] = bank # (0-4)
140
   //        [7:4]  = byte lane # (0-3)
141
   //        [3:0]  = bit lane # (0-11)
142
   // Note that not all elements in all parameters will be used - it 
143
   // depends on the actual widths of the DDR3 buses. The parameters are 
144
   // structured to support a maximum of: 
145
   //   - DQS groups: 18
146
   //   - data mask bits: 18
147
   // In addition, the default parameter size of some of the parameters will
148
   // support a certain number of bits, however, this can be expanded at 
149
   // compile time by expanding the width of the vector passed into this 
150
   // parameter
151
   //   - chip selects: 10
152
   //   - bank bits: 3
153
   //   - address bits: 16
154
   parameter CK_BYTE_MAP
155
     = 144'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00,
156
   parameter ADDR_MAP
157
     = 192'h000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
158
   parameter BANK_MAP   = 36'h000_000_000,
159
   parameter CAS_MAP    = 12'h000,
160
   parameter CKE_ODT_BYTE_MAP = 8'h00,
161
   parameter CKE_MAP    = 96'h000_000_000_000_000_000_000_000,
162
   parameter ODT_MAP    = 96'h000_000_000_000_000_000_000_000,
163
   parameter CKE_ODT_AUX = "FALSE",
164
   parameter CS_MAP     = 120'h000_000_000_000_000_000_000_000_000_000,
165
   parameter PARITY_MAP = 12'h000,
166
   parameter RAS_MAP    = 12'h000,
167
   parameter WE_MAP     = 12'h000,
168
   parameter DQS_BYTE_MAP
169
     = 144'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00,
170
   // DATAx_MAP parameter is used for byte lane X in the design
171
   parameter DATA0_MAP  = 96'h000_000_000_000_000_000_000_000,
172
   parameter DATA1_MAP  = 96'h000_000_000_000_000_000_000_000,
173
   parameter DATA2_MAP  = 96'h000_000_000_000_000_000_000_000,
174
   parameter DATA3_MAP  = 96'h000_000_000_000_000_000_000_000,
175
   parameter DATA4_MAP  = 96'h000_000_000_000_000_000_000_000,
176
   parameter DATA5_MAP  = 96'h000_000_000_000_000_000_000_000,
177
   parameter DATA6_MAP  = 96'h000_000_000_000_000_000_000_000,
178
   parameter DATA7_MAP  = 96'h000_000_000_000_000_000_000_000,
179
   parameter DATA8_MAP  = 96'h000_000_000_000_000_000_000_000,
180
   parameter DATA9_MAP  = 96'h000_000_000_000_000_000_000_000,
181
   parameter DATA10_MAP = 96'h000_000_000_000_000_000_000_000,
182
   parameter DATA11_MAP = 96'h000_000_000_000_000_000_000_000,
183
   parameter DATA12_MAP = 96'h000_000_000_000_000_000_000_000,
184
   parameter DATA13_MAP = 96'h000_000_000_000_000_000_000_000,
185
   parameter DATA14_MAP = 96'h000_000_000_000_000_000_000_000,
186
   parameter DATA15_MAP = 96'h000_000_000_000_000_000_000_000,
187
   parameter DATA16_MAP = 96'h000_000_000_000_000_000_000_000,
188
   parameter DATA17_MAP = 96'h000_000_000_000_000_000_000_000,
189
   // MASK0_MAP used for bytes [8:0], MASK1_MAP for bytes [17:9]
190
   parameter MASK0_MAP  = 108'h000_000_000_000_000_000_000_000_000,
191
   parameter MASK1_MAP  = 108'h000_000_000_000_000_000_000_000_000,
192
   // Simulation options
193
   parameter SIM_CAL_OPTION  = "NONE",
194
 
195
   // The PHY_CONTROL primitive in the bank where PLL exists is declared
196
   // as the Master PHY_CONTROL.
197
   parameter MASTER_PHY_CTL  = 1,
198
   parameter DRAM_WIDTH = 8
199
  )
200
  (
201
   input                               rst,
202
   input                               iddr_rst,
203
   input                               clk,
204
   input                               freq_refclk,
205
   input                               mem_refclk,
206
   input                               pll_lock,
207
   input                               sync_pulse,
208
   input                               mmcm_ps_clk,
209
   input                               idelayctrl_refclk,
210
   input                               phy_cmd_wr_en,
211
   input                               phy_data_wr_en,
212
   input [31:0]                        phy_ctl_wd,
213
   input                               phy_ctl_wr,
214
   input                               phy_if_empty_def,
215
   input                               phy_if_reset,
216
   input [5:0]                         data_offset_1,
217
   input [5:0]                         data_offset_2,
218
   input [3:0]                         aux_in_1,
219
   input [3:0]                         aux_in_2,
220
   output [4:0]                        idelaye2_init_val,
221
   output [5:0]                        oclkdelay_init_val,
222
   output                              if_empty,
223
   output                              phy_ctl_full,
224
   output                              phy_cmd_full,
225
   output                              phy_data_full,
226
   output                              phy_pre_data_a_full,
227
   output [(CK_WIDTH * LP_DDR_CK_WIDTH)-1:0] ddr_clk,
228
   output                              phy_mc_go,
229
   input                               phy_write_calib,
230
   input                               phy_read_calib,
231
   input                               calib_in_common,
232
   input [5:0]                         calib_sel,
233
   input [DQS_CNT_WIDTH:0]             byte_sel_cnt,
234
   input [DRAM_WIDTH-1:0]              fine_delay_incdec_pb,
235
   input                               fine_delay_sel,
236
   input [HIGHEST_BANK-1:0]            calib_zero_inputs,
237
   input [HIGHEST_BANK-1:0]            calib_zero_ctrl,
238
   input [2:0]                         po_fine_enable,
239
   input [2:0]                         po_coarse_enable,
240
   input [2:0]                         po_fine_inc,
241
   input [2:0]                         po_coarse_inc,
242
   input                               po_counter_load_en,
243
   input                               po_counter_read_en,
244
   input [2:0]                         po_sel_fine_oclk_delay,
245
   input [8:0]                         po_counter_load_val,
246
   output [8:0]                        po_counter_read_val,
247
   output [5:0]                        pi_counter_read_val,
248
   input [HIGHEST_BANK-1:0]            pi_rst_dqs_find,
249
   input                               pi_fine_enable,
250
   input                               pi_fine_inc,
251
   input                               pi_counter_load_en,
252
   input [5:0]                         pi_counter_load_val,
253
   input                               idelay_ce,
254
   input                               idelay_inc,
255
   input                               idelay_ld,
256
   input                               idle,
257
   output                              pi_phase_locked,
258
   output                              pi_phase_locked_all,
259
   output                              pi_dqs_found,
260
   output                              pi_dqs_found_all,
261
   output                              pi_dqs_out_of_range,
262
   // From/to calibration logic/soft PHY
263
   input                                         phy_init_data_sel,
264
   input [nCK_PER_CLK*ROW_WIDTH-1:0]             mux_address,
265
   input [nCK_PER_CLK*BANK_WIDTH-1:0]            mux_bank,
266
   input [nCK_PER_CLK-1:0]                       mux_cas_n,
267
   input [CS_WIDTH*nCS_PER_RANK*nCK_PER_CLK-1:0] mux_cs_n,
268
   input [nCK_PER_CLK-1:0]                       mux_ras_n,
269
   input [1:0]                                   mux_odt,
270
   input [nCK_PER_CLK-1:0]                       mux_cke,
271
   input [nCK_PER_CLK-1:0]                       mux_we_n,
272
   input [nCK_PER_CLK-1:0]                       parity_in,
273
   input [2*nCK_PER_CLK*DQ_WIDTH-1:0]            mux_wrdata,
274
   input [2*nCK_PER_CLK*(DQ_WIDTH/8)-1:0]        mux_wrdata_mask,
275
   input                                         mux_reset_n,
276
   output [2*nCK_PER_CLK*DQ_WIDTH-1:0]           rd_data,
277
   // Memory I/F
278
   output [ROW_WIDTH-1:0]                        ddr_addr,
279
   output [BANK_WIDTH-1:0]                       ddr_ba,
280
   output                                        ddr_cas_n,
281
   output [CKE_WIDTH-1:0]                        ddr_cke,
282
   output [CS_WIDTH*nCS_PER_RANK-1:0]            ddr_cs_n,
283
   output [DM_WIDTH-1:0]                         ddr_dm,
284
   output [ODT_WIDTH-1:0]                        ddr_odt,
285
   output                                        ddr_parity,
286
   output                                        ddr_ras_n,
287
   output                                        ddr_we_n,
288
   output                                        ddr_reset_n,
289
   inout [DQ_WIDTH-1:0]                          ddr_dq,
290
   inout [DQS_WIDTH-1:0]                         ddr_dqs,
291
   inout [DQS_WIDTH-1:0]                         ddr_dqs_n,
292
   //output                                        iodelay_ctrl_rdy,
293
   output                                        pd_out
294
 
295
   ,input                                        dbg_pi_counter_read_en
296
   ,output                                       ref_dll_lock
297
   ,input                                        rst_phaser_ref
298
   ,output [11:0]                                dbg_pi_phase_locked_phy4lanes
299
   ,output [11:0]                                dbg_pi_dqs_found_lanes_phy4lanes
300
   );
301
 
302
  function [71:0] generate_bytelanes_ddr_ck;
303
    input [143:0] ck_byte_map;
304
    integer v ;
305
    begin
306
      generate_bytelanes_ddr_ck = 'b0 ;
307
      for (v = 0; v < CK_WIDTH; v = v + 1) begin
308
        if ((CK_BYTE_MAP[((v*8)+4)+:4]) == 2)
309
          generate_bytelanes_ddr_ck[48+(4*v)+1*(CK_BYTE_MAP[(v*8)+:4])] = 1'b1;
310
        else if ((CK_BYTE_MAP[((v*8)+4)+:4]) == 1)
311
          generate_bytelanes_ddr_ck[24+(4*v)+1*(CK_BYTE_MAP[(v*8)+:4])] = 1'b1;
312
        else
313
          generate_bytelanes_ddr_ck[4*v+1*(CK_BYTE_MAP[(v*8)+:4])] = 1'b1;
314
      end
315
    end
316
  endfunction
317
 
318
  function [(2*CK_WIDTH*8)-1:0] generate_ddr_ck_map;
319
    input [143:0] ck_byte_map;
320
    integer g;
321
    begin
322
      generate_ddr_ck_map = 'b0 ;
323
      for(g = 0 ; g < CK_WIDTH ; g= g + 1) begin
324
        generate_ddr_ck_map[(g*2*8)+:8]  = (ck_byte_map[(g*8)+:4] == 4'd0) ? "A" :
325
                                           (ck_byte_map[(g*8)+:4] == 4'd1) ? "B" :
326
                                           (ck_byte_map[(g*8)+:4] == 4'd2) ? "C" : "D" ;
327
        generate_ddr_ck_map[(((g*2)+1)*8)+:8] = (ck_byte_map[((g*8)+4)+:4] == 4'd0) ? "0" :
328
                                                (ck_byte_map[((g*8)+4)+:4] == 4'd1) ? "1" :  "2" ; //each STRING charater takes 0 location
329
      end
330
    end
331
  endfunction
332
 
333
 
334
 
335
  // Enable low power mode for input buffer
336
  localparam IBUF_LOW_PWR
337
             = (IBUF_LPWR_MODE == "OFF") ? "FALSE" :
338
             ((IBUF_LPWR_MODE == "ON")  ? "TRUE" : "ILLEGAL");
339
 
340
  // Ratio of data to strobe
341
  localparam DQ_PER_DQS = DQ_WIDTH / DQS_WIDTH;
342
  // number of data phases per internal clock
343
  localparam PHASE_PER_CLK = 2*nCK_PER_CLK;
344
  // used to determine routing to OUT_FIFO for control/address for 2:1
345
  // vs. 4:1 memory:internal clock ratio modes
346
  localparam PHASE_DIV = 4 / nCK_PER_CLK;
347
 
348
  localparam CLK_PERIOD = tCK * nCK_PER_CLK;
349
 
350
  // Create an aggregate parameters for data mapping to reduce # of generate
351
  // statements required in remapping code. Need to account for the case
352
  // when the DQ:DQS ratio is not 8:1 - in this case, each DATAx_MAP 
353
  // parameter will have fewer than 8 elements used 
354
  localparam FULL_DATA_MAP = {DATA17_MAP[12*DQ_PER_DQS-1:0],
355
                              DATA16_MAP[12*DQ_PER_DQS-1:0],
356
                              DATA15_MAP[12*DQ_PER_DQS-1:0],
357
                              DATA14_MAP[12*DQ_PER_DQS-1:0],
358
                              DATA13_MAP[12*DQ_PER_DQS-1:0],
359
                              DATA12_MAP[12*DQ_PER_DQS-1:0],
360
                              DATA11_MAP[12*DQ_PER_DQS-1:0],
361
                              DATA10_MAP[12*DQ_PER_DQS-1:0],
362
                              DATA9_MAP[12*DQ_PER_DQS-1:0],
363
                              DATA8_MAP[12*DQ_PER_DQS-1:0],
364
                              DATA7_MAP[12*DQ_PER_DQS-1:0],
365
                              DATA6_MAP[12*DQ_PER_DQS-1:0],
366
                              DATA5_MAP[12*DQ_PER_DQS-1:0],
367
                              DATA4_MAP[12*DQ_PER_DQS-1:0],
368
                              DATA3_MAP[12*DQ_PER_DQS-1:0],
369
                              DATA2_MAP[12*DQ_PER_DQS-1:0],
370
                              DATA1_MAP[12*DQ_PER_DQS-1:0],
371
                              DATA0_MAP[12*DQ_PER_DQS-1:0]};
372
  // Same deal, but for data mask mapping
373
  localparam FULL_MASK_MAP = {MASK1_MAP, MASK0_MAP};
374
  localparam TMP_BYTELANES_DDR_CK  = generate_bytelanes_ddr_ck(CK_BYTE_MAP) ;
375
  localparam TMP_GENERATE_DDR_CK_MAP = generate_ddr_ck_map(CK_BYTE_MAP) ;
376
 
377
  // Temporary parameters to determine which bank is outputting the CK/CK#
378
  // Eventually there will be support for multiple CK/CK# output
379
  //localparam TMP_DDR_CLK_SELECT_BANK = (CK_BYTE_MAP[7:4]);
380
  //// Temporary method to force MC_PHY to generate ODDR associated with
381
  //// CK/CK# output only for a single byte lane in the design. All banks
382
  //// that won't be generating the CK/CK# will have "UNUSED" as their
383
  //// PHY_GENERATE_DDR_CK parameter
384
  //localparam TMP_PHY_0_GENERATE_DDR_CK 
385
  //           = (TMP_DDR_CLK_SELECT_BANK != 0) ? "UNUSED" : 
386
  //              ((CK_BYTE_MAP[1:0] == 2'b00) ? "A" :
387
  //               ((CK_BYTE_MAP[1:0] == 2'b01) ? "B" :
388
  //                ((CK_BYTE_MAP[1:0] == 2'b10) ? "C" : "D")));
389
  //localparam TMP_PHY_1_GENERATE_DDR_CK 
390
  //           = (TMP_DDR_CLK_SELECT_BANK != 1) ? "UNUSED" : 
391
  //              ((CK_BYTE_MAP[1:0] == 2'b00) ? "A" :
392
  //               ((CK_BYTE_MAP[1:0] == 2'b01) ? "B" :
393
  //                ((CK_BYTE_MAP[1:0] == 2'b10) ? "C" : "D")));
394
  //localparam TMP_PHY_2_GENERATE_DDR_CK 
395
  //           = (TMP_DDR_CLK_SELECT_BANK != 2) ? "UNUSED" : 
396
  //              ((CK_BYTE_MAP[1:0] == 2'b00) ? "A" :
397
  //               ((CK_BYTE_MAP[1:0] == 2'b01) ? "B" :
398
  //                ((CK_BYTE_MAP[1:0] == 2'b10) ? "C" : "D")));
399
 
400
  // Function to generate MC_PHY parameters PHY_BITLANES_OUTONLYx
401
  // which indicates which bit lanes in data byte lanes are 
402
  // output-only bitlanes (e.g. used specifically for data mask outputs)
403
  function [143:0] calc_phy_bitlanes_outonly;
404
    input [215:0] data_mask_in;
405
    integer       z;
406
    begin
407
      calc_phy_bitlanes_outonly = 'b0;
408
      // Only enable BITLANES parameters for data masks if, well, if
409
      // the data masks are actually enabled
410
      if (USE_DM_PORT == 1)
411
        for (z = 0; z < DM_WIDTH; z = z + 1)
412
          calc_phy_bitlanes_outonly[48*data_mask_in[(12*z+8)+:3] +
413
                                    12*data_mask_in[(12*z+4)+:2] +
414
                                    data_mask_in[12*z+:4]] = 1'b1;
415
    end
416
  endfunction
417
 
418
  localparam PHY_BITLANES_OUTONLY   = calc_phy_bitlanes_outonly(FULL_MASK_MAP);
419
  localparam PHY_0_BITLANES_OUTONLY = PHY_BITLANES_OUTONLY[47:0];
420
  localparam PHY_1_BITLANES_OUTONLY = PHY_BITLANES_OUTONLY[95:48];
421
  localparam PHY_2_BITLANES_OUTONLY = PHY_BITLANES_OUTONLY[143:96];
422
 
423
  // Determine which bank and byte lane generates the RCLK used to clock
424
  // out the auxilliary (ODT, CKE) outputs
425
  localparam CKE_ODT_RCLK_SELECT_BANK_AUX_ON
426
             = (CKE_ODT_BYTE_MAP[7:4] == 4'h0) ? 0 :
427
                 ((CKE_ODT_BYTE_MAP[7:4] == 4'h1) ? 1 :
428
                  ((CKE_ODT_BYTE_MAP[7:4] == 4'h2) ? 2 :
429
                   ((CKE_ODT_BYTE_MAP[7:4] == 4'h3) ? 3 :
430
                    ((CKE_ODT_BYTE_MAP[7:4] == 4'h4) ? 4 : -1))));
431
  localparam CKE_ODT_RCLK_SELECT_LANE_AUX_ON
432
             = (CKE_ODT_BYTE_MAP[3:0] == 4'h0) ? "A" :
433
                 ((CKE_ODT_BYTE_MAP[3:0] == 4'h1) ? "B" :
434
                  ((CKE_ODT_BYTE_MAP[3:0] == 4'h2) ? "C" :
435
                   ((CKE_ODT_BYTE_MAP[3:0] == 4'h3) ? "D" : "ILLEGAL")));
436
 
437
  localparam CKE_ODT_RCLK_SELECT_BANK_AUX_OFF
438
             = (CKE_MAP[11:8] == 4'h0) ? 0 :
439
                 ((CKE_MAP[11:8] == 4'h1) ? 1 :
440
                  ((CKE_MAP[11:8] == 4'h2) ? 2 :
441
                   ((CKE_MAP[11:8] == 4'h3) ? 3 :
442
                    ((CKE_MAP[11:8] == 4'h4) ? 4 : -1))));
443
  localparam CKE_ODT_RCLK_SELECT_LANE_AUX_OFF
444
             = (CKE_MAP[7:4] == 4'h0) ? "A" :
445
                 ((CKE_MAP[7:4] == 4'h1) ? "B" :
446
                  ((CKE_MAP[7:4] == 4'h2) ? "C" :
447
                   ((CKE_MAP[7:4] == 4'h3) ? "D" : "ILLEGAL")));
448
 
449
 
450
  localparam CKE_ODT_RCLK_SELECT_BANK = (CKE_ODT_AUX == "TRUE") ? CKE_ODT_RCLK_SELECT_BANK_AUX_ON : CKE_ODT_RCLK_SELECT_BANK_AUX_OFF ;
451
  localparam CKE_ODT_RCLK_SELECT_LANE = (CKE_ODT_AUX == "TRUE") ? CKE_ODT_RCLK_SELECT_LANE_AUX_ON : CKE_ODT_RCLK_SELECT_LANE_AUX_OFF ;
452
 
453
 
454
  //***************************************************************************
455
  // OCLKDELAYED tap setting calculation:
456
  // Parameters for calculating amount of phase shifting output clock to
457
  // achieve 90 degree offset between DQS and DQ on writes
458
  //***************************************************************************
459
 
460
  //90 deg equivalent to 0.25 for MEM_RefClk <= 300 MHz
461
  // and 1.25 for Mem_RefClk > 300 MHz
462
  localparam PO_OCLKDELAY_INV = (((SIM_CAL_OPTION == "NONE") && (tCK > 2500)) || (tCK >= 3333)) ?  "FALSE" : "TRUE";
463
 
464
  //DIV1: MemRefClk >= 400 MHz, DIV2: 200 <= MemRefClk < 400, 
465
  //DIV4: MemRefClk < 200 MHz
466
  localparam PHY_0_A_PI_FREQ_REF_DIV = tCK > 5000 ?  "DIV4" :
467
                                       tCK > 2500 ? "DIV2": "NONE";
468
 
469
  localparam FREQ_REF_DIV = (PHY_0_A_PI_FREQ_REF_DIV == "DIV4" ? 4 :
470
                             PHY_0_A_PI_FREQ_REF_DIV == "DIV2" ? 2 : 1);
471
 
472
  // Intrinsic delay between OCLK and OCLK_DELAYED Phaser Output
473
  localparam real INT_DELAY = 0.4392/FREQ_REF_DIV + 100.0/tCK;
474
 
475
  // Whether OCLK_DELAY output comes inverted or not
476
  localparam real HALF_CYCLE_DELAY = 0.5*(PO_OCLKDELAY_INV == "TRUE" ? 1 : 0);
477
 
478
  // Phaser-Out Stage3 Tap delay for 90 deg shift. 
479
  // Maximum tap delay is FreqRefClk period distributed over 64 taps
480
  // localparam real TAP_DELAY = MC_OCLK_DELAY/64/FREQ_REF_DIV;
481
  localparam real MC_OCLK_DELAY = ((PO_OCLKDELAY_INV == "TRUE" ? 1.25 : 0.25) -
482
                                   (INT_DELAY + HALF_CYCLE_DELAY))
483
                                   * 63 * FREQ_REF_DIV;
484
  //localparam integer PHY_0_A_PO_OCLK_DELAY = MC_OCLK_DELAY;
485
 
486
  localparam integer PHY_0_A_PO_OCLK_DELAY_HW
487
                     = (tCK > 2273)  ? 34 :
488
                       (tCK > 2000)  ? 33 :
489
                       (tCK > 1724)  ? 32 :
490
                       (tCK > 1515)  ? 31 :
491
                       (tCK > 1315)  ? 30 :
492
                       (tCK > 1136)  ? 29 :
493
                       (tCK > 1021)  ? 28 : 27;
494
 
495
  // Note that simulation requires a different value than in H/W because of the
496
  // difference in the way delays are modeled
497
  localparam integer PHY_0_A_PO_OCLK_DELAY = (SIM_CAL_OPTION == "NONE") ?
498
                                               ((tCK > 2500) ? 8 :
499
                                                (DRAM_TYPE == "DDR3") ? PHY_0_A_PO_OCLK_DELAY_HW : 30) :
500
                                             MC_OCLK_DELAY;
501
 
502
  // Initial DQ IDELAY value
503
  localparam PHY_0_A_IDELAYE2_IDELAY_VALUE = (SIM_CAL_OPTION != "FAST_CAL") ? 0 :
504
                  (tCK < 1000) ? 0 :
505
                  (tCK < 1330) ? 0 :
506
                  (tCK < 2300) ? 0 :
507
                  (tCK < 2500) ? 2 : 0;
508
  //localparam PHY_0_A_IDELAYE2_IDELAY_VALUE = 0;
509
 
510
  // Aux_out parameters RD_CMD_OFFSET = CL+2? and WR_CMD_OFFSET = CWL+3?
511
  localparam PHY_0_RD_CMD_OFFSET_0 = 10;
512
  localparam PHY_0_RD_CMD_OFFSET_1 = 10;
513
  localparam PHY_0_RD_CMD_OFFSET_2 = 10;
514
  localparam PHY_0_RD_CMD_OFFSET_3 = 10;
515
  // 4:1 and 2:1 have WR_CMD_OFFSET values for ODT timing
516
  localparam PHY_0_WR_CMD_OFFSET_0 = (nCK_PER_CLK == 4) ? 8 : 4;
517
  localparam PHY_0_WR_CMD_OFFSET_1 = (nCK_PER_CLK == 4) ? 8 : 4;
518
  localparam PHY_0_WR_CMD_OFFSET_2 = (nCK_PER_CLK == 4) ? 8 : 4;
519
  localparam PHY_0_WR_CMD_OFFSET_3 = (nCK_PER_CLK == 4) ? 8 : 4;
520
  // 4:1 and 2:1 have different values
521
  localparam PHY_0_WR_DURATION_0 = 7;
522
  localparam PHY_0_WR_DURATION_1 = 7;
523
  localparam PHY_0_WR_DURATION_2 = 7;
524
  localparam PHY_0_WR_DURATION_3 = 7;
525
  // Aux_out parameters for toggle mode (CKE)
526
  localparam CWL_M = (REG_CTRL == "ON") ? CWL + 1 : CWL;
527
  localparam PHY_0_CMD_OFFSET = (nCK_PER_CLK == 4) ?  (CWL_M % 2) ? 8 : 9 :
528
                                  (CWL < 7) ?
529
                                    4 + ((CWL_M % 2) ? 0 : 1) :
530
                                    5 + ((CWL_M % 2) ? 0 : 1);
531
 
532
  // temporary parameter to enable/disable PHY PC counters. In both 4:1 and 
533
  // 2:1 cases, this should be disabled. For now, enable for 4:1 mode to 
534
  // avoid making too many changes at once. 
535
  localparam PHY_COUNT_EN = (nCK_PER_CLK == 4) ? "TRUE" : "FALSE";
536
 
537
 
538
  wire [((HIGHEST_LANE+3)/4)*4-1:0] aux_out;
539
  wire [HIGHEST_LANE-1:0]           mem_dqs_in;
540
  wire [HIGHEST_LANE-1:0]           mem_dqs_out;
541
  wire [HIGHEST_LANE-1:0]           mem_dqs_ts;
542
  wire [HIGHEST_LANE*10-1:0]        mem_dq_in;
543
  wire [HIGHEST_LANE*12-1:0]        mem_dq_out;
544
  wire [HIGHEST_LANE*12-1:0]        mem_dq_ts;
545
  wire [DQ_WIDTH-1:0]               in_dq;
546
  wire [DQS_WIDTH-1:0]              in_dqs;
547
  wire [ROW_WIDTH-1:0]              out_addr;
548
  wire [BANK_WIDTH-1:0]             out_ba;
549
  wire                              out_cas_n;
550
  wire [CS_WIDTH*nCS_PER_RANK-1:0]  out_cs_n;
551
  wire [DM_WIDTH-1:0]               out_dm;
552
  wire [ODT_WIDTH -1:0]             out_odt;
553
  wire [CKE_WIDTH -1 :0]            out_cke ;
554
  wire [DQ_WIDTH-1:0]               out_dq;
555
  wire [DQS_WIDTH-1:0]              out_dqs;
556
  wire                              out_parity;
557
  wire                              out_ras_n;
558
  wire                              out_we_n;
559
  wire [HIGHEST_LANE*80-1:0]        phy_din;
560
  wire [HIGHEST_LANE*80-1:0]        phy_dout;
561
  wire                              phy_rd_en;
562
  wire [DM_WIDTH-1:0]               ts_dm;
563
  wire [DQ_WIDTH-1:0]               ts_dq;
564
  wire [DQS_WIDTH-1:0]              ts_dqs;
565
  wire [DQS_WIDTH-1:0]              in_dqs_lpbk_to_iddr;
566
  wire [DQS_WIDTH-1:0]              pd_out_pre;
567
  //wire                              metaQ;
568
 
569
  reg [31:0]                        phy_ctl_wd_i1;
570
  reg [31:0]                        phy_ctl_wd_i2;
571
  reg                               phy_ctl_wr_i1;
572
  reg                               phy_ctl_wr_i2;
573
  reg [5:0]                         data_offset_1_i1;
574
  reg [5:0]                         data_offset_1_i2;
575
  reg [5:0]                         data_offset_2_i1;
576
  reg [5:0]                         data_offset_2_i2;
577
  wire [31:0]                       phy_ctl_wd_temp;
578
  wire                              phy_ctl_wr_temp;
579
  wire [5:0]                        data_offset_1_temp;
580
  wire [5:0]                        data_offset_2_temp;
581
  wire [5:0]                        data_offset_1_of;
582
  wire [5:0]                        data_offset_2_of;
583
  wire [31:0]                       phy_ctl_wd_of;
584
  wire          phy_ctl_wr_of /* synthesis syn_maxfan = 1 */;
585
  wire [3:0]                        phy_ctl_full_temp;
586
 
587
  wire                              data_io_idle_pwrdwn;
588
  reg  [29:0]                       fine_delay_mod;    //3 bit per DQ 
589
  reg                               fine_delay_sel_r;  //timing adj with fine_delay_incdec_pb
590
 
591
  (* use_dsp48 = "no" *) wire [DQS_CNT_WIDTH:0]             byte_sel_cnt_w1;
592
 
593
  // Always read from input data FIFOs when not empty
594
  assign phy_rd_en = !if_empty;
595
 
596
  // IDELAYE2 initial value
597
  assign idelaye2_init_val = PHY_0_A_IDELAYE2_IDELAY_VALUE;
598
  assign oclkdelay_init_val = PHY_0_A_PO_OCLK_DELAY;
599
 
600
  // Idle powerdown when there are no pending reads in the MC
601
  assign data_io_idle_pwrdwn = DATA_IO_IDLE_PWRDWN == "ON" ? idle : 1'b0;
602
 
603
  //***************************************************************************
604
  // Auxiliary output steering
605
  //***************************************************************************
606
 
607
  // For a 4 rank I/F the aux_out[3:0] from the addr/ctl bank will be 
608
  // mapped to ddr_odt and the aux_out[7:4] from one of the data banks
609
  // will map to ddr_cke. For I/Fs less than 4 the aux_out[3:0] from the
610
  // addr/ctl bank would bank would map to both ddr_odt and ddr_cke.
611
  generate
612
  if(CKE_ODT_AUX == "TRUE")begin:cke_thru_auxpins
613
    if (CKE_WIDTH == 1) begin : gen_cke
614
      // Explicitly instantiate OBUF to ensure that these are present
615
      // in the netlist. Typically this is not required since NGDBUILD
616
      // at the top-level knows to infer an I/O/IOBUF and therefore a
617
      // top-level LOC constraint can be attached to that pin. This does
618
      // not work when a hierarchical flow is used and the LOC is applied
619
      // at the individual core-level UCF
620
      OBUF u_cke_obuf
621
        (
622
         .I (aux_out[4*CKE_ODT_RCLK_SELECT_BANK]),
623
         .O (ddr_cke)
624
         );
625
    end else begin: gen_2rank_cke
626
      OBUF u_cke0_obuf
627
        (
628
         .I (aux_out[4*CKE_ODT_RCLK_SELECT_BANK]),
629
         .O (ddr_cke[0])
630
         );
631
      OBUF u_cke1_obuf
632
        (
633
         .I (aux_out[4*CKE_ODT_RCLK_SELECT_BANK+2]),
634
         .O (ddr_cke[1])
635
         );
636
    end
637
  end
638
  endgenerate
639
 
640
  generate
641
  if(CKE_ODT_AUX == "TRUE")begin:odt_thru_auxpins
642
    if (USE_ODT_PORT == 1) begin : gen_use_odt
643
      // Explicitly instantiate OBUF to ensure that these are present
644
      // in the netlist. Typically this is not required since NGDBUILD
645
      // at the top-level knows to infer an I/O/IOBUF and therefore a
646
      // top-level LOC constraint can be attached to that pin. This does
647
      // not work when a hierarchical flow is used and the LOC is applied
648
      // at the individual core-level UCF
649
        OBUF u_odt_obuf
650
          (
651
           .I (aux_out[4*CKE_ODT_RCLK_SELECT_BANK+1]),
652
           .O (ddr_odt[0])
653
           );
654
      if (ODT_WIDTH == 2 && RANKS == 1) begin: gen_2port_odt
655
        OBUF u_odt1_obuf
656
          (
657
           .I (aux_out[4*CKE_ODT_RCLK_SELECT_BANK+2]),
658
           .O (ddr_odt[1])
659
           );
660
      end else if (ODT_WIDTH == 2 && RANKS == 2) begin: gen_2rank_odt
661
        OBUF u_odt1_obuf
662
          (
663
           .I (aux_out[4*CKE_ODT_RCLK_SELECT_BANK+3]),
664
           .O (ddr_odt[1])
665
           );
666
      end else if (ODT_WIDTH == 3 && RANKS == 1) begin: gen_3port_odt
667
        OBUF u_odt1_obuf
668
          (
669
           .I (aux_out[4*CKE_ODT_RCLK_SELECT_BANK+2]),
670
           .O (ddr_odt[1])
671
           );
672
        OBUF u_odt2_obuf
673
          (
674
           .I (aux_out[4*CKE_ODT_RCLK_SELECT_BANK+3]),
675
           .O (ddr_odt[2])
676
           );
677
      end
678
    end else begin
679
        assign ddr_odt = 'b0;
680
    end
681
  end
682
  endgenerate
683
 
684
  //***************************************************************************
685
  // Read data bit steering
686
  //***************************************************************************
687
 
688
  // Transpose elements of rd_data_map to form final read data output:
689
  // phy_din elements are grouped according to "physical bit" - e.g.
690
  // for nCK_PER_CLK = 4, there are 8 data phases transfered per physical
691
  // bit per clock cycle: 
692
  //   = {dq0_fall3, dq0_rise3, dq0_fall2, dq0_rise2, 
693
  //      dq0_fall1, dq0_rise1, dq0_fall0, dq0_rise0}
694
  // whereas rd_data is are grouped according to "phase" - e.g.
695
  //   = {dq7_rise0, dq6_rise0, dq5_rise0, dq4_rise0,
696
  //      dq3_rise0, dq2_rise0, dq1_rise0, dq0_rise0}
697
  // therefore rd_data is formed by transposing phy_din - e.g.
698
  //   for nCK_PER_CLK = 4, and DQ_WIDTH = 16, and assuming MC_PHY 
699
  //   bit_lane[0] maps to DQ[0], and bit_lane[1] maps to DQ[1], then 
700
  //   the assignments for bits of rd_data corresponding to DQ[1:0]
701
  //   would be:      
702
  //    {rd_data[112], rd_data[96], rd_data[80], rd_data[64],
703
  //     rd_data[48], rd_data[32], rd_data[16], rd_data[0]} = phy_din[7:0]
704
  //    {rd_data[113], rd_data[97], rd_data[81], rd_data[65],
705
  //     rd_data[49], rd_data[33], rd_data[17], rd_data[1]} = phy_din[15:8]   
706
  generate
707
    genvar i, j;
708
    for (i = 0; i < DQ_WIDTH; i = i + 1) begin: gen_loop_rd_data_1
709
      for (j = 0; j < PHASE_PER_CLK; j = j + 1) begin: gen_loop_rd_data_2
710
        assign rd_data[DQ_WIDTH*j + i]
711
                 = phy_din[(320*FULL_DATA_MAP[(12*i+8)+:3]+
712
                            80*FULL_DATA_MAP[(12*i+4)+:2] +
713
                            8*FULL_DATA_MAP[12*i+:4]) + j];
714
      end
715
    end
716
  endgenerate
717
 
718
  //generage idelay_inc per bits
719
 
720
  reg [11:0] cal_tmp;
721
  reg [95:0] byte_sel_data_map;
722
 
723
  assign byte_sel_cnt_w1 = byte_sel_cnt;
724
 
725
  always @ (posedge clk) begin
726
     byte_sel_data_map <= #TCQ FULL_DATA_MAP[12*DQ_PER_DQS*byte_sel_cnt_w1+:96];
727
  end
728
 
729
  always @ (posedge clk) begin
730
     fine_delay_mod[((byte_sel_data_map[3:0])*3)+:3] <= #TCQ {fine_delay_incdec_pb[0],2'b00};
731
     fine_delay_mod[((byte_sel_data_map[12+3:12])*3)+:3] <= #TCQ {fine_delay_incdec_pb[1],2'b00};
732
     fine_delay_mod[((byte_sel_data_map[24+3:24])*3)+:3] <= #TCQ {fine_delay_incdec_pb[2],2'b00};
733
     fine_delay_mod[((byte_sel_data_map[36+3:36])*3)+:3] <= #TCQ {fine_delay_incdec_pb[3],2'b00};
734
     fine_delay_mod[((byte_sel_data_map[48+3:48])*3)+:3] <= #TCQ {fine_delay_incdec_pb[4],2'b00};
735
     fine_delay_mod[((byte_sel_data_map[60+3:60])*3)+:3] <= #TCQ {fine_delay_incdec_pb[5],2'b00};
736
     fine_delay_mod[((byte_sel_data_map[72+3:72])*3)+:3] <= #TCQ {fine_delay_incdec_pb[6],2'b00};
737
     fine_delay_mod[((byte_sel_data_map[84+3:84])*3)+:3] <= #TCQ {fine_delay_incdec_pb[7],2'b00};
738
     fine_delay_sel_r <= #TCQ fine_delay_sel;
739
  end
740
 
741
  //***************************************************************************
742
  // Control/address
743
  //***************************************************************************
744
 
745
  assign out_cas_n
746
    = mem_dq_out[48*CAS_MAP[10:8] + 12*CAS_MAP[5:4] + CAS_MAP[3:0]];
747
 
748
  generate
749
    // if signal placed on bit lanes [0-9]    
750
    if (CAS_MAP[3:0] < 4'hA) begin: gen_cas_lt10
751
      // Determine routing based on clock ratio mode. If running in 4:1
752
      // mode, then all four bits from logic are used. If 2:1 mode, only
753
      // 2-bits are provided by logic, and each bit is repeated 2x to form
754
      // 4-bit input to IN_FIFO, e.g.
755
      //   4:1 mode: phy_dout[] = {in[3], in[2], in[1], in[0]}
756
      //   2:1 mode: phy_dout[] = {in[1], in[1], in[0], in[0]}
757
      assign phy_dout[(320*CAS_MAP[10:8] + 80*CAS_MAP[5:4] +
758
                       8*CAS_MAP[3:0])+:4]
759
               = {mux_cas_n[3/PHASE_DIV], mux_cas_n[2/PHASE_DIV],
760
                  mux_cas_n[1/PHASE_DIV], mux_cas_n[0]};
761
    end else begin: gen_cas_ge10
762
      // If signal is placed in bit lane [10] or [11], route to upper
763
      // nibble of phy_dout lane [5] or [6] respectively (in this case
764
      // phy_dout lane [5, 6] are multiplexed to take input for two
765
      // different SDR signals - this is how bits[10,11] need to be
766
      // provided to the OUT_FIFO
767
      assign phy_dout[(320*CAS_MAP[10:8] + 80*CAS_MAP[5:4] +
768
                       8*(CAS_MAP[3:0]-5) + 4)+:4]
769
               = {mux_cas_n[3/PHASE_DIV], mux_cas_n[2/PHASE_DIV],
770
                  mux_cas_n[1/PHASE_DIV], mux_cas_n[0]};
771
    end
772
  endgenerate
773
 
774
  assign out_ras_n
775
    = mem_dq_out[48*RAS_MAP[10:8] + 12*RAS_MAP[5:4] + RAS_MAP[3:0]];
776
 
777
  generate
778
    if (RAS_MAP[3:0] < 4'hA) begin: gen_ras_lt10
779
      assign phy_dout[(320*RAS_MAP[10:8] + 80*RAS_MAP[5:4] +
780
                       8*RAS_MAP[3:0])+:4]
781
               = {mux_ras_n[3/PHASE_DIV], mux_ras_n[2/PHASE_DIV],
782
                  mux_ras_n[1/PHASE_DIV], mux_ras_n[0]};
783
    end else begin: gen_ras_ge10
784
      assign phy_dout[(320*RAS_MAP[10:8] + 80*RAS_MAP[5:4] +
785
                       8*(RAS_MAP[3:0]-5) + 4)+:4]
786
               = {mux_ras_n[3/PHASE_DIV], mux_ras_n[2/PHASE_DIV],
787
                  mux_ras_n[1/PHASE_DIV], mux_ras_n[0]};
788
    end
789
  endgenerate
790
 
791
  assign out_we_n
792
    = mem_dq_out[48*WE_MAP[10:8] + 12*WE_MAP[5:4] + WE_MAP[3:0]];
793
 
794
  generate
795
    if (WE_MAP[3:0] < 4'hA) begin: gen_we_lt10
796
      assign phy_dout[(320*WE_MAP[10:8] + 80*WE_MAP[5:4] +
797
                       8*WE_MAP[3:0])+:4]
798
               = {mux_we_n[3/PHASE_DIV], mux_we_n[2/PHASE_DIV],
799
                  mux_we_n[1/PHASE_DIV], mux_we_n[0]};
800
    end else begin: gen_we_ge10
801
      assign phy_dout[(320*WE_MAP[10:8] + 80*WE_MAP[5:4] +
802
                       8*(WE_MAP[3:0]-5) + 4)+:4]
803
               = {mux_we_n[3/PHASE_DIV], mux_we_n[2/PHASE_DIV],
804
                  mux_we_n[1/PHASE_DIV], mux_we_n[0]};
805
    end
806
  endgenerate
807
 
808
  generate
809
    if (REG_CTRL == "ON") begin: gen_parity_out
810
      // Generate addr/ctrl parity output only for DDR3 and DDR2 registered DIMMs
811
      assign out_parity
812
        = mem_dq_out[48*PARITY_MAP[10:8] + 12*PARITY_MAP[5:4] +
813
                     PARITY_MAP[3:0]];
814
      if (PARITY_MAP[3:0] < 4'hA) begin: gen_lt10
815
        assign phy_dout[(320*PARITY_MAP[10:8] + 80*PARITY_MAP[5:4] +
816
                         8*PARITY_MAP[3:0])+:4]
817
                 = {parity_in[3/PHASE_DIV], parity_in[2/PHASE_DIV],
818
                    parity_in[1/PHASE_DIV], parity_in[0]};
819
      end else begin: gen_ge10
820
        assign phy_dout[(320*PARITY_MAP[10:8] + 80*PARITY_MAP[5:4] +
821
                         8*(PARITY_MAP[3:0]-5) + 4)+:4]
822
               = {parity_in[3/PHASE_DIV], parity_in[2/PHASE_DIV],
823
                  parity_in[1/PHASE_DIV], parity_in[0]};
824
      end
825
    end
826
  endgenerate
827
 
828
  //*****************************************************************  
829
 
830
  generate
831
    genvar m, n,x;
832
 
833
    //*****************************************************************
834
    // Control/address (multi-bit) buses
835
    //*****************************************************************
836
 
837
    // Row/Column address
838
    for (m = 0; m < ROW_WIDTH; m = m + 1) begin: gen_addr_out
839
      assign out_addr[m]
840
               = mem_dq_out[48*ADDR_MAP[(12*m+8)+:3] +
841
                            12*ADDR_MAP[(12*m+4)+:2] +
842
                            ADDR_MAP[12*m+:4]];
843
 
844
      if (ADDR_MAP[12*m+:4] < 4'hA) begin: gen_lt10
845
        // For multi-bit buses, we also have to deal with transposition 
846
        // when going from the logic-side control bus to phy_dout
847
        for (n = 0; n < 4; n = n + 1) begin: loop_xpose
848
          assign phy_dout[320*ADDR_MAP[(12*m+8)+:3] +
849
                          80*ADDR_MAP[(12*m+4)+:2] +
850
                          8*ADDR_MAP[12*m+:4] + n]
851
                   = mux_address[ROW_WIDTH*(n/PHASE_DIV) + m];
852
        end
853
      end else begin: gen_ge10
854
        for (n = 0; n < 4; n = n + 1) begin: loop_xpose
855
          assign phy_dout[320*ADDR_MAP[(12*m+8)+:3] +
856
                          80*ADDR_MAP[(12*m+4)+:2] +
857
                          8*(ADDR_MAP[12*m+:4]-5) + 4 + n]
858
                   = mux_address[ROW_WIDTH*(n/PHASE_DIV) + m];
859
        end
860
      end
861
    end
862
 
863
    // Bank address
864
    for (m = 0; m < BANK_WIDTH; m = m + 1) begin: gen_ba_out
865
        assign out_ba[m]
866
                 = mem_dq_out[48*BANK_MAP[(12*m+8)+:3] +
867
                              12*BANK_MAP[(12*m+4)+:2] +
868
                              BANK_MAP[12*m+:4]];
869
 
870
      if (BANK_MAP[12*m+:4] < 4'hA) begin: gen_lt10
871
        for (n = 0; n < 4; n = n + 1) begin: loop_xpose
872
          assign phy_dout[320*BANK_MAP[(12*m+8)+:3] +
873
                          80*BANK_MAP[(12*m+4)+:2] +
874
                          8*BANK_MAP[12*m+:4] + n]
875
                   = mux_bank[BANK_WIDTH*(n/PHASE_DIV) + m];
876
        end
877
      end else begin: gen_ge10
878
        for (n = 0; n < 4; n = n + 1) begin: loop_xpose
879
          assign phy_dout[320*BANK_MAP[(12*m+8)+:3] +
880
                          80*BANK_MAP[(12*m+4)+:2] +
881
                          8*(BANK_MAP[12*m+:4]-5) + 4 + n]
882
                   = mux_bank[BANK_WIDTH*(n/PHASE_DIV) + m];
883
        end
884
      end
885
    end
886
 
887
    // Chip select     
888
    if (USE_CS_PORT == 1) begin: gen_cs_n_out
889
      for (m = 0; m < CS_WIDTH*nCS_PER_RANK; m = m + 1) begin: gen_cs_out
890
        assign out_cs_n[m]
891
                 = mem_dq_out[48*CS_MAP[(12*m+8)+:3] +
892
                              12*CS_MAP[(12*m+4)+:2] +
893
                              CS_MAP[12*m+:4]];
894
        if (CS_MAP[12*m+:4] < 4'hA) begin: gen_lt10
895
          for (n = 0; n < 4; n = n + 1) begin: loop_xpose
896
            assign phy_dout[320*CS_MAP[(12*m+8)+:3] +
897
                            80*CS_MAP[(12*m+4)+:2] +
898
                            8*CS_MAP[12*m+:4] + n]
899
                     = mux_cs_n[CS_WIDTH*nCS_PER_RANK*(n/PHASE_DIV) + m];
900
          end
901
        end else begin: gen_ge10
902
          for (n = 0; n < 4; n = n + 1) begin: loop_xpose
903
            assign phy_dout[320*CS_MAP[(12*m+8)+:3] +
904
                            80*CS_MAP[(12*m+4)+:2] +
905
                            8*(CS_MAP[12*m+:4]-5) + 4 + n]
906
                     = mux_cs_n[CS_WIDTH*nCS_PER_RANK*(n/PHASE_DIV) + m];
907
          end
908
        end
909
      end
910
    end
911
 
912
 
913
   if(CKE_ODT_AUX == "FALSE") begin
914
     // ODT_ports     
915
     wire [ODT_WIDTH*nCK_PER_CLK -1 :0] mux_odt_remap  ;
916
 
917
     if(RANKS == 1) begin
918
        for(x =0 ; x < nCK_PER_CLK ; x = x+1) begin
919
          assign mux_odt_remap[(x*ODT_WIDTH)+:ODT_WIDTH] = {ODT_WIDTH{mux_odt[0]}} ;
920
        end
921
     end else begin
922
        for(x =0 ; x < 2*nCK_PER_CLK ; x = x+2) begin
923
          assign mux_odt_remap[(x*ODT_WIDTH/RANKS)+:ODT_WIDTH/RANKS] = {ODT_WIDTH/RANKS{mux_odt[0]}} ;
924
          assign mux_odt_remap[((x*ODT_WIDTH/RANKS)+(ODT_WIDTH/RANKS))+:ODT_WIDTH/RANKS] = {ODT_WIDTH/RANKS{mux_odt[1]}} ;
925
        end
926
     end
927
 
928
     if (USE_ODT_PORT == 1) begin: gen_odt_out
929
       for (m = 0; m < ODT_WIDTH; m = m + 1) begin: gen_odt_out_1
930
         assign out_odt[m]
931
                  = mem_dq_out[48*ODT_MAP[(12*m+8)+:3] +
932
                               12*ODT_MAP[(12*m+4)+:2] +
933
                               ODT_MAP[12*m+:4]];
934
         if (ODT_MAP[12*m+:4] < 4'hA) begin: gen_lt10
935
           for (n = 0; n < 4; n = n + 1) begin: loop_xpose
936
             assign phy_dout[320*ODT_MAP[(12*m+8)+:3] +
937
                             80*ODT_MAP[(12*m+4)+:2] +
938
                             8*ODT_MAP[12*m+:4] + n]
939
                      = mux_odt_remap[ODT_WIDTH*(n/PHASE_DIV) + m];
940
           end
941
         end else begin: gen_ge10
942
           for (n = 0; n < 4; n = n + 1) begin: loop_xpose
943
             assign phy_dout[320*ODT_MAP[(12*m+8)+:3] +
944
                             80*ODT_MAP[(12*m+4)+:2] +
945
                             8*(ODT_MAP[12*m+:4]-5) + 4 + n]
946
                      = mux_odt_remap[ODT_WIDTH*(n/PHASE_DIV) + m];
947
           end
948
         end
949
       end
950
     end
951
 
952
 
953
     wire [CKE_WIDTH*nCK_PER_CLK -1:0] mux_cke_remap ;
954
 
955
     for(x = 0 ; x < nCK_PER_CLK ; x = x +1) begin
956
      assign  mux_cke_remap[(x*CKE_WIDTH)+:CKE_WIDTH] = {CKE_WIDTH{mux_cke[x]}} ;
957
     end
958
 
959
 
960
 
961
     for (m = 0; m < CKE_WIDTH; m = m + 1) begin: gen_cke_out
962
       assign out_cke[m]
963
                = mem_dq_out[48*CKE_MAP[(12*m+8)+:3] +
964
                             12*CKE_MAP[(12*m+4)+:2] +
965
                             CKE_MAP[12*m+:4]];
966
       if (CKE_MAP[12*m+:4] < 4'hA) begin: gen_lt10
967
         for (n = 0; n < 4; n = n + 1) begin: loop_xpose
968
           assign phy_dout[320*CKE_MAP[(12*m+8)+:3] +
969
                           80*CKE_MAP[(12*m+4)+:2] +
970
                           8*CKE_MAP[12*m+:4] + n]
971
                    = mux_cke_remap[CKE_WIDTH*(n/PHASE_DIV) + m];
972
         end
973
       end else begin: gen_ge10
974
         for (n = 0; n < 4; n = n + 1) begin: loop_xpose
975
           assign phy_dout[320*CKE_MAP[(12*m+8)+:3] +
976
                           80*CKE_MAP[(12*m+4)+:2] +
977
                           8*(CKE_MAP[12*m+:4]-5) + 4 + n]
978
                    = mux_cke_remap[CKE_WIDTH*(n/PHASE_DIV) + m];
979
         end
980
       end
981
     end
982
   end
983
 
984
    //*****************************************************************
985
    // Data mask
986
    //*****************************************************************
987
 
988
    if (USE_DM_PORT == 1) begin: gen_dm_out
989
      for (m = 0; m < DM_WIDTH; m = m + 1) begin: gen_dm_out
990
        assign out_dm[m]
991
                 = mem_dq_out[48*FULL_MASK_MAP[(12*m+8)+:3] +
992
                              12*FULL_MASK_MAP[(12*m+4)+:2] +
993
                              FULL_MASK_MAP[12*m+:4]];
994
        assign ts_dm[m]
995
                 = mem_dq_ts[48*FULL_MASK_MAP[(12*m+8)+:3] +
996
                             12*FULL_MASK_MAP[(12*m+4)+:2] +
997
                             FULL_MASK_MAP[12*m+:4]];
998
        for (n = 0; n < PHASE_PER_CLK; n = n + 1) begin: loop_xpose
999
          assign phy_dout[320*FULL_MASK_MAP[(12*m+8)+:3] +
1000
                          80*FULL_MASK_MAP[(12*m+4)+:2] +
1001
                          8*FULL_MASK_MAP[12*m+:4] + n]
1002
                   = mux_wrdata_mask[DM_WIDTH*n + m];
1003
        end
1004
      end
1005
    end
1006
 
1007
    //*****************************************************************
1008
    // Input and output DQ
1009
    //*****************************************************************
1010
 
1011
    for (m = 0; m < DQ_WIDTH; m = m + 1) begin: gen_dq_inout
1012
      // to MC_PHY
1013
      assign mem_dq_in[40*FULL_DATA_MAP[(12*m+8)+:3] +
1014
                       10*FULL_DATA_MAP[(12*m+4)+:2] +
1015
                       FULL_DATA_MAP[12*m+:4]]
1016
               = in_dq[m];
1017
      // to I/O buffers
1018
      assign out_dq[m]
1019
               = mem_dq_out[48*FULL_DATA_MAP[(12*m+8)+:3] +
1020
                            12*FULL_DATA_MAP[(12*m+4)+:2] +
1021
                            FULL_DATA_MAP[12*m+:4]];
1022
      assign ts_dq[m]
1023
               = mem_dq_ts[48*FULL_DATA_MAP[(12*m+8)+:3] +
1024
                           12*FULL_DATA_MAP[(12*m+4)+:2] +
1025
                           FULL_DATA_MAP[12*m+:4]];
1026
      for (n = 0; n < PHASE_PER_CLK; n = n + 1) begin: loop_xpose
1027
        assign phy_dout[320*FULL_DATA_MAP[(12*m+8)+:3] +
1028
                        80*FULL_DATA_MAP[(12*m+4)+:2] +
1029
                        8*FULL_DATA_MAP[12*m+:4] + n]
1030
                 = mux_wrdata[DQ_WIDTH*n + m];
1031
      end
1032
    end
1033
 
1034
    //*****************************************************************
1035
    // Input and output DQS
1036
    //*****************************************************************
1037
 
1038
    for (m = 0; m < DQS_WIDTH; m = m + 1) begin: gen_dqs_inout
1039
      // to MC_PHY
1040
      assign mem_dqs_in[4*DQS_BYTE_MAP[(8*m+4)+:3] + DQS_BYTE_MAP[(8*m)+:2]]
1041
        = in_dqs[m];
1042
      // to I/O buffers
1043
      assign out_dqs[m]
1044
        = mem_dqs_out[4*DQS_BYTE_MAP[(8*m+4)+:3] + DQS_BYTE_MAP[(8*m)+:2]];
1045
      assign ts_dqs[m]
1046
        = mem_dqs_ts[4*DQS_BYTE_MAP[(8*m+4)+:3] + DQS_BYTE_MAP[(8*m)+:2]];
1047
    end
1048
  endgenerate
1049
 
1050
  assign pd_out = pd_out_pre[byte_sel_cnt_w1];
1051
 
1052
 
1053
  //***************************************************************************
1054
  // Memory I/F output and I/O buffer instantiation
1055
  //***************************************************************************
1056
 
1057
  // Note on instantiation - generally at the minimum, it's not required to 
1058
  // instantiate the output buffers - they can be inferred by the synthesis
1059
  // tool, and there aren't any attributes that need to be associated with
1060
  // them. Consider as a future option to take out the OBUF instantiations
1061
 
1062
  OBUF u_cas_n_obuf
1063
    (
1064
     .I (out_cas_n),
1065
     .O (ddr_cas_n)
1066
     );
1067
 
1068
  OBUF u_ras_n_obuf
1069
    (
1070
     .I (out_ras_n),
1071
     .O (ddr_ras_n)
1072
     );
1073
 
1074
  OBUF u_we_n_obuf
1075
    (
1076
     .I (out_we_n),
1077
     .O (ddr_we_n)
1078
     );
1079
 
1080
  generate
1081
    genvar p;
1082
 
1083
    for (p = 0; p < ROW_WIDTH; p = p + 1) begin: gen_addr_obuf
1084
      OBUF u_addr_obuf
1085
        (
1086
         .I (out_addr[p]),
1087
         .O (ddr_addr[p])
1088
         );
1089
    end
1090
 
1091
    for (p = 0; p < BANK_WIDTH; p = p + 1) begin: gen_bank_obuf
1092
      OBUF u_bank_obuf
1093
        (
1094
         .I (out_ba[p]),
1095
         .O (ddr_ba[p])
1096
         );
1097
    end
1098
 
1099
    if (USE_CS_PORT == 1) begin: gen_cs_n_obuf
1100
      for (p = 0; p < CS_WIDTH*nCS_PER_RANK; p = p + 1) begin: gen_cs_obuf
1101
        OBUF u_cs_n_obuf
1102
          (
1103
           .I (out_cs_n[p]),
1104
           .O (ddr_cs_n[p])
1105
           );
1106
      end
1107
    end
1108
    if(CKE_ODT_AUX == "FALSE")begin:cke_odt_thru_outfifo
1109
      if (USE_ODT_PORT== 1) begin: gen_odt_obuf
1110
        for (p = 0; p < ODT_WIDTH; p = p + 1) begin: gen_odt_obuf
1111
          OBUF u_cs_n_obuf
1112
            (
1113
             .I (out_odt[p]),
1114
             .O (ddr_odt[p])
1115
             );
1116
        end
1117
      end
1118
        for (p = 0; p < CKE_WIDTH; p = p + 1) begin: gen_cke_obuf
1119
          OBUF u_cs_n_obuf
1120
            (
1121
             .I (out_cke[p]),
1122
             .O (ddr_cke[p])
1123
             );
1124
        end
1125
    end
1126
 
1127
    if (REG_CTRL == "ON") begin: gen_parity_obuf
1128
      // Generate addr/ctrl parity output only for DDR3 registered DIMMs
1129
      OBUF u_parity_obuf
1130
        (
1131
         .I (out_parity),
1132
         .O (ddr_parity)
1133
         );
1134
    end else begin: gen_parity_tieoff
1135
      assign ddr_parity = 1'b0;
1136
    end
1137
 
1138
    if ((DRAM_TYPE == "DDR3") || (REG_CTRL == "ON")) begin: gen_reset_obuf
1139
      // Generate reset output only for DDR3 and DDR2 RDIMMs
1140
      OBUF u_reset_obuf
1141
        (
1142
         .I (mux_reset_n),
1143
         .O (ddr_reset_n)
1144
         );
1145
    end else begin: gen_reset_tieoff
1146
      assign ddr_reset_n = 1'b1;
1147
    end
1148
 
1149
    if (USE_DM_PORT == 1) begin: gen_dm_obuf
1150
      for (p = 0; p < DM_WIDTH; p = p + 1) begin: loop_dm
1151
        OBUFT u_dm_obuf
1152
          (
1153
           .I (out_dm[p]),
1154
           .T (ts_dm[p]),
1155
           .O (ddr_dm[p])
1156
           );
1157
      end
1158
    end else begin: gen_dm_tieoff
1159
      assign ddr_dm = 'b0;
1160
    end
1161
 
1162
    if (DATA_IO_PRIM_TYPE == "HP_LP") begin: gen_dq_iobuf_HP
1163
      for (p = 0; p < DQ_WIDTH; p = p + 1) begin: gen_dq_iobuf
1164
        IOBUF_DCIEN #
1165
          (
1166
           .IBUF_LOW_PWR (IBUF_LOW_PWR)
1167
           )
1168
          u_iobuf_dq
1169
            (
1170
             .DCITERMDISABLE (data_io_idle_pwrdwn),
1171
             .IBUFDISABLE    (data_io_idle_pwrdwn),
1172
             .I              (out_dq[p]),
1173
             .T              (ts_dq[p]),
1174
             .O              (in_dq[p]),
1175
             .IO             (ddr_dq[p])
1176
             );
1177
      end
1178
    end else if (DATA_IO_PRIM_TYPE == "HR_LP") begin: gen_dq_iobuf_HR
1179
      for (p = 0; p < DQ_WIDTH; p = p + 1) begin: gen_dq_iobuf
1180
        IOBUF_INTERMDISABLE #
1181
          (
1182
           .IBUF_LOW_PWR (IBUF_LOW_PWR)
1183
           )
1184
          u_iobuf_dq
1185
            (
1186
             .INTERMDISABLE  (data_io_idle_pwrdwn),
1187
             .IBUFDISABLE    (data_io_idle_pwrdwn),
1188
             .I              (out_dq[p]),
1189
             .T              (ts_dq[p]),
1190
             .O              (in_dq[p]),
1191
             .IO             (ddr_dq[p])
1192
             );
1193
      end
1194
    end else begin: gen_dq_iobuf_default
1195
      for (p = 0; p < DQ_WIDTH; p = p + 1) begin: gen_dq_iobuf
1196
        IOBUF #
1197
          (
1198
           .IBUF_LOW_PWR (IBUF_LOW_PWR)
1199
           )
1200
          u_iobuf_dq
1201
            (
1202
             .I  (out_dq[p]),
1203
             .T  (ts_dq[p]),
1204
             .O  (in_dq[p]),
1205
             .IO (ddr_dq[p])
1206
             );
1207
      end
1208
    end
1209
 
1210
    //if (DATA_IO_PRIM_TYPE == "HP_LP") begin: gen_dqs_iobuf_HP
1211
        if ((BANK_TYPE == "HP_IO") || (BANK_TYPE == "HPL_IO")) begin: gen_dqs_iobuf_HP
1212
      for (p = 0; p < DQS_WIDTH; p = p + 1) begin: gen_dqs_iobuf
1213
        if ((DRAM_TYPE == "DDR2") &&
1214
            (DDR2_DQSN_ENABLE != "YES")) begin: gen_ddr2_dqs_se
1215
          IOBUF_DCIEN #
1216
            (
1217
             .IBUF_LOW_PWR (IBUF_LOW_PWR)
1218
             )
1219
            u_iobuf_dqs
1220
              (
1221
               .DCITERMDISABLE (data_io_idle_pwrdwn),
1222
               .IBUFDISABLE    (data_io_idle_pwrdwn),
1223
               .I              (out_dqs[p]),
1224
               .T              (ts_dqs[p]),
1225
               .O              (in_dqs[p]),
1226
               .IO             (ddr_dqs[p])
1227
               );
1228
          assign ddr_dqs_n[p] = 1'b0;
1229
          assign pd_out_pre[p] = 1'b0;
1230
        end else if ((DRAM_TYPE == "DDR2") ||
1231
                     (tCK > 2500)) begin : gen_ddr2_or_low_dqs_diff
1232
          IOBUFDS_DCIEN #
1233
            (
1234
             .IBUF_LOW_PWR (IBUF_LOW_PWR),
1235
             .DQS_BIAS     ("TRUE")
1236
             )
1237
            u_iobuf_dqs
1238
              (
1239
               .DCITERMDISABLE (data_io_idle_pwrdwn),
1240
               .IBUFDISABLE    (data_io_idle_pwrdwn),
1241
               .I              (out_dqs[p]),
1242
               .T              (ts_dqs[p]),
1243
               .O              (in_dqs[p]),
1244
               .IO             (ddr_dqs[p]),
1245
               .IOB            (ddr_dqs_n[p])
1246
               );
1247
          assign pd_out_pre[p] = 1'b0;
1248
        end else begin: gen_dqs_diff
1249
          IOBUFDS_DIFF_OUT_DCIEN #
1250
            (
1251
             .IBUF_LOW_PWR (IBUF_LOW_PWR),
1252
             .DQS_BIAS     ("TRUE"),
1253
             .SIM_DEVICE   ("7SERIES"),
1254
             .USE_IBUFDISABLE ("FALSE")
1255
             )
1256
            u_iobuf_dqs
1257
              (
1258
               .DCITERMDISABLE (data_io_idle_pwrdwn),
1259
               .I              (out_dqs[p]),
1260
               .TM             (ts_dqs[p]),
1261
               .TS             (ts_dqs[p]),
1262
               .OB             (in_dqs_lpbk_to_iddr[p]),
1263
               .O              (in_dqs[p]),
1264
               .IO             (ddr_dqs[p]),
1265
               .IOB            (ddr_dqs_n[p])
1266
               );
1267
 
1268
              mig_7series_v2_3_poc_pd #
1269
              (
1270
               .TCQ        (TCQ),
1271
               .POC_USE_METASTABLE_SAMP (POC_USE_METASTABLE_SAMP)
1272
              )
1273
              u_iddr_edge_det
1274
              (
1275
                .clk         (clk),
1276
                    .iddr_rst         (iddr_rst),
1277
                    .kclk        (in_dqs_lpbk_to_iddr[p]),
1278
                    .mmcm_ps_clk (mmcm_ps_clk),
1279
                    .pd_out      (pd_out_pre[p])
1280
              );
1281
        end
1282
      end
1283
    //end else if (DATA_IO_PRIM_TYPE == "HR_LP") begin: gen_dqs_iobuf_HR
1284
        end else if ((BANK_TYPE == "HR_IO") || (BANK_TYPE == "HRL_IO")) begin: gen_dqs_iobuf_HR
1285
      for (p = 0; p < DQS_WIDTH; p = p + 1) begin: gen_dqs_iobuf
1286
        if ((DRAM_TYPE == "DDR2") &&
1287
            (DDR2_DQSN_ENABLE != "YES")) begin: gen_ddr2_dqs_se
1288
          IOBUF_INTERMDISABLE #
1289
            (
1290
             .IBUF_LOW_PWR (IBUF_LOW_PWR)
1291
             )
1292
            u_iobuf_dqs
1293
              (
1294
               .INTERMDISABLE  (data_io_idle_pwrdwn),
1295
               .IBUFDISABLE    (data_io_idle_pwrdwn),
1296
               .I              (out_dqs[p]),
1297
               .T              (ts_dqs[p]),
1298
               .O              (in_dqs[p]),
1299
               .IO             (ddr_dqs[p])
1300
               );
1301
          assign ddr_dqs_n[p] = 1'b0;
1302
          assign pd_out_pre[p] = 1'b0;
1303
        end else if ((DRAM_TYPE == "DDR2") ||
1304
                     (tCK > 2500)) begin: gen_ddr2_or_low_dqs_diff
1305
          IOBUFDS_INTERMDISABLE #
1306
            (
1307
             .IBUF_LOW_PWR (IBUF_LOW_PWR),
1308
             .DQS_BIAS     ("TRUE")
1309
             )
1310
            u_iobuf_dqs
1311
              (
1312
               .INTERMDISABLE  (data_io_idle_pwrdwn),
1313
               .IBUFDISABLE    (data_io_idle_pwrdwn),
1314
               .I              (out_dqs[p]),
1315
               .T              (ts_dqs[p]),
1316
               .O              (in_dqs[p]),
1317
               .IO             (ddr_dqs[p]),
1318
               .IOB            (ddr_dqs_n[p])
1319
               );
1320
          assign pd_out_pre[p] = 1'b0;
1321
        end else begin: gen_dqs_diff
1322
          IOBUFDS_DIFF_OUT_INTERMDISABLE #
1323
            (
1324
             .IBUF_LOW_PWR (IBUF_LOW_PWR),
1325
             .DQS_BIAS     ("TRUE"),
1326
             .SIM_DEVICE   ("7SERIES"),
1327
             .USE_IBUFDISABLE ("FALSE")
1328
             )
1329
            u_iobuf_dqs
1330
              (
1331
               .INTERMDISABLE  (data_io_idle_pwrdwn),
1332
               //.IBUFDISABLE    (data_io_idle_pwrdwn),
1333
               .I              (out_dqs[p]),
1334
               .TM             (ts_dqs[p]),
1335
               .TS             (ts_dqs[p]),
1336
               .OB             (in_dqs_lpbk_to_iddr[p]),
1337
               .O              (in_dqs[p]),
1338
               .IO             (ddr_dqs[p]),
1339
               .IOB            (ddr_dqs_n[p])
1340
               );
1341
 
1342
            mig_7series_v2_3_poc_pd #
1343
            (
1344
             .TCQ        (TCQ),
1345
             .POC_USE_METASTABLE_SAMP (POC_USE_METASTABLE_SAMP)
1346
            )
1347
            u_iddr_edge_det
1348
              (
1349
               .clk         (clk),
1350
               .iddr_rst    (iddr_rst),
1351
               .kclk        (in_dqs_lpbk_to_iddr[p]),
1352
               .mmcm_ps_clk (mmcm_ps_clk),
1353
               .pd_out      (pd_out_pre[p])
1354
              );
1355
        end
1356
      end
1357
    end else begin: gen_dqs_iobuf_default
1358
      for (p = 0; p < DQS_WIDTH; p = p + 1) begin: gen_dqs_iobuf
1359
        if ((DRAM_TYPE == "DDR2") &&
1360
            (DDR2_DQSN_ENABLE != "YES")) begin: gen_ddr2_dqs_se
1361
          IOBUF #
1362
            (
1363
             .IBUF_LOW_PWR (IBUF_LOW_PWR)
1364
             )
1365
            u_iobuf_dqs
1366
              (
1367
               .I   (out_dqs[p]),
1368
               .T   (ts_dqs[p]),
1369
               .O   (in_dqs[p]),
1370
               .IO  (ddr_dqs[p])
1371
               );
1372
          assign ddr_dqs_n[p] = 1'b0;
1373
          assign pd_out_pre[p] = 1'b0;
1374
        end else begin: gen_dqs_diff
1375
          IOBUFDS #
1376
            (
1377
             .IBUF_LOW_PWR (IBUF_LOW_PWR),
1378
             .DQS_BIAS     ("TRUE")
1379
             )
1380
            u_iobuf_dqs
1381
              (
1382
               .I   (out_dqs[p]),
1383
               .T   (ts_dqs[p]),
1384
               .O   (in_dqs[p]),
1385
               .IO  (ddr_dqs[p]),
1386
               .IOB (ddr_dqs_n[p])
1387
               );
1388
          assign pd_out_pre[p] = 1'b0;
1389
        end
1390
      end
1391
    end
1392
 
1393
  endgenerate
1394
 
1395
  always @(posedge clk) begin
1396
    phy_ctl_wd_i1 <= #TCQ phy_ctl_wd;
1397
    phy_ctl_wr_i1 <= #TCQ phy_ctl_wr;
1398
    phy_ctl_wd_i2 <= #TCQ phy_ctl_wd_i1;
1399
    phy_ctl_wr_i2 <= #TCQ phy_ctl_wr_i1;
1400
    data_offset_1_i1 <= #TCQ data_offset_1;
1401
    data_offset_1_i2 <= #TCQ data_offset_1_i1;
1402
    data_offset_2_i1 <= #TCQ data_offset_2;
1403
    data_offset_2_i2 <= #TCQ data_offset_2_i1;
1404
  end
1405
 
1406
 
1407
  // 2 cycles of command delay needed for 4;1 mode. 2:1 mode does not need it.
1408
  // 2:1 mode the command goes through pre fifo 
1409
  assign phy_ctl_wd_temp = (nCK_PER_CLK == 4) ? phy_ctl_wd_i2 : phy_ctl_wd_of;
1410
  assign phy_ctl_wr_temp = (nCK_PER_CLK == 4) ? phy_ctl_wr_i2 : phy_ctl_wr_of;
1411
  assign data_offset_1_temp = (nCK_PER_CLK == 4) ? data_offset_1_i2 : data_offset_1_of;
1412
  assign data_offset_2_temp = (nCK_PER_CLK == 4) ? data_offset_2_i2 : data_offset_2_of;
1413
 
1414
  generate
1415
    begin
1416
 
1417
      mig_7series_v2_3_ddr_of_pre_fifo #
1418
        (
1419
         .TCQ   (25),
1420
         .DEPTH (8),
1421
         .WIDTH (32)
1422
        )
1423
        phy_ctl_pre_fifo_0
1424
        (
1425
         .clk       (clk),
1426
         .rst       (rst),
1427
         .full_in   (phy_ctl_full_temp[1]),
1428
         .wr_en_in  (phy_ctl_wr),
1429
         .d_in      (phy_ctl_wd),
1430
         .wr_en_out (phy_ctl_wr_of),
1431
         .d_out     (phy_ctl_wd_of)
1432
        );
1433
 
1434
      mig_7series_v2_3_ddr_of_pre_fifo #
1435
        (
1436
         .TCQ   (25),
1437
         .DEPTH (8),
1438
         .WIDTH (6)
1439
        )
1440
        phy_ctl_pre_fifo_1
1441
        (
1442
         .clk       (clk),
1443
         .rst       (rst),
1444
         .full_in   (phy_ctl_full_temp[2]),
1445
         .wr_en_in  (phy_ctl_wr),
1446
         .d_in      (data_offset_1),
1447
         .wr_en_out (),
1448
         .d_out     (data_offset_1_of)
1449
        );
1450
 
1451
      mig_7series_v2_3_ddr_of_pre_fifo #
1452
        (
1453
         .TCQ   (25),
1454
         .DEPTH (8),
1455
         .WIDTH (6)
1456
        )
1457
        phy_ctl_pre_fifo_2
1458
        (
1459
         .clk       (clk),
1460
         .rst       (rst),
1461
         .full_in   (phy_ctl_full_temp[3]),
1462
         .wr_en_in  (phy_ctl_wr),
1463
         .d_in      (data_offset_2),
1464
         .wr_en_out (),
1465
         .d_out     (data_offset_2_of)
1466
        );
1467
 
1468
    end
1469
  endgenerate
1470
 
1471
 
1472
 
1473
  //***************************************************************************
1474
  // Hard PHY instantiation
1475
  //***************************************************************************
1476
 
1477
   assign phy_ctl_full = phy_ctl_full_temp[0];
1478
 
1479
  mig_7series_v2_3_ddr_mc_phy #
1480
    (
1481
     .BYTE_LANES_B0                 (BYTE_LANES_B0),
1482
     .BYTE_LANES_B1                 (BYTE_LANES_B1),
1483
     .BYTE_LANES_B2                 (BYTE_LANES_B2),
1484
     .BYTE_LANES_B3                 (BYTE_LANES_B3),
1485
     .BYTE_LANES_B4                 (BYTE_LANES_B4),
1486
     .DATA_CTL_B0                   (DATA_CTL_B0),
1487
     .DATA_CTL_B1                   (DATA_CTL_B1),
1488
     .DATA_CTL_B2                   (DATA_CTL_B2),
1489
     .DATA_CTL_B3                   (DATA_CTL_B3),
1490
     .DATA_CTL_B4                   (DATA_CTL_B4),
1491
     .PHY_0_BITLANES                (PHY_0_BITLANES),
1492
     .PHY_1_BITLANES                (PHY_1_BITLANES),
1493
     .PHY_2_BITLANES                (PHY_2_BITLANES),
1494
     .PHY_0_BITLANES_OUTONLY        (PHY_0_BITLANES_OUTONLY),
1495
     .PHY_1_BITLANES_OUTONLY        (PHY_1_BITLANES_OUTONLY),
1496
     .PHY_2_BITLANES_OUTONLY        (PHY_2_BITLANES_OUTONLY),
1497
     .RCLK_SELECT_BANK              (CKE_ODT_RCLK_SELECT_BANK),
1498
     .RCLK_SELECT_LANE              (CKE_ODT_RCLK_SELECT_LANE),
1499
     //.CKE_ODT_AUX                   (CKE_ODT_AUX),
1500
     .GENERATE_DDR_CK_MAP           (TMP_GENERATE_DDR_CK_MAP),
1501
     .BYTELANES_DDR_CK              (TMP_BYTELANES_DDR_CK),
1502
     .NUM_DDR_CK                    (CK_WIDTH),
1503
     .LP_DDR_CK_WIDTH               (LP_DDR_CK_WIDTH),
1504
     .PO_CTL_COARSE_BYPASS          ("FALSE"),
1505
     .PHYCTL_CMD_FIFO               ("FALSE"),
1506
     .PHY_CLK_RATIO                 (nCK_PER_CLK),
1507
     .MASTER_PHY_CTL                (MASTER_PHY_CTL),
1508
     .PHY_FOUR_WINDOW_CLOCKS        (63),
1509
     .PHY_EVENTS_DELAY              (18),
1510
     .PHY_COUNT_EN                  ("FALSE"), //PHY_COUNT_EN
1511
     .PHY_SYNC_MODE                 ("FALSE"),
1512
     .SYNTHESIS                     ((SIM_CAL_OPTION == "NONE") ? "TRUE" : "FALSE"),
1513
     .PHY_DISABLE_SEQ_MATCH         ("TRUE"), //"TRUE"     
1514
     .PHY_0_GENERATE_IDELAYCTRL     ("FALSE"),
1515
     .PHY_0_A_PI_FREQ_REF_DIV       (PHY_0_A_PI_FREQ_REF_DIV),
1516
     .PHY_0_CMD_OFFSET              (PHY_0_CMD_OFFSET),   //for CKE
1517
     .PHY_0_RD_CMD_OFFSET_0         (PHY_0_RD_CMD_OFFSET_0),
1518
     .PHY_0_RD_CMD_OFFSET_1         (PHY_0_RD_CMD_OFFSET_1),
1519
     .PHY_0_RD_CMD_OFFSET_2         (PHY_0_RD_CMD_OFFSET_2),
1520
     .PHY_0_RD_CMD_OFFSET_3         (PHY_0_RD_CMD_OFFSET_3),
1521
     .PHY_0_RD_DURATION_0           (6),
1522
     .PHY_0_RD_DURATION_1           (6),
1523
     .PHY_0_RD_DURATION_2           (6),
1524
     .PHY_0_RD_DURATION_3           (6),
1525
     .PHY_0_WR_CMD_OFFSET_0         (PHY_0_WR_CMD_OFFSET_0),
1526
     .PHY_0_WR_CMD_OFFSET_1         (PHY_0_WR_CMD_OFFSET_1),
1527
     .PHY_0_WR_CMD_OFFSET_2         (PHY_0_WR_CMD_OFFSET_2),
1528
     .PHY_0_WR_CMD_OFFSET_3         (PHY_0_WR_CMD_OFFSET_3),
1529
     .PHY_0_WR_DURATION_0           (PHY_0_WR_DURATION_0),
1530
     .PHY_0_WR_DURATION_1           (PHY_0_WR_DURATION_1),
1531
     .PHY_0_WR_DURATION_2           (PHY_0_WR_DURATION_2),
1532
     .PHY_0_WR_DURATION_3           (PHY_0_WR_DURATION_3),
1533
     .PHY_0_AO_TOGGLE               ((RANKS == 1) ? 1 : 5),
1534
     .PHY_0_A_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1535
     .PHY_0_B_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1536
     .PHY_0_C_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1537
     .PHY_0_D_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1538
     .PHY_0_A_PO_OCLKDELAY_INV      (PO_OCLKDELAY_INV),
1539
     .PHY_0_A_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1540
     .PHY_0_B_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1541
     .PHY_0_C_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1542
     .PHY_0_D_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1543
     .PHY_1_GENERATE_IDELAYCTRL     ("FALSE"),
1544
     //.PHY_1_GENERATE_DDR_CK         (TMP_PHY_1_GENERATE_DDR_CK),
1545
     //.PHY_1_NUM_DDR_CK              (1),
1546
     .PHY_1_A_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1547
     .PHY_1_B_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1548
     .PHY_1_C_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1549
     .PHY_1_D_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1550
     .PHY_1_A_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1551
     .PHY_1_B_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1552
     .PHY_1_C_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1553
     .PHY_1_D_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1554
     .PHY_2_GENERATE_IDELAYCTRL     ("FALSE"),
1555
     //.PHY_2_GENERATE_DDR_CK         (TMP_PHY_2_GENERATE_DDR_CK),
1556
     //.PHY_2_NUM_DDR_CK              (1),
1557
     .PHY_2_A_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1558
     .PHY_2_B_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1559
     .PHY_2_C_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1560
     .PHY_2_D_PO_OCLK_DELAY         (PHY_0_A_PO_OCLK_DELAY),
1561
     .PHY_2_A_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1562
     .PHY_2_B_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1563
     .PHY_2_C_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1564
     .PHY_2_D_IDELAYE2_IDELAY_VALUE (PHY_0_A_IDELAYE2_IDELAY_VALUE),
1565
     .TCK                           (tCK),
1566
     .PHY_0_IODELAY_GRP             (IODELAY_GRP),
1567
     .PHY_1_IODELAY_GRP             (IODELAY_GRP),
1568
     .PHY_2_IODELAY_GRP             (IODELAY_GRP),
1569
     .FPGA_SPEED_GRADE              (FPGA_SPEED_GRADE),
1570
     .BANK_TYPE                     (BANK_TYPE),
1571
     .CKE_ODT_AUX                   (CKE_ODT_AUX)
1572
     )
1573
    u_ddr_mc_phy
1574
      (
1575
       .rst                    (rst),
1576
       // Don't use MC_PHY to generate DDR_RESET_N output. Instead
1577
       // generate this output outside of MC_PHY (and synchronous to CLK)
1578
       .ddr_rst_in_n           (1'b1),
1579
       .phy_clk                (clk),
1580
       .freq_refclk            (freq_refclk),
1581
       .mem_refclk             (mem_refclk),
1582
       // Remove later - always same connection as phy_clk port
1583
       .mem_refclk_div4        (clk),
1584
       .pll_lock               (pll_lock),
1585
       .auxout_clk             (),
1586
       .sync_pulse             (sync_pulse),
1587
       // IDELAYCTRL instantiated outside of mc_phy module
1588
       .idelayctrl_refclk      (),
1589
       .phy_dout               (phy_dout),
1590
       .phy_cmd_wr_en          (phy_cmd_wr_en),
1591
       .phy_data_wr_en         (phy_data_wr_en),
1592
       .phy_rd_en              (phy_rd_en),
1593
       .phy_ctl_wd             (phy_ctl_wd_temp),
1594
       .phy_ctl_wr             (phy_ctl_wr_temp),
1595
       .if_empty_def           (phy_if_empty_def),
1596
       .if_rst                 (phy_if_reset),
1597
       .phyGo                  ('b1),
1598
       .aux_in_1               (aux_in_1),
1599
       .aux_in_2               (aux_in_2),
1600
       // No support yet for different data offsets for different I/O banks
1601
       // (possible use in supporting wider range of skew among bytes)
1602
       .data_offset_1          (data_offset_1_temp),
1603
       .data_offset_2          (data_offset_2_temp),
1604
       .cke_in                 (),
1605
       .if_a_empty             (),
1606
       .if_empty               (if_empty),
1607
       .if_empty_or            (),
1608
       .if_empty_and           (),
1609
       .of_ctl_a_full          (),
1610
      // .of_data_a_full         (phy_data_full),
1611
       .of_ctl_full            (phy_cmd_full),
1612
       .of_data_full           (),
1613
       .pre_data_a_full        (phy_pre_data_a_full),
1614
       .idelay_ld              (idelay_ld),
1615
       .idelay_ce              (idelay_ce),
1616
       .idelay_inc             (idelay_inc),
1617
       .input_sink             (),
1618
       .phy_din                (phy_din),
1619
       .phy_ctl_a_full         (),
1620
       .phy_ctl_full           (phy_ctl_full_temp),
1621
       .mem_dq_out             (mem_dq_out),
1622
       .mem_dq_ts              (mem_dq_ts),
1623
       .mem_dq_in              (mem_dq_in),
1624
       .mem_dqs_out            (mem_dqs_out),
1625
       .mem_dqs_ts             (mem_dqs_ts),
1626
       .mem_dqs_in             (mem_dqs_in),
1627
       .aux_out                (aux_out),
1628
       .phy_ctl_ready          (),
1629
       .rst_out                (),
1630
       .ddr_clk                (ddr_clk),
1631
       //.rclk                   (),
1632
       .mcGo                   (phy_mc_go),
1633
       .phy_write_calib        (phy_write_calib),
1634
       .phy_read_calib         (phy_read_calib),
1635
       .calib_sel              (calib_sel),
1636
       .calib_in_common        (calib_in_common),
1637
       .calib_zero_inputs      (calib_zero_inputs),
1638
       .calib_zero_ctrl        (calib_zero_ctrl),
1639
       .calib_zero_lanes       ('b0),
1640
       .po_fine_enable         (po_fine_enable),
1641
       .po_coarse_enable       (po_coarse_enable),
1642
       .po_fine_inc            (po_fine_inc),
1643
       .po_coarse_inc          (po_coarse_inc),
1644
       .po_counter_load_en     (po_counter_load_en),
1645
       .po_sel_fine_oclk_delay (po_sel_fine_oclk_delay),
1646
       .po_counter_load_val    (po_counter_load_val),
1647
       .po_counter_read_en     (po_counter_read_en),
1648
       .po_coarse_overflow     (),
1649
       .po_fine_overflow       (),
1650
       .po_counter_read_val    (po_counter_read_val),
1651
       .pi_rst_dqs_find        (pi_rst_dqs_find),
1652
       .pi_fine_enable         (pi_fine_enable),
1653
       .pi_fine_inc            (pi_fine_inc),
1654
       .pi_counter_load_en     (pi_counter_load_en),
1655
       .pi_counter_read_en     (dbg_pi_counter_read_en),
1656
       .pi_counter_load_val    (pi_counter_load_val),
1657
       .pi_fine_overflow       (),
1658
       .pi_counter_read_val    (pi_counter_read_val),
1659
       .pi_phase_locked        (pi_phase_locked),
1660
       .pi_phase_locked_all    (pi_phase_locked_all),
1661
       .pi_dqs_found           (),
1662
       .pi_dqs_found_any       (pi_dqs_found),
1663
       .pi_dqs_found_all       (pi_dqs_found_all),
1664
       .pi_dqs_found_lanes     (dbg_pi_dqs_found_lanes_phy4lanes),
1665
       // Currently not being used. May be used in future if periodic
1666
       // reads become a requirement. This output could be used to signal 
1667
       // a catastrophic failure in read capture and the need for 
1668
       // re-calibration.
1669
       .pi_dqs_out_of_range    (pi_dqs_out_of_range)
1670
 
1671
       ,.ref_dll_lock          (ref_dll_lock)
1672
       ,.pi_phase_locked_lanes (dbg_pi_phase_locked_phy4lanes)
1673
       ,.fine_delay            (fine_delay_mod)
1674
       ,.fine_delay_sel        (fine_delay_sel_r)
1675
//       ,.rst_phaser_ref        (rst_phaser_ref)
1676
       );
1677
 
1678
endmodule

powered by: WebSVN 2.1.0

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