Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / libs / tisram / soc / n2_l2t_sp_28kb_cust_l / n2_l2t_sp_28kb_cust / rtl / n2_l2t_array.v
CommitLineData
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
44module 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);
69wire ln1clk_unused;
70wire ln2clk_unused;
71wire l1clk_int_v2_unused;
72wire rd_en_b_unused;
73wire wr_en_b_unused;
74wire [1:0] wr_way_b_unused;
75wire l1clk_int;
76wire rd_en;
77wire [4:0] sf_l;
78wire [4:0] sf_r;
79wire shift_en_lft;
80wire shift_en_rgt;
81wire redundancy_en;
82wire [4:0] sh_index_lft;
83wire [4:0] sh_index_rgt;
84wire mem_wr_en0;
85wire 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
101input [`L2T_ARR_D_WIDTH - 1:0] din;
102input [8:0] addr_b;
103input l1clk_internal_v1;
104input l1clk_internal_v2;
105input ln1clk;
106input ln2clk;
107input rd_en_b;
108input rd_en_d1_a;
109input [1:0] rpda_lft;
110input [1:0] rpda_rgt;
111input [3:0] rpdb_lft;
112input [3:0] rpdb_rgt;
113input [3:0] rpdc_lft;
114input [3:0] rpdc_rgt;
115input w_inhibit_l;
116input wr_en_b;
117input wr_en_d1_a;
118input [1:0] wr_way_b;
119input [1:0] wr_way_b_l;
120
121// Added vnw_ary pin for n2 for 2.0
122
123input vnw_ary;
124
125output [`L2T_ARR_D_WIDTH - 1:0] sao_mx0_h;
126output [`L2T_ARR_D_WIDTH - 1:0] sao_mx0_l;
127output [`L2T_ARR_D_WIDTH - 1:0] sao_mx1_h;
128output [`L2T_ARR_D_WIDTH - 1:0] sao_mx1_l;
129
130
131reg [`L2T_ARR_D_WIDTH + 2:0] mem_lft[`L2T_ARR_DEPTH - 1 :0]; //one extra bit for redundancy
132reg [0:`L2T_ARR_D_WIDTH - 2] mem_rgt[`L2T_ARR_DEPTH - 1 :0];
133reg [`L2T_ARR_D_WIDTH + 2:0] mem_lft_reg ;
134reg [0:`L2T_ARR_D_WIDTH - 2] mem_rgt_reg ; // one entry of the memonry
135
136
137reg [`L2T_ARR_D_WIDTH + 2:0] mem_data_lft;
138reg [0:`L2T_ARR_D_WIDTH - 2] mem_data_rgt;
139
140reg [14:0] rdata0_lft;
141reg [14:0] rdata1_lft;
142reg [0:12] rdata0_rgt;
143reg [0:12] rdata1_rgt;
144reg [30:0] wdata_lft;
145reg [30:0] wdata_rgt;
146reg [29:0] tmp_lft;
147reg [25:0] tmp_rgt;
148
149wire [14:0] mem0_lft;
150wire [14:0] mem1_lft;
151wire [12:0] mem0_rgt;
152wire [12:0] mem1_rgt;
153wire [30:0] mem_all_lft;
154wire [26:0] mem_all_rgt;
155wire [30:0] rdata_out_lft;
156wire [26:0] rdata_out_rgt;
157integer i;
158integer j;
159integer l;
160integer k;
161
162reg [`L2T_ARR_D_WIDTH - 1:0] sao_mx0_h ;
163reg [`L2T_ARR_D_WIDTH - 1:0] sao_mx0_l ;
164reg [`L2T_ARR_D_WIDTH - 1:0] sao_mx1_h ;
165reg [`L2T_ARR_D_WIDTH - 1:0] sao_mx1_l ;
166
167wire [`L2T_ARR_D_WIDTH - 1:0] rdata0_out ;
168wire [`L2T_ARR_D_WIDTH - 1:0] rdata1_out ;
169//-----------------------------------------------------------------
170// INITIALIZE MEMORY
171//-----------------------------------------------------------------
172`ifndef NOINITMEM
173initial 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//-----------------------------------------------------------------
186assign ln1clk_unused = ln1clk;
187assign ln2clk_unused = ln2clk;
188assign l1clk_int_v2_unused = l1clk_internal_v2;
189assign rd_en_b_unused = rd_en_b;
190assign wr_en_b_unused = wr_en_b;
191assign wr_way_b_unused[1:0] = wr_way_b_l[1:0];
192
193
194assign 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//-----------------------------------------------------------------
238assign sf_l[4] = rpda_lft[1] ;
239assign sf_l[3:2] = rpdb_lft[3] ? 2'b11 :
240 rpdb_lft[2] ? 2'b10 :
241 rpdb_lft[1] ? 2'b01 :
242 2'b00;
243assign 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
248assign sf_r[4] = rpda_rgt[1] ;
249assign sf_r[3:2] = rpdb_rgt[3] ? 2'b11 :
250 rpdb_rgt[2] ? 2'b10 :
251 rpdb_rgt[1] ? 2'b01 :
252 2'b00;
253assign 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
258assign shift_en_lft = (sf_l[4:0] < 5'd30) ? (|rpda_lft[1:0]) && (|rpdb_lft[3:0]) && (|rpdc_lft[3:0]) : 1'b0;
259assign shift_en_rgt = (sf_r[4:0] < 5'd26) ? (|rpda_rgt[1:0]) && (|rpdb_rgt[3:0]) && (|rpdc_rgt[3:0]) : 1'b0;
260
261assign redundancy_en = shift_en_lft || shift_en_rgt;
262
263assign sh_index_lft[4:0] = shift_en_lft && (sf_l[4:0] < 5'd30) ? sf_l[4:0] : 5'b00000;
264assign 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
278wire [14:0] din_lft ;
279wire [0:12] din_rgt ;
280assign din_lft[14:0] = din[27:13];
281assign din_rgt[0:12] = din[12:0];
282
283// Add vnw_high check for write operation (implemented for n2_to_2.0)
284
285assign mem_wr_en0 = wr_way_b[0] && wr_en_b && ~rd_en_b && w_inhibit_l && wr_en_d1_a && vnw_ary;
286assign 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-------
292always @ (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
298begin
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
344end
345
346//-------right-------
347
348always @ (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
354begin
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
400end
401
402//-----------------------------------------------------------------
403// Read Arrays
404//-----------------------------------------------------------------
405
406//--------------------------------------
407// Read Redundancy Mapping
408//--------------------------------------
409
410
411//---------Left--------------
412always @ (sh_index_lft or shift_en_lft or rd_en or l1clk_int or addr_b[8:0] )
413begin
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
454end
455
456//---------Right--------------
457
458always @ (sh_index_rgt or shift_en_rgt or rd_en or l1clk_int or addr_b[8:0] )
459
460begin
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
501end
502
503
504endmodule
505