Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: n2_l2t_array.v | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | `define L2T_ARR_D_WIDTH 28 | |
36 | `define L2T_ARR_DEPTH 512 | |
37 | `define WAY_HIT_WIDTH 16 | |
38 | `define BADREAD BADBADD | |
39 | ||
40 | ||
41 | `define sh_index_lft 5'b00000 | |
42 | `define sh_index_rgt 5'b00000 | |
43 | ||
44 | module n2_l2t_array ( | |
45 | din, | |
46 | addr_b, | |
47 | l1clk_internal_v1, | |
48 | l1clk_internal_v2, | |
49 | ln1clk, | |
50 | ln2clk, | |
51 | rd_en_b, | |
52 | rd_en_d1_a, | |
53 | rpda_lft, | |
54 | rpda_rgt, | |
55 | rpdb_lft, | |
56 | rpdb_rgt, | |
57 | rpdc_lft, | |
58 | rpdc_rgt, | |
59 | w_inhibit_l, | |
60 | wr_en_b, | |
61 | wr_en_d1_a, | |
62 | wr_way_b, | |
63 | wr_way_b_l, | |
64 | vnw_ary, | |
65 | sao_mx0_h, | |
66 | sao_mx0_l, | |
67 | sao_mx1_h, | |
68 | sao_mx1_l); | |
69 | wire ln1clk_unused; | |
70 | wire ln2clk_unused; | |
71 | wire l1clk_int_v2_unused; | |
72 | wire rd_en_b_unused; | |
73 | wire wr_en_b_unused; | |
74 | wire [1:0] wr_way_b_unused; | |
75 | wire l1clk_int; | |
76 | wire rd_en; | |
77 | wire [4:0] sf_l; | |
78 | wire [4:0] sf_r; | |
79 | wire shift_en_lft; | |
80 | wire shift_en_rgt; | |
81 | wire redundancy_en; | |
82 | wire [4:0] sh_index_lft; | |
83 | wire [4:0] sh_index_rgt; | |
84 | wire mem_wr_en0; | |
85 | wire mem_wr_en1; | |
86 | ||
87 | ||
88 | // input l2clk; // cmp clock | |
89 | // input iol2clk; // io clock | |
90 | // input scan_in; | |
91 | // input tcu_pce_ov; // scan signals | |
92 | // input tcu_clk_stop; | |
93 | // input tcu_aclk; | |
94 | // input tcu_bclk; | |
95 | // input tcu_scan_en; | |
96 | // input tcu_muxtest; | |
97 | // input tcu_dectest; | |
98 | // output scan_out; | |
99 | ||
100 | ||
101 | input [`L2T_ARR_D_WIDTH - 1:0] din; | |
102 | input [8:0] addr_b; | |
103 | input l1clk_internal_v1; | |
104 | input l1clk_internal_v2; | |
105 | input ln1clk; | |
106 | input ln2clk; | |
107 | input rd_en_b; | |
108 | input rd_en_d1_a; | |
109 | input [1:0] rpda_lft; | |
110 | input [1:0] rpda_rgt; | |
111 | input [3:0] rpdb_lft; | |
112 | input [3:0] rpdb_rgt; | |
113 | input [3:0] rpdc_lft; | |
114 | input [3:0] rpdc_rgt; | |
115 | input w_inhibit_l; | |
116 | input wr_en_b; | |
117 | input wr_en_d1_a; | |
118 | input [1:0] wr_way_b; | |
119 | input [1:0] wr_way_b_l; | |
120 | ||
121 | // Added vnw_ary pin for n2 for 2.0 | |
122 | ||
123 | input vnw_ary; | |
124 | ||
125 | output [`L2T_ARR_D_WIDTH - 1:0] sao_mx0_h; | |
126 | output [`L2T_ARR_D_WIDTH - 1:0] sao_mx0_l; | |
127 | output [`L2T_ARR_D_WIDTH - 1:0] sao_mx1_h; | |
128 | output [`L2T_ARR_D_WIDTH - 1:0] sao_mx1_l; | |
129 | ||
130 | ||
131 | reg [`L2T_ARR_D_WIDTH + 2:0] mem_lft[`L2T_ARR_DEPTH - 1 :0]; //one extra bit for redundancy | |
132 | reg [0:`L2T_ARR_D_WIDTH - 2] mem_rgt[`L2T_ARR_DEPTH - 1 :0]; | |
133 | reg [`L2T_ARR_D_WIDTH + 2:0] mem_lft_reg ; | |
134 | reg [0:`L2T_ARR_D_WIDTH - 2] mem_rgt_reg ; // one entry of the memonry | |
135 | ||
136 | ||
137 | reg [`L2T_ARR_D_WIDTH + 2:0] mem_data_lft; | |
138 | reg [0:`L2T_ARR_D_WIDTH - 2] mem_data_rgt; | |
139 | ||
140 | reg [14:0] rdata0_lft; | |
141 | reg [14:0] rdata1_lft; | |
142 | reg [0:12] rdata0_rgt; | |
143 | reg [0:12] rdata1_rgt; | |
144 | reg [30:0] wdata_lft; | |
145 | reg [30:0] wdata_rgt; | |
146 | reg [29:0] tmp_lft; | |
147 | reg [25:0] tmp_rgt; | |
148 | ||
149 | wire [14:0] mem0_lft; | |
150 | wire [14:0] mem1_lft; | |
151 | wire [12:0] mem0_rgt; | |
152 | wire [12:0] mem1_rgt; | |
153 | wire [30:0] mem_all_lft; | |
154 | wire [26:0] mem_all_rgt; | |
155 | wire [30:0] rdata_out_lft; | |
156 | wire [26:0] rdata_out_rgt; | |
157 | integer i; | |
158 | integer j; | |
159 | integer l; | |
160 | integer k; | |
161 | ||
162 | reg [`L2T_ARR_D_WIDTH - 1:0] sao_mx0_h ; | |
163 | reg [`L2T_ARR_D_WIDTH - 1:0] sao_mx0_l ; | |
164 | reg [`L2T_ARR_D_WIDTH - 1:0] sao_mx1_h ; | |
165 | reg [`L2T_ARR_D_WIDTH - 1:0] sao_mx1_l ; | |
166 | ||
167 | wire [`L2T_ARR_D_WIDTH - 1:0] rdata0_out ; | |
168 | wire [`L2T_ARR_D_WIDTH - 1:0] rdata1_out ; | |
169 | //----------------------------------------------------------------- | |
170 | // INITIALIZE MEMORY | |
171 | //----------------------------------------------------------------- | |
172 | `ifndef NOINITMEM | |
173 | initial begin | |
174 | for (i = 0; i < `L2T_ARR_DEPTH - 1; i = i + 1) | |
175 | begin | |
176 | mem_rgt[i]=27'h0; | |
177 | mem_lft[i]=31'h0; | |
178 | end | |
179 | end | |
180 | `endif | |
181 | ||
182 | ||
183 | //----------------------------------------------------------------- | |
184 | // UNUSED SIGNALS | |
185 | //----------------------------------------------------------------- | |
186 | assign ln1clk_unused = ln1clk; | |
187 | assign ln2clk_unused = ln2clk; | |
188 | assign l1clk_int_v2_unused = l1clk_internal_v2; | |
189 | assign rd_en_b_unused = rd_en_b; | |
190 | assign wr_en_b_unused = wr_en_b; | |
191 | assign wr_way_b_unused[1:0] = wr_way_b_l[1:0]; | |
192 | ||
193 | ||
194 | assign l1clk_int = l1clk_internal_v1; | |
195 | ||
196 | //----------------------------------------------------------------- | |
197 | // OUTPUTS | |
198 | //----------------------------------------------------------------- | |
199 | // | |
200 | //always @ (l1clk_int or rd_en) | |
201 | // if (l1clk_int || ~rd_en) | |
202 | // begin | |
203 | // sao_mx0_h [`L2T_ARR_D_WIDTH - 1:0] <= 28'h0; | |
204 | // sao_mx0_l [`L2T_ARR_D_WIDTH - 1:0] <= 28'h0; | |
205 | // sao_mx1_h [`L2T_ARR_D_WIDTH - 1:0] <= 28'h0; | |
206 | // sao_mx1_l [`L2T_ARR_D_WIDTH - 1:0] <= 28'h0; | |
207 | // end | |
208 | // | |
209 | //----------------------------------------------------------------- | |
210 | // INTERNAL LOGIC | |
211 | //----------------------------------------------------------------- | |
212 | // Add vnw_ary high check for read operation for n2_to_2.0 | |
213 | // assign rd_en = rd_en_d1_a && ~wr_en_d1_a && w_inhibit_l; | |
214 | assign rd_en = rd_en_d1_a && ~wr_en_d1_a && w_inhibit_l && vnw_ary; | |
215 | ||
216 | //----------------------------------------------------------------- | |
217 | // REDUNDANCY | |
218 | //----------------------------------------------------------------- | |
219 | // Use [511:0] way0[29] as the redundancy bit, there are total 512 redundancy | |
220 | // bits. | |
221 | // Left side : way0_tmp[29:15] = mem0_lft[14:0] | |
222 | // way1_tmp[27:13] = mem1_lft[14:0] | |
223 | // way0_tmp[14] = red_bit_lft (redundancy bit) | |
224 | // Shift mem1_lft[n] -> mem0_lft[n] , shift mem0_lft[n]->men1_rgt[n-1] | |
225 | // mem0_lft[0]->redundancy bit = red_bit_lft. | |
226 | // | |
227 | // Right side : way0_tmp[12:0] = mem0_rgt[12:0] | |
228 | // way1_tmp[12:0] = mem1_rgt[12:0] | |
229 | // way0_tmp[13] = red_bit_rgt (redundancy bit) | |
230 | // Shift mem1_rgt[n] -> mem0_rgt[n] , shift mem0_rgt[n]->men1_rgt[n+1] | |
231 | // mem0_rgt[0]->redundancy bit = red_bit_rgt. | |
232 | // | |
233 | //----------------------------------------------------------------- | |
234 | ||
235 | //----------------------------------------------------------------- | |
236 | // recover the shift index from rpda, rpdb, rpdc | |
237 | //----------------------------------------------------------------- | |
238 | assign sf_l[4] = rpda_lft[1] ; | |
239 | assign sf_l[3:2] = rpdb_lft[3] ? 2'b11 : | |
240 | rpdb_lft[2] ? 2'b10 : | |
241 | rpdb_lft[1] ? 2'b01 : | |
242 | 2'b00; | |
243 | assign sf_l[1:0] = rpdc_lft[3] ? 2'b11 : | |
244 | rpdc_lft[2] ? 2'b10 : | |
245 | rpdc_lft[1] ? 2'b01 : | |
246 | 2'b00; | |
247 | ||
248 | assign sf_r[4] = rpda_rgt[1] ; | |
249 | assign sf_r[3:2] = rpdb_rgt[3] ? 2'b11 : | |
250 | rpdb_rgt[2] ? 2'b10 : | |
251 | rpdb_rgt[1] ? 2'b01 : | |
252 | 2'b00; | |
253 | assign sf_r[1:0] = rpdc_rgt[3] ? 2'b11 : | |
254 | rpdc_rgt[2] ? 2'b10 : | |
255 | rpdc_rgt[1] ? 2'b01 : | |
256 | 2'b00; | |
257 | ||
258 | assign shift_en_lft = (sf_l[4:0] < 5'd30) ? (|rpda_lft[1:0]) && (|rpdb_lft[3:0]) && (|rpdc_lft[3:0]) : 1'b0; | |
259 | assign shift_en_rgt = (sf_r[4:0] < 5'd26) ? (|rpda_rgt[1:0]) && (|rpdb_rgt[3:0]) && (|rpdc_rgt[3:0]) : 1'b0; | |
260 | ||
261 | assign redundancy_en = shift_en_lft || shift_en_rgt; | |
262 | ||
263 | assign sh_index_lft[4:0] = shift_en_lft && (sf_l[4:0] < 5'd30) ? sf_l[4:0] : 5'b00000; | |
264 | assign sh_index_rgt[4:0] = shift_en_rgt && (sf_r[4:0] < 5'd26) ? sf_r[4:0] : 5'b00000; | |
265 | ||
266 | ||
267 | ||
268 | //----------------------------------------------------------------- | |
269 | // Write Arrays | |
270 | //----------------------------------------------------------------- | |
271 | ||
272 | ||
273 | //-------------------------------------- | |
274 | // Write Redundancy Mapping | |
275 | //-------------------------------------- | |
276 | // Shifting of redundancy base on the sh_index_lft and sh_index_rgt | |
277 | ||
278 | wire [14:0] din_lft ; | |
279 | wire [0:12] din_rgt ; | |
280 | assign din_lft[14:0] = din[27:13]; | |
281 | assign din_rgt[0:12] = din[12:0]; | |
282 | ||
283 | // Add vnw_high check for write operation (implemented for n2_to_2.0) | |
284 | ||
285 | assign mem_wr_en0 = wr_way_b[0] && wr_en_b && ~rd_en_b && w_inhibit_l && wr_en_d1_a && vnw_ary; | |
286 | assign mem_wr_en1 = wr_way_b[1] && wr_en_b && ~rd_en_b && w_inhibit_l && wr_en_d1_a && vnw_ary; | |
287 | ||
288 | ||
289 | ||
290 | ||
291 | //-------left------- | |
292 | always @ (sh_index_lft or din_lft[14:0] or shift_en_lft or mem_wr_en0 or mem_wr_en1 | |
293 | or l1clk_int or addr_b[8:0] ) | |
294 | ||
295 | ||
296 | #0 | |
297 | ||
298 | begin | |
299 | ||
300 | ||
301 | mem_lft_reg[`L2T_ARR_D_WIDTH + 2:0] = mem_lft[addr_b] ; | |
302 | ||
303 | ||
304 | ||
305 | // Write to redundant bit in write cycle for way0 with no redundancy | |
306 | if (l1clk_int && (~shift_en_lft) && mem_wr_en0) | |
307 | begin | |
308 | mem_lft_reg[0] = din_lft[0]; | |
309 | end | |
310 | ||
311 | for (i=14; i >= 0; i=i-1) | |
312 | begin | |
313 | if (mem_wr_en0 && l1clk_int) //way0 | |
314 | begin | |
315 | if (( sh_index_lft < (2*i)) || ~shift_en_lft) | |
316 | mem_lft_reg[2*i+1] = din_lft[i]; //no shift | |
317 | else | |
318 | begin | |
319 | mem_lft_reg[2*i] = din_lft[i]; // shift | |
320 | end | |
321 | end | |
322 | if(shift_en_lft) | |
323 | mem_lft_reg[sh_index_lft+1] = 1'bx; // write "x" to bad bit | |
324 | end //for | |
325 | ||
326 | for (i=14; i >= 0; i=i-1) | |
327 | begin | |
328 | if (mem_wr_en1 && l1clk_int ) //way1 | |
329 | begin | |
330 | if (( sh_index_lft < (2*i + 1)) || ~shift_en_lft) | |
331 | mem_lft_reg[2*i+2] = din_lft[i]; //no shift | |
332 | else | |
333 | begin | |
334 | mem_lft_reg[2*i+1] = din_lft[i]; //shift | |
335 | end | |
336 | end | |
337 | if(shift_en_lft) | |
338 | mem_lft_reg[sh_index_lft+1] = 1'bx; //write "x" to bad bit | |
339 | end | |
340 | ||
341 | if (l1clk_int) mem_lft[addr_b] = mem_lft_reg[`L2T_ARR_D_WIDTH + 2:0] ; | |
342 | ||
343 | ||
344 | end | |
345 | ||
346 | //-------right------- | |
347 | ||
348 | always @ (sh_index_rgt or din_rgt[0:12] or shift_en_rgt or mem_wr_en0 or mem_wr_en1 | |
349 | or l1clk_int or addr_b[8:0] ) | |
350 | ||
351 | ||
352 | #0 | |
353 | ||
354 | begin | |
355 | ||
356 | mem_rgt_reg[0 : `L2T_ARR_D_WIDTH - 2] = mem_rgt[addr_b]; | |
357 | ||
358 | ||
359 | ||
360 | // Write to redundant bit in write cycle for way0 with no redundancy | |
361 | if (l1clk_int && (~shift_en_rgt) && mem_wr_en0) | |
362 | begin | |
363 | mem_rgt_reg[0] = din_rgt[0]; | |
364 | end | |
365 | ||
366 | for (k=12; k >= 0; k=k-1) | |
367 | begin | |
368 | if (mem_wr_en0 && l1clk_int) //WAY0 | |
369 | begin | |
370 | if (( sh_index_rgt < (2*k )) || ~shift_en_rgt) | |
371 | mem_rgt_reg[2*k+1] = din_rgt[k]; //no shift | |
372 | else | |
373 | begin | |
374 | mem_rgt_reg[2*k] = din_rgt[k]; // shift | |
375 | end | |
376 | end | |
377 | if(shift_en_rgt) | |
378 | mem_rgt_reg[sh_index_rgt+1] = 1'bx; // Write "X" to the bad bit | |
379 | end //for | |
380 | ||
381 | for (k=12; k >= 0; k=k-1) | |
382 | begin | |
383 | if (mem_wr_en1 && l1clk_int ) //WAY1 | |
384 | begin | |
385 | if (( sh_index_rgt < (2*k + 1)) || ~shift_en_rgt) | |
386 | mem_rgt_reg[2*k+2] = din_rgt[k]; //no shift | |
387 | else | |
388 | begin | |
389 | mem_rgt_reg[2*k+1] = din_rgt[k]; // shift | |
390 | end | |
391 | end | |
392 | if(shift_en_rgt) | |
393 | mem_rgt_reg[sh_index_rgt+1] = 1'bx; // Write "X" to the bad bit | |
394 | end //for | |
395 | ||
396 | if (l1clk_int) mem_rgt[addr_b] = mem_rgt_reg[0 : `L2T_ARR_D_WIDTH - 2] ; | |
397 | ||
398 | ||
399 | ||
400 | end | |
401 | ||
402 | //----------------------------------------------------------------- | |
403 | // Read Arrays | |
404 | //----------------------------------------------------------------- | |
405 | ||
406 | //-------------------------------------- | |
407 | // Read Redundancy Mapping | |
408 | //-------------------------------------- | |
409 | ||
410 | ||
411 | //---------Left-------------- | |
412 | always @ (sh_index_lft or shift_en_lft or rd_en or l1clk_int or addr_b[8:0] ) | |
413 | begin | |
414 | if (l1clk_int) | |
415 | begin | |
416 | ||
417 | mem_data_lft[`L2T_ARR_D_WIDTH + 2:0] = ~rd_en ? 31'hx : mem_lft[addr_b] ; | |
418 | ||
419 | end | |
420 | ||
421 | ||
422 | if (rd_en && ~l1clk_int) | |
423 | ||
424 | ||
425 | begin | |
426 | ||
427 | for (j=14; j >= 0; j=j-1) //WAY0 | |
428 | begin | |
429 | if (( sh_index_lft < (2*j )) || ~shift_en_lft) | |
430 | rdata0_lft[j] = mem_data_lft[2*j+1]; // no shift | |
431 | else | |
432 | rdata0_lft[j] = mem_data_lft[2*j]; // shift | |
433 | end //for | |
434 | ||
435 | for (j=14; j >= 0; j=j-1) //WAY1 | |
436 | begin | |
437 | if (( sh_index_lft < (2*j + 1)) || ~shift_en_lft) | |
438 | rdata1_lft[j] = mem_data_lft[2*j+2]; //no shift | |
439 | else | |
440 | rdata1_lft[j] = mem_data_lft[2*j+1]; // shift | |
441 | end | |
442 | sao_mx0_h[27:13] = rdata0_lft[14:0] & {15{rd_en}}; | |
443 | sao_mx0_l[27:13] = ~rdata0_lft[14:0] & {15{rd_en}}; | |
444 | sao_mx1_h[27:13] = rdata1_lft[14:0] & {15{rd_en}}; | |
445 | sao_mx1_l[27:13] = ~rdata1_lft[14:0] & {15{rd_en}}; | |
446 | end | |
447 | else if(l1clk_int || ~rd_en) | |
448 | begin | |
449 | sao_mx0_h[27:13] = 15'h0; | |
450 | sao_mx0_l[27:13] = 15'h0; | |
451 | sao_mx1_h[27:13] = 15'h0; | |
452 | sao_mx1_l[27:13] = 15'h0; | |
453 | end | |
454 | end | |
455 | ||
456 | //---------Right-------------- | |
457 | ||
458 | always @ (sh_index_rgt or shift_en_rgt or rd_en or l1clk_int or addr_b[8:0] ) | |
459 | ||
460 | begin | |
461 | if (l1clk_int) | |
462 | begin | |
463 | ||
464 | mem_data_rgt[0: `L2T_ARR_D_WIDTH - 2] = ~rd_en ? 27'hx : mem_rgt[addr_b] ; | |
465 | ||
466 | end | |
467 | ||
468 | ||
469 | if (rd_en && ~l1clk_int) | |
470 | ||
471 | ||
472 | begin | |
473 | ||
474 | for (l=12; l >= 0; l=l-1) //WAY0 | |
475 | begin | |
476 | if (( sh_index_rgt < (2*l)) || ~shift_en_rgt) | |
477 | rdata0_rgt[l] = mem_data_rgt[2*l+1]; // no shift | |
478 | else | |
479 | rdata0_rgt[l] = mem_data_rgt[2*l]; // shift | |
480 | end //for | |
481 | ||
482 | for (l=12; l >= 0; l=l-1) //WAY1 | |
483 | begin | |
484 | if (( sh_index_rgt < (2*l + 1)) || ~shift_en_rgt) | |
485 | rdata1_rgt[l] = mem_data_rgt[2*l+2]; //no shift | |
486 | else | |
487 | rdata1_rgt[l] = mem_data_rgt[2*l+1]; // shift | |
488 | end | |
489 | sao_mx0_h[12:0] = rdata0_rgt[0:12] & {13{rd_en}}; | |
490 | sao_mx0_l[12:0] = ~rdata0_rgt[0:12] & {13{rd_en}}; | |
491 | sao_mx1_h[12:0] = rdata1_rgt[0:12] & {13{rd_en}}; | |
492 | sao_mx1_l[12:0] = ~rdata1_rgt[0:12] & {13{rd_en}}; | |
493 | end | |
494 | else if (l1clk_int || ~rd_en) | |
495 | begin | |
496 | sao_mx0_h[12:0] = 13'h0; | |
497 | sao_mx0_l[12:0] = 13'h0; | |
498 | sao_mx1_h[12:0] = 13'h0; | |
499 | sao_mx1_l[12:0] = 13'h0; | |
500 | end | |
501 | end | |
502 | ||
503 | ||
504 | endmodule | |
505 |