1 |
2 |
dmitryr |
// ========== Copyright Header Begin ==========================================
|
2 |
|
|
//
|
3 |
|
|
// OpenSPARC T1 Processor File: sparc_ifu_mbist.v
|
4 |
|
|
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
|
5 |
|
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
|
6 |
|
|
//
|
7 |
|
|
// The above named program is free software; you can redistribute it and/or
|
8 |
|
|
// modify it under the terms of the GNU General Public
|
9 |
|
|
// License version 2 as published by the Free Software Foundation.
|
10 |
|
|
//
|
11 |
|
|
// The above named program is distributed in the hope that it will be
|
12 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 |
|
|
// General Public License for more details.
|
15 |
|
|
//
|
16 |
|
|
// You should have received a copy of the GNU General Public
|
17 |
|
|
// License along with this work; if not, write to the Free Software
|
18 |
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
19 |
|
|
//
|
20 |
|
|
// ========== Copyright Header End ============================================
|
21 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
22 |
|
|
//
|
23 |
|
|
// Description: Memory BIST Controller for the L1 ICache and DCache
|
24 |
|
|
// Block Type: Control Block
|
25 |
|
|
// Module: mbist_engine
|
26 |
|
|
//
|
27 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
module sparc_ifu_mbist(
|
31 |
|
|
mbist_dcache_read,
|
32 |
|
|
mbist_dcache_write,
|
33 |
|
|
mbist_dcache_word,
|
34 |
|
|
mbist_dcache_index,
|
35 |
|
|
mbist_dcache_way,
|
36 |
|
|
mbist_icache_read,
|
37 |
|
|
mbist_icache_write,
|
38 |
|
|
mbist_icache_index,
|
39 |
|
|
mbist_icache_word,
|
40 |
|
|
mbist_icache_way,
|
41 |
|
|
mbist_icache_wdata,
|
42 |
|
|
mbist_dcache_wdata,
|
43 |
|
|
mbist_done,
|
44 |
|
|
mbist_dcache_fail,
|
45 |
|
|
mbist_icache_fail,
|
46 |
|
|
rclk,
|
47 |
|
|
mbist_start,
|
48 |
|
|
mbist_ifq_run_bist,
|
49 |
|
|
mbist_userdata_mode,
|
50 |
|
|
mbist_bisi_mode,
|
51 |
|
|
mbist_loop_mode,
|
52 |
|
|
mbist_loop_on_address,
|
53 |
|
|
mbist_stop_on_fail,
|
54 |
|
|
mbist_stop_on_next_fail,
|
55 |
|
|
mbist_dcache_data_in,
|
56 |
|
|
mbist_icache_data_in,
|
57 |
|
|
grst_l,
|
58 |
|
|
arst_l,
|
59 |
|
|
mbist_si,
|
60 |
|
|
mbist_so,
|
61 |
|
|
mbist_se
|
62 |
|
|
);
|
63 |
|
|
|
64 |
|
|
|
65 |
|
|
|
66 |
|
|
|
67 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
68 |
|
|
// Outputs
|
69 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
70 |
|
|
|
71 |
|
|
output mbist_dcache_read;
|
72 |
|
|
output mbist_dcache_write;
|
73 |
|
|
output mbist_dcache_word;
|
74 |
|
|
output[6:0] mbist_dcache_index;
|
75 |
|
|
output[1:0] mbist_dcache_way;
|
76 |
|
|
|
77 |
|
|
output mbist_icache_read;
|
78 |
|
|
output mbist_icache_write;
|
79 |
|
|
output[7:0] mbist_icache_index;
|
80 |
|
|
output mbist_icache_word;
|
81 |
|
|
output[1:0] mbist_icache_way;
|
82 |
|
|
output mbist_ifq_run_bist;
|
83 |
|
|
|
84 |
|
|
output[7:0] mbist_icache_wdata;
|
85 |
|
|
output[7:0] mbist_dcache_wdata;
|
86 |
|
|
|
87 |
|
|
output mbist_done;
|
88 |
|
|
output mbist_dcache_fail;
|
89 |
|
|
output mbist_icache_fail;
|
90 |
|
|
|
91 |
|
|
output mbist_so;
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
|
95 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
96 |
|
|
// Inputs
|
97 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
98 |
|
|
|
99 |
|
|
input rclk;
|
100 |
|
|
input mbist_si;
|
101 |
|
|
input mbist_se;
|
102 |
|
|
|
103 |
|
|
input grst_l;
|
104 |
|
|
input arst_l;
|
105 |
|
|
|
106 |
|
|
input mbist_start;
|
107 |
|
|
input mbist_userdata_mode;
|
108 |
|
|
input mbist_bisi_mode;
|
109 |
|
|
input mbist_loop_mode;
|
110 |
|
|
input mbist_loop_on_address;
|
111 |
|
|
input mbist_stop_on_fail;
|
112 |
|
|
input mbist_stop_on_next_fail;
|
113 |
|
|
|
114 |
|
|
input[71:0] mbist_dcache_data_in;
|
115 |
|
|
input[67:0] mbist_icache_data_in;
|
116 |
|
|
|
117 |
|
|
|
118 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
119 |
|
|
// Wires
|
120 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
121 |
|
|
|
122 |
|
|
wire [7:0] config_in;
|
123 |
|
|
wire [7:0] config_out;
|
124 |
|
|
wire start_transition;
|
125 |
|
|
wire reset_engine;
|
126 |
|
|
wire loop;
|
127 |
|
|
wire run;
|
128 |
|
|
wire bisi;
|
129 |
|
|
wire userdata_mode;
|
130 |
|
|
wire stop_on_fail;
|
131 |
|
|
wire stop_on_next_fail;
|
132 |
|
|
wire loop_on_address;
|
133 |
|
|
wire [7:0] userdata_in;
|
134 |
|
|
wire [7:0] userdata_out;
|
135 |
|
|
wire [6:0] useradd_in;
|
136 |
|
|
wire [6:0] useradd_out;
|
137 |
|
|
wire [20:0] control_in;
|
138 |
|
|
wire [20:0] control_out;
|
139 |
|
|
wire msb;
|
140 |
|
|
wire array_sel;
|
141 |
|
|
wire [1:0] data_control;
|
142 |
|
|
wire address_mix;
|
143 |
|
|
wire [2:0] march_element;
|
144 |
|
|
wire [9:0] array_address;
|
145 |
|
|
wire dcache_sel;
|
146 |
|
|
wire [1:0] read_write_control;
|
147 |
|
|
wire [20:0] qual_control_out;
|
148 |
|
|
wire four_cycle_march;
|
149 |
|
|
wire [9:0] add;
|
150 |
|
|
wire upaddress_march;
|
151 |
|
|
wire [10:0] mbist_address;
|
152 |
|
|
wire array_write;
|
153 |
|
|
wire array_read;
|
154 |
|
|
wire initialize;
|
155 |
|
|
wire fail;
|
156 |
|
|
wire true_data;
|
157 |
|
|
wire [7:0] data_pattern;
|
158 |
|
|
wire second_time_through;
|
159 |
|
|
wire icache_sel;
|
160 |
|
|
wire dc_read_pipe_out1;
|
161 |
|
|
wire dc_read_pipe_out2;
|
162 |
|
|
wire dcache_piped_read;
|
163 |
|
|
wire ic_read_pipe_out1;
|
164 |
|
|
wire ic_read_pipe_out2;
|
165 |
|
|
wire icache_piped_read;
|
166 |
|
|
wire [7:0] data_pipe_out1;
|
167 |
|
|
wire [7:0] data_pipe_out2;
|
168 |
|
|
wire [10:0] add_pipe_out1;
|
169 |
|
|
wire [10:0] add_pipe_out2;
|
170 |
|
|
wire [9:0] dcache_piped_address;
|
171 |
|
|
wire [10:0] icache_piped_address;
|
172 |
|
|
wire [1:0] fail_reg_in;
|
173 |
|
|
wire [1:0] fail_reg_out;
|
174 |
|
|
wire qual_dcache_fail;
|
175 |
|
|
wire qual_icache_fail;
|
176 |
|
|
wire beyond_last_fail;
|
177 |
|
|
wire dcache_fail;
|
178 |
|
|
wire icache_fail;
|
179 |
|
|
wire mismatch, mbist_word_sel;
|
180 |
|
|
wire [71:0] expect_data;
|
181 |
|
|
wire [71:0] compare_data;
|
182 |
|
|
wire qual_fail, dcache_data_sel;
|
183 |
|
|
wire [10:0] fail_add_reg_in;
|
184 |
|
|
wire [10:0] fail_add_reg_out;
|
185 |
|
|
wire [71:0] fail_data_reg_in;
|
186 |
|
|
wire [71:0] fail_data_reg_out;
|
187 |
|
|
wire [20:0] fail_control_reg_in;
|
188 |
|
|
wire [20:0] fail_control_reg_out;
|
189 |
|
|
wire mbist_icache_read_bf, mbist_icache_write_bf;
|
190 |
|
|
wire [71:0] compare_data_bf;
|
191 |
|
|
wire msb_rst, msb_d1_rst, msb_d2_rst, msb_d3_rst, mbist_done_int;
|
192 |
|
|
wire msb_d1, msb_d2, msb_d3, msb_d4, mbist_reset_l, mbist_reset;
|
193 |
|
|
|
194 |
|
|
|
195 |
|
|
//// reset buffer ////
|
196 |
|
|
|
197 |
|
|
dffrl_async rstff(.din (grst_l),
|
198 |
|
|
.q (mbist_reset_l),
|
199 |
|
|
.clk (rclk), .se(mbist_se), .si(), .so(),
|
200 |
|
|
.rst_l (arst_l));
|
201 |
|
|
|
202 |
|
|
assign mbist_reset = ~mbist_reset_l;
|
203 |
|
|
|
204 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
205 |
|
|
//
|
206 |
|
|
// MBIST Config Register
|
207 |
|
|
//
|
208 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
209 |
|
|
//
|
210 |
|
|
// A low to high transition on mbist_start will reset and start the engine.
|
211 |
|
|
// mbist_start must remain active high for the duration of MBIST.
|
212 |
|
|
// If mbist_start deasserts the engine will stop but not reset.
|
213 |
|
|
// Once MBIST has completed mbist_done will assert and the fail status
|
214 |
|
|
// signals will be valid.
|
215 |
|
|
// To run MBIST again the mbist_start signal must transition low then high.
|
216 |
|
|
//
|
217 |
|
|
// Loop on Address will disable the address mix function.
|
218 |
|
|
//
|
219 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
220 |
|
|
|
221 |
|
|
|
222 |
|
|
|
223 |
|
|
dff_s #(8) config_reg (
|
224 |
|
|
.clk ( rclk ),
|
225 |
|
|
.din ( config_in[7:0] ),
|
226 |
|
|
.q ( config_out[7:0] ), .se(mbist_se), .si(), .so());
|
227 |
|
|
|
228 |
|
|
|
229 |
|
|
|
230 |
|
|
assign config_in[0] = mbist_start;
|
231 |
|
|
assign config_in[1] = config_out[0];
|
232 |
|
|
assign start_transition = config_out[0] & ~config_out[1];
|
233 |
|
|
assign reset_engine = mbist_reset | start_transition | ((loop | loop_on_address) & mbist_done);
|
234 |
|
|
assign run = config_out[1] & ~mbist_done_int;
|
235 |
|
|
assign mbist_ifq_run_bist = run;
|
236 |
|
|
|
237 |
|
|
assign config_in[2] = start_transition ? mbist_bisi_mode: config_out[2];
|
238 |
|
|
assign bisi = config_out[2];
|
239 |
|
|
|
240 |
|
|
assign config_in[3] = start_transition ? mbist_userdata_mode: config_out[3];
|
241 |
|
|
assign userdata_mode = config_out[3];
|
242 |
|
|
|
243 |
|
|
assign config_in[4] = start_transition ? mbist_loop_mode: config_out[4];
|
244 |
|
|
assign loop = config_out[4];
|
245 |
|
|
|
246 |
|
|
assign config_in[5] = start_transition ? mbist_stop_on_fail: config_out[5];
|
247 |
|
|
assign stop_on_fail = config_out[5];
|
248 |
|
|
|
249 |
|
|
assign config_in[6] = start_transition ? mbist_stop_on_next_fail: config_out[6];
|
250 |
|
|
assign stop_on_next_fail = config_out[6];
|
251 |
|
|
|
252 |
|
|
assign config_in[7] = start_transition ? mbist_loop_on_address: config_out[7];
|
253 |
|
|
assign loop_on_address = config_out[7];
|
254 |
|
|
|
255 |
|
|
|
256 |
|
|
dff_s #(8) userdata_reg (
|
257 |
|
|
.clk ( rclk ),
|
258 |
|
|
.din ( userdata_in[7:0] ),
|
259 |
|
|
.q ( userdata_out[7:0] ), .se(mbist_se), .si(), .so());
|
260 |
|
|
|
261 |
|
|
|
262 |
|
|
assign userdata_in[7:0] = userdata_out[7:0];
|
263 |
|
|
|
264 |
|
|
|
265 |
|
|
|
266 |
|
|
|
267 |
|
|
dff_s #(7) user_address_reg (
|
268 |
|
|
.clk ( rclk ),
|
269 |
|
|
.din ( useradd_in[6:0] ),
|
270 |
|
|
.q ( useradd_out[6:0] ), .se(mbist_se), .si(), .so());
|
271 |
|
|
|
272 |
|
|
assign useradd_in[6:0] = useradd_out[6:0];
|
273 |
|
|
|
274 |
|
|
|
275 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
276 |
|
|
//
|
277 |
|
|
// MBIST Control Register
|
278 |
|
|
//
|
279 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
280 |
|
|
// Remove Address mix disable before delivery
|
281 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
282 |
|
|
|
283 |
|
|
|
284 |
|
|
dff_s #(21) control_reg (
|
285 |
|
|
.clk ( rclk ),
|
286 |
|
|
.din ( control_in[20:0] ),
|
287 |
|
|
.q ( control_out[20:0] ), .se(mbist_se), .si(), .so());
|
288 |
|
|
|
289 |
|
|
assign msb = control_out[20];
|
290 |
|
|
assign array_sel = control_out[19];
|
291 |
|
|
assign data_control[1:0] = userdata_mode ? 2'b11 : control_out[18:17];
|
292 |
|
|
assign address_mix = loop_on_address ? 1'b1: control_out[16];
|
293 |
|
|
assign mbist_word_sel = loop_on_address ? 1'b1 : control_out[15];
|
294 |
|
|
assign march_element[2:0] = control_out[14:12];
|
295 |
|
|
assign array_address[9:0] = loop_on_address ? {6'h3f, control_out[5:2]}:
|
296 |
|
|
(dcache_sel & ~bisi) ? {1'd1, control_out[10:2]}: control_out[11:2];
|
297 |
|
|
assign read_write_control[1:0] = control_out[1:0];
|
298 |
|
|
|
299 |
|
|
assign qual_control_out[20:0] = {msb, array_sel, data_control[1:0], address_mix, mbist_word_sel, march_element[2:0], array_address[9:0], read_write_control[1:0]};
|
300 |
|
|
|
301 |
|
|
// added by Chandra
|
302 |
|
|
|
303 |
|
|
wire [1:0] add_data_int;
|
304 |
|
|
wire [20:0] add_data;
|
305 |
|
|
wire [9:0] mbist_address_bf;
|
306 |
|
|
|
307 |
|
|
assign add_data_int[1:0] = four_cycle_march ? 2'b01: 2'b10;
|
308 |
|
|
assign add_data[20:0] = qual_control_out[20:0] + {19'd0, add_data_int};
|
309 |
|
|
assign control_in[20:0] = {21{~run & ~reset_engine}} & qual_control_out | {21{run & ~reset_engine}} & add_data;
|
310 |
|
|
|
311 |
|
|
assign add[9:0] = upaddress_march ? array_address[9:0]: ~array_address[9:0];
|
312 |
|
|
assign mbist_address_bf[9:0] = loop_on_address ? {useradd_out[5:0], add[3:0]}:
|
313 |
|
|
address_mix ? (dcache_sel ? ({add[9:8], add[0], add[7:1]}) : ({add[9:8], add[6:0], add[7]})) :
|
314 |
|
|
add[9:0];
|
315 |
|
|
|
316 |
|
|
|
317 |
|
|
|
318 |
|
|
assign array_write = ~run ? 1'b0:
|
319 |
|
|
four_cycle_march ? (read_write_control[0] ^ read_write_control[1]): read_write_control[1];
|
320 |
|
|
assign array_read = ~array_write && run && ~initialize;
|
321 |
|
|
|
322 |
|
|
assign mbist_done_int = (stop_on_fail && fail) || (stop_on_next_fail && fail) ||
|
323 |
|
|
(bisi && march_element[0]) || msb;
|
324 |
|
|
|
325 |
|
|
assign mbist_done = (stop_on_fail && fail) || (stop_on_next_fail && fail) ||
|
326 |
|
|
(bisi && march_element[0]) || msb_d4;
|
327 |
|
|
|
328 |
|
|
////////////
|
329 |
|
|
////////////
|
330 |
|
|
|
331 |
|
|
wire [7:0] mbist_write_data_bf;
|
332 |
|
|
|
333 |
|
|
assign mbist_write_data_bf[7:0] = true_data ? data_pattern[7:0]: ~data_pattern[7:0];
|
334 |
|
|
assign mbist_dcache_wdata[7:0] = mbist_write_data_bf[7:0];
|
335 |
|
|
|
336 |
|
|
assign second_time_through = ~loop_on_address && address_mix;
|
337 |
|
|
assign initialize = (march_element[2:0] == 3'b000) && ~second_time_through;
|
338 |
|
|
assign four_cycle_march = (march_element[2:0] == 3'h6) || (march_element[2:0] == 3'h7);
|
339 |
|
|
assign upaddress_march = (march_element[2:0] == 3'h0) || (march_element[2:0] == 3'h1) ||
|
340 |
|
|
(march_element[2:0] == 3'h2) || (march_element[2:0] == 3'h6);
|
341 |
|
|
|
342 |
|
|
assign true_data = read_write_control[1] ^ ~march_element[0];
|
343 |
|
|
assign data_pattern[7:0] = userdata_mode ? userdata_out[7:0]:
|
344 |
|
|
bisi ? 8'hFF: // true_data function will invert to 8'h00
|
345 |
|
|
(data_control[1:0] == 2'h0) ? 8'hAA:
|
346 |
|
|
(data_control[1:0] == 2'h1) ? 8'h99:
|
347 |
|
|
(data_control[1:0] == 2'h2) ? 8'hCC:
|
348 |
|
|
8'h00;
|
349 |
|
|
assign dcache_sel = ~array_sel;
|
350 |
|
|
assign icache_sel = array_sel;
|
351 |
|
|
|
352 |
|
|
////////////
|
353 |
|
|
////////////
|
354 |
|
|
|
355 |
|
|
assign mbist_dcache_index[6:0] = mbist_address[6:0];
|
356 |
|
|
assign mbist_dcache_way[1:0] = (mbist_address[8:7] & {2{config_out[0]}});
|
357 |
|
|
assign mbist_dcache_word = mbist_address[10];
|
358 |
|
|
assign mbist_dcache_read = dcache_sel && array_read;
|
359 |
|
|
assign mbist_dcache_write = (dcache_sel || bisi) && array_write;
|
360 |
|
|
|
361 |
|
|
assign mbist_icache_index[7:0] = mbist_address[7:0];
|
362 |
|
|
assign mbist_icache_way[1:0] = (mbist_address[9:8] & {2{config_out[0]}});
|
363 |
|
|
assign mbist_icache_word = mbist_address[10];
|
364 |
|
|
assign mbist_icache_read_bf = icache_sel && array_read;
|
365 |
|
|
assign mbist_icache_write_bf = (icache_sel || bisi) && array_write;
|
366 |
|
|
|
367 |
|
|
////////////////////////
|
368 |
|
|
////////////////////////
|
369 |
|
|
|
370 |
|
|
assign msb_rst = msb & ~reset_engine;
|
371 |
|
|
dff_s #(1) msb_d1_inst(
|
372 |
|
|
.clk ( rclk ),
|
373 |
|
|
.din ( msb_rst ),
|
374 |
|
|
.q ( msb_d1 ), .se(mbist_se), .si(), .so());
|
375 |
|
|
assign msb_d1_rst = msb_d1 & ~reset_engine;
|
376 |
|
|
dff_s #(1) msb_d2_inst(
|
377 |
|
|
.clk ( rclk ),
|
378 |
|
|
.din ( msb_d1_rst ),
|
379 |
|
|
.q ( msb_d2 ), .se(mbist_se), .si(), .so());
|
380 |
|
|
assign msb_d2_rst = msb_d2 & ~reset_engine;
|
381 |
|
|
dff_s #(1) msb_d3_inst(
|
382 |
|
|
.clk ( rclk ),
|
383 |
|
|
.din ( msb_d2_rst ),
|
384 |
|
|
.q ( msb_d3 ), .se(mbist_se), .si(), .so());
|
385 |
|
|
assign msb_d3_rst = msb_d3 & ~reset_engine;
|
386 |
|
|
dff_s #(1) msb_d4_inst(
|
387 |
|
|
.clk ( rclk ),
|
388 |
|
|
.din ( msb_d3_rst ),
|
389 |
|
|
.q ( msb_d4 ), .se(mbist_se), .si(), .so());
|
390 |
|
|
|
391 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
392 |
|
|
// Pipeline for Read, Data, and Address
|
393 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
394 |
|
|
|
395 |
|
|
wire dc_read_pipe_out3, dc_read_pipe_out4, ic_read_pipe_out3, ic_read_pipe_out4;
|
396 |
|
|
wire dc_read_pipe_out1_bf, dc_read_pipe_out2_bf, dc_read_pipe_out3_bf;
|
397 |
|
|
wire ic_read_pipe_out1_bf, ic_read_pipe_out2_bf, ic_read_pipe_out3_bf;
|
398 |
|
|
|
399 |
|
|
////////////
|
400 |
|
|
////////////
|
401 |
|
|
|
402 |
|
|
dff_s #(1) dc_read_pipe_reg1 (
|
403 |
|
|
.clk ( rclk ),
|
404 |
|
|
.din ( mbist_dcache_read ),
|
405 |
|
|
.q ( dc_read_pipe_out1 ), .se(mbist_se), .si(), .so());
|
406 |
|
|
|
407 |
|
|
assign dc_read_pipe_out1_bf = dc_read_pipe_out1 & ~reset_engine;
|
408 |
|
|
|
409 |
|
|
dff_s #(1) dc_read_pipe_reg2 (
|
410 |
|
|
.clk ( rclk ),
|
411 |
|
|
.din ( dc_read_pipe_out1_bf ),
|
412 |
|
|
.q ( dc_read_pipe_out2 ), .se(mbist_se), .si(), .so());
|
413 |
|
|
|
414 |
|
|
assign dc_read_pipe_out2_bf = dc_read_pipe_out2 & ~reset_engine;
|
415 |
|
|
|
416 |
|
|
dff_s #(1) dc_read_pipe_reg3 (
|
417 |
|
|
.clk ( rclk ),
|
418 |
|
|
.din ( dc_read_pipe_out2_bf ),
|
419 |
|
|
.q ( dc_read_pipe_out3 ), .se(mbist_se), .si(), .so());
|
420 |
|
|
|
421 |
|
|
assign dc_read_pipe_out3_bf = dc_read_pipe_out3 & ~reset_engine;
|
422 |
|
|
assign dcache_data_sel = dc_read_pipe_out3_bf;
|
423 |
|
|
|
424 |
|
|
dff_s #(1) dc_read_pipe_reg4 (
|
425 |
|
|
.clk ( rclk ),
|
426 |
|
|
.din ( dc_read_pipe_out3_bf ),
|
427 |
|
|
.q ( dc_read_pipe_out4 ), .se(mbist_se), .si(), .so());
|
428 |
|
|
|
429 |
|
|
assign dcache_piped_read = dc_read_pipe_out4 & ~reset_engine;
|
430 |
|
|
|
431 |
|
|
////////////
|
432 |
|
|
////////////
|
433 |
|
|
|
434 |
|
|
dff_s #(1) ic_read_pipe_reg1 (
|
435 |
|
|
.clk ( rclk ),
|
436 |
|
|
.din ( mbist_icache_read_bf ),
|
437 |
|
|
.q ( ic_read_pipe_out1 ), .se(mbist_se), .si(), .so());
|
438 |
|
|
|
439 |
|
|
assign ic_read_pipe_out1_bf = ic_read_pipe_out1 & ~reset_engine;
|
440 |
|
|
assign mbist_icache_read = ic_read_pipe_out1;
|
441 |
|
|
|
442 |
|
|
dff_s #(1) ic_read_pipe_reg2 (
|
443 |
|
|
.clk ( rclk ),
|
444 |
|
|
.din ( ic_read_pipe_out1_bf ),
|
445 |
|
|
.q ( ic_read_pipe_out2 ), .se(mbist_se), .si(), .so());
|
446 |
|
|
|
447 |
|
|
assign ic_read_pipe_out2_bf = ic_read_pipe_out2 & ~reset_engine;
|
448 |
|
|
|
449 |
|
|
dff_s #(1) ic_read_pipe_reg3 (
|
450 |
|
|
.clk ( rclk ),
|
451 |
|
|
.din ( ic_read_pipe_out2_bf ),
|
452 |
|
|
.q ( ic_read_pipe_out3 ), .se(mbist_se), .si(), .so());
|
453 |
|
|
|
454 |
|
|
assign ic_read_pipe_out3_bf = ic_read_pipe_out3 & ~reset_engine;
|
455 |
|
|
|
456 |
|
|
dff_s #(1) ic_read_pipe_reg4 (
|
457 |
|
|
.clk ( rclk ),
|
458 |
|
|
.din ( ic_read_pipe_out3_bf ),
|
459 |
|
|
.q ( ic_read_pipe_out4 ), .se(mbist_se), .si(), .so());
|
460 |
|
|
|
461 |
|
|
|
462 |
|
|
assign icache_piped_read = ic_read_pipe_out4 & ~reset_engine;
|
463 |
|
|
|
464 |
|
|
////////////
|
465 |
|
|
////////////
|
466 |
|
|
|
467 |
|
|
dff_s #(1) ic_write_pipe_reg1 (
|
468 |
|
|
.clk ( rclk ),
|
469 |
|
|
.din ( mbist_icache_write_bf ),
|
470 |
|
|
.q ( mbist_icache_write ), .se(mbist_se), .si(), .so());
|
471 |
|
|
|
472 |
|
|
////////////
|
473 |
|
|
////////////
|
474 |
|
|
|
475 |
|
|
wire [7:0] data_pipe_out3, data_pipe_out4;
|
476 |
|
|
|
477 |
|
|
dff_s #(8) data_pipe_reg1 (
|
478 |
|
|
.clk ( rclk ),
|
479 |
|
|
.din ( mbist_write_data_bf[7:0] ),
|
480 |
|
|
.q ( data_pipe_out1[7:0] ), .se(mbist_se), .si(), .so());
|
481 |
|
|
|
482 |
|
|
assign mbist_icache_wdata = data_pipe_out1;
|
483 |
|
|
|
484 |
|
|
dff_s #(8) data_pipe_reg2 (
|
485 |
|
|
.clk ( rclk ),
|
486 |
|
|
.din ( data_pipe_out1[7:0] ),
|
487 |
|
|
.q ( data_pipe_out2[7:0] ), .se(mbist_se), .si(), .so());
|
488 |
|
|
|
489 |
|
|
dff_s #(8) data_pipe_reg3 (
|
490 |
|
|
.clk ( rclk ),
|
491 |
|
|
.din ( data_pipe_out2[7:0] ),
|
492 |
|
|
.q ( data_pipe_out3[7:0] ), .se(mbist_se), .si(), .so());
|
493 |
|
|
|
494 |
|
|
dff_s #(8) data_pipe_reg4 (
|
495 |
|
|
.clk ( rclk ),
|
496 |
|
|
.din ( data_pipe_out3[7:0] ),
|
497 |
|
|
.q ( data_pipe_out4[7:0] ), .se(mbist_se), .si(), .so());
|
498 |
|
|
|
499 |
|
|
|
500 |
|
|
////////////
|
501 |
|
|
////////////
|
502 |
|
|
|
503 |
|
|
wire [10:0] add_pipe_out3, add_pipe_out4;
|
504 |
|
|
wire mbist_word_sel_bf;
|
505 |
|
|
|
506 |
|
|
assign mbist_word_sel_bf = loop_on_address ? useradd_out[6] : mbist_word_sel;
|
507 |
|
|
|
508 |
|
|
dff_s #(11) add_pipe_reg1 (
|
509 |
|
|
.clk ( rclk ),
|
510 |
|
|
.din ( {mbist_word_sel_bf, mbist_address_bf[9:0]} ),
|
511 |
|
|
.q ( add_pipe_out1[10:0] ), .se(mbist_se), .si(), .so());
|
512 |
|
|
|
513 |
|
|
assign mbist_address = add_pipe_out1;
|
514 |
|
|
|
515 |
|
|
dff_s #(11) add_pipe_reg2 (
|
516 |
|
|
.clk ( rclk ),
|
517 |
|
|
.din ( add_pipe_out1[10:0] ),
|
518 |
|
|
.q ( add_pipe_out2[10:0] ), .se(mbist_se), .si(), .so());
|
519 |
|
|
|
520 |
|
|
dff_s #(11) add_pipe_reg3 (
|
521 |
|
|
.clk ( rclk ),
|
522 |
|
|
.din ( add_pipe_out2[10:0] ),
|
523 |
|
|
.q ( add_pipe_out3[10:0] ), .se(mbist_se), .si(), .so());
|
524 |
|
|
|
525 |
|
|
dff_s #(11) add_pipe_reg4 (
|
526 |
|
|
.clk ( rclk ),
|
527 |
|
|
.din ( add_pipe_out3[10:0] ),
|
528 |
|
|
.q ( add_pipe_out4[10:0] ), .se(mbist_se), .si(), .so());
|
529 |
|
|
|
530 |
|
|
|
531 |
|
|
assign dcache_piped_address[9:0] = {add_pipe_out4[10], add_pipe_out4[8:0]};
|
532 |
|
|
assign icache_piped_address[10:0] = add_pipe_out4[10:0];
|
533 |
|
|
|
534 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
535 |
|
|
// Shared Fail Detection
|
536 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
537 |
|
|
|
538 |
|
|
dff_s #(2) fail_reg (
|
539 |
|
|
.clk ( rclk ),
|
540 |
|
|
.din ( fail_reg_in[1:0] ),
|
541 |
|
|
.q ( fail_reg_out[1:0] ), .se(mbist_se), .si(), .so());
|
542 |
|
|
|
543 |
|
|
|
544 |
|
|
assign fail_reg_in[1:0] = reset_engine ? 2'b0: {qual_dcache_fail,qual_icache_fail} | fail_reg_out[1:0];
|
545 |
|
|
|
546 |
|
|
|
547 |
|
|
assign qual_dcache_fail = (!stop_on_next_fail || (stop_on_next_fail && beyond_last_fail)) && dcache_fail;
|
548 |
|
|
assign qual_icache_fail = (!stop_on_next_fail || (stop_on_next_fail && beyond_last_fail)) && icache_fail;
|
549 |
|
|
|
550 |
|
|
assign dcache_fail = dcache_piped_read && mismatch;
|
551 |
|
|
assign icache_fail = icache_piped_read && mismatch;
|
552 |
|
|
|
553 |
|
|
// added by Chandra
|
554 |
|
|
|
555 |
|
|
// assign expect_data[71:0] = { ({4{dcache_piped_read}} & data_pipe_out4[7:4]),
|
556 |
|
|
// (icache_piped_read ? {2{data_pipe_out4[1:0]}} : data_pipe_out4[3:0]), {8{data_pipe_out4[7:0]}}};
|
557 |
|
|
|
558 |
|
|
assign expect_data[71:0] = { ({4{dcache_piped_read}} & data_pipe_out4[7:4]),
|
559 |
|
|
(icache_piped_read ? {2{data_pipe_out4[1:0]}} : data_pipe_out4[3:0]), {7{data_pipe_out4[7:0]}},
|
560 |
|
|
(icache_piped_read ? data_pipe_out4[7:4] : data_pipe_out4[3:0]), data_pipe_out4[3:0] };
|
561 |
|
|
|
562 |
|
|
assign compare_data_bf[71:0] = dcache_data_sel ? mbist_dcache_data_in[71:0]: {4'h0,mbist_icache_data_in[67:0]};
|
563 |
|
|
|
564 |
|
|
dff_s #(72) compare_data_inst(
|
565 |
|
|
.clk ( rclk ),
|
566 |
|
|
.din ( compare_data_bf[71:0] ),
|
567 |
|
|
.q ( compare_data[71:0] ), .se(mbist_se), .si(), .so());
|
568 |
|
|
|
569 |
|
|
assign mismatch = expect_data[71:0] != compare_data[71:0];
|
570 |
|
|
|
571 |
|
|
|
572 |
|
|
assign mbist_dcache_fail = fail_reg_out[1];
|
573 |
|
|
assign mbist_icache_fail = fail_reg_out[0];
|
574 |
|
|
|
575 |
|
|
assign fail = |fail_reg_out[1:0];
|
576 |
|
|
assign qual_fail = qual_dcache_fail || qual_icache_fail;
|
577 |
|
|
|
578 |
|
|
|
579 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
580 |
|
|
// Fail Address and Data Capture and Control Reg Store
|
581 |
|
|
// /////////////////////////////////////////////////////////////////////////////
|
582 |
|
|
|
583 |
|
|
|
584 |
|
|
|
585 |
|
|
dff_s #(11) fail_add_reg(
|
586 |
|
|
.clk ( rclk ),
|
587 |
|
|
.din ( fail_add_reg_in[10:0] ),
|
588 |
|
|
.q ( fail_add_reg_out[10:0] ), .se(mbist_se), .si(), .so());
|
589 |
|
|
|
590 |
|
|
|
591 |
|
|
assign fail_add_reg_in[10:0] = reset_engine ? 11'b0:
|
592 |
|
|
qual_dcache_fail ? {1'b0,dcache_piped_address[9:0]}:
|
593 |
|
|
qual_icache_fail ? icache_piped_address[10:0]:
|
594 |
|
|
fail_add_reg_out[10:0];
|
595 |
|
|
|
596 |
|
|
|
597 |
|
|
dff_s #(72) fail_data_reg(
|
598 |
|
|
.clk ( rclk ),
|
599 |
|
|
.din ( fail_data_reg_in[71:0] ),
|
600 |
|
|
.q ( fail_data_reg_out[71:0] ), .se(mbist_se), .si(), .so());
|
601 |
|
|
|
602 |
|
|
|
603 |
|
|
assign fail_data_reg_in[71:0] = reset_engine ? 72'b0:
|
604 |
|
|
qual_fail ? compare_data[71:0]:
|
605 |
|
|
fail_data_reg_out[71:0];
|
606 |
|
|
|
607 |
|
|
|
608 |
|
|
assign fail_control_reg_in[20:0] = (reset_engine && !mbist_stop_on_next_fail) ? 21'b0:
|
609 |
|
|
qual_fail ? qual_control_out[20:0]:
|
610 |
|
|
fail_control_reg_out[20:0];
|
611 |
|
|
|
612 |
|
|
dff_s #(21) fail_control_reg_inst(
|
613 |
|
|
.clk ( rclk ),
|
614 |
|
|
.din ( fail_control_reg_in[20:0] ),
|
615 |
|
|
.q ( fail_control_reg_out[20:0] ), .se(mbist_se), .si(), .so());
|
616 |
|
|
|
617 |
|
|
////////
|
618 |
|
|
|
619 |
|
|
assign beyond_last_fail = qual_control_out[20:0] > fail_control_reg_out[20:0];
|
620 |
|
|
|
621 |
|
|
|
622 |
|
|
endmodule
|