AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
mig_7series_v1_9_arb_row_col.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_row_col.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 // This block receives request to send row and column commands. These requests
68 // come the individual bank machines. The arbitration winner is selected
69 // and driven back to the bank machines.
70 //
71 // The CS enables are generated. For 2:1 mode, row commands are sent
72 // in the "0" phase, and column commands are sent in the "1" phase.
73 //
74 // In 2T mode, a further arbitration is performed between the row
75 // and column commands. The winner of this arbitration inhibits
76 // arbitration by the loser. The winner is allowed to arbitrate, the loser is
77 // blocked until the next state. The winning address command
78 // is repeated on both the "0" and the "1" phases and the CS
79 // is asserted for just the "1" phase.
80 
81 `timescale 1 ps / 1 ps
82 
84  (
85  parameter TCQ = 100,
86  parameter ADDR_CMD_MODE = "1T",
87  parameter CWL = 5,
88  parameter EARLY_WR_DATA_ADDR = "OFF",
89  parameter nBANK_MACHS = 4,
90  parameter nCK_PER_CLK = 2,
91  parameter nRAS = 37500, // ACT->PRE cmd period (CKs)
92  parameter nRCD = 12500, // ACT->R/W delay (CKs)
93  parameter nWR = 6 // Write recovery (CKs)
94  )
95  (/*AUTOARG**/
96  // Outputs
97  grant_row_r, grant_pre_r, sent_row, sending_row, sending_pre, grant_config_r,
98  rnk_config_strobe, rnk_config_valid_r, grant_col_r,
99  sending_col, sent_col, sent_col_r, grant_col_wr, send_cmd0_row, send_cmd0_col,
100  send_cmd1_row, send_cmd1_col, send_cmd2_row, send_cmd2_col, send_cmd2_pre,
101  send_cmd3_col, col_channel_offset, cs_en0, cs_en1, cs_en2, cs_en3,
102  insert_maint_r1, rnk_config_kill_rts_col,
103  // Inputs
104  clk, rst, rts_row, rts_pre, insert_maint_r, rts_col, rtc, col_rdy_wr
105  );
106 
107  // Create a delay when switching ranks
108  localparam RNK2RNK_DLY = 12;
109  localparam RNK2RNK_DLY_CLKS =
110  (RNK2RNK_DLY / nCK_PER_CLK) + (RNK2RNK_DLY % nCK_PER_CLK ? 1 : 0);
111 
112  input clk;
113  input rst;
114 
115  input [nBANK_MACHS-1:0] rts_row;
116  input insert_maint_r;
117  input [nBANK_MACHS-1:0] rts_col;
118  reg [RNK2RNK_DLY_CLKS-1:0] rnk_config_strobe_r;
119  wire block_grant_row;
120  wire block_grant_col;
121  wire rnk_config_kill_rts_col_lcl =
122  RNK2RNK_DLY_CLKS > 0 ? |rnk_config_strobe_r : 1'b0;
123 
124  output rnk_config_kill_rts_col;
125  assign rnk_config_kill_rts_col = rnk_config_kill_rts_col_lcl;
126 
127  wire [nBANK_MACHS-1:0] col_request;
128  wire granted_col_ns = |col_request;
129  wire [nBANK_MACHS-1:0] row_request =
130  rts_row & {nBANK_MACHS{~insert_maint_r}};
131  wire granted_row_ns = |row_request;
132  generate
133  if (ADDR_CMD_MODE == "2T" && nCK_PER_CLK != 4) begin : row_col_2T_arb
134  assign col_request =
135  rts_col & {nBANK_MACHS{~(rnk_config_kill_rts_col_lcl || insert_maint_r)}};
136 // Give column command priority whenever previous state has no row request.
137  wire [1:0] row_col_grant;
138  wire [1:0] current_master = ~granted_row_ns ? 2'b10 : row_col_grant;
139  wire upd_last_master = ~granted_row_ns || |row_col_grant;
141  (.WIDTH (2))
142  row_col_arb0
143  (.grant_ns (),
144  .grant_r (row_col_grant),
145  .upd_last_master (upd_last_master),
146  .current_master (current_master),
147  .clk (clk),
148  .rst (rst),
149  .req ({granted_row_ns, granted_col_ns}),
150  .disable_grant (1'b0));
151  assign {block_grant_col, block_grant_row} = row_col_grant;
152  end
153  else begin : row_col_1T_arb
154  assign col_request = rts_col & {nBANK_MACHS{~rnk_config_kill_rts_col_lcl}};
155  assign block_grant_row = 1'b0;
156  assign block_grant_col = 1'b0;
157  end
158  endgenerate
159 
160 // Row address/command arbitration.
161  wire[nBANK_MACHS-1:0] grant_row_r_lcl;
162  output wire[nBANK_MACHS-1:0] grant_row_r;
163  assign grant_row_r = grant_row_r_lcl;
164  reg granted_row_r;
165  always @(posedge clk) granted_row_r <= #TCQ granted_row_ns;
166  wire sent_row_lcl = granted_row_r && ~block_grant_row;
167  output wire sent_row;
168  assign sent_row = sent_row_lcl;
170  (.WIDTH (nBANK_MACHS))
171  row_arb0
172  (.grant_ns (),
173  .grant_r (grant_row_r_lcl[nBANK_MACHS-1:0]),
174  .upd_last_master (sent_row_lcl),
175  .current_master (grant_row_r_lcl[nBANK_MACHS-1:0]),
176  .clk (clk),
177  .rst (rst),
178  .req (row_request),
179  .disable_grant (1'b0));
180 
181  output wire [nBANK_MACHS-1:0] sending_row;
182  assign sending_row = grant_row_r_lcl & {nBANK_MACHS{~block_grant_row}};
183 
184  // Precharge arbitration for 4:1 mode
185  input [nBANK_MACHS-1:0] rts_pre;
186  output wire[nBANK_MACHS-1:0] grant_pre_r;
187  output wire [nBANK_MACHS-1:0] sending_pre;
188  wire sent_pre_lcl;
189 
190  generate
191 
192  if((nCK_PER_CLK == 4) && (ADDR_CMD_MODE != "2T")) begin : pre_4_1_1T_arb
193 
194  reg granted_pre_r;
195  wire[nBANK_MACHS-1:0] grant_pre_r_lcl;
196 
197  wire granted_pre_ns = |rts_pre;
198  assign grant_pre_r = grant_pre_r_lcl;
199  always @(posedge clk) granted_pre_r <= #TCQ granted_pre_ns;
200  assign sent_pre_lcl = granted_pre_r;
201  assign sending_pre = grant_pre_r_lcl;
202 
204  (.WIDTH (nBANK_MACHS))
205  pre_arb0
206  (.grant_ns (),
207  .grant_r (grant_pre_r_lcl[nBANK_MACHS-1:0]),
208  .upd_last_master (sent_pre_lcl),
209  .current_master (grant_pre_r_lcl[nBANK_MACHS-1:0]),
210  .clk (clk),
211  .rst (rst),
212  .req (rts_pre),
213  .disable_grant (1'b0));
214 
215  end
216 
217  endgenerate
218 
219 `ifdef MC_SVA
220  all_bank_machines_row_arb:
221  cover property (@(posedge clk) (~rst && &rts_row));
222 `endif
223 
224 // Rank config arbitration.
225  input [nBANK_MACHS-1:0] rtc;
226  wire [nBANK_MACHS-1:0] grant_config_r_lcl;
227  output wire [nBANK_MACHS-1:0] grant_config_r;
228  assign grant_config_r = grant_config_r_lcl;
229  wire upd_rnk_config_last_master;
231  (.WIDTH (nBANK_MACHS))
232  config_arb0
233  (.grant_ns (),
234  .grant_r (grant_config_r_lcl[nBANK_MACHS-1:0]),
235  .upd_last_master (upd_rnk_config_last_master),
236  .current_master (grant_config_r_lcl[nBANK_MACHS-1:0]),
237  .clk (clk),
238  .rst (rst),
239  .req (rtc[nBANK_MACHS-1:0]),
240  .disable_grant (1'b0));
241 
242 `ifdef MC_SVA
243  all_bank_machines_config_arb: cover property (@(posedge clk) (~rst && &rtc));
244 `endif
245 
246  wire rnk_config_strobe_ns = ~rnk_config_strobe_r[0] && |rtc && ~granted_col_ns;
247  always @(posedge clk) rnk_config_strobe_r[0] <= #TCQ rnk_config_strobe_ns;
248 
249  genvar i;
250  generate
251  for(i = 1; i < RNK2RNK_DLY_CLKS; i = i + 1)
252  always @(posedge clk)
253  rnk_config_strobe_r[i] <= #TCQ rnk_config_strobe_r[i-1];
254  endgenerate
255 
256  output wire rnk_config_strobe;
257  assign rnk_config_strobe = rnk_config_strobe_r[0];
258 
259  assign upd_rnk_config_last_master = rnk_config_strobe_r[0];
260 
261 // Generate rnk_config_valid.
262  reg rnk_config_valid_r_lcl;
263  wire rnk_config_valid_ns;
264  assign rnk_config_valid_ns =
265  ~rst && (rnk_config_valid_r_lcl || rnk_config_strobe_ns);
266  always @(posedge clk) rnk_config_valid_r_lcl <= #TCQ rnk_config_valid_ns;
267  output wire rnk_config_valid_r;
268  assign rnk_config_valid_r = rnk_config_valid_r_lcl;
269 
270 // Column address/command arbitration.
271  wire [nBANK_MACHS-1:0] grant_col_r_lcl;
272  output wire [nBANK_MACHS-1:0] grant_col_r;
273  assign grant_col_r = grant_col_r_lcl;
274  reg granted_col_r;
275  always @(posedge clk) granted_col_r <= #TCQ granted_col_ns;
276  wire sent_col_lcl;
278  (.WIDTH (nBANK_MACHS))
279  col_arb0
280  (.grant_ns (),
281  .grant_r (grant_col_r_lcl[nBANK_MACHS-1:0]),
282  .upd_last_master (sent_col_lcl),
283  .current_master (grant_col_r_lcl[nBANK_MACHS-1:0]),
284  .clk (clk),
285  .rst (rst),
286  .req (col_request),
287  .disable_grant (1'b0));
288 
289 `ifdef MC_SVA
290  all_bank_machines_col_arb:
291  cover property (@(posedge clk) (~rst && &rts_col));
292 `endif
293 
294  output wire [nBANK_MACHS-1:0] sending_col;
295  assign sending_col = grant_col_r_lcl & {nBANK_MACHS{~block_grant_col}};
296  assign sent_col_lcl = granted_col_r && ~block_grant_col;
297  reg sent_col_lcl_r = 1'b0;
298  always @(posedge clk) sent_col_lcl_r <= #TCQ sent_col_lcl;
299  output wire sent_col;
300  assign sent_col = sent_col_lcl;
301  output wire sent_col_r;
302  assign sent_col_r = sent_col_lcl_r;
303 
304  // If we need early wr_data_addr because ECC is on, arbitrate
305  // to see which bank machine might sent the next wr_data_addr;
306  input [nBANK_MACHS-1:0] col_rdy_wr;
307  output wire [nBANK_MACHS-1:0] grant_col_wr;
308  generate
309  if (EARLY_WR_DATA_ADDR == "OFF") begin : early_wr_addr_arb_off
310  assign grant_col_wr = {nBANK_MACHS{1'b0}};
311  end
312  else begin : early_wr_addr_arb_on
313  wire [nBANK_MACHS-1:0] grant_col_wr_raw;
315  (.WIDTH (nBANK_MACHS))
316  col_arb0
317  (.grant_ns (grant_col_wr_raw),
318  .grant_r (),
319  .upd_last_master (sent_col_lcl),
320  .current_master (grant_col_r_lcl[nBANK_MACHS-1:0]),
321  .clk (clk),
322  .rst (rst),
323  .req (col_rdy_wr),
324  .disable_grant (1'b0));
325  reg [nBANK_MACHS-1:0] grant_col_wr_r;
326  wire [nBANK_MACHS-1:0] grant_col_wr_ns = granted_col_ns
327  ? grant_col_wr_raw
328  : grant_col_wr_r;
329  always @(posedge clk) grant_col_wr_r <= #TCQ grant_col_wr_ns;
330  assign grant_col_wr = grant_col_wr_ns;
331  end // block: early_wr_addr_arb_on
332  endgenerate
333 
334  output reg send_cmd0_row = 1'b0;
335  output reg send_cmd0_col = 1'b0;
336  output reg send_cmd1_row = 1'b0;
337  output reg send_cmd1_col = 1'b0;
338  output reg send_cmd2_row = 1'b0;
339  output reg send_cmd2_col = 1'b0;
340  output reg send_cmd2_pre = 1'b0;
341  output reg send_cmd3_col = 1'b0;
342 
343  output reg cs_en0 = 1'b0;
344  output reg cs_en1 = 1'b0;
345  output reg cs_en2 = 1'b0;
346  output reg cs_en3 = 1'b0;
347 
348  output wire [5:0] col_channel_offset;
349 
350  reg insert_maint_r1_lcl;
351  always @(posedge clk) insert_maint_r1_lcl <= #TCQ insert_maint_r;
352  output wire insert_maint_r1;
353  assign insert_maint_r1 = insert_maint_r1_lcl;
354 
355  wire sent_row_or_maint = sent_row_lcl || insert_maint_r1_lcl;
356  reg sent_row_or_maint_r = 1'b0;
357  always @(posedge clk) sent_row_or_maint_r <= #TCQ sent_row_or_maint;
358  generate
359  case ({(nCK_PER_CLK == 4), (nCK_PER_CLK == 2), (ADDR_CMD_MODE == "2T")})
360  3'b000 : begin : one_one_not2T
361  end
362  3'b001 : begin : one_one_2T
363  end
364  3'b010 : begin : two_one_not2T
365 
366  if(!(CWL % 2)) begin // Place column commands on slot 0 for even CWL
367 
368  always @(sent_col_lcl) begin
369  cs_en0 = sent_col_lcl;
370  send_cmd0_col = sent_col_lcl;
371  end
372 
373  always @(sent_row_or_maint) begin
374  cs_en1 = sent_row_or_maint;
375  send_cmd1_row = sent_row_or_maint;
376  end
377 
378  assign col_channel_offset = 0;
379 
380  end
381 
382  else begin // Place column commands on slot 1 for odd CWL
383 
384  always @(sent_row_or_maint) begin
385  cs_en0 = sent_row_or_maint;
386  send_cmd0_row = sent_row_or_maint;
387  end
388 
389  always @(sent_col_lcl) begin
390  cs_en1 = sent_col_lcl;
391  send_cmd1_col = sent_col_lcl;
392  end
393 
394  assign col_channel_offset = 1;
395 
396  end
397 
398  end
399  3'b011 : begin : two_one_2T
400 
401  if(!(CWL % 2)) begin // Place column commands on slot 1->0 for even CWL
402 
403  always @(sent_row_or_maint_r or sent_col_lcl_r)
404  cs_en0 = sent_row_or_maint_r || sent_col_lcl_r;
405 
406  always @(sent_row_or_maint or sent_row_or_maint_r) begin
407  send_cmd0_row = sent_row_or_maint_r;
408  send_cmd1_row = sent_row_or_maint;
409  end
410 
411  always @(sent_col_lcl or sent_col_lcl_r) begin
412  send_cmd0_col = sent_col_lcl_r;
413  send_cmd1_col = sent_col_lcl;
414  end
415 
416  assign col_channel_offset = 0;
417 
418  end
419 
420  else begin // Place column commands on slot 0->1 for odd CWL
421 
422  always @(sent_col_lcl or sent_row_or_maint)
423  cs_en1 = sent_row_or_maint || sent_col_lcl;
424 
425  always @(sent_row_or_maint) begin
426  send_cmd0_row = sent_row_or_maint;
427  send_cmd1_row = sent_row_or_maint;
428  end
429 
430  always @(sent_col_lcl) begin
431  send_cmd0_col = sent_col_lcl;
432  send_cmd1_col = sent_col_lcl;
433  end
434 
435  assign col_channel_offset = 1;
436 
437  end
438 
439  end
440  3'b100 : begin : four_one_not2T
441 
442  if(!(CWL % 2)) begin // Place column commands on slot 0 for even CWL
443 
444  always @(sent_col_lcl) begin
445  cs_en0 = sent_col_lcl;
446  send_cmd0_col = sent_col_lcl;
447  end
448 
449  always @(sent_row_or_maint) begin
450  cs_en1 = sent_row_or_maint;
451  send_cmd1_row = sent_row_or_maint;
452  end
453 
454  assign col_channel_offset = 0;
455 
456  end
457 
458  else begin // Place column commands on slot 1 for odd CWL
459 
460  always @(sent_row_or_maint) begin
461  cs_en0 = sent_row_or_maint;
462  send_cmd0_row = sent_row_or_maint;
463  end
464 
465  always @(sent_col_lcl) begin
466  cs_en1 = sent_col_lcl;
467  send_cmd1_col = sent_col_lcl;
468  end
469 
470  assign col_channel_offset = 1;
471 
472  end
473 
474  always @(sent_pre_lcl) begin
475  cs_en2 = sent_pre_lcl;
476  send_cmd2_pre = sent_pre_lcl;
477  end
478 
479  end
480  3'b101 : begin : four_one_2T
481 
482  if(!(CWL % 2)) begin // Place column commands on slot 3->0 for even CWL
483 
484  always @(sent_col_lcl or sent_col_lcl_r) begin
485  cs_en0 = sent_col_lcl_r;
486  send_cmd0_col = sent_col_lcl_r;
487  send_cmd3_col = sent_col_lcl;
488  end
489 
490  always @(sent_row_or_maint) begin
491  cs_en2 = sent_row_or_maint;
492  send_cmd1_row = sent_row_or_maint;
493  send_cmd2_row = sent_row_or_maint;
494  end
495 
496  assign col_channel_offset = 0;
497 
498  end
499 
500  else begin // Place column commands on slot 2->3 for odd CWL
501 
502  always @(sent_row_or_maint) begin
503  cs_en1 = sent_row_or_maint;
504  send_cmd0_row = sent_row_or_maint;
505  send_cmd1_row = sent_row_or_maint;
506  end
507 
508  always @(sent_col_lcl) begin
509  cs_en3 = sent_col_lcl;
510  send_cmd2_col = sent_col_lcl;
511  send_cmd3_col = sent_col_lcl;
512  end
513 
514  assign col_channel_offset = 3;
515 
516  end
517 
518  end
519  endcase
520  endgenerate
521 
522 
523 
524 endmodule