1 |
2 |
ZTEX |
//*****************************************************************************
|
2 |
|
|
// (c) Copyright 2008 - 2013 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 : mc.v
|
55 |
|
|
// /___/ /\ Date Last Modified : $date$
|
56 |
|
|
// \ \ / \ Date Created : Tue Jun 30 2009
|
57 |
|
|
// \___\/\___\
|
58 |
|
|
//
|
59 |
|
|
//Device : 7-Series
|
60 |
|
|
//Design Name : DDR3 SDRAM
|
61 |
|
|
//Purpose :
|
62 |
|
|
//Reference :
|
63 |
|
|
//Revision History :
|
64 |
|
|
//*****************************************************************************
|
65 |
|
|
|
66 |
|
|
//*****************************************************************************
|
67 |
|
|
// Top level memory sequencer structural block. This block
|
68 |
|
|
// instantiates the rank, bank, and column machines.
|
69 |
|
|
//*****************************************************************************
|
70 |
|
|
|
71 |
|
|
`timescale 1ps/1ps
|
72 |
|
|
|
73 |
|
|
module mig_7series_v2_3_mc #
|
74 |
|
|
(
|
75 |
|
|
parameter TCQ = 100, // clk->out delay(sim only)
|
76 |
|
|
parameter ADDR_CMD_MODE = "1T", // registered or
|
77 |
|
|
// 1Tfered mem?
|
78 |
|
|
parameter BANK_WIDTH = 3, // bank address width
|
79 |
|
|
parameter BM_CNT_WIDTH = 2, // # BM counter width
|
80 |
|
|
// i.e., log2(nBANK_MACHS)
|
81 |
|
|
parameter BURST_MODE = "8", // Burst length
|
82 |
|
|
parameter CL = 5, // Read CAS latency
|
83 |
|
|
// (in clk cyc)
|
84 |
|
|
parameter CMD_PIPE_PLUS1 = "ON", // add register stage
|
85 |
|
|
// between MC and PHY
|
86 |
|
|
parameter COL_WIDTH = 12, // column address width
|
87 |
|
|
parameter CS_WIDTH = 4, // # of unique CS outputs
|
88 |
|
|
parameter CWL = 5, // Write CAS latency
|
89 |
|
|
// (in clk cyc)
|
90 |
|
|
parameter DATA_BUF_ADDR_WIDTH = 8, // User request tag (e.g.
|
91 |
|
|
// user src/dest buf addr)
|
92 |
|
|
parameter DATA_BUF_OFFSET_WIDTH = 1, // User buffer offset width
|
93 |
|
|
parameter DATA_WIDTH = 64, // Data bus width
|
94 |
|
|
parameter DQ_WIDTH = 64, // # of DQ (data)
|
95 |
|
|
parameter DQS_WIDTH = 8, // # of DQS (strobe)
|
96 |
|
|
parameter DRAM_TYPE = "DDR3", // Memory I/F type:
|
97 |
|
|
// "DDR3", "DDR2"
|
98 |
|
|
parameter ECC = "OFF", // ECC ON/OFF?
|
99 |
|
|
parameter ECC_WIDTH = 8, // # of ECC bits
|
100 |
|
|
parameter MAINT_PRESCALER_PERIOD= 200000, // maintenance period (ps)
|
101 |
|
|
parameter MC_ERR_ADDR_WIDTH = 31, // # of error address bits
|
102 |
|
|
parameter nBANK_MACHS = 4, // # of bank machines (BM)
|
103 |
|
|
parameter nCK_PER_CLK = 4, // DRAM clock : MC clock
|
104 |
|
|
// frequency ratio
|
105 |
|
|
parameter nCS_PER_RANK = 1, // # of unique CS outputs
|
106 |
|
|
// per rank
|
107 |
|
|
parameter nREFRESH_BANK = 1, // # of REF cmds to pull-in
|
108 |
|
|
parameter nSLOTS = 1, // # DIMM slots in system
|
109 |
|
|
parameter ORDERING = "NORM", // request ordering mode
|
110 |
|
|
parameter PAYLOAD_WIDTH = 64, // Width of data payload
|
111 |
|
|
// from PHY
|
112 |
|
|
parameter RANK_WIDTH = 2, // # of bits to count ranks
|
113 |
|
|
parameter RANKS = 4, // # of ranks of DRAM
|
114 |
|
|
parameter REG_CTRL = "ON", // "ON" for registered DIMM
|
115 |
|
|
parameter ROW_WIDTH = 16, // row address width
|
116 |
|
|
parameter RTT_NOM = "40", // Nominal ODT value
|
117 |
|
|
parameter RTT_WR = "120", // Write ODT value
|
118 |
|
|
parameter SLOT_0_CONFIG = 8'b0000_0101, // ranks allowed in slot 0
|
119 |
|
|
parameter SLOT_1_CONFIG = 8'b0000_1010, // ranks allowed in slot 1
|
120 |
|
|
parameter STARVE_LIMIT = 2, // max # of times a user
|
121 |
|
|
// request is allowed to
|
122 |
|
|
// lose arbitration when
|
123 |
|
|
// reordering is enabled
|
124 |
|
|
parameter tCK = 2500, // memory clk period(ps)
|
125 |
|
|
parameter tCKE = 10000, // CKE minimum pulse (ps)
|
126 |
|
|
parameter tFAW = 40000, // four activate window(ps)
|
127 |
|
|
parameter tRAS = 37500, // ACT->PRE cmd period (ps)
|
128 |
|
|
parameter tRCD = 12500, // ACT->R/W delay (ps)
|
129 |
|
|
parameter tREFI = 7800000, // average periodic
|
130 |
|
|
// refresh interval(ps)
|
131 |
|
|
parameter CKE_ODT_AUX = "FALSE", //Parameter to turn on/off the aux_out signal
|
132 |
|
|
parameter tRFC = 110000, // REF->ACT/REF delay (ps)
|
133 |
|
|
parameter tRP = 12500, // PRE cmd period (ps)
|
134 |
|
|
parameter tRRD = 10000, // ACT->ACT period (ps)
|
135 |
|
|
parameter tRTP = 7500, // Read->PRE cmd delay (ps)
|
136 |
|
|
parameter tWTR = 7500, // Internal write->read
|
137 |
|
|
// delay (ps)
|
138 |
|
|
// requiring DLL lock (CKs)
|
139 |
|
|
parameter tZQCS = 64, // ZQCS cmd period (CKs)
|
140 |
|
|
parameter tZQI = 128_000_000, // ZQCS interval (ps)
|
141 |
|
|
parameter tPRDI = 1_000_000, // pS
|
142 |
|
|
parameter USER_REFRESH = "OFF" // Whether user manages REF
|
143 |
|
|
)
|
144 |
|
|
(
|
145 |
|
|
|
146 |
|
|
// System inputs
|
147 |
|
|
|
148 |
|
|
input clk,
|
149 |
|
|
input rst,
|
150 |
|
|
|
151 |
|
|
// Physical memory slot presence
|
152 |
|
|
|
153 |
|
|
input [7:0] slot_0_present,
|
154 |
|
|
input [7:0] slot_1_present,
|
155 |
|
|
|
156 |
|
|
// Native Interface
|
157 |
|
|
|
158 |
|
|
input [2:0] cmd,
|
159 |
|
|
input [DATA_BUF_ADDR_WIDTH-1:0] data_buf_addr,
|
160 |
|
|
input hi_priority,
|
161 |
|
|
input size,
|
162 |
|
|
|
163 |
|
|
input [BANK_WIDTH-1:0] bank,
|
164 |
|
|
input [COL_WIDTH-1:0] col,
|
165 |
|
|
input [RANK_WIDTH-1:0] rank,
|
166 |
|
|
input [ROW_WIDTH-1:0] row,
|
167 |
|
|
input use_addr,
|
168 |
|
|
|
169 |
|
|
input [2*nCK_PER_CLK*PAYLOAD_WIDTH-1:0] wr_data,
|
170 |
|
|
input [2*nCK_PER_CLK*DATA_WIDTH/8-1:0] wr_data_mask,
|
171 |
|
|
|
172 |
|
|
output accept,
|
173 |
|
|
output accept_ns,
|
174 |
|
|
|
175 |
|
|
output [BM_CNT_WIDTH-1:0] bank_mach_next,
|
176 |
|
|
|
177 |
|
|
output wire [2*nCK_PER_CLK*PAYLOAD_WIDTH-1:0] rd_data,
|
178 |
|
|
output [DATA_BUF_ADDR_WIDTH-1:0] rd_data_addr,
|
179 |
|
|
output rd_data_en,
|
180 |
|
|
output rd_data_end,
|
181 |
|
|
output [DATA_BUF_OFFSET_WIDTH-1:0] rd_data_offset,
|
182 |
|
|
|
183 |
|
|
output reg [DATA_BUF_ADDR_WIDTH-1:0] wr_data_addr /* synthesis syn_maxfan = 30 */,
|
184 |
|
|
output reg wr_data_en,
|
185 |
|
|
output reg [DATA_BUF_OFFSET_WIDTH-1:0] wr_data_offset /* synthesis syn_maxfan = 30 */,
|
186 |
|
|
|
187 |
|
|
output mc_read_idle,
|
188 |
|
|
output mc_ref_zq_wip,
|
189 |
|
|
|
190 |
|
|
// ECC interface
|
191 |
|
|
|
192 |
|
|
input correct_en,
|
193 |
|
|
input [2*nCK_PER_CLK-1:0] raw_not_ecc,
|
194 |
|
|
|
195 |
|
|
input [DQS_WIDTH - 1:0] fi_xor_we,
|
196 |
|
|
input [DQ_WIDTH -1 :0 ] fi_xor_wrdata,
|
197 |
|
|
|
198 |
|
|
output [MC_ERR_ADDR_WIDTH-1:0] ecc_err_addr,
|
199 |
|
|
output [2*nCK_PER_CLK-1:0] ecc_single,
|
200 |
|
|
output [2*nCK_PER_CLK-1:0] ecc_multiple,
|
201 |
|
|
|
202 |
|
|
// User maintenance requests
|
203 |
|
|
|
204 |
|
|
input app_periodic_rd_req,
|
205 |
|
|
input app_ref_req,
|
206 |
|
|
input app_zq_req,
|
207 |
|
|
input app_sr_req,
|
208 |
|
|
output app_sr_active,
|
209 |
|
|
output app_ref_ack,
|
210 |
|
|
output app_zq_ack,
|
211 |
|
|
|
212 |
|
|
// MC <==> PHY Interface
|
213 |
|
|
|
214 |
|
|
output reg [nCK_PER_CLK-1:0] mc_ras_n,
|
215 |
|
|
output reg [nCK_PER_CLK-1:0] mc_cas_n,
|
216 |
|
|
output reg [nCK_PER_CLK-1:0] mc_we_n,
|
217 |
|
|
output reg [nCK_PER_CLK*ROW_WIDTH-1:0] mc_address,
|
218 |
|
|
output reg [nCK_PER_CLK*BANK_WIDTH-1:0] mc_bank,
|
219 |
|
|
output reg [CS_WIDTH*nCS_PER_RANK*nCK_PER_CLK-1:0] mc_cs_n,
|
220 |
|
|
output reg [1:0] mc_odt,
|
221 |
|
|
output reg [nCK_PER_CLK-1:0] mc_cke,
|
222 |
|
|
output wire mc_reset_n,
|
223 |
|
|
output wire [2*nCK_PER_CLK*DQ_WIDTH-1:0] mc_wrdata,
|
224 |
|
|
output wire [2*nCK_PER_CLK*DQ_WIDTH/8-1:0]mc_wrdata_mask,
|
225 |
|
|
output reg mc_wrdata_en,
|
226 |
|
|
|
227 |
|
|
output wire mc_cmd_wren,
|
228 |
|
|
output wire mc_ctl_wren,
|
229 |
|
|
output reg [2:0] mc_cmd,
|
230 |
|
|
output reg [5:0] mc_data_offset,
|
231 |
|
|
output reg [5:0] mc_data_offset_1,
|
232 |
|
|
output reg [5:0] mc_data_offset_2,
|
233 |
|
|
output reg [1:0] mc_cas_slot,
|
234 |
|
|
output reg [3:0] mc_aux_out0,
|
235 |
|
|
output reg [3:0] mc_aux_out1,
|
236 |
|
|
output reg [1:0] mc_rank_cnt,
|
237 |
|
|
|
238 |
|
|
input phy_mc_ctl_full,
|
239 |
|
|
input phy_mc_cmd_full,
|
240 |
|
|
input phy_mc_data_full,
|
241 |
|
|
input [2*nCK_PER_CLK*DQ_WIDTH-1:0] phy_rd_data,
|
242 |
|
|
input phy_rddata_valid,
|
243 |
|
|
|
244 |
|
|
input init_calib_complete,
|
245 |
|
|
input [6*RANKS-1:0] calib_rd_data_offset,
|
246 |
|
|
input [6*RANKS-1:0] calib_rd_data_offset_1,
|
247 |
|
|
input [6*RANKS-1:0] calib_rd_data_offset_2
|
248 |
|
|
|
249 |
|
|
);
|
250 |
|
|
|
251 |
|
|
assign mc_reset_n = 1'b1; // never reset memory
|
252 |
|
|
assign mc_cmd_wren = 1'b1; // always write CMD FIFO(issue DSEL when idle)
|
253 |
|
|
assign mc_ctl_wren = 1'b1; // always write CTL FIFO(issue nondata when idle)
|
254 |
|
|
|
255 |
|
|
// Ensure there is always at least one rank present during operation
|
256 |
|
|
`ifdef MC_SVA
|
257 |
|
|
ranks_present: assert property
|
258 |
|
|
(@(posedge clk) (rst || (|(slot_0_present | slot_1_present))));
|
259 |
|
|
`endif
|
260 |
|
|
|
261 |
|
|
// Reserved. Do not change.
|
262 |
|
|
localparam nPHY_WRLAT = 2;
|
263 |
|
|
|
264 |
|
|
// always delay write data control unless ECC mode is enabled
|
265 |
|
|
localparam DELAY_WR_DATA_CNTRL = ECC == "ON" ? 0 : 1;
|
266 |
|
|
|
267 |
|
|
// Ensure that write control is delayed for appropriate CWL
|
268 |
|
|
/*`ifdef MC_SVA
|
269 |
|
|
delay_wr_data_zero_CWL_le_6: assert property
|
270 |
|
|
(@(posedge clk) ((CWL > 6) || (DELAY_WR_DATA_CNTRL == 0)));
|
271 |
|
|
`endif*/
|
272 |
|
|
|
273 |
|
|
// Never retrieve WR_DATA_ADDR early
|
274 |
|
|
localparam EARLY_WR_DATA_ADDR = "OFF";
|
275 |
|
|
|
276 |
|
|
//***************************************************************************
|
277 |
|
|
// Convert timing parameters from time to clock cycles
|
278 |
|
|
//***************************************************************************
|
279 |
|
|
|
280 |
|
|
localparam nCKE = cdiv(tCKE, tCK);
|
281 |
|
|
localparam nRP = cdiv(tRP, tCK);
|
282 |
|
|
localparam nRCD = cdiv(tRCD, tCK);
|
283 |
|
|
localparam nRAS = cdiv(tRAS, tCK);
|
284 |
|
|
localparam nFAW = cdiv(tFAW, tCK);
|
285 |
|
|
localparam nRFC = cdiv(tRFC, tCK);
|
286 |
|
|
|
287 |
|
|
// Convert tWR. As per specification, write recover for autoprecharge
|
288 |
|
|
// cycles doesn't support values of 9 and 11. Round up 9 to 10 and 11 to 12
|
289 |
|
|
localparam nWR_CK = cdiv(15000, tCK) ;
|
290 |
|
|
localparam nWR = (nWR_CK == 9) ? 10 : (nWR_CK == 11) ? 12 : nWR_CK;
|
291 |
|
|
|
292 |
|
|
// tRRD, tWTR at tRTP have a 4 cycle floor in DDR3 and 2 cycle floor in DDR2
|
293 |
|
|
localparam nRRD_CK = cdiv(tRRD, tCK);
|
294 |
|
|
localparam nRRD = (DRAM_TYPE == "DDR3") ? (nRRD_CK < 4) ? 4 : nRRD_CK
|
295 |
|
|
: (nRRD_CK < 2) ? 2 : nRRD_CK;
|
296 |
|
|
localparam nWTR_CK = cdiv(tWTR, tCK);
|
297 |
|
|
localparam nWTR = (DRAM_TYPE == "DDR3") ? (nWTR_CK < 4) ? 4 : nWTR_CK
|
298 |
|
|
: (nWTR_CK < 2) ? 2 : nWTR_CK;
|
299 |
|
|
localparam nRTP_CK = cdiv(tRTP, tCK);
|
300 |
|
|
localparam nRTP = (DRAM_TYPE == "DDR3") ? (nRTP_CK < 4) ? 4 : nRTP_CK
|
301 |
|
|
: (nRTP_CK < 2) ? 2 : nRTP_CK;
|
302 |
|
|
|
303 |
|
|
// Add a cycle to CL/CWL for the register in RDIMM devices
|
304 |
|
|
localparam CWL_M = (REG_CTRL == "ON") ? CWL + 1 : CWL;
|
305 |
|
|
localparam CL_M = (REG_CTRL == "ON") ? CL + 1 : CL;
|
306 |
|
|
|
307 |
|
|
// Tuneable delay between read and write data on the DQ bus
|
308 |
|
|
localparam DQRD2DQWR_DLY = 4;
|
309 |
|
|
|
310 |
|
|
// CKE minimum pulse width for self-refresh (SRE->SRX minimum time)
|
311 |
|
|
localparam nCKESR = nCKE + 1;
|
312 |
|
|
|
313 |
|
|
// Delay from SRE to command requiring locked DLL. Currently fixed at 512 for
|
314 |
|
|
// all devices per JEDEC spec.
|
315 |
|
|
localparam tXSDLL = 512;
|
316 |
|
|
|
317 |
|
|
//***************************************************************************
|
318 |
|
|
// Set up maintenance counter dividers
|
319 |
|
|
//***************************************************************************
|
320 |
|
|
|
321 |
|
|
// CK clock divisor to generate maintenance prescaler period (round down)
|
322 |
|
|
localparam MAINT_PRESCALER_DIV = MAINT_PRESCALER_PERIOD / (tCK*nCK_PER_CLK);
|
323 |
|
|
|
324 |
|
|
// Maintenance prescaler divisor for refresh timer. Essentially, this is
|
325 |
|
|
// just (tREFI / MAINT_PRESCALER_PERIOD), but we must account for the worst
|
326 |
|
|
// case delay from the time we get a tick from the refresh counter to the
|
327 |
|
|
// time that we can actually issue the REF command. Thus, subtract tRCD, CL,
|
328 |
|
|
// data burst time and tRP for each implemented bank machine to ensure that
|
329 |
|
|
// all transactions can complete before tREFI expires
|
330 |
|
|
localparam REFRESH_TIMER_DIV =
|
331 |
|
|
USER_REFRESH == "ON" ? 0 :
|
332 |
|
|
(tREFI-((tRCD+((CL+4)*tCK)+tRP)*nBANK_MACHS)) / MAINT_PRESCALER_PERIOD;
|
333 |
|
|
|
334 |
|
|
// Periodic read (RESERVED - not currently required or supported in 7 series)
|
335 |
|
|
// tPRDI should only be set to 0
|
336 |
|
|
// localparam tPRDI = 0; // Do NOT change.
|
337 |
|
|
localparam PERIODIC_RD_TIMER_DIV = tPRDI / MAINT_PRESCALER_PERIOD;
|
338 |
|
|
|
339 |
|
|
// Convert maintenance prescaler from ps to ns
|
340 |
|
|
localparam MAINT_PRESCALER_PERIOD_NS = MAINT_PRESCALER_PERIOD / 1000;
|
341 |
|
|
|
342 |
|
|
// Maintenance prescaler divisor for ZQ calibration (ZQCS) timer
|
343 |
|
|
localparam ZQ_TIMER_DIV = tZQI / MAINT_PRESCALER_PERIOD_NS;
|
344 |
|
|
|
345 |
|
|
// Bus width required to broadcast a single bit rank signal among all the
|
346 |
|
|
// bank machines - 1 bit per rank, per bank
|
347 |
|
|
localparam RANK_BM_BV_WIDTH = nBANK_MACHS * RANKS;
|
348 |
|
|
|
349 |
|
|
//***************************************************************************
|
350 |
|
|
// Define 2T, CWL-even mode to enable multi-fabric-cycle 2T commands
|
351 |
|
|
//***************************************************************************
|
352 |
|
|
localparam EVEN_CWL_2T_MODE =
|
353 |
|
|
((ADDR_CMD_MODE == "2T") && (!(CWL % 2))) ? "ON" : "OFF";
|
354 |
|
|
|
355 |
|
|
//***************************************************************************
|
356 |
|
|
// Reserved feature control.
|
357 |
|
|
//***************************************************************************
|
358 |
|
|
|
359 |
|
|
// Open page wait mode is reserved.
|
360 |
|
|
// nOP_WAIT is the number of states a bank machine will park itself
|
361 |
|
|
// on an otherwise inactive open page before closing the page. If
|
362 |
|
|
// nOP_WAIT == 0, open page wait mode is disabled. If nOP_WAIT == -1,
|
363 |
|
|
// the bank machine will remain parked until the pool of idle bank machines
|
364 |
|
|
// are less than LOW_IDLE_CNT. At which point parked bank machines
|
365 |
|
|
// are selected to exit until the number of idle bank machines exceeds the
|
366 |
|
|
// LOW_IDLE_CNT.
|
367 |
|
|
localparam nOP_WAIT = 0; // Open page mode
|
368 |
|
|
localparam LOW_IDLE_CNT = 0; // Low idle bank machine threshold
|
369 |
|
|
|
370 |
|
|
//***************************************************************************
|
371 |
|
|
// Internal wires
|
372 |
|
|
//***************************************************************************
|
373 |
|
|
|
374 |
|
|
wire [RANK_BM_BV_WIDTH-1:0] act_this_rank_r;
|
375 |
|
|
wire [ROW_WIDTH-1:0] col_a;
|
376 |
|
|
wire [BANK_WIDTH-1:0] col_ba;
|
377 |
|
|
wire [DATA_BUF_ADDR_WIDTH-1:0] col_data_buf_addr;
|
378 |
|
|
wire col_periodic_rd;
|
379 |
|
|
wire [RANK_WIDTH-1:0] col_ra;
|
380 |
|
|
wire col_rmw;
|
381 |
|
|
wire col_rd_wr;
|
382 |
|
|
wire [ROW_WIDTH-1:0] col_row;
|
383 |
|
|
wire col_size;
|
384 |
|
|
wire [DATA_BUF_ADDR_WIDTH-1:0] col_wr_data_buf_addr;
|
385 |
|
|
wire dq_busy_data;
|
386 |
|
|
wire ecc_status_valid;
|
387 |
|
|
wire [RANKS-1:0] inhbt_act_faw_r;
|
388 |
|
|
wire [RANKS-1:0] inhbt_rd;
|
389 |
|
|
wire [RANKS-1:0] inhbt_wr;
|
390 |
|
|
wire insert_maint_r1;
|
391 |
|
|
wire [RANK_WIDTH-1:0] maint_rank_r;
|
392 |
|
|
wire maint_req_r;
|
393 |
|
|
wire maint_wip_r;
|
394 |
|
|
wire maint_zq_r;
|
395 |
|
|
wire maint_sre_r;
|
396 |
|
|
wire maint_srx_r;
|
397 |
|
|
wire periodic_rd_ack_r;
|
398 |
|
|
wire periodic_rd_r;
|
399 |
|
|
wire [RANK_WIDTH-1:0] periodic_rd_rank_r;
|
400 |
|
|
wire [(RANKS*nBANK_MACHS)-1:0] rank_busy_r;
|
401 |
|
|
wire rd_rmw;
|
402 |
|
|
wire [RANK_BM_BV_WIDTH-1:0] rd_this_rank_r;
|
403 |
|
|
wire [nBANK_MACHS-1:0] sending_col;
|
404 |
|
|
wire [nBANK_MACHS-1:0] sending_row;
|
405 |
|
|
wire sent_col;
|
406 |
|
|
wire sent_col_r;
|
407 |
|
|
wire wr_ecc_buf;
|
408 |
|
|
wire [RANK_BM_BV_WIDTH-1:0] wr_this_rank_r;
|
409 |
|
|
|
410 |
|
|
// MC/PHY optional pipeline stage support
|
411 |
|
|
wire [nCK_PER_CLK-1:0] mc_ras_n_ns;
|
412 |
|
|
wire [nCK_PER_CLK-1:0] mc_cas_n_ns;
|
413 |
|
|
wire [nCK_PER_CLK-1:0] mc_we_n_ns;
|
414 |
|
|
wire [nCK_PER_CLK*ROW_WIDTH-1:0] mc_address_ns;
|
415 |
|
|
wire [nCK_PER_CLK*BANK_WIDTH-1:0] mc_bank_ns;
|
416 |
|
|
wire [CS_WIDTH*nCS_PER_RANK*nCK_PER_CLK-1:0] mc_cs_n_ns;
|
417 |
|
|
wire [1:0] mc_odt_ns;
|
418 |
|
|
wire [nCK_PER_CLK-1:0] mc_cke_ns;
|
419 |
|
|
wire [3:0] mc_aux_out0_ns;
|
420 |
|
|
wire [3:0] mc_aux_out1_ns;
|
421 |
|
|
wire [1:0] mc_rank_cnt_ns = col_ra;
|
422 |
|
|
wire [2:0] mc_cmd_ns;
|
423 |
|
|
wire [5:0] mc_data_offset_ns;
|
424 |
|
|
wire [5:0] mc_data_offset_1_ns;
|
425 |
|
|
wire [5:0] mc_data_offset_2_ns;
|
426 |
|
|
wire [1:0] mc_cas_slot_ns;
|
427 |
|
|
wire mc_wrdata_en_ns;
|
428 |
|
|
|
429 |
|
|
wire [DATA_BUF_ADDR_WIDTH-1:0] wr_data_addr_ns;
|
430 |
|
|
wire wr_data_en_ns;
|
431 |
|
|
wire [DATA_BUF_OFFSET_WIDTH-1:0] wr_data_offset_ns;
|
432 |
|
|
|
433 |
|
|
integer i;
|
434 |
|
|
|
435 |
|
|
// MC Read idle support
|
436 |
|
|
wire col_read_fifo_empty;
|
437 |
|
|
wire mc_read_idle_ns;
|
438 |
|
|
reg mc_read_idle_r;
|
439 |
|
|
|
440 |
|
|
// MC Maintenance in progress with bus idle indication
|
441 |
|
|
wire maint_ref_zq_wip;
|
442 |
|
|
wire mc_ref_zq_wip_ns;
|
443 |
|
|
reg mc_ref_zq_wip_r;
|
444 |
|
|
|
445 |
|
|
//***************************************************************************
|
446 |
|
|
// Function cdiv
|
447 |
|
|
// Description:
|
448 |
|
|
// This function performs ceiling division (divide and round-up)
|
449 |
|
|
// Inputs:
|
450 |
|
|
// num: integer to be divided
|
451 |
|
|
// div: divisor
|
452 |
|
|
// Outputs:
|
453 |
|
|
// cdiv: result of ceiling division (num/div, rounded up)
|
454 |
|
|
//***************************************************************************
|
455 |
|
|
|
456 |
|
|
function integer cdiv (input integer num, input integer div);
|
457 |
|
|
begin
|
458 |
|
|
// perform division, then add 1 if and only if remainder is non-zero
|
459 |
|
|
cdiv = (num/div) + (((num%div)>0) ? 1 : 0);
|
460 |
|
|
end
|
461 |
|
|
endfunction // cdiv
|
462 |
|
|
|
463 |
|
|
//***************************************************************************
|
464 |
|
|
// Optional pipeline register stage on MC/PHY interface
|
465 |
|
|
//***************************************************************************
|
466 |
|
|
|
467 |
|
|
generate
|
468 |
|
|
|
469 |
|
|
if (CMD_PIPE_PLUS1 == "ON") begin : cmd_pipe_plus // register interface
|
470 |
|
|
|
471 |
|
|
always @(posedge clk) begin
|
472 |
|
|
|
473 |
|
|
mc_address <= #TCQ mc_address_ns;
|
474 |
|
|
mc_bank <= #TCQ mc_bank_ns;
|
475 |
|
|
mc_cas_n <= #TCQ mc_cas_n_ns;
|
476 |
|
|
mc_cs_n <= #TCQ mc_cs_n_ns;
|
477 |
|
|
mc_odt <= #TCQ mc_odt_ns;
|
478 |
|
|
mc_cke <= #TCQ mc_cke_ns;
|
479 |
|
|
mc_aux_out0 <= #TCQ mc_aux_out0_ns;
|
480 |
|
|
mc_aux_out1 <= #TCQ mc_aux_out1_ns;
|
481 |
|
|
mc_cmd <= #TCQ mc_cmd_ns;
|
482 |
|
|
mc_ras_n <= #TCQ mc_ras_n_ns;
|
483 |
|
|
mc_we_n <= #TCQ mc_we_n_ns;
|
484 |
|
|
mc_data_offset <= #TCQ mc_data_offset_ns;
|
485 |
|
|
mc_data_offset_1 <= #TCQ mc_data_offset_1_ns;
|
486 |
|
|
mc_data_offset_2 <= #TCQ mc_data_offset_2_ns;
|
487 |
|
|
mc_cas_slot <= #TCQ mc_cas_slot_ns;
|
488 |
|
|
mc_wrdata_en <= #TCQ mc_wrdata_en_ns;
|
489 |
|
|
mc_rank_cnt <= #TCQ mc_rank_cnt_ns;
|
490 |
|
|
|
491 |
|
|
wr_data_addr <= #TCQ wr_data_addr_ns;
|
492 |
|
|
wr_data_en <= #TCQ wr_data_en_ns;
|
493 |
|
|
wr_data_offset <= #TCQ wr_data_offset_ns;
|
494 |
|
|
|
495 |
|
|
end // always @ (posedge clk)
|
496 |
|
|
|
497 |
|
|
end // block: cmd_pipe_plus
|
498 |
|
|
|
499 |
|
|
else begin : cmd_pipe_plus0 // don't register interface
|
500 |
|
|
|
501 |
|
|
always @( mc_address_ns or mc_aux_out0_ns or mc_aux_out1_ns or
|
502 |
|
|
mc_bank_ns or mc_cas_n_ns or mc_cmd_ns or mc_cs_n_ns or
|
503 |
|
|
mc_odt_ns or mc_cke_ns or mc_data_offset_ns or
|
504 |
|
|
mc_data_offset_1_ns or mc_data_offset_2_ns or mc_rank_cnt_ns or
|
505 |
|
|
mc_ras_n_ns or mc_we_n_ns or mc_wrdata_en_ns or
|
506 |
|
|
wr_data_addr_ns or wr_data_en_ns or wr_data_offset_ns or
|
507 |
|
|
mc_cas_slot_ns)
|
508 |
|
|
begin
|
509 |
|
|
|
510 |
|
|
mc_address = #TCQ mc_address_ns;
|
511 |
|
|
mc_bank = #TCQ mc_bank_ns;
|
512 |
|
|
mc_cas_n = #TCQ mc_cas_n_ns;
|
513 |
|
|
mc_cs_n = #TCQ mc_cs_n_ns;
|
514 |
|
|
mc_odt = #TCQ mc_odt_ns;
|
515 |
|
|
mc_cke = #TCQ mc_cke_ns;
|
516 |
|
|
mc_aux_out0 = #TCQ mc_aux_out0_ns;
|
517 |
|
|
mc_aux_out1 = #TCQ mc_aux_out1_ns;
|
518 |
|
|
mc_cmd = #TCQ mc_cmd_ns;
|
519 |
|
|
mc_ras_n = #TCQ mc_ras_n_ns;
|
520 |
|
|
mc_we_n = #TCQ mc_we_n_ns;
|
521 |
|
|
mc_data_offset = #TCQ mc_data_offset_ns;
|
522 |
|
|
mc_data_offset_1 = #TCQ mc_data_offset_1_ns;
|
523 |
|
|
mc_data_offset_2 = #TCQ mc_data_offset_2_ns;
|
524 |
|
|
mc_cas_slot = #TCQ mc_cas_slot_ns;
|
525 |
|
|
mc_wrdata_en = #TCQ mc_wrdata_en_ns;
|
526 |
|
|
mc_rank_cnt = #TCQ mc_rank_cnt_ns;
|
527 |
|
|
|
528 |
|
|
wr_data_addr = #TCQ wr_data_addr_ns;
|
529 |
|
|
wr_data_en = #TCQ wr_data_en_ns;
|
530 |
|
|
wr_data_offset = #TCQ wr_data_offset_ns;
|
531 |
|
|
|
532 |
|
|
end // always @ (...
|
533 |
|
|
|
534 |
|
|
end // block: cmd_pipe_plus0
|
535 |
|
|
|
536 |
|
|
endgenerate
|
537 |
|
|
|
538 |
|
|
//***************************************************************************
|
539 |
|
|
// Indicate when there are no pending reads so that input features can be
|
540 |
|
|
// powered down
|
541 |
|
|
//***************************************************************************
|
542 |
|
|
|
543 |
|
|
assign mc_read_idle_ns = col_read_fifo_empty & init_calib_complete;
|
544 |
|
|
always @(posedge clk) mc_read_idle_r <= #TCQ mc_read_idle_ns;
|
545 |
|
|
assign mc_read_idle = mc_read_idle_r;
|
546 |
|
|
|
547 |
|
|
//***************************************************************************
|
548 |
|
|
// Indicate when there is a refresh in progress and the bus is idle so that
|
549 |
|
|
// tap adjustments can be made
|
550 |
|
|
//***************************************************************************
|
551 |
|
|
|
552 |
|
|
assign mc_ref_zq_wip_ns = maint_ref_zq_wip && col_read_fifo_empty;
|
553 |
|
|
always @(posedge clk) mc_ref_zq_wip_r <= mc_ref_zq_wip_ns;
|
554 |
|
|
assign mc_ref_zq_wip = mc_ref_zq_wip_r;
|
555 |
|
|
|
556 |
|
|
//***************************************************************************
|
557 |
|
|
// Manage rank-level timing and maintanence
|
558 |
|
|
//***************************************************************************
|
559 |
|
|
|
560 |
|
|
mig_7series_v2_3_rank_mach #
|
561 |
|
|
(
|
562 |
|
|
// Parameters
|
563 |
|
|
.BURST_MODE (BURST_MODE),
|
564 |
|
|
.CL (CL),
|
565 |
|
|
.CWL (CWL),
|
566 |
|
|
.CS_WIDTH (CS_WIDTH),
|
567 |
|
|
.DQRD2DQWR_DLY (DQRD2DQWR_DLY),
|
568 |
|
|
.DRAM_TYPE (DRAM_TYPE),
|
569 |
|
|
.MAINT_PRESCALER_DIV (MAINT_PRESCALER_DIV),
|
570 |
|
|
.nBANK_MACHS (nBANK_MACHS),
|
571 |
|
|
.nCKESR (nCKESR),
|
572 |
|
|
.nCK_PER_CLK (nCK_PER_CLK),
|
573 |
|
|
.nFAW (nFAW),
|
574 |
|
|
.nREFRESH_BANK (nREFRESH_BANK),
|
575 |
|
|
.nRRD (nRRD),
|
576 |
|
|
.nWTR (nWTR),
|
577 |
|
|
.PERIODIC_RD_TIMER_DIV (PERIODIC_RD_TIMER_DIV),
|
578 |
|
|
.RANK_BM_BV_WIDTH (RANK_BM_BV_WIDTH),
|
579 |
|
|
.RANK_WIDTH (RANK_WIDTH),
|
580 |
|
|
.RANKS (RANKS),
|
581 |
|
|
.REFRESH_TIMER_DIV (REFRESH_TIMER_DIV),
|
582 |
|
|
.ZQ_TIMER_DIV (ZQ_TIMER_DIV)
|
583 |
|
|
)
|
584 |
|
|
rank_mach0
|
585 |
|
|
(
|
586 |
|
|
// Outputs
|
587 |
|
|
.inhbt_act_faw_r (inhbt_act_faw_r[RANKS-1:0]),
|
588 |
|
|
.inhbt_rd (inhbt_rd[RANKS-1:0]),
|
589 |
|
|
.inhbt_wr (inhbt_wr[RANKS-1:0]),
|
590 |
|
|
.maint_rank_r (maint_rank_r[RANK_WIDTH-1:0]),
|
591 |
|
|
.maint_req_r (maint_req_r),
|
592 |
|
|
.maint_zq_r (maint_zq_r),
|
593 |
|
|
.maint_sre_r (maint_sre_r),
|
594 |
|
|
.maint_srx_r (maint_srx_r),
|
595 |
|
|
.maint_ref_zq_wip (maint_ref_zq_wip),
|
596 |
|
|
.periodic_rd_r (periodic_rd_r),
|
597 |
|
|
.periodic_rd_rank_r (periodic_rd_rank_r[RANK_WIDTH-1:0]),
|
598 |
|
|
// Inputs
|
599 |
|
|
.act_this_rank_r (act_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
|
600 |
|
|
.app_periodic_rd_req (app_periodic_rd_req),
|
601 |
|
|
.app_ref_req (app_ref_req),
|
602 |
|
|
.app_ref_ack (app_ref_ack),
|
603 |
|
|
.app_zq_req (app_zq_req),
|
604 |
|
|
.app_zq_ack (app_zq_ack),
|
605 |
|
|
.app_sr_req (app_sr_req),
|
606 |
|
|
.app_sr_active (app_sr_active),
|
607 |
|
|
.col_rd_wr (col_rd_wr),
|
608 |
|
|
.clk (clk),
|
609 |
|
|
.init_calib_complete (init_calib_complete),
|
610 |
|
|
.insert_maint_r1 (insert_maint_r1),
|
611 |
|
|
.maint_wip_r (maint_wip_r),
|
612 |
|
|
.periodic_rd_ack_r (periodic_rd_ack_r),
|
613 |
|
|
.rank_busy_r (rank_busy_r[(RANKS*nBANK_MACHS)-1:0]),
|
614 |
|
|
.rd_this_rank_r (rd_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
|
615 |
|
|
.rst (rst),
|
616 |
|
|
.sending_col (sending_col[nBANK_MACHS-1:0]),
|
617 |
|
|
.sending_row (sending_row[nBANK_MACHS-1:0]),
|
618 |
|
|
.slot_0_present (slot_0_present[7:0]),
|
619 |
|
|
.slot_1_present (slot_1_present[7:0]),
|
620 |
|
|
.wr_this_rank_r (wr_this_rank_r[RANK_BM_BV_WIDTH-1:0])
|
621 |
|
|
);
|
622 |
|
|
|
623 |
|
|
//***************************************************************************
|
624 |
|
|
// Manage requests, reordering and bank timing
|
625 |
|
|
//***************************************************************************
|
626 |
|
|
|
627 |
|
|
mig_7series_v2_3_bank_mach #
|
628 |
|
|
(
|
629 |
|
|
// Parameters
|
630 |
|
|
.TCQ (TCQ),
|
631 |
|
|
.EVEN_CWL_2T_MODE (EVEN_CWL_2T_MODE),
|
632 |
|
|
.ADDR_CMD_MODE (ADDR_CMD_MODE),
|
633 |
|
|
.BANK_WIDTH (BANK_WIDTH),
|
634 |
|
|
.BM_CNT_WIDTH (BM_CNT_WIDTH),
|
635 |
|
|
.BURST_MODE (BURST_MODE),
|
636 |
|
|
.COL_WIDTH (COL_WIDTH),
|
637 |
|
|
.CS_WIDTH (CS_WIDTH),
|
638 |
|
|
.CL (CL_M),
|
639 |
|
|
.CWL (CWL_M),
|
640 |
|
|
.CKE_ODT_AUX (CKE_ODT_AUX),
|
641 |
|
|
.DATA_BUF_ADDR_WIDTH (DATA_BUF_ADDR_WIDTH),
|
642 |
|
|
.DRAM_TYPE (DRAM_TYPE),
|
643 |
|
|
.EARLY_WR_DATA_ADDR (EARLY_WR_DATA_ADDR),
|
644 |
|
|
.ECC (ECC),
|
645 |
|
|
.LOW_IDLE_CNT (LOW_IDLE_CNT),
|
646 |
|
|
.nBANK_MACHS (nBANK_MACHS),
|
647 |
|
|
.nCK_PER_CLK (nCK_PER_CLK),
|
648 |
|
|
.nCS_PER_RANK (nCS_PER_RANK),
|
649 |
|
|
.nOP_WAIT (nOP_WAIT),
|
650 |
|
|
.nRAS (nRAS),
|
651 |
|
|
.nRCD (nRCD),
|
652 |
|
|
.nRFC (nRFC),
|
653 |
|
|
.nRP (nRP),
|
654 |
|
|
.nRTP (nRTP),
|
655 |
|
|
.nSLOTS (nSLOTS),
|
656 |
|
|
.nWR (nWR),
|
657 |
|
|
.nXSDLL (tXSDLL),
|
658 |
|
|
.ORDERING (ORDERING),
|
659 |
|
|
.RANK_BM_BV_WIDTH (RANK_BM_BV_WIDTH),
|
660 |
|
|
.RANK_WIDTH (RANK_WIDTH),
|
661 |
|
|
.RANKS (RANKS),
|
662 |
|
|
.ROW_WIDTH (ROW_WIDTH),
|
663 |
|
|
.RTT_NOM (RTT_NOM),
|
664 |
|
|
.RTT_WR (RTT_WR),
|
665 |
|
|
.SLOT_0_CONFIG (SLOT_0_CONFIG),
|
666 |
|
|
.SLOT_1_CONFIG (SLOT_1_CONFIG),
|
667 |
|
|
.STARVE_LIMIT (STARVE_LIMIT),
|
668 |
|
|
.tZQCS (tZQCS)
|
669 |
|
|
)
|
670 |
|
|
bank_mach0
|
671 |
|
|
(
|
672 |
|
|
// Outputs
|
673 |
|
|
.accept (accept),
|
674 |
|
|
.accept_ns (accept_ns),
|
675 |
|
|
.act_this_rank_r (act_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
|
676 |
|
|
.bank_mach_next (bank_mach_next[BM_CNT_WIDTH-1:0]),
|
677 |
|
|
.col_a (col_a[ROW_WIDTH-1:0]),
|
678 |
|
|
.col_ba (col_ba[BANK_WIDTH-1:0]),
|
679 |
|
|
.col_data_buf_addr (col_data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
|
680 |
|
|
.col_periodic_rd (col_periodic_rd),
|
681 |
|
|
.col_ra (col_ra[RANK_WIDTH-1:0]),
|
682 |
|
|
.col_rmw (col_rmw),
|
683 |
|
|
.col_rd_wr (col_rd_wr),
|
684 |
|
|
.col_row (col_row[ROW_WIDTH-1:0]),
|
685 |
|
|
.col_size (col_size),
|
686 |
|
|
.col_wr_data_buf_addr (col_wr_data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
|
687 |
|
|
.mc_bank (mc_bank_ns),
|
688 |
|
|
.mc_address (mc_address_ns),
|
689 |
|
|
.mc_ras_n (mc_ras_n_ns),
|
690 |
|
|
.mc_cas_n (mc_cas_n_ns),
|
691 |
|
|
.mc_we_n (mc_we_n_ns),
|
692 |
|
|
.mc_cs_n (mc_cs_n_ns),
|
693 |
|
|
.mc_odt (mc_odt_ns),
|
694 |
|
|
.mc_cke (mc_cke_ns),
|
695 |
|
|
.mc_aux_out0 (mc_aux_out0_ns),
|
696 |
|
|
.mc_aux_out1 (mc_aux_out1_ns),
|
697 |
|
|
.mc_cmd (mc_cmd_ns),
|
698 |
|
|
.mc_data_offset (mc_data_offset_ns),
|
699 |
|
|
.mc_data_offset_1 (mc_data_offset_1_ns),
|
700 |
|
|
.mc_data_offset_2 (mc_data_offset_2_ns),
|
701 |
|
|
.mc_cas_slot (mc_cas_slot_ns),
|
702 |
|
|
.insert_maint_r1 (insert_maint_r1),
|
703 |
|
|
.maint_wip_r (maint_wip_r),
|
704 |
|
|
.periodic_rd_ack_r (periodic_rd_ack_r),
|
705 |
|
|
.rank_busy_r (rank_busy_r[(RANKS*nBANK_MACHS)-1:0]),
|
706 |
|
|
.rd_this_rank_r (rd_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
|
707 |
|
|
.sending_row (sending_row[nBANK_MACHS-1:0]),
|
708 |
|
|
.sending_col (sending_col[nBANK_MACHS-1:0]),
|
709 |
|
|
.sent_col (sent_col),
|
710 |
|
|
.sent_col_r (sent_col_r),
|
711 |
|
|
.wr_this_rank_r (wr_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
|
712 |
|
|
// Inputs
|
713 |
|
|
.bank (bank[BANK_WIDTH-1:0]),
|
714 |
|
|
.calib_rddata_offset (calib_rd_data_offset),
|
715 |
|
|
.calib_rddata_offset_1 (calib_rd_data_offset_1),
|
716 |
|
|
.calib_rddata_offset_2 (calib_rd_data_offset_2),
|
717 |
|
|
.clk (clk),
|
718 |
|
|
.cmd (cmd[2:0]),
|
719 |
|
|
.col (col[COL_WIDTH-1:0]),
|
720 |
|
|
.data_buf_addr (data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
|
721 |
|
|
.init_calib_complete (init_calib_complete),
|
722 |
|
|
.phy_rddata_valid (phy_rddata_valid),
|
723 |
|
|
.dq_busy_data (dq_busy_data),
|
724 |
|
|
.hi_priority (hi_priority),
|
725 |
|
|
.inhbt_act_faw_r (inhbt_act_faw_r[RANKS-1:0]),
|
726 |
|
|
.inhbt_rd (inhbt_rd[RANKS-1:0]),
|
727 |
|
|
.inhbt_wr (inhbt_wr[RANKS-1:0]),
|
728 |
|
|
.maint_rank_r (maint_rank_r[RANK_WIDTH-1:0]),
|
729 |
|
|
.maint_req_r (maint_req_r),
|
730 |
|
|
.maint_zq_r (maint_zq_r),
|
731 |
|
|
.maint_sre_r (maint_sre_r),
|
732 |
|
|
.maint_srx_r (maint_srx_r),
|
733 |
|
|
.periodic_rd_r (periodic_rd_r),
|
734 |
|
|
.periodic_rd_rank_r (periodic_rd_rank_r[RANK_WIDTH-1:0]),
|
735 |
|
|
.phy_mc_cmd_full (phy_mc_cmd_full),
|
736 |
|
|
.phy_mc_ctl_full (phy_mc_ctl_full),
|
737 |
|
|
.phy_mc_data_full (phy_mc_data_full),
|
738 |
|
|
.rank (rank[RANK_WIDTH-1:0]),
|
739 |
|
|
.rd_data_addr (rd_data_addr[DATA_BUF_ADDR_WIDTH-1:0]),
|
740 |
|
|
.rd_rmw (rd_rmw),
|
741 |
|
|
.row (row[ROW_WIDTH-1:0]),
|
742 |
|
|
.rst (rst),
|
743 |
|
|
.size (size),
|
744 |
|
|
.slot_0_present (slot_0_present[7:0]),
|
745 |
|
|
.slot_1_present (slot_1_present[7:0]),
|
746 |
|
|
.use_addr (use_addr)
|
747 |
|
|
);
|
748 |
|
|
|
749 |
|
|
//***************************************************************************
|
750 |
|
|
// Manage DQ bus
|
751 |
|
|
//***************************************************************************
|
752 |
|
|
|
753 |
|
|
mig_7series_v2_3_col_mach #
|
754 |
|
|
(
|
755 |
|
|
// Parameters
|
756 |
|
|
.TCQ (TCQ),
|
757 |
|
|
.BANK_WIDTH (BANK_WIDTH),
|
758 |
|
|
.BURST_MODE (BURST_MODE),
|
759 |
|
|
.COL_WIDTH (COL_WIDTH),
|
760 |
|
|
.CS_WIDTH (CS_WIDTH),
|
761 |
|
|
.DATA_BUF_ADDR_WIDTH (DATA_BUF_ADDR_WIDTH),
|
762 |
|
|
.DATA_BUF_OFFSET_WIDTH (DATA_BUF_OFFSET_WIDTH),
|
763 |
|
|
.DELAY_WR_DATA_CNTRL (DELAY_WR_DATA_CNTRL),
|
764 |
|
|
.DQS_WIDTH (DQS_WIDTH),
|
765 |
|
|
.DRAM_TYPE (DRAM_TYPE),
|
766 |
|
|
.EARLY_WR_DATA_ADDR (EARLY_WR_DATA_ADDR),
|
767 |
|
|
.ECC (ECC),
|
768 |
|
|
.MC_ERR_ADDR_WIDTH (MC_ERR_ADDR_WIDTH),
|
769 |
|
|
.nCK_PER_CLK (nCK_PER_CLK),
|
770 |
|
|
.nPHY_WRLAT (nPHY_WRLAT),
|
771 |
|
|
.RANK_WIDTH (RANK_WIDTH),
|
772 |
|
|
.ROW_WIDTH (ROW_WIDTH)
|
773 |
|
|
)
|
774 |
|
|
col_mach0
|
775 |
|
|
(
|
776 |
|
|
// Outputs
|
777 |
|
|
.mc_wrdata_en (mc_wrdata_en_ns),
|
778 |
|
|
.dq_busy_data (dq_busy_data),
|
779 |
|
|
.ecc_err_addr (ecc_err_addr[MC_ERR_ADDR_WIDTH-1:0]),
|
780 |
|
|
.ecc_status_valid (ecc_status_valid),
|
781 |
|
|
.rd_data_addr (rd_data_addr[DATA_BUF_ADDR_WIDTH-1:0]),
|
782 |
|
|
.rd_data_en (rd_data_en),
|
783 |
|
|
.rd_data_end (rd_data_end),
|
784 |
|
|
.rd_data_offset (rd_data_offset),
|
785 |
|
|
.rd_rmw (rd_rmw),
|
786 |
|
|
.wr_data_addr (wr_data_addr_ns),
|
787 |
|
|
.wr_data_en (wr_data_en_ns),
|
788 |
|
|
.wr_data_offset (wr_data_offset_ns),
|
789 |
|
|
.wr_ecc_buf (wr_ecc_buf),
|
790 |
|
|
.col_read_fifo_empty (col_read_fifo_empty),
|
791 |
|
|
// Inputs
|
792 |
|
|
.clk (clk),
|
793 |
|
|
.rst (rst),
|
794 |
|
|
.col_a (col_a[ROW_WIDTH-1:0]),
|
795 |
|
|
.col_ba (col_ba[BANK_WIDTH-1:0]),
|
796 |
|
|
.col_data_buf_addr (col_data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
|
797 |
|
|
.col_periodic_rd (col_periodic_rd),
|
798 |
|
|
.col_ra (col_ra[RANK_WIDTH-1:0]),
|
799 |
|
|
.col_rmw (col_rmw),
|
800 |
|
|
.col_rd_wr (col_rd_wr),
|
801 |
|
|
.col_row (col_row[ROW_WIDTH-1:0]),
|
802 |
|
|
.col_size (col_size),
|
803 |
|
|
.col_wr_data_buf_addr (col_wr_data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
|
804 |
|
|
.phy_rddata_valid (phy_rddata_valid),
|
805 |
|
|
.sent_col (EVEN_CWL_2T_MODE == "ON" ? sent_col_r : sent_col)
|
806 |
|
|
);
|
807 |
|
|
|
808 |
|
|
//***************************************************************************
|
809 |
|
|
// Implement ECC
|
810 |
|
|
//***************************************************************************
|
811 |
|
|
|
812 |
|
|
// Total ECC word length = ECC code width + Data width
|
813 |
|
|
localparam CODE_WIDTH = DATA_WIDTH + ECC_WIDTH;
|
814 |
|
|
|
815 |
|
|
generate
|
816 |
|
|
|
817 |
|
|
if (ECC == "OFF") begin : ecc_off
|
818 |
|
|
|
819 |
|
|
assign rd_data = phy_rd_data;
|
820 |
|
|
assign mc_wrdata = wr_data;
|
821 |
|
|
assign mc_wrdata_mask = wr_data_mask;
|
822 |
|
|
assign ecc_single = 4'b0;
|
823 |
|
|
assign ecc_multiple = 4'b0;
|
824 |
|
|
|
825 |
|
|
end
|
826 |
|
|
|
827 |
|
|
else begin : ecc_on
|
828 |
|
|
|
829 |
|
|
wire [CODE_WIDTH*ECC_WIDTH-1:0] h_rows;
|
830 |
|
|
wire [2*nCK_PER_CLK*DATA_WIDTH-1:0] rd_merge_data;
|
831 |
|
|
wire [2*nCK_PER_CLK*DQ_WIDTH-1:0] mc_wrdata_i;
|
832 |
|
|
|
833 |
|
|
|
834 |
|
|
// Merge and encode
|
835 |
|
|
mig_7series_v2_3_ecc_merge_enc #
|
836 |
|
|
(
|
837 |
|
|
// Parameters
|
838 |
|
|
.TCQ (TCQ),
|
839 |
|
|
.CODE_WIDTH (CODE_WIDTH),
|
840 |
|
|
.DATA_BUF_ADDR_WIDTH (DATA_BUF_ADDR_WIDTH),
|
841 |
|
|
.DATA_WIDTH (DATA_WIDTH),
|
842 |
|
|
.DQ_WIDTH (DQ_WIDTH),
|
843 |
|
|
.ECC_WIDTH (ECC_WIDTH),
|
844 |
|
|
.PAYLOAD_WIDTH (PAYLOAD_WIDTH),
|
845 |
|
|
.nCK_PER_CLK (nCK_PER_CLK)
|
846 |
|
|
)
|
847 |
|
|
ecc_merge_enc0
|
848 |
|
|
(
|
849 |
|
|
// Outputs
|
850 |
|
|
.mc_wrdata (mc_wrdata_i),
|
851 |
|
|
.mc_wrdata_mask (mc_wrdata_mask),
|
852 |
|
|
// Inputs
|
853 |
|
|
.clk (clk),
|
854 |
|
|
.rst (rst),
|
855 |
|
|
.h_rows (h_rows),
|
856 |
|
|
.rd_merge_data (rd_merge_data),
|
857 |
|
|
.raw_not_ecc (raw_not_ecc),
|
858 |
|
|
.wr_data (wr_data),
|
859 |
|
|
.wr_data_mask (wr_data_mask)
|
860 |
|
|
);
|
861 |
|
|
|
862 |
|
|
// Decode and fix
|
863 |
|
|
mig_7series_v2_3_ecc_dec_fix #
|
864 |
|
|
(
|
865 |
|
|
// Parameters
|
866 |
|
|
.TCQ (TCQ),
|
867 |
|
|
.CODE_WIDTH (CODE_WIDTH),
|
868 |
|
|
.DATA_WIDTH (DATA_WIDTH),
|
869 |
|
|
.DQ_WIDTH (DQ_WIDTH),
|
870 |
|
|
.ECC_WIDTH (ECC_WIDTH),
|
871 |
|
|
.PAYLOAD_WIDTH (PAYLOAD_WIDTH),
|
872 |
|
|
.nCK_PER_CLK (nCK_PER_CLK)
|
873 |
|
|
)
|
874 |
|
|
ecc_dec_fix0
|
875 |
|
|
(
|
876 |
|
|
// Outputs
|
877 |
|
|
.ecc_multiple (ecc_multiple),
|
878 |
|
|
.ecc_single (ecc_single),
|
879 |
|
|
.rd_data (rd_data),
|
880 |
|
|
// Inputs
|
881 |
|
|
.clk (clk),
|
882 |
|
|
.rst (rst),
|
883 |
|
|
.correct_en (correct_en),
|
884 |
|
|
.phy_rddata (phy_rd_data),
|
885 |
|
|
.ecc_status_valid (ecc_status_valid),
|
886 |
|
|
.h_rows (h_rows)
|
887 |
|
|
);
|
888 |
|
|
|
889 |
|
|
// ECC Buffer
|
890 |
|
|
mig_7series_v2_3_ecc_buf #
|
891 |
|
|
(
|
892 |
|
|
// Parameters
|
893 |
|
|
.TCQ (TCQ),
|
894 |
|
|
.DATA_BUF_ADDR_WIDTH (DATA_BUF_ADDR_WIDTH),
|
895 |
|
|
.DATA_BUF_OFFSET_WIDTH (DATA_BUF_OFFSET_WIDTH),
|
896 |
|
|
.DATA_WIDTH (DATA_WIDTH),
|
897 |
|
|
.PAYLOAD_WIDTH (PAYLOAD_WIDTH),
|
898 |
|
|
.nCK_PER_CLK (nCK_PER_CLK)
|
899 |
|
|
)
|
900 |
|
|
ecc_buf0
|
901 |
|
|
(
|
902 |
|
|
// Outputs
|
903 |
|
|
.rd_merge_data (rd_merge_data),
|
904 |
|
|
// Inputs
|
905 |
|
|
.clk (clk),
|
906 |
|
|
.rst (rst),
|
907 |
|
|
.rd_data (rd_data),
|
908 |
|
|
.rd_data_addr (rd_data_addr),
|
909 |
|
|
.rd_data_offset (rd_data_offset),
|
910 |
|
|
.wr_data_addr (wr_data_addr),
|
911 |
|
|
.wr_data_offset (wr_data_offset),
|
912 |
|
|
.wr_ecc_buf (wr_ecc_buf)
|
913 |
|
|
);
|
914 |
|
|
|
915 |
|
|
// Generate ECC table
|
916 |
|
|
mig_7series_v2_3_ecc_gen #
|
917 |
|
|
(
|
918 |
|
|
// Parameters
|
919 |
|
|
.CODE_WIDTH (CODE_WIDTH),
|
920 |
|
|
.DATA_WIDTH (DATA_WIDTH),
|
921 |
|
|
.ECC_WIDTH (ECC_WIDTH)
|
922 |
|
|
)
|
923 |
|
|
ecc_gen0
|
924 |
|
|
(
|
925 |
|
|
// Outputs
|
926 |
|
|
.h_rows (h_rows)
|
927 |
|
|
);
|
928 |
|
|
|
929 |
|
|
|
930 |
|
|
|
931 |
|
|
if (ECC == "ON") begin : gen_fi_xor_inst
|
932 |
|
|
reg mc_wrdata_en_r;
|
933 |
|
|
wire mc_wrdata_en_i;
|
934 |
|
|
|
935 |
|
|
always @(posedge clk) begin
|
936 |
|
|
mc_wrdata_en_r <= mc_wrdata_en;
|
937 |
|
|
end
|
938 |
|
|
|
939 |
|
|
assign mc_wrdata_en_i = mc_wrdata_en_r;
|
940 |
|
|
|
941 |
|
|
mig_7series_v2_3_fi_xor #(
|
942 |
|
|
.DQ_WIDTH (DQ_WIDTH),
|
943 |
|
|
.DQS_WIDTH (DQS_WIDTH),
|
944 |
|
|
.nCK_PER_CLK (nCK_PER_CLK)
|
945 |
|
|
)
|
946 |
|
|
fi_xor0
|
947 |
|
|
(
|
948 |
|
|
.clk (clk),
|
949 |
|
|
.wrdata_in (mc_wrdata_i),
|
950 |
|
|
.wrdata_out (mc_wrdata),
|
951 |
|
|
.wrdata_en (mc_wrdata_en_i),
|
952 |
|
|
.fi_xor_we (fi_xor_we),
|
953 |
|
|
.fi_xor_wrdata (fi_xor_wrdata)
|
954 |
|
|
);
|
955 |
|
|
end
|
956 |
|
|
else begin : gen_wrdata_passthru
|
957 |
|
|
assign mc_wrdata = mc_wrdata_i;
|
958 |
|
|
end
|
959 |
|
|
|
960 |
|
|
|
961 |
|
|
`ifdef DISPLAY_H_MATRIX
|
962 |
|
|
|
963 |
|
|
integer i;
|
964 |
|
|
|
965 |
|
|
always @(negedge rst) begin
|
966 |
|
|
|
967 |
|
|
$display ("**********************************************");
|
968 |
|
|
$display ("H Matrix:");
|
969 |
|
|
|
970 |
|
|
for (i=0; i<ECC_WIDTH; i=i+1)
|
971 |
|
|
$display ("%b", h_rows[i*CODE_WIDTH+:CODE_WIDTH]);
|
972 |
|
|
|
973 |
|
|
$display ("**********************************************");
|
974 |
|
|
|
975 |
|
|
end
|
976 |
|
|
|
977 |
|
|
`endif
|
978 |
|
|
|
979 |
|
|
end
|
980 |
|
|
|
981 |
|
|
endgenerate
|
982 |
|
|
|
983 |
|
|
endmodule // mc
|