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

Subversion Repositories usb_fpga_2_14

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
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              : 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
 
75
module mig_7series_v2_3_arb_select #
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

powered by: WebSVN 2.1.0

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