AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
mig_7series_v1_9_arb_select.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 : arb_select.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 // Based on granta_r and grantc_r, this module selects a
67 // row and column command from the request information
68 // provided by the bank machines.
69 //
70 // Depending on address mode configuration, nCL and nCWL, a column
71 // command pipeline of up to three states will be created.
72 
73 `timescale 1 ps / 1 ps
74 
76  (
77  parameter TCQ = 100,
78  parameter EVEN_CWL_2T_MODE = "OFF",
79  parameter ADDR_CMD_MODE = "1T",
80  parameter BANK_VECT_INDX = 11,
81  parameter BANK_WIDTH = 3,
82  parameter BURST_MODE = "8",
83  parameter CS_WIDTH = 4,
84  parameter CL = 5,
85  parameter CWL = 5,
86  parameter DATA_BUF_ADDR_VECT_INDX = 31,
87  parameter DATA_BUF_ADDR_WIDTH = 8,
88  parameter DRAM_TYPE = "DDR3",
89  parameter EARLY_WR_DATA_ADDR = "OFF",
90  parameter ECC = "OFF",
91  parameter nBANK_MACHS = 4,
92  parameter nCK_PER_CLK = 2,
93  parameter nCS_PER_RANK = 1,
94  parameter CKE_ODT_AUX = "FALSE",
95  parameter nSLOTS = 2,
96  parameter RANKS = 1,
97  parameter RANK_VECT_INDX = 15,
98  parameter RANK_WIDTH = 2,
99  parameter ROW_VECT_INDX = 63,
100  parameter ROW_WIDTH = 16,
101  parameter RTT_NOM = "40",
102  parameter RTT_WR = "120",
103  parameter SLOT_0_CONFIG = 8'b0000_0101,
104  parameter SLOT_1_CONFIG = 8'b0000_1010
105  )
106  (
107 
108  // Outputs
109 
110  output wire col_periodic_rd,
111  output wire [RANK_WIDTH-1:0] col_ra,
112  output wire [BANK_WIDTH-1:0] col_ba,
113  output wire [ROW_WIDTH-1:0] col_a,
114  output wire col_rmw,
115  output wire col_rd_wr,
116  output wire col_size,
117  output wire [ROW_WIDTH-1:0] col_row,
118  output wire [DATA_BUF_ADDR_WIDTH-1:0] col_data_buf_addr,
119  output wire [DATA_BUF_ADDR_WIDTH-1:0] col_wr_data_buf_addr,
120 
121  output wire [nCK_PER_CLK-1:0] mc_ras_n,
122  output wire [nCK_PER_CLK-1:0] mc_cas_n,
123  output wire [nCK_PER_CLK-1:0] mc_we_n,
124  output wire [nCK_PER_CLK*ROW_WIDTH-1:0] mc_address,
125  output wire [nCK_PER_CLK*BANK_WIDTH-1:0] mc_bank,
126  output wire [CS_WIDTH*nCS_PER_RANK*nCK_PER_CLK-1:0] mc_cs_n,
127  output wire [1:0] mc_odt,
128  output wire [nCK_PER_CLK-1:0] mc_cke,
129  output wire [3:0] mc_aux_out0,
130  output wire [3:0] mc_aux_out1,
131  output [2:0] mc_cmd,
132  output wire [5:0] mc_data_offset,
133  output wire [5:0] mc_data_offset_1,
134  output wire [5:0] mc_data_offset_2,
135  output wire [1:0] mc_cas_slot,
136 
137  output wire [RANK_WIDTH-1:0] rnk_config,
138 
139  // Inputs
140 
141  input clk,
142  input rst,
143  input init_calib_complete,
144 
145  input [RANK_VECT_INDX:0] req_rank_r,
146  input [BANK_VECT_INDX:0] req_bank_r,
147  input [nBANK_MACHS-1:0] req_ras,
148  input [nBANK_MACHS-1:0] req_cas,
149  input [nBANK_MACHS-1:0] req_wr_r,
150  input [nBANK_MACHS-1:0] grant_row_r,
151  input [nBANK_MACHS-1:0] grant_pre_r,
152  input [ROW_VECT_INDX:0] row_addr,
153  input [nBANK_MACHS-1:0] row_cmd_wr,
154  input insert_maint_r1,
155  input maint_zq_r,
156  input maint_sre_r,
157  input maint_srx_r,
158  input [RANK_WIDTH-1:0] maint_rank_r,
159 
160  input [nBANK_MACHS-1:0] req_periodic_rd_r,
161  input [nBANK_MACHS-1:0] req_size_r,
162  input [nBANK_MACHS-1:0] rd_wr_r,
163  input [ROW_VECT_INDX:0] req_row_r,
164  input [ROW_VECT_INDX:0] col_addr,
165  input [DATA_BUF_ADDR_VECT_INDX:0] req_data_buf_addr_r,
166  input [nBANK_MACHS-1:0] grant_col_r,
167  input [nBANK_MACHS-1:0] grant_col_wr,
168 
169  input [6*RANKS-1:0] calib_rddata_offset,
170  input [6*RANKS-1:0] calib_rddata_offset_1,
171  input [6*RANKS-1:0] calib_rddata_offset_2,
172  input [5:0] col_channel_offset,
173 
174  input [nBANK_MACHS-1:0] grant_config_r,
175  input rnk_config_strobe,
176 
177  input [7:0] slot_0_present,
178  input [7:0] slot_1_present,
179 
180  input send_cmd0_row,
181  input send_cmd0_col,
182  input send_cmd1_row,
183  input send_cmd1_col,
184  input send_cmd2_row,
185  input send_cmd2_col,
186  input send_cmd2_pre,
187  input send_cmd3_col,
188 
189  input sent_col,
190 
191  input cs_en0,
192  input cs_en1,
193  input cs_en2,
194  input cs_en3
195 
196  );
197 
198  localparam OUT_CMD_WIDTH = RANK_WIDTH + BANK_WIDTH + ROW_WIDTH + 1 + 1 + 1;
199 
200  reg col_rd_wr_ns;
201  reg col_rd_wr_r = 1'b0;
202  reg [OUT_CMD_WIDTH-1:0] col_cmd_r = {OUT_CMD_WIDTH {1'b0}};
203  reg [OUT_CMD_WIDTH-1:0] row_cmd_r = {OUT_CMD_WIDTH {1'b0}};
204 
205  // calib_rd_data_offset for currently targeted rank
206  reg [5:0] rank_rddata_offset_0;
207  reg [5:0] rank_rddata_offset_1;
208  reg [5:0] rank_rddata_offset_2;
209 
210  // Toggle CKE[0] when entering and exiting self-refresh, disable CKE[1]
211  assign mc_aux_out0[0] = (maint_sre_r || maint_srx_r) & insert_maint_r1;
212  assign mc_aux_out0[2] = 1'b0;
213 
214  reg cke_r;
215  reg cke_ns;
216  generate
217  if(CKE_ODT_AUX == "FALSE")begin
218  always @(posedge clk)
219  begin
220  if (rst)
221  cke_r = 1'b1;
222  else
223  cke_r = cke_ns;
224  end
225 
226  always @(*)
227  begin
228  cke_ns = 1'b1;
229  if (maint_sre_r & insert_maint_r1)
230  cke_ns = 1'b0;
231  else if (cke_r==1'b0)
232  begin
233  if (maint_srx_r & insert_maint_r1)
234  cke_ns = 1'b1;
235  else
236  cke_ns = 1'b0;
237  end
238  end
239  end
240  endgenerate
241 
242  // Disable ODT & CKE toggle enable high bits
243  assign mc_aux_out1 = 4'b0;
244 
245  // implement PHY command word
246  assign mc_cmd[0] = sent_col;
247  assign mc_cmd[1] = EVEN_CWL_2T_MODE == "ON" ?
248  sent_col && col_rd_wr_r :
249  sent_col && col_rd_wr_ns;
250  assign mc_cmd[2] = ~sent_col;
251 
252  // generate calib_rd_data_offset for current rank - only use rank 0 values for now
253  always @(calib_rddata_offset or calib_rddata_offset_1 or calib_rddata_offset_2) begin
254  rank_rddata_offset_0 = calib_rddata_offset[5:0];
255  rank_rddata_offset_1 = calib_rddata_offset_1[5:0];
256  rank_rddata_offset_2 = calib_rddata_offset_2[5:0];
257  end
258 
259  // generate data offset
260  generate
261  if(EVEN_CWL_2T_MODE == "ON") begin : gen_mc_data_offset_even_cwl_2t
262  assign mc_data_offset = ~sent_col ?
263  6'b0 :
264  col_rd_wr_r ?
265  rank_rddata_offset_0 + col_channel_offset :
266  nCK_PER_CLK == 2 ?
267  CWL - 2 + col_channel_offset :
268  // nCK_PER_CLK == 4
269  CWL + 2 + col_channel_offset;
270  assign mc_data_offset_1 = ~sent_col ?
271  6'b0 :
272  col_rd_wr_r ?
273  rank_rddata_offset_1 + col_channel_offset :
274  nCK_PER_CLK == 2 ?
275  CWL - 2 + col_channel_offset :
276  // nCK_PER_CLK == 4
277  CWL + 2 + col_channel_offset;
278  assign mc_data_offset_2 = ~sent_col ?
279  6'b0 :
280  col_rd_wr_r ?
281  rank_rddata_offset_2 + col_channel_offset :
282  nCK_PER_CLK == 2 ?
283  CWL - 2 + col_channel_offset :
284  // nCK_PER_CLK == 4
285  CWL + 2 + col_channel_offset;
286  end
287  else begin : gen_mc_data_offset_not_even_cwl_2t
288  assign mc_data_offset = ~sent_col ?
289  6'b0 :
290  col_rd_wr_ns ?
291  rank_rddata_offset_0 + col_channel_offset :
292  nCK_PER_CLK == 2 ?
293  CWL - 2 + col_channel_offset :
294  // nCK_PER_CLK == 4
295  CWL + 2 + col_channel_offset;
296  assign mc_data_offset_1 = ~sent_col ?
297  6'b0 :
298  col_rd_wr_ns ?
299  rank_rddata_offset_1 + col_channel_offset :
300  nCK_PER_CLK == 2 ?
301  CWL - 2 + col_channel_offset :
302  // nCK_PER_CLK == 4
303  CWL + 2 + col_channel_offset;
304  assign mc_data_offset_2 = ~sent_col ?
305  6'b0 :
306  col_rd_wr_ns ?
307  rank_rddata_offset_2 + col_channel_offset :
308  nCK_PER_CLK == 2 ?
309  CWL - 2 + col_channel_offset :
310  // nCK_PER_CLK == 4
311  CWL + 2 + col_channel_offset;
312  end
313  endgenerate
314 
315  assign mc_cas_slot = col_channel_offset[1:0];
316 
317 // Based on arbitration results, select the row and column commands.
318 
319  integer i;
320  reg [OUT_CMD_WIDTH-1:0] row_cmd_ns;
321  generate
322  begin : row_mux
323  wire [OUT_CMD_WIDTH-1:0] maint_cmd =
324  {maint_rank_r, // maintenance rank
325  row_cmd_r[15+:(BANK_WIDTH+ROW_WIDTH-11)],
326  // bank plus upper address bits
327  1'b0, // A10 = 0 for ZQCS
328  row_cmd_r[3+:10], // address bits [9:0]
329  // ZQ, SRX or SRE/REFRESH
330  (maint_zq_r ? 3'b110 : maint_srx_r ? 3'b111 : 3'b001)
331  };
332  always @(/*AS**/grant_row_r or insert_maint_r1 or maint_cmd
333  or req_bank_r or req_cas or req_rank_r or req_ras
334  or row_addr or row_cmd_r or row_cmd_wr or rst)
335  begin
336  row_cmd_ns = rst
337  ? {RANK_WIDTH{1'b0}}
338  : insert_maint_r1
339  ? maint_cmd
340  : row_cmd_r;
341  for (i=0; i<nBANK_MACHS; i=i+1)
342  if (grant_row_r[i])
343  row_cmd_ns = {req_rank_r[(RANK_WIDTH*i)+:RANK_WIDTH],
344  req_bank_r[(BANK_WIDTH*i)+:BANK_WIDTH],
345  row_addr[(ROW_WIDTH*i)+:ROW_WIDTH],
346  req_ras[i],
347  req_cas[i],
348  row_cmd_wr[i]};
349  end
350 
351  if (ADDR_CMD_MODE == "2T" && nCK_PER_CLK == 2)
352  always @(posedge clk) row_cmd_r <= #TCQ row_cmd_ns;
353 
354  end // row_mux
355  endgenerate
356 
357  reg [OUT_CMD_WIDTH-1:0] pre_cmd_ns;
358  generate
359  if((nCK_PER_CLK == 4) && (ADDR_CMD_MODE != "2T")) begin : pre_mux
360  reg [OUT_CMD_WIDTH-1:0] pre_cmd_r = {OUT_CMD_WIDTH {1'b0}};
361  always @(/*AS**/grant_pre_r or req_bank_r or req_cas or req_rank_r or req_ras
362  or row_addr or pre_cmd_r or row_cmd_wr or rst)
363  begin
364  pre_cmd_ns = rst
365  ? {RANK_WIDTH{1'b0}}
366  : pre_cmd_r;
367  for (i=0; i<nBANK_MACHS; i=i+1)
368  if (grant_pre_r[i])
369  pre_cmd_ns = {req_rank_r[(RANK_WIDTH*i)+:RANK_WIDTH],
370  req_bank_r[(BANK_WIDTH*i)+:BANK_WIDTH],
371  row_addr[(ROW_WIDTH*i)+:ROW_WIDTH],
372  req_ras[i],
373  req_cas[i],
374  row_cmd_wr[i]};
375  end
376 
377  end // pre_mux
378  endgenerate
379 
380  reg [OUT_CMD_WIDTH-1:0] col_cmd_ns;
381  generate
382  begin : col_mux
383  reg col_periodic_rd_ns;
384  reg col_periodic_rd_r;
385  reg col_rmw_ns;
386  reg col_rmw_r;
387  reg col_size_ns;
388  reg col_size_r;
389  reg [ROW_WIDTH-1:0] col_row_ns;
390  reg [ROW_WIDTH-1:0] col_row_r;
391  reg [DATA_BUF_ADDR_WIDTH-1:0] col_data_buf_addr_ns;
392  reg [DATA_BUF_ADDR_WIDTH-1:0] col_data_buf_addr_r;
393 
394  always @(col_addr or col_cmd_r or col_data_buf_addr_r
395  or col_periodic_rd_r or col_rmw_r or col_row_r
396  or col_size_r or grant_col_r or rd_wr_r or req_bank_r
397  or req_data_buf_addr_r or req_periodic_rd_r
398  or req_rank_r or req_row_r or req_size_r or req_wr_r
399  or rst or col_rd_wr_r)
400  begin
401  col_periodic_rd_ns = ~rst && col_periodic_rd_r;
402  col_cmd_ns = {(rst ? {RANK_WIDTH{1'b0}}
403  : col_cmd_r[(OUT_CMD_WIDTH-1)-:RANK_WIDTH]),
404  ((rst && ECC != "OFF")
405  ? {OUT_CMD_WIDTH-3-RANK_WIDTH{1'b0}}
406  : col_cmd_r[3+:(OUT_CMD_WIDTH-3-RANK_WIDTH)]),
407  (rst ? 3'b0 : col_cmd_r[2:0])};
408  col_rmw_ns = col_rmw_r;
409  col_size_ns = rst ? 1'b0 : col_size_r;
410  col_row_ns = col_row_r;
411  col_rd_wr_ns = col_rd_wr_r;
412  col_data_buf_addr_ns = col_data_buf_addr_r;
413  for (i=0; i<nBANK_MACHS; i=i+1)
414  if (grant_col_r[i]) begin
415  col_periodic_rd_ns = req_periodic_rd_r[i];
416  col_cmd_ns = {req_rank_r[(RANK_WIDTH*i)+:RANK_WIDTH],
417  req_bank_r[(BANK_WIDTH*i)+:BANK_WIDTH],
418  col_addr[(ROW_WIDTH*i)+:ROW_WIDTH],
419  1'b1,
420  1'b0,
421  rd_wr_r[i]};
422  col_rmw_ns = req_wr_r[i] && rd_wr_r[i];
423  col_size_ns = req_size_r[i];
424  col_row_ns = req_row_r[(ROW_WIDTH*i)+:ROW_WIDTH];
425  col_rd_wr_ns = rd_wr_r[i];
426  col_data_buf_addr_ns =
427  req_data_buf_addr_r[(DATA_BUF_ADDR_WIDTH*i)+:DATA_BUF_ADDR_WIDTH];
428  end
429  end // always @ (...
430 
431  if (EARLY_WR_DATA_ADDR == "OFF") begin : early_wr_data_addr_off
432  assign col_wr_data_buf_addr = col_data_buf_addr_ns;
433  end
434  else begin : early_wr_data_addr_on
435  reg [DATA_BUF_ADDR_WIDTH-1:0] col_wr_data_buf_addr_ns;
436  reg [DATA_BUF_ADDR_WIDTH-1:0] col_wr_data_buf_addr_r;
437  always @(/*AS**/col_wr_data_buf_addr_r or grant_col_wr
438  or req_data_buf_addr_r) begin
439  col_wr_data_buf_addr_ns = col_wr_data_buf_addr_r;
440  for (i=0; i<nBANK_MACHS; i=i+1)
441  if (grant_col_wr[i])
442  col_wr_data_buf_addr_ns =
443  req_data_buf_addr_r[(DATA_BUF_ADDR_WIDTH*i)+:DATA_BUF_ADDR_WIDTH];
444  end
445  always @(posedge clk) col_wr_data_buf_addr_r <=
446  #TCQ col_wr_data_buf_addr_ns;
447  assign col_wr_data_buf_addr = col_wr_data_buf_addr_ns;
448  end
449 
450  always @(posedge clk) col_periodic_rd_r <= #TCQ col_periodic_rd_ns;
451  always @(posedge clk) col_rmw_r <= #TCQ col_rmw_ns;
452  always @(posedge clk) col_size_r <= #TCQ col_size_ns;
453  always @(posedge clk) col_data_buf_addr_r <=
454  #TCQ col_data_buf_addr_ns;
455 
456  if (ECC != "OFF" || EVEN_CWL_2T_MODE == "ON") begin
457  always @(posedge clk) col_cmd_r <= #TCQ col_cmd_ns;
458  always @(posedge clk) col_row_r <= #TCQ col_row_ns;
459  end
460 
461  always @(posedge clk) col_rd_wr_r <= #TCQ col_rd_wr_ns;
462 
463  if(EVEN_CWL_2T_MODE == "ON") begin
464 
465  assign col_periodic_rd = col_periodic_rd_r;
466  assign col_ra = col_cmd_r[3+ROW_WIDTH+BANK_WIDTH+:RANK_WIDTH];
467  assign col_ba = col_cmd_r[3+ROW_WIDTH+:BANK_WIDTH];
468  assign col_a = col_cmd_r[3+:ROW_WIDTH];
469  assign col_rmw = col_rmw_r;
470  assign col_rd_wr = col_rd_wr_r;
471  assign col_size = col_size_r;
472  assign col_row = col_row_r;
473  assign col_data_buf_addr = col_data_buf_addr_r;
474 
475  end
476 
477  else begin
478 
479  assign col_periodic_rd = col_periodic_rd_ns;
480  assign col_ra = col_cmd_ns[3+ROW_WIDTH+BANK_WIDTH+:RANK_WIDTH];
481  assign col_ba = col_cmd_ns[3+ROW_WIDTH+:BANK_WIDTH];
482  assign col_a = col_cmd_ns[3+:ROW_WIDTH];
483  assign col_rmw = col_rmw_ns;
484  assign col_rd_wr = col_rd_wr_ns;
485  assign col_size = col_size_ns;
486  assign col_row = col_row_ns;
487  assign col_data_buf_addr = col_data_buf_addr_ns;
488 
489  end
490 
491  end // col_mux
492  endgenerate
493 
494  reg [OUT_CMD_WIDTH-1:0] cmd0 = {OUT_CMD_WIDTH{1'b1}};
495  reg cke0;
496  always @(send_cmd0_row or send_cmd0_col or row_cmd_ns or row_cmd_r or col_cmd_ns or col_cmd_r or cke_ns or cke_r ) begin
497  cmd0 = {OUT_CMD_WIDTH{1'b1}};
498  if (send_cmd0_row) cmd0 = row_cmd_ns;
499  if (send_cmd0_row && EVEN_CWL_2T_MODE == "ON" && nCK_PER_CLK == 2) cmd0 = row_cmd_r;
500  if (send_cmd0_col) cmd0 = col_cmd_ns;
501  if (send_cmd0_col && EVEN_CWL_2T_MODE == "ON") cmd0 = col_cmd_r;
502  if (send_cmd0_row) cke0 = cke_ns;
503  else cke0 = cke_r ;
504  end
505 
506  reg [OUT_CMD_WIDTH-1:0] cmd1 = {OUT_CMD_WIDTH{1'b1}};
507  generate
508  if ((nCK_PER_CLK == 2) || (nCK_PER_CLK == 4))
509  always @(send_cmd1_row or send_cmd1_col or row_cmd_ns or col_cmd_ns or pre_cmd_ns) begin
510  cmd1 = {OUT_CMD_WIDTH{1'b1}};
511  if (send_cmd1_row) cmd1 = row_cmd_ns;
512  if (send_cmd1_col) cmd1 = col_cmd_ns;
513  end
514  endgenerate
515 
516  reg [OUT_CMD_WIDTH-1:0] cmd2 = {OUT_CMD_WIDTH{1'b1}};
517  reg [OUT_CMD_WIDTH-1:0] cmd3 = {OUT_CMD_WIDTH{1'b1}};
518  generate
519  if (nCK_PER_CLK == 4)
520  always @(send_cmd2_row or send_cmd2_col or send_cmd2_pre or send_cmd3_col or row_cmd_ns or col_cmd_ns or pre_cmd_ns) begin
521  cmd2 = {OUT_CMD_WIDTH{1'b1}};
522  cmd3 = {OUT_CMD_WIDTH{1'b1}};
523  if (send_cmd2_row) cmd2 = row_cmd_ns;
524  if (send_cmd2_col) cmd2 = col_cmd_ns;
525  if (send_cmd2_pre) cmd2 = pre_cmd_ns;
526  if (send_cmd3_col) cmd3 = col_cmd_ns;
527  end
528  endgenerate
529 
530  // Output command bus 0.
531  wire [RANK_WIDTH-1:0] ra0;
532 
533  // assign address
534  assign {ra0, mc_bank[BANK_WIDTH-1:0], mc_address[ROW_WIDTH-1:0], mc_ras_n[0], mc_cas_n[0], mc_we_n[0]} = cmd0;
535 
536  // Output command bus 1.
537  wire [RANK_WIDTH-1:0] ra1;
538 
539  // assign address
540  assign {ra1, mc_bank[2*BANK_WIDTH-1:BANK_WIDTH], mc_address[2*ROW_WIDTH-1:ROW_WIDTH], mc_ras_n[1], mc_cas_n[1], mc_we_n[1]} = cmd1;
541 
542  wire [RANK_WIDTH-1:0] ra2;
543  wire [RANK_WIDTH-1:0] ra3;
544 generate
545 if(nCK_PER_CLK == 4) begin
546  // Output command bus 2.
547 
548  // assign address
549  assign {ra2, mc_bank[3*BANK_WIDTH-1:2*BANK_WIDTH], mc_address[3*ROW_WIDTH-1:2*ROW_WIDTH], mc_ras_n[2], mc_cas_n[2], mc_we_n[2]} = cmd2;
550 
551  // Output command bus 3.
552 
553  // assign address
554  assign {ra3, mc_bank[4*BANK_WIDTH-1:3*BANK_WIDTH], mc_address[4*ROW_WIDTH-1:3*ROW_WIDTH], mc_ras_n[3], mc_cas_n[3], mc_we_n[3]} =
555  cmd3;
556 
557 end
558 endgenerate
559 
560 
561 generate
562  if(CKE_ODT_AUX == "FALSE")begin
563  assign mc_cke[0] = cke0;
564  assign mc_cke[1] = cke_ns;
565  if(nCK_PER_CLK == 4) begin
566  assign mc_cke[2] = cke_ns;
567  assign mc_cke[3] = cke_ns;
568  end
569  end
570 endgenerate
571 
572 // Output cs busses.
573 
574  localparam ONE = {nCS_PER_RANK{1'b1}};
575 
576  wire [(CS_WIDTH*nCS_PER_RANK)-1:0] cs_one_hot =
577  {{CS_WIDTH{1'b0}},ONE};
578  assign mc_cs_n[CS_WIDTH*nCS_PER_RANK -1 :0 ] =
579  {(~(cs_one_hot << (nCS_PER_RANK*ra0)) | {CS_WIDTH*nCS_PER_RANK{~cs_en0}})};
580  assign mc_cs_n[2*CS_WIDTH*nCS_PER_RANK -1 : CS_WIDTH*nCS_PER_RANK ] =
581  {(~(cs_one_hot << (nCS_PER_RANK*ra1)) | {CS_WIDTH*nCS_PER_RANK{~cs_en1}})};
582 
583  generate
584  if(nCK_PER_CLK == 4) begin
585 
586  assign mc_cs_n[3*CS_WIDTH*nCS_PER_RANK -1 :2*CS_WIDTH*nCS_PER_RANK ] =
587  {(~(cs_one_hot << (nCS_PER_RANK*ra2)) | {CS_WIDTH*nCS_PER_RANK{~cs_en2}})};
588 
589  assign mc_cs_n[4*CS_WIDTH*nCS_PER_RANK -1 :3*CS_WIDTH*nCS_PER_RANK ] =
590  {(~(cs_one_hot << (nCS_PER_RANK*ra3)) | {CS_WIDTH*nCS_PER_RANK{~cs_en3}})};
591 
592  end
593  endgenerate
594 
595  // Output rnk_config info.
596 
597  reg [RANK_WIDTH-1:0] rnk_config_ns;
598  reg [RANK_WIDTH-1:0] rnk_config_r;
599  always @(/*AS**/grant_config_r
600  or rnk_config_r or rnk_config_strobe or req_rank_r or rst) begin
601  if (rst) rnk_config_ns = {RANK_WIDTH{1'b0}};
602  else begin
603  rnk_config_ns = rnk_config_r;
604  if (rnk_config_strobe)
605  for (i=0; i<nBANK_MACHS; i=i+1)
606  if (grant_config_r[i]) rnk_config_ns = req_rank_r[(RANK_WIDTH*i)+:RANK_WIDTH];
607  end
608  end
609 
610  always @(posedge clk) rnk_config_r <= #TCQ rnk_config_ns;
611  assign rnk_config = rnk_config_ns;
612 
613 // Generate ODT signals.
614 
615  wire [CS_WIDTH-1:0] col_ra_one_hot = cs_one_hot << col_ra;
616 
617  wire slot_0_select = (nSLOTS == 1) ? |(col_ra_one_hot & slot_0_present)
618  : (slot_0_present[2] & slot_0_present[0]) ?
619  |(col_ra_one_hot[CS_WIDTH-1:0] & {slot_0_present[2],
620  slot_0_present[0]}) : (slot_0_present[0])?
621  col_ra_one_hot[0] : 1'b0;
622  wire slot_0_read = EVEN_CWL_2T_MODE == "ON" ?
623  slot_0_select && col_rd_wr_r :
624  slot_0_select && col_rd_wr_ns;
625  wire slot_0_write = EVEN_CWL_2T_MODE == "ON" ?
626  slot_0_select && ~col_rd_wr_r :
627  slot_0_select && ~col_rd_wr_ns;
628 
629  reg [1:0] slot_1_population = 2'b0;
630 
631  reg[1:0] slot_0_population;
632  always @(/*AS**/slot_0_present) begin
633  slot_0_population = 2'b0;
634  for (i=0; i<8; i=i+1)
635  if (~slot_0_population[1])
636  if (slot_0_present[i] == 1'b1) slot_0_population =
637  slot_0_population + 2'b1;
638  end
639 
640  // ODT on in slot 0 for writes to slot 0 (and R/W to slot 1 for DDR3)
641  wire slot_0_odt = (DRAM_TYPE == "DDR3") ? ~slot_0_read : slot_0_write;
642  assign mc_aux_out0[1] = slot_0_odt & sent_col; // Only send for COL cmds
643 
644  generate
645  if (nSLOTS > 1) begin : slot_1_configured
646  wire slot_1_select = (slot_1_present[3] & slot_1_present[1])?
647  |({col_ra_one_hot[slot_0_population+1],
648  col_ra_one_hot[slot_0_population]}) :
649  (slot_1_present[1]) ? col_ra_one_hot[slot_0_population] :1'b0;
650  wire slot_1_read = EVEN_CWL_2T_MODE == "ON" ?
651  slot_1_select && col_rd_wr_r :
652  slot_1_select && col_rd_wr_ns;
653  wire slot_1_write = EVEN_CWL_2T_MODE == "ON" ?
654  slot_1_select && ~col_rd_wr_r :
655  slot_1_select && ~col_rd_wr_ns;
656 
657  // ODT on in slot 1 for writes to slot 1 (and R/W to slot 0 for DDR3)
658  wire slot_1_odt = (DRAM_TYPE == "DDR3") ? ~slot_1_read : slot_1_write;
659  assign mc_aux_out0[3] = slot_1_odt & sent_col; // Only send for COL cmds
660 
661  end // if (nSLOTS > 1)
662  else begin
663 
664  // Disable slot 1 ODT when not present
665  assign mc_aux_out0[3] = 1'b0;
666 
667  end // else: !if(nSLOTS > 1)
668  endgenerate
669 
670 
671  generate
672  if(CKE_ODT_AUX == "FALSE")begin
673  reg[1:0] mc_aux_out_r ;
674  reg[1:0] mc_aux_out_r_1 ;
675  reg[1:0] mc_aux_out_r_2 ;
676 
677  always@(posedge clk) begin
678  mc_aux_out_r[0] <= #TCQ mc_aux_out0[1] ;
679  mc_aux_out_r[1] <= #TCQ mc_aux_out0[3] ;
680  mc_aux_out_r_1 <= #TCQ mc_aux_out_r ;
681  mc_aux_out_r_2 <= #TCQ mc_aux_out_r_1 ;
682  end
683 
684  if((nCK_PER_CLK == 4) && (nSLOTS > 1 )) begin:odt_high_time_4_1_dslot
685  assign mc_odt[0] = mc_aux_out0[1] | mc_aux_out_r[0] | mc_aux_out_r_1[0];
686  assign mc_odt[1] = mc_aux_out0[3] | mc_aux_out_r[1] | mc_aux_out_r_1[1];
687  end else if(nCK_PER_CLK == 4) begin:odt_high_time_4_1
688  assign mc_odt[0] = mc_aux_out0[1] | mc_aux_out_r[0] ;
689  assign mc_odt[1] = mc_aux_out0[3] | mc_aux_out_r[1] ;
690  end else if(nCK_PER_CLK == 2) begin:odt_high_time_2_1
691  assign mc_odt[0] = mc_aux_out0[1] | mc_aux_out_r[0] | mc_aux_out_r_1[0] | mc_aux_out_r_2[0] ;
692  assign mc_odt[1] = mc_aux_out0[3] | mc_aux_out_r[1] | mc_aux_out_r_1[1] | mc_aux_out_r_2[1] ;
693  end
694  end
695  endgenerate
696 
697 
698 endmodule