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
|