AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
mig_7series_v1_9_mc.v
1  //*****************************************************************************
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 
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 (* keep = "true", max_fanout = 30 *) output reg [DATA_BUF_ADDR_WIDTH-1:0] wr_data_addr /* synthesis syn_maxfan = 30 **/,
184  output reg wr_data_en,
185 (* keep = "true", max_fanout = 30 *) 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  output [MC_ERR_ADDR_WIDTH-1:0] ecc_err_addr,
196  output [2*nCK_PER_CLK-1:0] ecc_single,
197  output [2*nCK_PER_CLK-1:0] ecc_multiple,
198 
199  // User maintenance requests
200 
201  input app_periodic_rd_req,
202  input app_ref_req,
203  input app_zq_req,
204  input app_sr_req,
205  output app_sr_active,
206  output app_ref_ack,
207  output app_zq_ack,
208 
209  // MC <==> PHY Interface
210 
211  output reg [nCK_PER_CLK-1:0] mc_ras_n,
212  output reg [nCK_PER_CLK-1:0] mc_cas_n,
213  output reg [nCK_PER_CLK-1:0] mc_we_n,
214  output reg [nCK_PER_CLK*ROW_WIDTH-1:0] mc_address,
215  output reg [nCK_PER_CLK*BANK_WIDTH-1:0] mc_bank,
216  output reg [CS_WIDTH*nCS_PER_RANK*nCK_PER_CLK-1:0] mc_cs_n,
217  output reg [1:0] mc_odt,
218  output reg [nCK_PER_CLK-1:0] mc_cke,
219  output wire mc_reset_n,
220  output wire [2*nCK_PER_CLK*DQ_WIDTH-1:0] mc_wrdata,
221  output wire [2*nCK_PER_CLK*DQ_WIDTH/8-1:0]mc_wrdata_mask,
222  output reg mc_wrdata_en,
223 
224  output wire mc_cmd_wren,
225  output wire mc_ctl_wren,
226  output reg [2:0] mc_cmd,
227  output reg [5:0] mc_data_offset,
228  output reg [5:0] mc_data_offset_1,
229  output reg [5:0] mc_data_offset_2,
230  output reg [1:0] mc_cas_slot,
231  output reg [3:0] mc_aux_out0,
232  output reg [3:0] mc_aux_out1,
233  output reg [1:0] mc_rank_cnt,
234 
235  input phy_mc_ctl_full,
236  input phy_mc_cmd_full,
237  input phy_mc_data_full,
238  input [2*nCK_PER_CLK*DQ_WIDTH-1:0] phy_rd_data,
239  input phy_rddata_valid,
240 
241  input init_calib_complete,
242  input [6*RANKS-1:0] calib_rd_data_offset,
243  input [6*RANKS-1:0] calib_rd_data_offset_1,
244  input [6*RANKS-1:0] calib_rd_data_offset_2
245 
246  );
247 
248  assign mc_reset_n = 1'b1; // never reset memory
249  assign mc_cmd_wren = 1'b1; // always write CMD FIFO(issue DSEL when idle)
250  assign mc_ctl_wren = 1'b1; // always write CTL FIFO(issue nondata when idle)
251 
252  // Ensure there is always at least one rank present during operation
253  `ifdef MC_SVA
254  ranks_present: assert property
255  (@(posedge clk) (rst || (|(slot_0_present | slot_1_present))));
256  `endif
257 
258  // Reserved. Do not change.
259  localparam nPHY_WRLAT = 2;
260 
261  // always delay write data control unless ECC mode is enabled
262  localparam DELAY_WR_DATA_CNTRL = ECC == "ON" ? 0 : 1;
263 
264  // Ensure that write control is delayed for appropriate CWL
265  /*`ifdef MC_SVA
266  delay_wr_data_zero_CWL_le_6: assert property
267  (@(posedge clk) ((CWL > 6) || (DELAY_WR_DATA_CNTRL == 0)));
268  `endif**/
269 
270  // Never retrieve WR_DATA_ADDR early
271  localparam EARLY_WR_DATA_ADDR = "OFF";
272 
273  //***************************************************************************
274  // Convert timing parameters from time to clock cycles
275  //***************************************************************************
276 
277  localparam nCKE = cdiv(tCKE, tCK);
278  localparam nRP = cdiv(tRP, tCK);
279  localparam nRCD = cdiv(tRCD, tCK);
280  localparam nRAS = cdiv(tRAS, tCK);
281  localparam nFAW = cdiv(tFAW, tCK);
282  localparam nRFC = cdiv(tRFC, tCK);
283 
284  // Convert tWR. As per specification, write recover for autoprecharge
285  // cycles doesn't support values of 9 and 11. Round up 9 to 10 and 11 to 12
286  localparam nWR_CK = cdiv(15000, tCK) ;
287  localparam nWR = (nWR_CK == 9) ? 10 : (nWR_CK == 11) ? 12 : nWR_CK;
288 
289  // tRRD, tWTR at tRTP have a 4 cycle floor in DDR3 and 2 cycle floor in DDR2
290  localparam nRRD_CK = cdiv(tRRD, tCK);
291  localparam nRRD = (DRAM_TYPE == "DDR3") ? (nRRD_CK < 4) ? 4 : nRRD_CK
292  : (nRRD_CK < 2) ? 2 : nRRD_CK;
293  localparam nWTR_CK = cdiv(tWTR, tCK);
294  localparam nWTR = (DRAM_TYPE == "DDR3") ? (nWTR_CK < 4) ? 4 : nWTR_CK
295  : (nWTR_CK < 2) ? 2 : nWTR_CK;
296  localparam nRTP_CK = cdiv(tRTP, tCK);
297  localparam nRTP = (DRAM_TYPE == "DDR3") ? (nRTP_CK < 4) ? 4 : nRTP_CK
298  : (nRTP_CK < 2) ? 2 : nRTP_CK;
299 
300  // Add a cycle to CL/CWL for the register in RDIMM devices
301  localparam CWL_M = (REG_CTRL == "ON") ? CWL + 1 : CWL;
302  localparam CL_M = (REG_CTRL == "ON") ? CL + 1 : CL;
303 
304  // Tuneable delay between read and write data on the DQ bus
305  localparam DQRD2DQWR_DLY = 4;
306 
307  // CKE minimum pulse width for self-refresh (SRE->SRX minimum time)
308  localparam nCKESR = nCKE + 1;
309 
310  // Delay from SRE to command requiring locked DLL. Currently fixed at 512 for
311  // all devices per JEDEC spec.
312  localparam tXSDLL = 512;
313 
314  //***************************************************************************
315  // Set up maintenance counter dividers
316  //***************************************************************************
317 
318  // CK clock divisor to generate maintenance prescaler period (round down)
319  localparam MAINT_PRESCALER_DIV = MAINT_PRESCALER_PERIOD / (tCK*nCK_PER_CLK);
320 
321  // Maintenance prescaler divisor for refresh timer. Essentially, this is
322  // just (tREFI / MAINT_PRESCALER_PERIOD), but we must account for the worst
323  // case delay from the time we get a tick from the refresh counter to the
324  // time that we can actually issue the REF command. Thus, subtract tRCD, CL,
325  // data burst time and tRP for each implemented bank machine to ensure that
326  // all transactions can complete before tREFI expires
327  localparam REFRESH_TIMER_DIV =
328  USER_REFRESH == "ON" ? 0 :
329  (tREFI-((tRCD+((CL+4)*tCK)+tRP)*nBANK_MACHS)) / MAINT_PRESCALER_PERIOD;
330 
331  // Periodic read (RESERVED - not currently required or supported in 7 series)
332  // tPRDI should only be set to 0
333  // localparam tPRDI = 0; // Do NOT change.
334  localparam PERIODIC_RD_TIMER_DIV = tPRDI / MAINT_PRESCALER_PERIOD;
335 
336  // Convert maintenance prescaler from ps to ns
337  localparam MAINT_PRESCALER_PERIOD_NS = MAINT_PRESCALER_PERIOD / 1000;
338 
339  // Maintenance prescaler divisor for ZQ calibration (ZQCS) timer
340  localparam ZQ_TIMER_DIV = tZQI / MAINT_PRESCALER_PERIOD_NS;
341 
342  // Bus width required to broadcast a single bit rank signal among all the
343  // bank machines - 1 bit per rank, per bank
344  localparam RANK_BM_BV_WIDTH = nBANK_MACHS * RANKS;
345 
346  //***************************************************************************
347  // Define 2T, CWL-even mode to enable multi-fabric-cycle 2T commands
348  //***************************************************************************
349  localparam EVEN_CWL_2T_MODE =
350  ((ADDR_CMD_MODE == "2T") && (!(CWL % 2))) ? "ON" : "OFF";
351 
352  //***************************************************************************
353  // Reserved feature control.
354  //***************************************************************************
355 
356  // Open page wait mode is reserved.
357  // nOP_WAIT is the number of states a bank machine will park itself
358  // on an otherwise inactive open page before closing the page. If
359  // nOP_WAIT == 0, open page wait mode is disabled. If nOP_WAIT == -1,
360  // the bank machine will remain parked until the pool of idle bank machines
361  // are less than LOW_IDLE_CNT. At which point parked bank machines
362  // are selected to exit until the number of idle bank machines exceeds the
363  // LOW_IDLE_CNT.
364  localparam nOP_WAIT = 0; // Open page mode
365  localparam LOW_IDLE_CNT = 0; // Low idle bank machine threshold
366 
367  //***************************************************************************
368  // Internal wires
369  //***************************************************************************
370 
371  wire [RANK_BM_BV_WIDTH-1:0] act_this_rank_r;
372  wire [ROW_WIDTH-1:0] col_a;
373  wire [BANK_WIDTH-1:0] col_ba;
374  wire [DATA_BUF_ADDR_WIDTH-1:0] col_data_buf_addr;
375  wire col_periodic_rd;
376  wire [RANK_WIDTH-1:0] col_ra;
377  wire col_rmw;
378  wire col_rd_wr;
379  wire [ROW_WIDTH-1:0] col_row;
380  wire col_size;
381  wire [DATA_BUF_ADDR_WIDTH-1:0] col_wr_data_buf_addr;
382  wire dq_busy_data;
383  wire ecc_status_valid;
384  wire [RANKS-1:0] inhbt_act_faw_r;
385  wire [RANKS-1:0] inhbt_rd;
386  wire [RANKS-1:0] inhbt_wr;
387  wire insert_maint_r1;
388  wire [RANK_WIDTH-1:0] maint_rank_r;
389  wire maint_req_r;
390  wire maint_wip_r;
391  wire maint_zq_r;
392  wire maint_sre_r;
393  wire maint_srx_r;
394  wire periodic_rd_ack_r;
395  wire periodic_rd_r;
396  wire [RANK_WIDTH-1:0] periodic_rd_rank_r;
397  wire [(RANKS*nBANK_MACHS)-1:0] rank_busy_r;
398  wire rd_rmw;
399  wire [RANK_BM_BV_WIDTH-1:0] rd_this_rank_r;
400  wire [nBANK_MACHS-1:0] sending_col;
401  wire [nBANK_MACHS-1:0] sending_row;
402  wire sent_col;
403  wire sent_col_r;
404  wire wr_ecc_buf;
405  wire [RANK_BM_BV_WIDTH-1:0] wr_this_rank_r;
406 
407  // MC/PHY optional pipeline stage support
408  wire [nCK_PER_CLK-1:0] mc_ras_n_ns;
409  wire [nCK_PER_CLK-1:0] mc_cas_n_ns;
410  wire [nCK_PER_CLK-1:0] mc_we_n_ns;
411  wire [nCK_PER_CLK*ROW_WIDTH-1:0] mc_address_ns;
412  wire [nCK_PER_CLK*BANK_WIDTH-1:0] mc_bank_ns;
413  wire [CS_WIDTH*nCS_PER_RANK*nCK_PER_CLK-1:0] mc_cs_n_ns;
414  wire [1:0] mc_odt_ns;
415  wire [nCK_PER_CLK-1:0] mc_cke_ns;
416  wire [3:0] mc_aux_out0_ns;
417  wire [3:0] mc_aux_out1_ns;
418  wire [1:0] mc_rank_cnt_ns = col_ra;
419  wire [2:0] mc_cmd_ns;
420  wire [5:0] mc_data_offset_ns;
421  wire [5:0] mc_data_offset_1_ns;
422  wire [5:0] mc_data_offset_2_ns;
423  wire [1:0] mc_cas_slot_ns;
424  wire mc_wrdata_en_ns;
425 
426  wire [DATA_BUF_ADDR_WIDTH-1:0] wr_data_addr_ns;
427  wire wr_data_en_ns;
428  wire [DATA_BUF_OFFSET_WIDTH-1:0] wr_data_offset_ns;
429 
430  integer i;
431 
432  // MC Read idle support
433  wire col_read_fifo_empty;
434  wire mc_read_idle_ns;
435  reg mc_read_idle_r;
436 
437  // MC Maintenance in progress with bus idle indication
438  wire maint_ref_zq_wip;
439  wire mc_ref_zq_wip_ns;
440  reg mc_ref_zq_wip_r;
441 
442  //***************************************************************************
443  // Function cdiv
444  // Description:
445  // This function performs ceiling division (divide and round-up)
446  // Inputs:
447  // num: integer to be divided
448  // div: divisor
449  // Outputs:
450  // cdiv: result of ceiling division (num/div, rounded up)
451  //***************************************************************************
452 
453  function integer cdiv (input integer num, input integer div);
454  begin
455  // perform division, then add 1 if and only if remainder is non-zero
456  cdiv = (num/div) + (((num%div)>0) ? 1 : 0);
457  end
458  endfunction // cdiv
459 
460  //***************************************************************************
461  // Optional pipeline register stage on MC/PHY interface
462  //***************************************************************************
463 
464  generate
465 
466  if (CMD_PIPE_PLUS1 == "ON") begin : cmd_pipe_plus // register interface
467 
468  always @(posedge clk) begin
469 
470  mc_address <= #TCQ mc_address_ns;
471  mc_bank <= #TCQ mc_bank_ns;
472  mc_cas_n <= #TCQ mc_cas_n_ns;
473  mc_cs_n <= #TCQ mc_cs_n_ns;
474  mc_odt <= #TCQ mc_odt_ns;
475  mc_cke <= #TCQ mc_cke_ns;
476  mc_aux_out0 <= #TCQ mc_aux_out0_ns;
477  mc_aux_out1 <= #TCQ mc_aux_out1_ns;
478  mc_cmd <= #TCQ mc_cmd_ns;
479  mc_ras_n <= #TCQ mc_ras_n_ns;
480  mc_we_n <= #TCQ mc_we_n_ns;
481  mc_data_offset <= #TCQ mc_data_offset_ns;
482  mc_data_offset_1 <= #TCQ mc_data_offset_1_ns;
483  mc_data_offset_2 <= #TCQ mc_data_offset_2_ns;
484  mc_cas_slot <= #TCQ mc_cas_slot_ns;
485  mc_wrdata_en <= #TCQ mc_wrdata_en_ns;
486  mc_rank_cnt <= #TCQ mc_rank_cnt_ns;
487 
488  wr_data_addr <= #TCQ wr_data_addr_ns;
489  wr_data_en <= #TCQ wr_data_en_ns;
490  wr_data_offset <= #TCQ wr_data_offset_ns;
491 
492  end // always @ (posedge clk)
493 
494  end // block: cmd_pipe_plus
495 
496  else begin : cmd_pipe_plus0 // don't register interface
497 
498  always @( mc_address_ns or mc_aux_out0_ns or mc_aux_out1_ns or
499  mc_bank_ns or mc_cas_n_ns or mc_cmd_ns or mc_cs_n_ns or
500  mc_odt_ns or mc_cke_ns or mc_data_offset_ns or
501  mc_data_offset_1_ns or mc_data_offset_2_ns or mc_rank_cnt_ns or
502  mc_ras_n_ns or mc_we_n_ns or mc_wrdata_en_ns or
503  wr_data_addr_ns or wr_data_en_ns or wr_data_offset_ns or
504  mc_cas_slot_ns)
505  begin
506 
507  mc_address = #TCQ mc_address_ns;
508  mc_bank = #TCQ mc_bank_ns;
509  mc_cas_n = #TCQ mc_cas_n_ns;
510  mc_cs_n = #TCQ mc_cs_n_ns;
511  mc_odt = #TCQ mc_odt_ns;
512  mc_cke = #TCQ mc_cke_ns;
513  mc_aux_out0 = #TCQ mc_aux_out0_ns;
514  mc_aux_out1 = #TCQ mc_aux_out1_ns;
515  mc_cmd = #TCQ mc_cmd_ns;
516  mc_ras_n = #TCQ mc_ras_n_ns;
517  mc_we_n = #TCQ mc_we_n_ns;
518  mc_data_offset = #TCQ mc_data_offset_ns;
519  mc_data_offset_1 = #TCQ mc_data_offset_1_ns;
520  mc_data_offset_2 = #TCQ mc_data_offset_2_ns;
521  mc_cas_slot = #TCQ mc_cas_slot_ns;
522  mc_wrdata_en = #TCQ mc_wrdata_en_ns;
523  mc_rank_cnt = #TCQ mc_rank_cnt_ns;
524 
525  wr_data_addr = #TCQ wr_data_addr_ns;
526  wr_data_en = #TCQ wr_data_en_ns;
527  wr_data_offset = #TCQ wr_data_offset_ns;
528 
529  end // always @ (...
530 
531  end // block: cmd_pipe_plus0
532 
533  endgenerate
534 
535  //***************************************************************************
536  // Indicate when there are no pending reads so that input features can be
537  // powered down
538  //***************************************************************************
539 
540  assign mc_read_idle_ns = col_read_fifo_empty & init_calib_complete;
541  always @(posedge clk) mc_read_idle_r <= #TCQ mc_read_idle_ns;
542  assign mc_read_idle = mc_read_idle_r;
543 
544  //***************************************************************************
545  // Indicate when there is a refresh in progress and the bus is idle so that
546  // tap adjustments can be made
547  //***************************************************************************
548 
549  assign mc_ref_zq_wip_ns = maint_ref_zq_wip && col_read_fifo_empty;
550  always @(posedge clk) mc_ref_zq_wip_r <= mc_ref_zq_wip_ns;
551  assign mc_ref_zq_wip = mc_ref_zq_wip_r;
552 
553  //***************************************************************************
554  // Manage rank-level timing and maintanence
555  //***************************************************************************
556 
558  (
559  // Parameters
560  .BURST_MODE (BURST_MODE),
561  .CL (CL),
562  .CWL (CWL),
563  .CS_WIDTH (CS_WIDTH),
564  .DQRD2DQWR_DLY (DQRD2DQWR_DLY),
565  .DRAM_TYPE (DRAM_TYPE),
566  .MAINT_PRESCALER_DIV (MAINT_PRESCALER_DIV),
567  .nBANK_MACHS (nBANK_MACHS),
568  .nCKESR (nCKESR),
569  .nCK_PER_CLK (nCK_PER_CLK),
570  .nFAW (nFAW),
571  .nREFRESH_BANK (nREFRESH_BANK),
572  .nRRD (nRRD),
573  .nWTR (nWTR),
574  .PERIODIC_RD_TIMER_DIV (PERIODIC_RD_TIMER_DIV),
575  .RANK_BM_BV_WIDTH (RANK_BM_BV_WIDTH),
576  .RANK_WIDTH (RANK_WIDTH),
577  .RANKS (RANKS),
578  .REFRESH_TIMER_DIV (REFRESH_TIMER_DIV),
579  .ZQ_TIMER_DIV (ZQ_TIMER_DIV)
580  )
581  rank_mach0
582  (
583  // Outputs
584  .inhbt_act_faw_r (inhbt_act_faw_r[RANKS-1:0]),
585  .inhbt_rd (inhbt_rd[RANKS-1:0]),
586  .inhbt_wr (inhbt_wr[RANKS-1:0]),
587  .maint_rank_r (maint_rank_r[RANK_WIDTH-1:0]),
588  .maint_req_r (maint_req_r),
589  .maint_zq_r (maint_zq_r),
590  .maint_sre_r (maint_sre_r),
591  .maint_srx_r (maint_srx_r),
592  .maint_ref_zq_wip (maint_ref_zq_wip),
593  .periodic_rd_r (periodic_rd_r),
594  .periodic_rd_rank_r (periodic_rd_rank_r[RANK_WIDTH-1:0]),
595  // Inputs
596  .act_this_rank_r (act_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
597  .app_periodic_rd_req (app_periodic_rd_req),
598  .app_ref_req (app_ref_req),
599  .app_ref_ack (app_ref_ack),
600  .app_zq_req (app_zq_req),
601  .app_zq_ack (app_zq_ack),
602  .app_sr_req (app_sr_req),
603  .app_sr_active (app_sr_active),
604  .col_rd_wr (col_rd_wr),
605  .clk (clk),
606  .init_calib_complete (init_calib_complete),
607  .insert_maint_r1 (insert_maint_r1),
608  .maint_wip_r (maint_wip_r),
609  .periodic_rd_ack_r (periodic_rd_ack_r),
610  .rank_busy_r (rank_busy_r[(RANKS*nBANK_MACHS)-1:0]),
611  .rd_this_rank_r (rd_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
612  .rst (rst),
613  .sending_col (sending_col[nBANK_MACHS-1:0]),
614  .sending_row (sending_row[nBANK_MACHS-1:0]),
615  .slot_0_present (slot_0_present[7:0]),
616  .slot_1_present (slot_1_present[7:0]),
617  .wr_this_rank_r (wr_this_rank_r[RANK_BM_BV_WIDTH-1:0])
618  );
619 
620  //***************************************************************************
621  // Manage requests, reordering and bank timing
622  //***************************************************************************
623 
625  (
626  // Parameters
627  .TCQ (TCQ),
628  .EVEN_CWL_2T_MODE (EVEN_CWL_2T_MODE),
629  .ADDR_CMD_MODE (ADDR_CMD_MODE),
630  .BANK_WIDTH (BANK_WIDTH),
631  .BM_CNT_WIDTH (BM_CNT_WIDTH),
632  .BURST_MODE (BURST_MODE),
633  .COL_WIDTH (COL_WIDTH),
634  .CS_WIDTH (CS_WIDTH),
635  .CL (CL_M),
636  .CWL (CWL_M),
637  .CKE_ODT_AUX (CKE_ODT_AUX),
638  .DATA_BUF_ADDR_WIDTH (DATA_BUF_ADDR_WIDTH),
639  .DRAM_TYPE (DRAM_TYPE),
640  .EARLY_WR_DATA_ADDR (EARLY_WR_DATA_ADDR),
641  .ECC (ECC),
642  .LOW_IDLE_CNT (LOW_IDLE_CNT),
643  .nBANK_MACHS (nBANK_MACHS),
644  .nCK_PER_CLK (nCK_PER_CLK),
645  .nCS_PER_RANK (nCS_PER_RANK),
646  .nOP_WAIT (nOP_WAIT),
647  .nRAS (nRAS),
648  .nRCD (nRCD),
649  .nRFC (nRFC),
650  .nRP (nRP),
651  .nRTP (nRTP),
652  .nSLOTS (nSLOTS),
653  .nWR (nWR),
654  .nXSDLL (tXSDLL),
655  .ORDERING (ORDERING),
656  .RANK_BM_BV_WIDTH (RANK_BM_BV_WIDTH),
657  .RANK_WIDTH (RANK_WIDTH),
658  .RANKS (RANKS),
659  .ROW_WIDTH (ROW_WIDTH),
660  .RTT_NOM (RTT_NOM),
661  .RTT_WR (RTT_WR),
662  .SLOT_0_CONFIG (SLOT_0_CONFIG),
663  .SLOT_1_CONFIG (SLOT_1_CONFIG),
664  .STARVE_LIMIT (STARVE_LIMIT),
665  .tZQCS (tZQCS)
666  )
667  bank_mach0
668  (
669  // Outputs
670  .accept (accept),
671  .accept_ns (accept_ns),
672  .act_this_rank_r (act_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
673  .bank_mach_next (bank_mach_next[BM_CNT_WIDTH-1:0]),
674  .col_a (col_a[ROW_WIDTH-1:0]),
675  .col_ba (col_ba[BANK_WIDTH-1:0]),
676  .col_data_buf_addr (col_data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
677  .col_periodic_rd (col_periodic_rd),
678  .col_ra (col_ra[RANK_WIDTH-1:0]),
679  .col_rmw (col_rmw),
680  .col_rd_wr (col_rd_wr),
681  .col_row (col_row[ROW_WIDTH-1:0]),
682  .col_size (col_size),
683  .col_wr_data_buf_addr (col_wr_data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
684  .mc_bank (mc_bank_ns),
685  .mc_address (mc_address_ns),
686  .mc_ras_n (mc_ras_n_ns),
687  .mc_cas_n (mc_cas_n_ns),
688  .mc_we_n (mc_we_n_ns),
689  .mc_cs_n (mc_cs_n_ns),
690  .mc_odt (mc_odt_ns),
691  .mc_cke (mc_cke_ns),
692  .mc_aux_out0 (mc_aux_out0_ns),
693  .mc_aux_out1 (mc_aux_out1_ns),
694  .mc_cmd (mc_cmd_ns),
695  .mc_data_offset (mc_data_offset_ns),
696  .mc_data_offset_1 (mc_data_offset_1_ns),
697  .mc_data_offset_2 (mc_data_offset_2_ns),
698  .mc_cas_slot (mc_cas_slot_ns),
699  .insert_maint_r1 (insert_maint_r1),
700  .maint_wip_r (maint_wip_r),
701  .periodic_rd_ack_r (periodic_rd_ack_r),
702  .rank_busy_r (rank_busy_r[(RANKS*nBANK_MACHS)-1:0]),
703  .rd_this_rank_r (rd_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
704  .sending_row (sending_row[nBANK_MACHS-1:0]),
705  .sending_col (sending_col[nBANK_MACHS-1:0]),
706  .sent_col (sent_col),
707  .sent_col_r (sent_col_r),
708  .wr_this_rank_r (wr_this_rank_r[RANK_BM_BV_WIDTH-1:0]),
709  // Inputs
710  .bank (bank[BANK_WIDTH-1:0]),
711  .calib_rddata_offset (calib_rd_data_offset),
712  .calib_rddata_offset_1 (calib_rd_data_offset_1),
713  .calib_rddata_offset_2 (calib_rd_data_offset_2),
714  .clk (clk),
715  .cmd (cmd[2:0]),
716  .col (col[COL_WIDTH-1:0]),
717  .data_buf_addr (data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
718  .init_calib_complete (init_calib_complete),
719  .phy_rddata_valid (phy_rddata_valid),
720  .dq_busy_data (dq_busy_data),
721  .hi_priority (hi_priority),
722  .inhbt_act_faw_r (inhbt_act_faw_r[RANKS-1:0]),
723  .inhbt_rd (inhbt_rd[RANKS-1:0]),
724  .inhbt_wr (inhbt_wr[RANKS-1:0]),
725  .maint_rank_r (maint_rank_r[RANK_WIDTH-1:0]),
726  .maint_req_r (maint_req_r),
727  .maint_zq_r (maint_zq_r),
728  .maint_sre_r (maint_sre_r),
729  .maint_srx_r (maint_srx_r),
730  .periodic_rd_r (periodic_rd_r),
731  .periodic_rd_rank_r (periodic_rd_rank_r[RANK_WIDTH-1:0]),
732  .phy_mc_cmd_full (phy_mc_cmd_full),
733  .phy_mc_ctl_full (phy_mc_ctl_full),
734  .phy_mc_data_full (phy_mc_data_full),
735  .rank (rank[RANK_WIDTH-1:0]),
736  .rd_data_addr (rd_data_addr[DATA_BUF_ADDR_WIDTH-1:0]),
737  .rd_rmw (rd_rmw),
738  .row (row[ROW_WIDTH-1:0]),
739  .rst (rst),
740  .size (size),
741  .slot_0_present (slot_0_present[7:0]),
742  .slot_1_present (slot_1_present[7:0]),
743  .use_addr (use_addr)
744  );
745 
746  //***************************************************************************
747  // Manage DQ bus
748  //***************************************************************************
749 
751  (
752  // Parameters
753  .TCQ (TCQ),
754  .BANK_WIDTH (BANK_WIDTH),
755  .BURST_MODE (BURST_MODE),
756  .COL_WIDTH (COL_WIDTH),
757  .CS_WIDTH (CS_WIDTH),
758  .DATA_BUF_ADDR_WIDTH (DATA_BUF_ADDR_WIDTH),
759  .DATA_BUF_OFFSET_WIDTH (DATA_BUF_OFFSET_WIDTH),
760  .DELAY_WR_DATA_CNTRL (DELAY_WR_DATA_CNTRL),
761  .DQS_WIDTH (DQS_WIDTH),
762  .DRAM_TYPE (DRAM_TYPE),
763  .EARLY_WR_DATA_ADDR (EARLY_WR_DATA_ADDR),
764  .ECC (ECC),
765  .MC_ERR_ADDR_WIDTH (MC_ERR_ADDR_WIDTH),
766  .nCK_PER_CLK (nCK_PER_CLK),
767  .nPHY_WRLAT (nPHY_WRLAT),
768  .RANK_WIDTH (RANK_WIDTH),
769  .ROW_WIDTH (ROW_WIDTH)
770  )
771  col_mach0
772  (
773  // Outputs
774  .mc_wrdata_en (mc_wrdata_en_ns),
775  .dq_busy_data (dq_busy_data),
776  .ecc_err_addr (ecc_err_addr[MC_ERR_ADDR_WIDTH-1:0]),
777  .ecc_status_valid (ecc_status_valid),
778  .rd_data_addr (rd_data_addr[DATA_BUF_ADDR_WIDTH-1:0]),
779  .rd_data_en (rd_data_en),
780  .rd_data_end (rd_data_end),
781  .rd_data_offset (rd_data_offset),
782  .rd_rmw (rd_rmw),
783  .wr_data_addr (wr_data_addr_ns),
784  .wr_data_en (wr_data_en_ns),
785  .wr_data_offset (wr_data_offset_ns),
786  .wr_ecc_buf (wr_ecc_buf),
787  .col_read_fifo_empty (col_read_fifo_empty),
788  // Inputs
789  .clk (clk),
790  .rst (rst),
791  .col_a (col_a[ROW_WIDTH-1:0]),
792  .col_ba (col_ba[BANK_WIDTH-1:0]),
793  .col_data_buf_addr (col_data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
794  .col_periodic_rd (col_periodic_rd),
795  .col_ra (col_ra[RANK_WIDTH-1:0]),
796  .col_rmw (col_rmw),
797  .col_rd_wr (col_rd_wr),
798  .col_row (col_row[ROW_WIDTH-1:0]),
799  .col_size (col_size),
800  .col_wr_data_buf_addr (col_wr_data_buf_addr[DATA_BUF_ADDR_WIDTH-1:0]),
801  .phy_rddata_valid (phy_rddata_valid),
802  .sent_col (EVEN_CWL_2T_MODE == "ON" ? sent_col_r : sent_col)
803  );
804 
805  //***************************************************************************
806  // Implement ECC
807  //***************************************************************************
808 
809  // Total ECC word length = ECC code width + Data width
810  localparam CODE_WIDTH = DATA_WIDTH + ECC_WIDTH;
811 
812  generate
813 
814  if (ECC == "OFF") begin : ecc_off
815 
816  assign rd_data = phy_rd_data;
817  assign mc_wrdata = wr_data;
818  assign mc_wrdata_mask = wr_data_mask;
819  assign ecc_single = 4'b0;
820  assign ecc_multiple = 4'b0;
821 
822  end
823 
824  else begin : ecc_on
825 
826  wire [CODE_WIDTH*ECC_WIDTH-1:0] h_rows;
827  wire [2*nCK_PER_CLK*DATA_WIDTH-1:0] rd_merge_data;
828 
829  // Merge and encode
831  (
832  // Parameters
833  .TCQ (TCQ),
834  .CODE_WIDTH (CODE_WIDTH),
835  .DATA_BUF_ADDR_WIDTH (DATA_BUF_ADDR_WIDTH),
836  .DATA_WIDTH (DATA_WIDTH),
837  .DQ_WIDTH (DQ_WIDTH),
838  .ECC_WIDTH (ECC_WIDTH),
839  .PAYLOAD_WIDTH (PAYLOAD_WIDTH),
840  .nCK_PER_CLK (nCK_PER_CLK)
841  )
842  ecc_merge_enc0
843  (
844  // Outputs
845  .mc_wrdata (mc_wrdata),
846  .mc_wrdata_mask (mc_wrdata_mask),
847  // Inputs
848  .clk (clk),
849  .rst (rst),
850  .h_rows (h_rows),
851  .rd_merge_data (rd_merge_data),
852  .raw_not_ecc (raw_not_ecc),
853  .wr_data (wr_data),
854  .wr_data_mask (wr_data_mask)
855  );
856 
857  // Decode and fix
859  (
860  // Parameters
861  .TCQ (TCQ),
862  .CODE_WIDTH (CODE_WIDTH),
863  .DATA_WIDTH (DATA_WIDTH),
864  .DQ_WIDTH (DQ_WIDTH),
865  .ECC_WIDTH (ECC_WIDTH),
866  .PAYLOAD_WIDTH (PAYLOAD_WIDTH),
867  .nCK_PER_CLK (nCK_PER_CLK)
868  )
869  ecc_dec_fix0
870  (
871  // Outputs
872  .ecc_multiple (ecc_multiple),
873  .ecc_single (ecc_single),
874  .rd_data (rd_data),
875  // Inputs
876  .clk (clk),
877  .rst (rst),
878  .correct_en (correct_en),
879  .phy_rddata (phy_rd_data),
880  .ecc_status_valid (ecc_status_valid),
881  .h_rows (h_rows)
882  );
883 
884  // ECC Buffer
886  (
887  // Parameters
888  .TCQ (TCQ),
889  .DATA_BUF_ADDR_WIDTH (DATA_BUF_ADDR_WIDTH),
890  .DATA_BUF_OFFSET_WIDTH (DATA_BUF_OFFSET_WIDTH),
891  .DATA_WIDTH (DATA_WIDTH),
892  .PAYLOAD_WIDTH (PAYLOAD_WIDTH),
893  .nCK_PER_CLK (nCK_PER_CLK)
894  )
895  ecc_buf0
896  (
897  // Outputs
898  .rd_merge_data (rd_merge_data),
899  // Inputs
900  .clk (clk),
901  .rst (rst),
902  .rd_data (rd_data),
903  .rd_data_addr (rd_data_addr),
904  .rd_data_offset (rd_data_offset),
905  .wr_data_addr (wr_data_addr),
906  .wr_data_offset (wr_data_offset),
907  .wr_ecc_buf (wr_ecc_buf)
908  );
909 
910  // Generate ECC table
912  (
913  // Parameters
914  .CODE_WIDTH (CODE_WIDTH),
915  .DATA_WIDTH (DATA_WIDTH),
916  .ECC_WIDTH (ECC_WIDTH)
917  )
918  ecc_gen0
919  (
920  // Outputs
921  .h_rows (h_rows)
922  );
923 
924  `ifdef DISPLAY_H_MATRIX
925 
926  integer i;
927 
928  always @(negedge rst) begin
929 
930  $display ("**********************************************");
931  $display ("H Matrix:");
932 
933  for (i=0; i<ECC_WIDTH; i=i+1)
934  $display ("%b", h_rows[i*CODE_WIDTH+:CODE_WIDTH]);
935 
936  $display ("**********************************************");
937 
938  end
939 
940  `endif
941 
942  end
943 
944  endgenerate
945 
946 endmodule // mc