AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
mig_7series_v1_9_bank_state.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 : bank_state.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 // Primary bank state machine. All bank specific timing is generated here.
68 //
69 // Conceptually, when a bank machine is assigned a request, conflicts are
70 // checked. If there is a conflict, then the new request is added
71 // to the queue for that rank-bank.
72 //
73 // Eventually, that request will find itself at the head of the queue for
74 // its rank-bank. Forthwith, the bank machine will begin arbitration to send an
75 // activate command to the DRAM. Once arbitration is successful and the
76 // activate is sent, the row state machine waits the RCD delay. The RAS
77 // counter is also started when the activate is sent.
78 //
79 // Upon completion of the RCD delay, the bank state machine will begin
80 // arbitration for sending out the column command. Once the column
81 // command has been sent, the bank state machine waits the RTP latency, and
82 // if the command is a write, the RAS counter is loaded with the WR latency.
83 //
84 // When the RTP counter reaches zero, the pre charge wait state is entered.
85 // Once the RAS timer reaches zero, arbitration to send a precharge command
86 // begins.
87 //
88 // Upon successful transmission of the precharge command, the bank state
89 // machine waits the precharge period and then rejoins the idle list.
90 //
91 // For an open rank-bank hit, a bank machine passes management of the rank-bank to
92 // a bank machine that is managing the subsequent request to the same page. A bank
93 // machine can either be a "passer" or a "passee" in this handoff. There
94 // are two conditions that have to occur before an open bank can be passed.
95 // A spatial condition, ie same rank-bank and row address. And a temporal condition,
96 // ie the passee has completed it work with the bank, but has not issued a precharge.
97 //
98 // The spatial condition is signalled by pass_open_bank_ns. The temporal condition
99 // is when the column command is issued, or when the bank_wait_in_progress
100 // signal is true. Bank_wait_in_progress is true when the RTP timer is not
101 // zero, or when the RAS/WR timer is not zero and the state machine is waiting
102 // to send out a precharge command.
103 //
104 // On an open bank pass, the passer transitions from the temporal condition
105 // noted above and performs the end of request processing and eventually lands
106 // in the act_wait_r state.
107 //
108 // On an open bank pass, the passee lands in the col_wait_r state and waits
109 // for its chance to send out a column command.
110 //
111 // Since there is a single data bus shared by all columns in all ranks, there
112 // is a single column machine. The column machine is primarily in charge of
113 // managing the timing on the DQ data bus. It reserves states for data transfer,
114 // driver turnaround states, and preambles. It also has the ability to add
115 // additional programmable delay for read to write changeovers. This read to write
116 // delay is generated in the column machine which inhibits writes via the
117 // inhbt_wr signal.
118 //
119 // There is a rank machine for every rank. The rank machines are responsible
120 // for enforcing rank specific timing such as FAW, and WTR. RRD is guaranteed
121 // in the bank machine since it is closely coupled to the operation of the
122 // bank machine and is timing critical.
123 //
124 // Since a bank machine can be working on a request for any rank, all rank machines
125 // inhibits are input to all bank machines. Based on the rank of the current
126 // request, each bank machine selects the rank information corresponding
127 // to the rank of its current request.
128 //
129 // Since driver turnaround states and WTR delays are so severe with DDRIII, the
130 // memory interface has the ability to promote requests that use the same
131 // driver as the most recent request. There is logic in this block that
132 // detects when the driver for its request is the same as the driver for
133 // the most recent request. In such a case, this block will send out special
134 // "same" request early enough to eliminate dead states when there is no
135 // driver changeover.
136 
137 
138 `timescale 1ps/1ps
139 `define BM_SHARED_BV (ID+nBANK_MACHS-1):(ID+1)
140 
142  (
143  parameter TCQ = 100,
144  parameter ADDR_CMD_MODE = "1T",
145  parameter BM_CNT_WIDTH = 2,
146  parameter BURST_MODE = "8",
147  parameter CWL = 5,
148  parameter DATA_BUF_ADDR_WIDTH = 8,
149  parameter DRAM_TYPE = "DDR3",
150  parameter ECC = "OFF",
151  parameter ID = 0,
152  parameter nBANK_MACHS = 4,
153  parameter nCK_PER_CLK = 2,
154  parameter nOP_WAIT = 0,
155  parameter nRAS_CLKS = 10,
156  parameter nRP = 10,
157  parameter nRTP = 4,
158  parameter nRCD = 5,
159  parameter nWTP_CLKS = 5,
160  parameter ORDERING = "NORM",
161  parameter RANKS = 4,
162  parameter RANK_WIDTH = 4,
163  parameter RAS_TIMER_WIDTH = 5,
164  parameter STARVE_LIMIT = 2
165  )
166  (/*AUTOARG**/
167  // Outputs
168  start_rcd, act_wait_r, rd_half_rmw, ras_timer_ns, end_rtp,
169  bank_wait_in_progress, start_pre_wait, op_exit_req, pre_wait_r,
170  allow_auto_pre, precharge_bm_end, demand_act_priority, rts_row,
171  act_this_rank_r, demand_priority, col_rdy_wr, rts_col, wr_this_rank_r,
172  rd_this_rank_r, rts_pre, rtc,
173  // Inputs
174  clk, rst, bm_end, pass_open_bank_r, sending_row, sending_pre, rcv_open_bank,
175  sending_col, rd_wr_r, req_wr_r, rd_data_addr, req_data_buf_addr_r,
176  phy_rddata_valid, rd_rmw, ras_timer_ns_in, rb_hit_busies_r, idle_r,
177  passing_open_bank, low_idle_cnt_r, op_exit_grant, tail_r,
178  auto_pre_r, pass_open_bank_ns, req_rank_r, req_rank_r_in,
179  start_rcd_in, inhbt_act_faw_r, wait_for_maint_r, head_r, sent_row,
180  demand_act_priority_in, order_q_zero, sent_col, q_has_rd,
181  q_has_priority, req_priority_r, idle_ns, demand_priority_in, inhbt_rd,
182  inhbt_wr, dq_busy_data, rnk_config_strobe, rnk_config_valid_r, rnk_config,
183  rnk_config_kill_rts_col, phy_mc_cmd_full, phy_mc_ctl_full, phy_mc_data_full
184  );
185 
186  function integer clogb2 (input integer size); // ceiling logb2
187  begin
188  size = size - 1;
189  for (clogb2=1; size>1; clogb2=clogb2+1)
190  size = size >> 1;
191  end
192  endfunction // clogb2
193 
194  input clk;
195  input rst;
196 
197 // Activate wait state machine.
198  input bm_end;
199  reg bm_end_r1;
200  always @(posedge clk) bm_end_r1 <= #TCQ bm_end;
201 
202  reg col_wait_r;
203 
204  input pass_open_bank_r;
205  input sending_row;
206  reg act_wait_r_lcl;
207  input rcv_open_bank;
208  wire start_rcd_lcl = act_wait_r_lcl && sending_row;
209  output wire start_rcd;
210  assign start_rcd = start_rcd_lcl;
211  wire act_wait_ns = rst ||
212  ((act_wait_r_lcl && ~start_rcd_lcl && ~rcv_open_bank) ||
213  bm_end_r1 || (pass_open_bank_r && bm_end));
214  always @(posedge clk) act_wait_r_lcl <= #TCQ act_wait_ns;
215  output wire act_wait_r;
216  assign act_wait_r = act_wait_r_lcl;
217 
218 // RCD timer
219 //
220 // When CWL is even, CAS commands are issued on slot 0 and RAS commands are
221 // issued on slot 1. This implies that the RCD can never expire in the same
222 // cycle as the RAS (otherwise the CAS for a given transaction would precede
223 // the RAS). Similarly, this can also cause premature expiration for longer
224 // RCD. An offset must be added to RCD before translating it to the FPGA clock
225 // domain. In this mode, CAS are on the first DRAM clock cycle corresponding to
226 // a given FPGA cycle. In 2:1 mode add 2 to generate this offset aligned to
227 // the FPGA cycle. Likewise, add 4 to generate an aligned offset in 4:1 mode.
228 //
229 // When CWL is odd, RAS commands are issued on slot 0 and CAS commands are
230 // issued on slot 1. There is a natural 1 cycle seperation between RAS and CAS
231 // in the DRAM clock domain so the RCD can expire in the same FPGA cycle as the
232 // RAS command. In 2:1 mode, there are only 2 slots so direct translation
233 // correctly places the CAS with respect to the corresponding RAS. In 4:1 mode,
234 // there are two slots after CAS, so 2 is added to shift the timer into the
235 // next FPGA cycle for cases that can't expire in the current cycle.
236 //
237 // In 2T mode, the offset from ROW to COL commands is fixed at 2. In 2:1 mode,
238 // It is sufficient to translate to the half-rate domain and add the remainder.
239 // In 4:1 mode, we must translate to the quarter-rate domain and add an
240 // additional fabric cycle only if the remainder exceeds the fixed offset of 2
241 
242  localparam nRCD_CLKS =
243  nCK_PER_CLK == 1 ?
244  nRCD :
245  nCK_PER_CLK == 2 ?
246  ADDR_CMD_MODE == "2T" ?
247  (nRCD/2) + (nRCD%2) :
248  CWL % 2 ?
249  (nRCD/2) :
250  (nRCD+2) / 2 :
251 // (nCK_PER_CLK == 4)
252  ADDR_CMD_MODE == "2T" ?
253  (nRCD/4) + (nRCD%4 > 2 ? 1 : 0) :
254  CWL % 2 ?
255  (nRCD-2 ? (nRCD-2) / 4 + 1 : 1) :
256  nRCD/4 + 1;
257 
258  localparam nRCD_CLKS_M2 = (nRCD_CLKS-2 <0) ? 0 : nRCD_CLKS-2;
259  localparam RCD_TIMER_WIDTH = clogb2(nRCD_CLKS_M2+1);
260  localparam ZERO = 0;
261  localparam ONE = 1;
262  reg [RCD_TIMER_WIDTH-1:0] rcd_timer_r = {RCD_TIMER_WIDTH{1'b0}};
263  reg end_rcd;
264  reg rcd_active_r = 1'b0;
265 
266  generate
267  if (nRCD_CLKS <= 2) begin : rcd_timer_leq_2
268  always @(/*AS**/start_rcd_lcl) end_rcd = start_rcd_lcl;
269  end
270  else if (nRCD_CLKS > 2) begin : rcd_timer_gt_2
271  reg [RCD_TIMER_WIDTH-1:0] rcd_timer_ns;
272  always @(/*AS**/rcd_timer_r or rst or start_rcd_lcl) begin
273  if (rst) rcd_timer_ns = ZERO[RCD_TIMER_WIDTH-1:0];
274  else begin
275  rcd_timer_ns = rcd_timer_r;
276  if (start_rcd_lcl) rcd_timer_ns = nRCD_CLKS_M2[RCD_TIMER_WIDTH-1:0];
277  else if (|rcd_timer_r) rcd_timer_ns =
278  rcd_timer_r - ONE[RCD_TIMER_WIDTH-1:0];
279  end
280  end
281  always @(posedge clk) rcd_timer_r <= #TCQ rcd_timer_ns;
282  wire end_rcd_ns = (rcd_timer_ns == ONE[RCD_TIMER_WIDTH-1:0]);
283  always @(posedge clk) end_rcd = end_rcd_ns;
284  wire rcd_active_ns = |rcd_timer_ns;
285  always @(posedge clk) rcd_active_r <= #TCQ rcd_active_ns;
286  end
287  endgenerate
288 
289 // Figure out if the read that's completing is for an RMW for
290 // this bank machine. Delay by a state if CWL != 8 since the
291 // data is not ready in the RMW buffer for the early write
292 // data fetch that happens with ECC and CWL != 8.
293 // Create a state bit indicating we're waiting for the read
294 // half of the rmw to complete.
295  input sending_col;
296  input rd_wr_r;
297  input req_wr_r;
298  input [DATA_BUF_ADDR_WIDTH-1:0] rd_data_addr;
299  input [DATA_BUF_ADDR_WIDTH-1:0] req_data_buf_addr_r;
300  input phy_rddata_valid;
301  input rd_rmw;
302  reg rmw_rd_done = 1'b0;
303  reg rd_half_rmw_lcl = 1'b0;
304  output wire rd_half_rmw;
305  assign rd_half_rmw = rd_half_rmw_lcl;
306  reg rmw_wait_r = 1'b0;
307  generate
308  if (ECC != "OFF") begin : rmw_on
309 // Delay phy_rddata_valid and rd_rmw by one cycle to align them
310 // to req_data_buf_addr_r so that rmw_wait_r clears properly
311  reg phy_rddata_valid_r;
312  reg rd_rmw_r;
313  always @(posedge clk) begin
314  phy_rddata_valid_r <= #TCQ phy_rddata_valid;
315  rd_rmw_r <= #TCQ rd_rmw;
316  end
317  wire my_rmw_rd_ns = phy_rddata_valid_r && rd_rmw_r &&
318  (rd_data_addr == req_data_buf_addr_r);
319  if (CWL == 8) always @(my_rmw_rd_ns) rmw_rd_done = my_rmw_rd_ns;
320  else always @(posedge clk) rmw_rd_done = #TCQ my_rmw_rd_ns;
321  always @(/*AS**/rd_wr_r or req_wr_r) rd_half_rmw_lcl = req_wr_r && rd_wr_r;
322  wire rmw_wait_ns = ~rst &&
323  ((rmw_wait_r && ~rmw_rd_done) || (rd_half_rmw_lcl && sending_col));
324  always @(posedge clk) rmw_wait_r <= #TCQ rmw_wait_ns;
325  end
326  endgenerate
327 
328 // column wait state machine.
329  wire col_wait_ns = ~rst && ((col_wait_r && ~sending_col) || end_rcd
330  || rcv_open_bank || (rmw_rd_done && rmw_wait_r));
331  always @(posedge clk) col_wait_r <= #TCQ col_wait_ns;
332 
333 // Set up various RAS timer parameters, wires, etc.
334 
335  localparam TWO = 2;
336  output reg [RAS_TIMER_WIDTH-1:0] ras_timer_ns;
337  reg [RAS_TIMER_WIDTH-1:0] ras_timer_r;
338  input [(2*(RAS_TIMER_WIDTH*nBANK_MACHS))-1:0] ras_timer_ns_in;
339  input [(nBANK_MACHS*2)-1:0] rb_hit_busies_r;
340 
341 // On a bank pass, select the RAS timer from the passing bank machine.
342  reg [RAS_TIMER_WIDTH-1:0] passed_ras_timer;
343  integer i;
344  always @(/*AS**/ras_timer_ns_in or rb_hit_busies_r) begin
345  passed_ras_timer = {RAS_TIMER_WIDTH{1'b0}};
346  for (i=ID+1; i<(ID+nBANK_MACHS); i=i+1)
347  if (rb_hit_busies_r[i])
348  passed_ras_timer = ras_timer_ns_in[i*RAS_TIMER_WIDTH+:RAS_TIMER_WIDTH];
349  end
350 
351 // RAS and (reused for) WTP timer. When an open bank is passed, this
352 // timer is passed to the new owner. The existing RAS prevents
353 // an activate from occuring too early.
354 
355 
356  wire start_wtp_timer = sending_col && ~rd_wr_r;
357  input idle_r;
358 
359  always @(/*AS**/bm_end_r1 or ras_timer_r or rst or start_rcd_lcl
360  or start_wtp_timer) begin
361  if (bm_end_r1 || rst) ras_timer_ns = ZERO[RAS_TIMER_WIDTH-1:0];
362  else begin
363  ras_timer_ns = ras_timer_r;
364  if (start_rcd_lcl) ras_timer_ns =
365  nRAS_CLKS[RAS_TIMER_WIDTH-1:0] - TWO[RAS_TIMER_WIDTH-1:0];
366  if (start_wtp_timer) ras_timer_ns =
367  // As the timer is being reused, it is essential to compare
368  // before new value is loaded.
369  (ras_timer_r <= (nWTP_CLKS-2)) ? nWTP_CLKS[RAS_TIMER_WIDTH-1:0] - TWO[RAS_TIMER_WIDTH-1:0]
370  : ras_timer_r - ONE[RAS_TIMER_WIDTH-1:0];
371  if (|ras_timer_r && ~start_wtp_timer) ras_timer_ns =
372  ras_timer_r - ONE[RAS_TIMER_WIDTH-1:0];
373  end
374  end // always @ (...
375 
376  wire [RAS_TIMER_WIDTH-1:0] ras_timer_passed_ns = rcv_open_bank
377  ? passed_ras_timer
378  : ras_timer_ns;
379  always @(posedge clk) ras_timer_r <= #TCQ ras_timer_passed_ns;
380 
381  wire ras_timer_zero_ns = (ras_timer_ns == ZERO[RAS_TIMER_WIDTH-1:0]);
382  reg ras_timer_zero_r;
383  always @(posedge clk) ras_timer_zero_r <= #TCQ ras_timer_zero_ns;
384 
385 // RTP timer. Unless 2T mode, add one for 2:1 mode. This accounts for loss of
386 // one DRAM CK due to column command to row command fixed offset. In 2T mode,
387 // Add the remainder. In 4:1 mode, the fixed offset is -2. Add 2 unless in 2T
388 // mode, in which case we add 1 if the remainder exceeds the fixed offset.
389  localparam nRTP_CLKS = (nCK_PER_CLK == 1)
390  ? nRTP :
391  (nCK_PER_CLK == 2)
392  ? (nRTP/2) + ((ADDR_CMD_MODE == "2T") ? nRTP%2 : 1) :
393  (nRTP/4) + ((ADDR_CMD_MODE == "2T") ? (nRTP%4 > 2 ? 2 : 1) : 2);
394  localparam nRTP_CLKS_M1 = ((nRTP_CLKS-1) <= 0) ? 0 : nRTP_CLKS-1;
395  localparam RTP_TIMER_WIDTH = clogb2(nRTP_CLKS_M1 + 1);
396  reg [RTP_TIMER_WIDTH-1:0] rtp_timer_ns;
397  reg [RTP_TIMER_WIDTH-1:0] rtp_timer_r;
398  wire sending_col_not_rmw_rd = sending_col && ~rd_half_rmw_lcl;
399  always @(/*AS**/pass_open_bank_r or rst or rtp_timer_r
400  or sending_col_not_rmw_rd) begin
401  rtp_timer_ns = rtp_timer_r;
402  if (rst || pass_open_bank_r)
403  rtp_timer_ns = ZERO[RTP_TIMER_WIDTH-1:0];
404  else begin
405  if (sending_col_not_rmw_rd)
406  rtp_timer_ns = nRTP_CLKS_M1[RTP_TIMER_WIDTH-1:0];
407  if (|rtp_timer_r) rtp_timer_ns = rtp_timer_r - ONE[RTP_TIMER_WIDTH-1:0];
408  end
409  end
410  always @(posedge clk) rtp_timer_r <= #TCQ rtp_timer_ns;
411 
412  wire end_rtp_lcl = ~pass_open_bank_r &&
413  ((rtp_timer_r == ONE[RTP_TIMER_WIDTH-1:0]) ||
414  ((nRTP_CLKS_M1 == 0) && sending_col_not_rmw_rd));
415  output wire end_rtp;
416  assign end_rtp = end_rtp_lcl;
417 
418 // Optionally implement open page mode timer.
419  localparam OP_WIDTH = clogb2(nOP_WAIT + 1);
420  output wire bank_wait_in_progress;
421  output wire start_pre_wait;
422  input passing_open_bank;
423  input low_idle_cnt_r;
424  output wire op_exit_req;
425  input op_exit_grant;
426  input tail_r;
427  output reg pre_wait_r;
428 
429  generate
430  if (nOP_WAIT == 0) begin : op_mode_disabled
431  assign bank_wait_in_progress = sending_col_not_rmw_rd || |rtp_timer_r ||
432  (pre_wait_r && ~ras_timer_zero_r);
433  assign start_pre_wait = end_rtp_lcl;
434  assign op_exit_req = 1'b0;
435  end
436  else begin : op_mode_enabled
437  reg op_wait_r;
438  assign bank_wait_in_progress = sending_col || |rtp_timer_r ||
439  (pre_wait_r && ~ras_timer_zero_r) ||
440  op_wait_r;
441  wire op_active = ~rst && ~passing_open_bank && ((end_rtp_lcl && tail_r)
442  || op_wait_r);
443  wire op_wait_ns = ~op_exit_grant && op_active;
444  always @(posedge clk) op_wait_r <= #TCQ op_wait_ns;
445  assign start_pre_wait = op_exit_grant ||
446  (end_rtp_lcl && ~tail_r && ~passing_open_bank);
447  if (nOP_WAIT == -1)
448  assign op_exit_req = (low_idle_cnt_r && op_active);
449  else begin : op_cnt
450  reg [OP_WIDTH-1:0] op_cnt_r;
451  wire [OP_WIDTH-1:0] op_cnt_ns =
452  (passing_open_bank || op_exit_grant || rst)
453  ? ZERO[OP_WIDTH-1:0]
454  : end_rtp_lcl
455  ? nOP_WAIT[OP_WIDTH-1:0]
456  : |op_cnt_r
457  ? op_cnt_r - ONE[OP_WIDTH-1:0]
458  : op_cnt_r;
459  always @(posedge clk) op_cnt_r <= #TCQ op_cnt_ns;
460  assign op_exit_req = (low_idle_cnt_r && op_active) ||
461  (op_wait_r && ~|op_cnt_r);
462  end
463  end
464  endgenerate
465 
466  output allow_auto_pre;
467  wire allow_auto_pre = act_wait_r_lcl || rcd_active_r ||
468  (col_wait_r && ~sending_col);
469 
470 // precharge wait state machine.
471  input auto_pre_r;
472  wire start_pre;
473  input pass_open_bank_ns;
474  wire pre_wait_ns = ~rst && (~pass_open_bank_ns &&
475  (start_pre_wait || (pre_wait_r && ~start_pre)));
476  always @(posedge clk) pre_wait_r <= #TCQ pre_wait_ns;
477  wire pre_request = pre_wait_r && ras_timer_zero_r && ~auto_pre_r;
478 
479 // precharge timer.
480  localparam nRP_CLKS = (nCK_PER_CLK == 1) ? nRP :
481  (nCK_PER_CLK == 2) ? ((nRP/2) + (nRP%2)) :
482  /*(nCK_PER_CLK == 4)**/ ((nRP/4) + ((nRP%4) ? 1 : 0));
483 
484 // Subtract two because there are a minimum of two fabric states from
485 // end of RP timer until earliest possible arb to send act.
486  localparam nRP_CLKS_M2 = (nRP_CLKS-2 < 0) ? 0 : nRP_CLKS-2;
487  localparam RP_TIMER_WIDTH = clogb2(nRP_CLKS_M2 + 1);
488 
489  input sending_pre;
490  output rts_pre;
491 
492  generate
493 
494  if((nCK_PER_CLK == 4) && (ADDR_CMD_MODE != "2T")) begin
495 
496  assign start_pre = pre_wait_r && ras_timer_zero_r &&
497  (sending_pre || auto_pre_r);
498 
499  assign rts_pre = ~sending_pre && pre_request;
500 
501  end
502 
503  else begin
504 
505  assign start_pre = pre_wait_r && ras_timer_zero_r &&
506  (sending_row || auto_pre_r);
507 
508  assign rts_pre = 1'b0;
509 
510  end
511 
512  endgenerate
513 
514  reg [RP_TIMER_WIDTH-1:0] rp_timer_r = ZERO[RP_TIMER_WIDTH-1:0];
515 
516  generate
517  if (nRP_CLKS_M2 > ZERO) begin : rp_timer
518  reg [RP_TIMER_WIDTH-1:0] rp_timer_ns;
519  always @(/*AS**/rp_timer_r or rst or start_pre)
520  if (rst) rp_timer_ns = ZERO[RP_TIMER_WIDTH-1:0];
521  else begin
522  rp_timer_ns = rp_timer_r;
523  if (start_pre) rp_timer_ns = nRP_CLKS_M2[RP_TIMER_WIDTH-1:0];
524  else if (|rp_timer_r) rp_timer_ns =
525  rp_timer_r - ONE[RP_TIMER_WIDTH-1:0];
526  end
527  always @(posedge clk) rp_timer_r <= #TCQ rp_timer_ns;
528  end // block: rp_timer
529  endgenerate
530 
531  output wire precharge_bm_end;
532  assign precharge_bm_end = (rp_timer_r == ONE[RP_TIMER_WIDTH-1:0]) ||
533  (start_pre && (nRP_CLKS_M2 == ZERO));
534 
535 // Compute RRD related activate inhibit.
536 // Compare this bank machine's rank with others, then
537 // select result based on grant. An alternative is to
538 // select the just issued rank with the grant and simply
539 // compare against this bank machine's rank. However, this
540 // serializes the selection of the rank and the compare processes.
541 // As implemented below, the compare occurs first, then the
542 // selection based on grant. This is faster.
543 
544  input [RANK_WIDTH-1:0] req_rank_r;
545  input [(RANK_WIDTH*nBANK_MACHS*2)-1:0] req_rank_r_in;
546 
547  reg inhbt_act_rrd;
548  input [(nBANK_MACHS*2)-1:0] start_rcd_in;
549 
550  generate
551  integer j;
552  if (RANKS == 1)
553  always @(/*AS**/req_rank_r or req_rank_r_in or start_rcd_in) begin
554  inhbt_act_rrd = 1'b0;
555  for (j=(ID+1); j<(ID+nBANK_MACHS); j=j+1)
556  inhbt_act_rrd = inhbt_act_rrd || start_rcd_in[j];
557  end
558  else begin
559  always @(/*AS**/req_rank_r or req_rank_r_in or start_rcd_in) begin
560  inhbt_act_rrd = 1'b0;
561  for (j=(ID+1); j<(ID+nBANK_MACHS); j=j+1)
562  inhbt_act_rrd = inhbt_act_rrd ||
563  (start_rcd_in[j] &&
564  (req_rank_r_in[(j*RANK_WIDTH)+:RANK_WIDTH] == req_rank_r));
565  end
566  end
567 
568  endgenerate
569 
570 // Extract the activate command inhibit for the rank associated
571 // with this request. FAW and RRD are computed separately so that
572 // gate level timing can be carefully managed.
573  input [RANKS-1:0] inhbt_act_faw_r;
574  wire my_inhbt_act_faw = inhbt_act_faw_r[req_rank_r];
575 
576  input wait_for_maint_r;
577  input head_r;
578  wire act_req = ~idle_r && head_r && act_wait_r && ras_timer_zero_r &&
579  ~wait_for_maint_r;
580 
581 // Implement simple starvation avoidance for act requests. Precharge
582 // requests don't need this because they are never gated off by
583 // timing events such as inhbt_act_rrd. Priority request timeout
584 // is fixed at a single trip around the round robin arbiter.
585 
586  input sent_row;
587  wire rts_act_denied = act_req && sent_row && ~sending_row;
588 
589  reg [BM_CNT_WIDTH-1:0] act_starve_limit_cntr_ns;
590  reg [BM_CNT_WIDTH-1:0] act_starve_limit_cntr_r;
591 
592  generate
593  if (BM_CNT_WIDTH > 1) // Number of Bank Machs > 2
594  begin :BM_MORE_THAN_2
595  always @(/*AS**/act_req or act_starve_limit_cntr_r or rts_act_denied)
596  begin
597  act_starve_limit_cntr_ns = act_starve_limit_cntr_r;
598  if (~act_req)
599  act_starve_limit_cntr_ns = {BM_CNT_WIDTH{1'b0}};
600  else
601  if (rts_act_denied && &act_starve_limit_cntr_r)
602  act_starve_limit_cntr_ns = act_starve_limit_cntr_r +
603  {{BM_CNT_WIDTH-1{1'b0}}, 1'b1};
604  end
605  end
606  else // Number of Bank Machs == 2
607  begin :BM_EQUAL_2
608  always @(/*AS**/act_req or act_starve_limit_cntr_r or rts_act_denied)
609  begin
610  act_starve_limit_cntr_ns = act_starve_limit_cntr_r;
611  if (~act_req)
612  act_starve_limit_cntr_ns = {BM_CNT_WIDTH{1'b0}};
613  else
614  if (rts_act_denied && &act_starve_limit_cntr_r)
615  act_starve_limit_cntr_ns = act_starve_limit_cntr_r +
616  {1'b1};
617  end
618  end
619  endgenerate
620 
621  always @(posedge clk) act_starve_limit_cntr_r <=
622  #TCQ act_starve_limit_cntr_ns;
623 
624  reg demand_act_priority_r;
625  wire demand_act_priority_ns = act_req &&
626  (demand_act_priority_r || (rts_act_denied && &act_starve_limit_cntr_r));
627  always @(posedge clk) demand_act_priority_r <= #TCQ demand_act_priority_ns;
628 
629 `ifdef MC_SVA
630  cover_demand_act_priority:
631  cover property (@(posedge clk) (~rst && demand_act_priority_r));
632 `endif
633 
634  output wire demand_act_priority;
635  assign demand_act_priority = demand_act_priority_r && ~sending_row;
636 
637 // compute act_demanded from other demand_act_priorities
638  input [(nBANK_MACHS*2)-1:0] demand_act_priority_in;
639  reg act_demanded = 1'b0;
640  generate
641  if (nBANK_MACHS > 1) begin : compute_act_demanded
642  always @(demand_act_priority_in[`BM_SHARED_BV])
643  act_demanded = |demand_act_priority_in[`BM_SHARED_BV];
644  end
645  endgenerate
646 
647  wire row_demand_ok = demand_act_priority_r || ~act_demanded;
648 
649 // Generate the Request To Send row arbitation signal.
650  output wire rts_row;
651 
652  generate
653 
654  if((nCK_PER_CLK == 4) && (ADDR_CMD_MODE != "2T"))
655  assign rts_row = ~sending_row && row_demand_ok &&
656  (act_req && ~my_inhbt_act_faw && ~inhbt_act_rrd);
657  else
658  assign rts_row = ~sending_row && row_demand_ok &&
659  ((act_req && ~my_inhbt_act_faw && ~inhbt_act_rrd) ||
660  pre_request);
661  endgenerate
662 
663 `ifdef MC_SVA
664  four_activate_window_wait:
665  cover property (@(posedge clk)
666  (~rst && ~sending_row && act_req && my_inhbt_act_faw));
667  ras_ras_delay_wait:
668  cover property (@(posedge clk)
669  (~rst && ~sending_row && act_req && inhbt_act_rrd));
670 `endif
671 
672 // Provide rank machines early knowledge that this bank machine is
673 // going to send an activate to the rank. In this way, the rank
674 // machines just need to use the sending_row wire to figure out if
675 // they need to keep track of the activate.
676  output reg [RANKS-1:0] act_this_rank_r;
677  reg [RANKS-1:0] act_this_rank_ns;
678  always @(/*AS**/act_wait_r or req_rank_r) begin
679  act_this_rank_ns = {RANKS{1'b0}};
680  for (i = 0; i < RANKS; i = i + 1)
681  act_this_rank_ns[i] = act_wait_r && (i[RANK_WIDTH-1:0] == req_rank_r);
682  end
683  always @(posedge clk) act_this_rank_r <= #TCQ act_this_rank_ns;
684 
685 
686 // Generate request to send column command signal.
687 
688  input order_q_zero;
689  wire req_bank_rdy_ns = order_q_zero && col_wait_r;
690  reg req_bank_rdy_r;
691  always @(posedge clk) req_bank_rdy_r <= #TCQ req_bank_rdy_ns;
692 
693 // Determine is we have been denied a column command request.
694  input sent_col;
695  wire rts_col_denied = req_bank_rdy_r && sent_col && ~sending_col;
696 
697 // Implement a starvation limit counter. Count the number of times a
698 // request to send a column command has been denied.
699  localparam STARVE_LIMIT_CNT = STARVE_LIMIT * nBANK_MACHS;
700  localparam STARVE_LIMIT_WIDTH = clogb2(STARVE_LIMIT_CNT);
701  reg [STARVE_LIMIT_WIDTH-1:0] starve_limit_cntr_r;
702  reg [STARVE_LIMIT_WIDTH-1:0] starve_limit_cntr_ns;
703  always @(/*AS**/col_wait_r or rts_col_denied or starve_limit_cntr_r)
704  if (~col_wait_r)
705  starve_limit_cntr_ns = {STARVE_LIMIT_WIDTH{1'b0}};
706  else
707  if (rts_col_denied && (starve_limit_cntr_r != STARVE_LIMIT_CNT-1))
708  starve_limit_cntr_ns = starve_limit_cntr_r +
709  {{STARVE_LIMIT_WIDTH-1{1'b0}}, 1'b1};
710  else starve_limit_cntr_ns = starve_limit_cntr_r;
711  always @(posedge clk) starve_limit_cntr_r <= #TCQ starve_limit_cntr_ns;
712 
713  input q_has_rd;
714  input q_has_priority;
715 
716 // Decide if this bank machine should demand priority. Priority is demanded
717 // when starvation limit counter is reached, or a bit in the request.
718  wire starved = ((starve_limit_cntr_r == (STARVE_LIMIT_CNT-1)) &&
719  rts_col_denied);
720  input req_priority_r;
721  input idle_ns;
722  reg demand_priority_r;
723  wire demand_priority_ns = ~idle_ns && col_wait_ns &&
724  (demand_priority_r ||
725  (order_q_zero &&
726  (req_priority_r || q_has_priority)) ||
727  (starved && (q_has_rd || ~req_wr_r)));
728 
729  always @(posedge clk) demand_priority_r <= #TCQ demand_priority_ns;
730 
731 `ifdef MC_SVA
732  wire rdy_for_priority = ~rst && ~demand_priority_r && ~idle_ns &&
733  col_wait_ns;
734  req_triggers_demand_priority:
735  cover property (@(posedge clk)
736  (rdy_for_priority && req_priority_r && ~q_has_priority && ~starved));
737  q_priority_triggers_demand_priority:
738  cover property (@(posedge clk)
739  (rdy_for_priority && ~req_priority_r && q_has_priority && ~starved));
740  wire not_req_or_q_rdy_for_priority =
741  rdy_for_priority && ~req_priority_r && ~q_has_priority;
742  starved_req_triggers_demand_priority:
743  cover property (@(posedge clk)
744  (not_req_or_q_rdy_for_priority && starved && ~q_has_rd && ~req_wr_r));
745  starved_q_triggers_demand_priority:
746  cover property (@(posedge clk)
747  (not_req_or_q_rdy_for_priority && starved && q_has_rd && req_wr_r));
748 `endif
749 
750 // compute demanded from other demand_priorities
751  input [(nBANK_MACHS*2)-1:0] demand_priority_in;
752  reg demanded = 1'b0;
753  generate
754  if (nBANK_MACHS > 1) begin : compute_demanded
755  always @(demand_priority_in[`BM_SHARED_BV]) demanded =
756  |demand_priority_in[`BM_SHARED_BV];
757  end
758  endgenerate
759 
760 
761 // In order to make sure that there is no starvation amongst a possibly
762 // unlimited stream of priority requests, add a second stage to the demand
763 // priority signal. If there are no other requests demanding priority, then
764 // go ahead and assert demand_priority. If any other requests are asserting
765 // demand_priority, hold off asserting demand_priority until these clear, then
766 // assert demand priority. Its possible to get multiple requests asserting
767 // demand priority simultaneously, but that's OK. Those requests will be
768 // serviced, demanded will fall, and another group of requests will be
769 // allowed to assert demand_priority.
770 
771  reg demanded_prior_r;
772  wire demanded_prior_ns = demanded &&
773  (demanded_prior_r || ~demand_priority_r);
774  always @(posedge clk) demanded_prior_r <= #TCQ demanded_prior_ns;
775 
776  output wire demand_priority;
777  assign demand_priority = demand_priority_r && ~demanded_prior_r &&
778  ~sending_col;
779 
780 `ifdef MC_SVA
781  demand_priority_gated:
782  cover property (@(posedge clk) (demand_priority_r && ~demand_priority));
783  generate
784  if (nBANK_MACHS >1) multiple_demand_priority:
785  cover property (@(posedge clk)
786  ($countones(demand_priority_in[`BM_SHARED_BV]) > 1));
787  endgenerate
788 `endif
789 
790  wire demand_ok = demand_priority_r || ~demanded;
791 
792  // Figure out if the request in this bank machine matches the current rank
793  // configuration.
794  input rnk_config_strobe;
795  input rnk_config_kill_rts_col;
796  input rnk_config_valid_r;
797  input [RANK_WIDTH-1:0] rnk_config;
798  output wire rtc;
799 
800  wire rnk_config_match = rnk_config_valid_r && (rnk_config == req_rank_r);
801  assign rtc = ~rnk_config_match && ~rnk_config_kill_rts_col && order_q_zero && col_wait_r && demand_ok;
802 
803 // Using rank state provided by the rank machines, figure out if
804 // a read requests should wait for WTR or RTW.
805  input [RANKS-1:0] inhbt_rd;
806  wire my_inhbt_rd = inhbt_rd[req_rank_r];
807  input [RANKS-1:0] inhbt_wr;
808  wire my_inhbt_wr = inhbt_wr[req_rank_r];
809  wire allow_rw = ~rd_wr_r ? ~my_inhbt_wr : ~my_inhbt_rd;
810 
811 // DQ bus timing constraints.
812  input dq_busy_data;
813 
814 // Column command is ready to arbitrate, except for databus restrictions.
815  wire col_rdy = (col_wait_r || ((nRCD_CLKS <= 1) && end_rcd) ||
816  (rcv_open_bank && nCK_PER_CLK == 2 && DRAM_TYPE=="DDR2" && BURST_MODE == "4") ||
817  (rcv_open_bank && nCK_PER_CLK == 4 && BURST_MODE == "8")) &&
818  order_q_zero;
819 
820 // Column command is ready to arbitrate for sending a write. Used
821 // to generate early wr_data_addr for ECC mode.
822  output wire col_rdy_wr;
823  assign col_rdy_wr = col_rdy && ~rd_wr_r;
824 
825 // Figure out if we're ready to send a column command based on all timing
826 // constraints.
827 // if timing is an issue.
828  wire col_cmd_rts = col_rdy && ~dq_busy_data && allow_rw && rnk_config_match;
829 
830 `ifdef MC_SVA
831  col_wait_for_order_q: cover property
832  (@(posedge clk)
833  (~rst && col_wait_r && ~order_q_zero && ~dq_busy_data &&
834  allow_rw));
835  col_wait_for_dq_busy: cover property
836  (@(posedge clk)
837  (~rst && col_wait_r && order_q_zero && dq_busy_data &&
838  allow_rw));
839  col_wait_for_allow_rw: cover property
840  (@(posedge clk)
841  (~rst && col_wait_r && order_q_zero && ~dq_busy_data &&
842  ~allow_rw));
843 `endif
844 
845 // Implement flow control for the command and control FIFOs and for the data
846 // FIFO during writes
847  input phy_mc_ctl_full;
848  input phy_mc_cmd_full;
849  input phy_mc_data_full;
850 
851  // Register ctl_full and cmd_full
852  reg phy_mc_ctl_full_r = 1'b0;
853  reg phy_mc_cmd_full_r = 1'b0;
854  always @(posedge clk)
855  if(rst) begin
856  phy_mc_ctl_full_r <= #TCQ 1'b0;
857  phy_mc_cmd_full_r <= #TCQ 1'b0;
858  end else begin
859  phy_mc_ctl_full_r <= #TCQ phy_mc_ctl_full;
860  phy_mc_cmd_full_r <= #TCQ phy_mc_cmd_full;
861  end
862 
863  // register output data pre-fifo almost full condition and fold in WR status
864  reg ofs_rdy_r = 1'b0;
865  always @(posedge clk)
866  if(rst)
867  ofs_rdy_r <= #TCQ 1'b0;
868  else
869  ofs_rdy_r <= #TCQ ~phy_mc_cmd_full_r && ~phy_mc_ctl_full_r && ~(phy_mc_data_full && ~rd_wr_r);
870 
871 // Disable priority feature for one state after a config to insure
872 // forward progress on the just installed io config.
873  reg override_demand_r;
874  wire override_demand_ns = rnk_config_strobe || rnk_config_kill_rts_col;
875  always @(posedge clk) override_demand_r <= override_demand_ns;
876  output wire rts_col;
877  assign rts_col = ~sending_col && (demand_ok || override_demand_r) &&
878  col_cmd_rts && ofs_rdy_r;
879 
880 // As in act_this_rank, wr/rd_this_rank informs rank machines
881 // that this bank machine is doing a write/rd. Removes logic
882 // after the grant.
883  reg [RANKS-1:0] wr_this_rank_ns;
884  reg [RANKS-1:0] rd_this_rank_ns;
885  always @(/*AS**/rd_wr_r or req_rank_r) begin
886  wr_this_rank_ns = {RANKS{1'b0}};
887  rd_this_rank_ns = {RANKS{1'b0}};
888  for (i=0; i<RANKS; i=i+1) begin
889  wr_this_rank_ns[i] = ~rd_wr_r && (i[RANK_WIDTH-1:0] == req_rank_r);
890  rd_this_rank_ns[i] = rd_wr_r && (i[RANK_WIDTH-1:0] == req_rank_r);
891  end
892  end
893  output reg [RANKS-1:0] wr_this_rank_r;
894  always @(posedge clk) wr_this_rank_r <= #TCQ wr_this_rank_ns;
895  output reg [RANKS-1:0] rd_this_rank_r;
896  always @(posedge clk) rd_this_rank_r <= #TCQ rd_this_rank_ns;
897 
898 endmodule // bank_state