AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
mig_7series_v1_9_bank_compare.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_compare.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 // This block stores the request for this bank machine.
67 //
68 // All possible new requests are compared against the request stored
69 // here. The compare results are shared with the bank machines and
70 // is used to determine where to enqueue a new request.
71 
72 `timescale 1ps/1ps
73 
75  (parameter BANK_WIDTH = 3,
76  parameter TCQ = 100,
77  parameter BURST_MODE = "8",
78  parameter COL_WIDTH = 12,
79  parameter DATA_BUF_ADDR_WIDTH = 8,
80  parameter ECC = "OFF",
81  parameter RANK_WIDTH = 2,
82  parameter RANKS = 4,
83  parameter ROW_WIDTH = 16)
84  (/*AUTOARG**/
85  // Outputs
86  req_data_buf_addr_r, req_periodic_rd_r, req_size_r, rd_wr_r,
87  req_rank_r, req_bank_r, req_row_r, req_wr_r, req_priority_r,
88  rb_hit_busy_r, rb_hit_busy_ns, row_hit_r, maint_hit, col_addr,
89  req_ras, req_cas, row_cmd_wr, row_addr, rank_busy_r,
90  // Inputs
91  clk, idle_ns, idle_r, data_buf_addr, periodic_rd_insert, size, cmd,
92  sending_col, rank, periodic_rd_rank_r, bank, row, col, hi_priority,
93  maint_rank_r, maint_zq_r, maint_sre_r, auto_pre_r, rd_half_rmw, act_wait_r
94  );
95 
96  input clk;
97 
98  input idle_ns;
99  input idle_r;
100 
101  input [DATA_BUF_ADDR_WIDTH-1:0]data_buf_addr;
102  output reg [DATA_BUF_ADDR_WIDTH-1:0] req_data_buf_addr_r;
103  wire [DATA_BUF_ADDR_WIDTH-1:0] req_data_buf_addr_ns =
104  idle_r
105  ? data_buf_addr
106  : req_data_buf_addr_r;
107  always @(posedge clk) req_data_buf_addr_r <= #TCQ req_data_buf_addr_ns;
108 
109  input periodic_rd_insert;
110 
111  reg req_periodic_rd_r_lcl;
112  wire req_periodic_rd_ns = idle_ns
113  ? periodic_rd_insert
114  : req_periodic_rd_r_lcl;
115  always @(posedge clk) req_periodic_rd_r_lcl <= #TCQ req_periodic_rd_ns;
116  output wire req_periodic_rd_r;
117  assign req_periodic_rd_r = req_periodic_rd_r_lcl;
118 
119  input size;
120  wire req_size_r_lcl;
121  generate
122  if (BURST_MODE == "4") begin : burst_mode_4
123  assign req_size_r_lcl = 1'b0;
124  end
125  else
126  if (BURST_MODE == "8") begin : burst_mode_8
127  assign req_size_r_lcl = 1'b1;
128  end
129  else
130  if (BURST_MODE == "OTF") begin : burst_mode_otf
131  reg req_size;
132  wire req_size_ns = idle_ns
133  ? (periodic_rd_insert || size)
134  : req_size;
135  always @(posedge clk) req_size <= #TCQ req_size_ns;
136  assign req_size_r_lcl = req_size;
137  end
138  endgenerate
139  output wire req_size_r;
140  assign req_size_r = req_size_r_lcl;
141 
142 
143 
144  input [2:0] cmd;
145  reg [2:0] req_cmd_r;
146  wire [2:0] req_cmd_ns = idle_ns
147  ? (periodic_rd_insert ? 3'b001 : cmd)
148  : req_cmd_r;
149 
150  always @(posedge clk) req_cmd_r <= #TCQ req_cmd_ns;
151 
152 `ifdef MC_SVA
153  rd_wr_only_wo_ecc: assert property
154  (@(posedge clk) ((ECC != "OFF") || idle_ns || ~|req_cmd_ns[2:1]));
155 `endif
156 
157  input sending_col;
158  reg rd_wr_r_lcl;
159  wire rd_wr_ns = idle_ns
160  ? ((req_cmd_ns[1:0] == 2'b11) || req_cmd_ns[0])
161  : ~sending_col && rd_wr_r_lcl;
162  always @(posedge clk) rd_wr_r_lcl <= #TCQ rd_wr_ns;
163  output wire rd_wr_r;
164  assign rd_wr_r = rd_wr_r_lcl;
165 
166  input [RANK_WIDTH-1:0] rank;
167  input [RANK_WIDTH-1:0] periodic_rd_rank_r;
168  reg [RANK_WIDTH-1:0] req_rank_r_lcl = {RANK_WIDTH{1'b0}};
169  reg [RANK_WIDTH-1:0] req_rank_ns = {RANK_WIDTH{1'b0}};
170  generate
171  if (RANKS != 1) begin
172  always @(/*AS**/idle_ns or periodic_rd_insert
173  or periodic_rd_rank_r or rank or req_rank_r_lcl) req_rank_ns = idle_ns
174  ? periodic_rd_insert
175  ? periodic_rd_rank_r
176  : rank
177  : req_rank_r_lcl;
178  always @(posedge clk) req_rank_r_lcl <= #TCQ req_rank_ns;
179  end
180  endgenerate
181  output wire [RANK_WIDTH-1:0] req_rank_r;
182  assign req_rank_r = req_rank_r_lcl;
183 
184  input [BANK_WIDTH-1:0] bank;
185  reg [BANK_WIDTH-1:0] req_bank_r_lcl;
186  wire [BANK_WIDTH-1:0] req_bank_ns = idle_ns ? bank : req_bank_r_lcl;
187  always @(posedge clk) req_bank_r_lcl <= #TCQ req_bank_ns;
188  output wire[BANK_WIDTH-1:0] req_bank_r;
189  assign req_bank_r = req_bank_r_lcl;
190 
191  input [ROW_WIDTH-1:0] row;
192  reg [ROW_WIDTH-1:0] req_row_r_lcl;
193  wire [ROW_WIDTH-1:0] req_row_ns = idle_ns ? row : req_row_r_lcl;
194  always @(posedge clk) req_row_r_lcl <= #TCQ req_row_ns;
195  output wire [ROW_WIDTH-1:0] req_row_r;
196  assign req_row_r = req_row_r_lcl;
197 
198  // Make req_col_r as wide as the max row address. This
199  // makes it easier to deal with indexing different column widths.
200  input [COL_WIDTH-1:0] col;
201  reg [15:0] req_col_r = 16'b0;
202  wire [COL_WIDTH-1:0] req_col_ns = idle_ns ? col : req_col_r[COL_WIDTH-1:0];
203  always @(posedge clk) req_col_r[COL_WIDTH-1:0] <= #TCQ req_col_ns;
204 
205  reg req_wr_r_lcl;
206  wire req_wr_ns = idle_ns
207  ? ((req_cmd_ns[1:0] == 2'b11) || ~req_cmd_ns[0])
208  : req_wr_r_lcl;
209  always @(posedge clk) req_wr_r_lcl <= #TCQ req_wr_ns;
210  output wire req_wr_r;
211  assign req_wr_r = req_wr_r_lcl;
212 
213  input hi_priority;
214  output reg req_priority_r;
215  wire req_priority_ns = idle_ns ? hi_priority : req_priority_r;
216  always @(posedge clk) req_priority_r <= #TCQ req_priority_ns;
217 
218  wire rank_hit = (req_rank_r_lcl == (periodic_rd_insert
219  ? periodic_rd_rank_r
220  : rank));
221  wire bank_hit = (req_bank_r_lcl == bank);
222  wire rank_bank_hit = rank_hit && bank_hit;
223 
224  output reg rb_hit_busy_r; // rank-bank hit on non idle row machine
225  wire rb_hit_busy_ns_lcl;
226  assign rb_hit_busy_ns_lcl = rank_bank_hit && ~idle_ns;
227  output wire rb_hit_busy_ns;
228  assign rb_hit_busy_ns = rb_hit_busy_ns_lcl;
229 
230  wire row_hit_ns = (req_row_r_lcl == row);
231  output reg row_hit_r;
232 
233  always @(posedge clk) rb_hit_busy_r <= #TCQ rb_hit_busy_ns_lcl;
234  always @(posedge clk) row_hit_r <= #TCQ row_hit_ns;
235 
236  input [RANK_WIDTH-1:0] maint_rank_r;
237  input maint_zq_r;
238  input maint_sre_r;
239  output wire maint_hit;
240  assign maint_hit = (req_rank_r_lcl == maint_rank_r) || maint_zq_r || maint_sre_r;
241 
242 // Assemble column address. Structure to be the same
243 // width as the row address. This makes it easier
244 // for the downstream muxing. Depending on the sizes
245 // of the row and column addresses, fill in as appropriate.
246  input auto_pre_r;
247  input rd_half_rmw;
248  reg [15:0] col_addr_template = 16'b0;
249  always @(/*AS**/auto_pre_r or rd_half_rmw or req_col_r
250  or req_size_r_lcl) begin
251  col_addr_template = req_col_r;
252  col_addr_template[10] = auto_pre_r && ~rd_half_rmw;
253  col_addr_template[11] = req_col_r[10];
254  col_addr_template[12] = req_size_r_lcl;
255  col_addr_template[13] = req_col_r[11];
256  end
257  output wire [ROW_WIDTH-1:0] col_addr;
258  assign col_addr = col_addr_template[ROW_WIDTH-1:0];
259 
260  output wire req_ras;
261  output wire req_cas;
262  output wire row_cmd_wr;
263  input act_wait_r;
264  assign req_ras = 1'b0;
265  assign req_cas = 1'b1;
266  assign row_cmd_wr = act_wait_r;
267 
268  output reg [ROW_WIDTH-1:0] row_addr;
269  always @(/*AS**/act_wait_r or req_row_r_lcl) begin
270  row_addr = req_row_r_lcl;
271 // This causes all precharges to be precharge single bank command.
272  if (~act_wait_r) row_addr[10] = 1'b0;
273  end
274 
275 // Indicate which, if any, rank this bank machine is busy with.
276 // Not registering the result would probably be more accurate, but
277 // would create timing issues. This is used for refresh banking, perfect
278 // accuracy is not required.
279  localparam ONE = 1;
280  output reg [RANKS-1:0] rank_busy_r;
281  wire [RANKS-1:0] rank_busy_ns = {RANKS{~idle_ns}} & (ONE[RANKS-1:0] << req_rank_ns);
282  always @(posedge clk) rank_busy_r <= #TCQ rank_busy_ns;
283 
284 endmodule // bank_compare