Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: system_reset.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 | module system_reset ( | |
36 | Sysclk, | |
37 | Core_clk, | |
38 | Ssi_sync_l, | |
39 | Tck, | |
40 | Button_xir_l, | |
41 | Pb_rst_l, | |
42 | Pwr_on_rst_l, | |
43 | Trst_l, | |
44 | Tb_reset, | |
45 | Fbdimm_rst, | |
46 | niu_reset, | |
47 | flush_reset_complete | |
48 | ); | |
49 | ||
50 | input Sysclk; | |
51 | input Core_clk; | |
52 | input Ssi_sync_l; | |
53 | input Tck; | |
54 | output Button_xir_l; | |
55 | output Pb_rst_l; | |
56 | output Pwr_on_rst_l; | |
57 | output Trst_l; | |
58 | output Tb_reset; | |
59 | output Fbdimm_rst; | |
60 | output niu_reset; | |
61 | output flush_reset_complete; | |
62 | ||
63 | ||
64 | /* | |
65 | * stick to old names | |
66 | */ | |
67 | wire sysclk_i = Sysclk; | |
68 | wire core_clk_i = Core_clk; | |
69 | wire ssi_sync_l_i = Ssi_sync_l; | |
70 | ||
71 | wire POR_from_UserEvent; //// vera interface signal mono-shot NR0 | |
72 | wire PB_RST_from_UserEvent; // vera interface signal mono-shot NR0 | |
73 | ||
74 | // Note: gOutOfBoot starts out 0 at time 0, then each bit | |
75 | // becomes 1 as its thread executes the bootEnd user event. | |
76 | // It gets cleared when each thread executes bootStart, | |
77 | // NOT when POR/WMR gets asserted. | |
78 | // NB: Not_in_Boot is monitored by fc_csr_cabinet.v | |
79 | wire Not_in_Boot = (`TOP.gOutOfBoot == `PARGS.finish_mask); | |
80 | ||
81 | wire POR_pulse_mux; | |
82 | ||
83 | reg button_xir_l_o; | |
84 | reg pb_rst_l_o; | |
85 | reg pwr_on_rst_l_o; | |
86 | reg trst_l_o; | |
87 | reg tb_reset_o; | |
88 | reg fbdimm_rst_o; | |
89 | reg niu_reset_o; | |
90 | reg flush_reset_complete_o; | |
91 | ||
92 | integer status; | |
93 | ||
94 | /* | |
95 | * When we do not slam for vectors the complete control for | |
96 | * these signals is given to vera and all primary outputs are | |
97 | * driven to Z | |
98 | */ | |
99 | `ifdef NON_SLAM_VECTORS | |
100 | initial begin | |
101 | button_xir_l_o = 1'bz; | |
102 | pb_rst_l_o = 1'bz; | |
103 | pwr_on_rst_l_o = 1'bz; | |
104 | trst_l_o = 1'bz; | |
105 | end | |
106 | `endif | |
107 | ||
108 | /* | |
109 | * A mux is used to turn on user event driven resets, | |
110 | * after the intial POR is done then we can use the | |
111 | * software based resets | |
112 | */ | |
113 | reg user_event_por, user_event_pb; | |
114 | initial begin | |
115 | if($test$plusargs("SW_RANDOM_PB_RST")) | |
116 | user_event_pb = 1; | |
117 | else | |
118 | user_event_pb = 0; | |
119 | end | |
120 | ||
121 | initial begin | |
122 | if($test$plusargs("SW_RANDOM_POR")) | |
123 | user_event_por = 1; | |
124 | else | |
125 | user_event_por = 0; | |
126 | end | |
127 | ||
128 | ||
129 | /* | |
130 | * Flush reset complete is a test bench signal | |
131 | */ | |
132 | initial flush_reset_complete_o = 0; | |
133 | always @(posedge core_clk_i) begin | |
134 | if (`CPU.rst_ncu_unpark_thread) | |
135 | flush_reset_complete_o=1; | |
136 | else if (`CPU.rst_wmr_protect == 1) | |
137 | flush_reset_complete_o= 0; | |
138 | end | |
139 | // core_clk_i stops during POR, so we cannot use the above loop | |
140 | // to sample Pwr_on_rst_l (only a problem if there is a second POR) | |
141 | always @(posedge sysclk_i) begin | |
142 | if (Pwr_on_rst_l === 1'b0) // Make sure it isn't X | |
143 | flush_reset_complete_o= 0; | |
144 | end | |
145 | ||
146 | ||
147 | /* | |
148 | * Mission mode & SLAM VECTORS model | |
149 | */ | |
150 | /**************************************************************************** | |
151 | * Drive POR -- POWER ON RESET | |
152 | ****************************************************************************/ | |
153 | integer delay_to_first_POR; | |
154 | integer delay_between_POR; | |
155 | integer max_num_injected_POR; | |
156 | reg POR_pulse; | |
157 | reg start_POR_delay; | |
158 | event end_POR_delay; | |
159 | integer injected_POR_count; | |
160 | reg max_injected_POR_count_reached; | |
161 | integer POR_pulse_width; | |
162 | integer POR_delay; | |
163 | ||
164 | // Set up the user-adjustable values for POR | |
165 | initial begin | |
166 | // Set the duration of POR pulse width in SYSCLK cycles | |
167 | if (0 == $value$plusargs("POR_pulse_width=%d",POR_pulse_width)) | |
168 | POR_pulse_width = 2; | |
169 | `PR_NORMAL("system_reset", `NORMAL, "PWRON_RST_L pulse width = %d SYSCLK cycles (+POR_pulse_width)", POR_pulse_width); | |
170 | // Set the delay in SYSCLK cycles from bootEnd to the first POR | |
171 | if (0 == $value$plusargs("delay_to_first_POR=%d", delay_to_first_POR)) | |
172 | delay_to_first_POR = 200; | |
173 | `PR_NORMAL("system_reset", `NORMAL, "Delay to first injected PWRON_RST_L = %d SYSCLK cycles (+delay_to_first_POR)", delay_to_first_POR); | |
174 | POR_delay = delay_to_first_POR; | |
175 | // Set the delay between PORs in terms of SYSCLK cycles | |
176 | if (0 == $value$plusargs("delay_between_POR=%d", delay_between_POR)) | |
177 | delay_between_POR = 1000; | |
178 | `PR_NORMAL("system_reset", `NORMAL, "Additional delay per injected PWRON_RST_L pulse = %d SYSCLK cycles (+delay_between_POR)", delay_between_POR); | |
179 | // Set the maximum number of injected PORs; 0=>just initial POR | |
180 | if (0 == $value$plusargs("max_num_injected_POR=%d", max_num_injected_POR)) | |
181 | max_num_injected_POR = 0; | |
182 | `PR_NORMAL("system_reset", `NORMAL, "Maximum number of injected PWRON_RST_L pulse = %d (+max_num_injected_POR)", max_num_injected_POR); | |
183 | max_injected_POR_count_reached = (max_num_injected_POR == 0); | |
184 | end // initial begin | |
185 | ||
186 | initial begin | |
187 | injected_POR_count = 0; | |
188 | POR_pulse = 0; | |
189 | @(negedge sysclk_i); // Wait for first system clock | |
190 | POR_pulse <= 1; | |
191 | // Wait for TRST_L to assert and deassert | |
192 | wait (Trst_l === 1'b0); | |
193 | wait (Trst_l === 1'b1); | |
194 | #1; // Eliminate any race between posedge Trst_l and negedge Tck | |
195 | // Per PRM section 13.9.1, we need to wait for 5 TCKs after TRST_L | |
196 | repeat(5) @(negedge Tck); | |
197 | #1; // Eliminate any race between negedge Tck and negedge sysclk_i | |
198 | repeat(POR_pulse_width) @(negedge sysclk_i); // Deassert on negedge | |
199 | POR_pulse <= 0; | |
200 | `PR_NORMAL("system_reset", `NORMAL, "Deasserting initial PWRON_RST_L"); | |
201 | // Generate a POR pulse at end_POR_delay | |
202 | forever @(end_POR_delay) begin | |
203 | @(negedge sysclk_i); // Always assert on negedge: N2 samples on posedge | |
204 | `PR_NORMAL("system_reset", `NORMAL, "Asserting PWRON_RST_L"); | |
205 | POR_pulse <= 1; | |
206 | // Wait for TRST_L to assert and deassert | |
207 | wait (Trst_l === 1'b0); | |
208 | wait (Trst_l === 1'b1); | |
209 | #1; // Eliminate any race between posedge Trst_l and negedge Tck | |
210 | // Per PRM section 13.9.1, we need to wait for 5 TCKs after TRST_L | |
211 | repeat(5) @(negedge Tck); | |
212 | #1; // Eliminate any race between negedge Tck and negedge sysclk_i | |
213 | repeat(POR_pulse_width) @(negedge sysclk_i); // Deassert on negedge | |
214 | `PR_NORMAL("system_reset", `NORMAL, "Deasserting PWRON_RST_L"); | |
215 | POR_pulse <= 0; | |
216 | injected_POR_count = injected_POR_count + 1; | |
217 | if (injected_POR_count == max_num_injected_POR) | |
218 | max_injected_POR_count_reached = 1; | |
219 | end | |
220 | end // initial begin | |
221 | ||
222 | ||
223 | initial begin | |
224 | #1; // Wait for any glitches at time=0 to pass | |
225 | forever @(posedge start_POR_delay) begin | |
226 | repeat(POR_delay) @(posedge sysclk_i); | |
227 | -> end_POR_delay; | |
228 | // Increase the delay for the next time | |
229 | POR_delay = POR_delay + delay_between_POR; | |
230 | end | |
231 | end | |
232 | ||
233 | // Define the states for the reset injector state machines | |
234 | parameter START_RESET_COUNTDOWN = 0; | |
235 | parameter WAIT_FOR_RESET_COUNTDOWN = 1; | |
236 | parameter WAIT_FOR_BOOT_CODE_START = 2; | |
237 | parameter WAIT_FOR_BOOT_CODE_END = 3; | |
238 | parameter NO_MORE_INJECTED_RESETS = 4; | |
239 | ||
240 | integer POR_state, next_POR_state; | |
241 | initial begin | |
242 | start_POR_delay = 0; | |
243 | POR_state = WAIT_FOR_BOOT_CODE_START; | |
244 | next_POR_state = WAIT_FOR_BOOT_CODE_START; | |
245 | end | |
246 | ||
247 | always @(posedge sysclk_i) begin | |
248 | POR_state <= next_POR_state; | |
249 | end | |
250 | ||
251 | always @(POR_state or POR_pulse or Not_in_Boot or max_injected_POR_count_reached) begin | |
252 | case(POR_state) | |
253 | START_RESET_COUNTDOWN: begin | |
254 | next_POR_state = WAIT_FOR_RESET_COUNTDOWN; | |
255 | start_POR_delay = 1; | |
256 | end | |
257 | WAIT_FOR_RESET_COUNTDOWN: begin | |
258 | start_POR_delay = 0; | |
259 | if (POR_pulse) | |
260 | next_POR_state = WAIT_FOR_BOOT_CODE_START; | |
261 | else | |
262 | next_POR_state = WAIT_FOR_RESET_COUNTDOWN; | |
263 | end | |
264 | WAIT_FOR_BOOT_CODE_START: begin | |
265 | // On 2nd POR, Not_in_Boot will remain asserted until | |
266 | // the first instruction is executed ("bootStart" user event) | |
267 | if (Not_in_Boot) | |
268 | next_POR_state = WAIT_FOR_BOOT_CODE_START; | |
269 | else | |
270 | next_POR_state = WAIT_FOR_BOOT_CODE_END; | |
271 | end | |
272 | WAIT_FOR_BOOT_CODE_END: begin | |
273 | if (Not_in_Boot) begin | |
274 | if (max_injected_POR_count_reached) begin | |
275 | next_POR_state = NO_MORE_INJECTED_RESETS; | |
276 | end | |
277 | else begin | |
278 | next_POR_state = START_RESET_COUNTDOWN; | |
279 | end | |
280 | end else begin | |
281 | next_POR_state = WAIT_FOR_BOOT_CODE_END; | |
282 | end | |
283 | end | |
284 | NO_MORE_INJECTED_RESETS: begin | |
285 | next_POR_state = NO_MORE_INJECTED_RESETS; | |
286 | end | |
287 | endcase | |
288 | end | |
289 | ||
290 | /* | |
291 | * TRST asserts on every PWRON, but does not stay asserted as long | |
292 | */ | |
293 | always begin | |
294 | `ifndef USE_JTAG_DRIVER | |
295 | `PR_NORMAL("system_reset", `NORMAL, "Asserting TRST_L"); | |
296 | `endif | |
297 | trst_l_o <= 1'b0; | |
298 | // Wait for TCK to go thru one positive pulse (0->1->0) | |
299 | wait (Tck === 1'b0); | |
300 | @(negedge Tck); | |
301 | // Wait a little bit before deasserting TRST_L | |
302 | #1 @(negedge sysclk_i); | |
303 | `ifndef USE_JTAG_DRIVER | |
304 | `PR_NORMAL("system_reset", `NORMAL, "Deasserting TRST_L"); | |
305 | `endif | |
306 | trst_l_o <= 1'b1; | |
307 | // Done with this cycle. | |
308 | // Wait for next POR | |
309 | @(negedge Pwr_on_rst_l); | |
310 | end // always begin | |
311 | ||
312 | ||
313 | initial | |
314 | assign pwr_on_rst_l_o = ~POR_pulse; | |
315 | ||
316 | /* | |
317 | * FBDIMM reset is a mono shot reset | |
318 | */ | |
319 | reg mono_PWRON_RST_L; | |
320 | initial begin | |
321 | mono_PWRON_RST_L = 0; | |
322 | #1; // Wait for any glitches at time=0 to pass | |
323 | @(negedge POR_pulse); // Wait for end of first POR | |
324 | mono_PWRON_RST_L = 1; | |
325 | end | |
326 | assign Fbdimm_rst = mono_PWRON_RST_L; | |
327 | ||
328 | ||
329 | ||
330 | ||
331 | /*************************************************************************** | |
332 | * Drive PB reset | |
333 | ***************************************************************************/ | |
334 | integer delay_to_first_PB; | |
335 | integer delay_between_PB; | |
336 | integer max_num_injected_PB; | |
337 | reg PB_pulse; | |
338 | reg start_PB_delay; | |
339 | event end_PB_delay; | |
340 | integer injected_PB_count; | |
341 | reg max_injected_PB_count_reached; | |
342 | integer PB_pulse_width; | |
343 | integer PB_delay; | |
344 | ||
345 | // Set up the user-adjustable values for PB reset | |
346 | initial begin | |
347 | // Set the duration of PB pulse width in SYSCLK cycles | |
348 | if (0 == $value$plusargs("PB_pulse_width=%d",PB_pulse_width)) | |
349 | PB_pulse_width = 2; | |
350 | `PR_NORMAL("system_reset", `NORMAL, "PB_RST_L pulse width = %d SYSCLK cycles (+PB_pulse_width)", PB_pulse_width); | |
351 | // Set the delay in SYSCLK cycles from bootEnd to the first PB | |
352 | if (0 == $value$plusargs("delay_to_first_PB=%d", delay_to_first_PB)) | |
353 | delay_to_first_PB = 200; | |
354 | `PR_NORMAL("system_reset", `NORMAL, "Delay to first injected PB_RST_L = %d SYSCLK cycles (+delay_to_first_PB)", delay_to_first_PB); | |
355 | PB_delay = delay_to_first_PB; | |
356 | // Set the delay between PBs in terms of SYSCLK cycles | |
357 | if (0 == $value$plusargs("delay_between_PB=%d", delay_between_PB)) | |
358 | delay_between_PB = 1000; | |
359 | `PR_NORMAL("system_reset", `NORMAL, "Additional delay per injected PB_RST_L pulse = %d SYSCLK cycles (+delay_between_PB)", delay_between_PB); | |
360 | // Set the maximum number of injected PBs; 0=>no injected PBs | |
361 | if (0 == $value$plusargs("max_num_injected_PB=%d", max_num_injected_PB)) | |
362 | max_num_injected_PB = 0; | |
363 | `PR_NORMAL("system_reset", `NORMAL, "Maximum number of injected PB_RST_L pulse = %d (+max_num_injected_PB)", max_num_injected_PB); | |
364 | max_injected_PB_count_reached = (max_num_injected_PB == 0); | |
365 | end // initial begin | |
366 | ||
367 | initial begin | |
368 | injected_PB_count = 0; | |
369 | PB_pulse = 0; | |
370 | @(negedge sysclk_i); // Wait for first system clock | |
371 | // Generate a PB pulse at end_PB_delay | |
372 | forever @(end_PB_delay) begin | |
373 | @(negedge sysclk_i); // Always assert on negedge: N2 samples on posedge | |
374 | `PR_NORMAL("system_reset", `NORMAL, "Asserting PB_RST_L"); | |
375 | PB_pulse <= 1; | |
376 | repeat(PB_pulse_width) @(negedge sysclk_i); | |
377 | `PR_NORMAL("system_reset", `NORMAL, "Deasserting PB_RST_L"); | |
378 | PB_pulse <= 0; | |
379 | injected_PB_count = injected_PB_count + 1; | |
380 | if (injected_PB_count == max_num_injected_PB) | |
381 | max_injected_PB_count_reached = 1; | |
382 | end | |
383 | end // initial begin | |
384 | ||
385 | initial begin | |
386 | #1; // Wait for any glitches at time=0 to pass | |
387 | forever @(posedge start_PB_delay) begin | |
388 | repeat(PB_delay) @(posedge sysclk_i); | |
389 | -> end_PB_delay; | |
390 | // Increase the delay for the next time | |
391 | PB_delay = PB_delay + delay_between_PB; | |
392 | end | |
393 | end | |
394 | ||
395 | ||
396 | integer PB_state, next_PB_state; | |
397 | initial begin | |
398 | start_PB_delay = 0; | |
399 | PB_state = WAIT_FOR_BOOT_CODE_START; | |
400 | next_PB_state = WAIT_FOR_BOOT_CODE_START; | |
401 | end | |
402 | ||
403 | always @(posedge sysclk_i) begin | |
404 | PB_state <= next_PB_state; | |
405 | end | |
406 | ||
407 | always @(PB_state or PB_pulse or Not_in_Boot or max_injected_PB_count_reached) begin | |
408 | case(PB_state) | |
409 | START_RESET_COUNTDOWN: begin | |
410 | next_PB_state = WAIT_FOR_RESET_COUNTDOWN; | |
411 | start_PB_delay = 1; | |
412 | end | |
413 | WAIT_FOR_RESET_COUNTDOWN: begin | |
414 | start_PB_delay = 0; | |
415 | if (PB_pulse) | |
416 | next_PB_state = WAIT_FOR_BOOT_CODE_START; | |
417 | else | |
418 | next_PB_state = WAIT_FOR_RESET_COUNTDOWN; | |
419 | end | |
420 | WAIT_FOR_BOOT_CODE_START: begin | |
421 | // On 2nd POR, Not_in_Boot will remain asserted until | |
422 | // the first instruction is executed ("bootStart" user event) | |
423 | if (Not_in_Boot) | |
424 | next_PB_state = WAIT_FOR_BOOT_CODE_START; | |
425 | else | |
426 | next_PB_state = WAIT_FOR_BOOT_CODE_END; | |
427 | end | |
428 | WAIT_FOR_BOOT_CODE_END: begin | |
429 | if (Not_in_Boot) begin | |
430 | if (max_injected_PB_count_reached) begin | |
431 | next_PB_state = NO_MORE_INJECTED_RESETS; | |
432 | end | |
433 | else begin | |
434 | next_PB_state = START_RESET_COUNTDOWN; | |
435 | end | |
436 | end else begin | |
437 | next_PB_state = WAIT_FOR_BOOT_CODE_END; | |
438 | end | |
439 | end | |
440 | NO_MORE_INJECTED_RESETS: begin | |
441 | next_PB_state = NO_MORE_INJECTED_RESETS; | |
442 | end | |
443 | endcase | |
444 | end | |
445 | ||
446 | ||
447 | ||
448 | /*************************************************************************** | |
449 | * Drive XIR | |
450 | ***************************************************************************/ | |
451 | integer delay_to_first_XIR; | |
452 | integer delay_between_XIR; | |
453 | integer max_num_injected_XIR; | |
454 | reg XIR_pulse; | |
455 | reg start_XIR_delay; | |
456 | event end_XIR_delay; | |
457 | integer injected_XIR_count; | |
458 | reg max_injected_XIR_count_reached; | |
459 | integer XIR_pulse_width; | |
460 | integer XIR_delay; | |
461 | ||
462 | // Set up the user-adjustable values for XIR reset | |
463 | initial begin | |
464 | // Set the duration of XIR pulse width in SYSCLK cycles | |
465 | if (0 == $value$plusargs("XIR_pulse_width=%d",XIR_pulse_width)) | |
466 | XIR_pulse_width = 2; | |
467 | `PR_NORMAL("system_reset", `NORMAL, "BUTTON_XIR_L pulse width = %d SYSCLK cycles (+XIR_pulse_width)", XIR_pulse_width); | |
468 | // Set the delay in SYSCLK cycles from bootEnd to the first XIR | |
469 | if (0 == $value$plusargs("delay_to_first_XIR=%d", delay_to_first_XIR)) | |
470 | delay_to_first_XIR = 200; | |
471 | `PR_NORMAL("system_reset", `NORMAL, "Delay to first injected BUTTON_XIR_L = %d SYSCLK cycles (+delay_to_first_XIR)", delay_to_first_XIR); | |
472 | XIR_delay = delay_to_first_XIR; | |
473 | // Set the delay between XIRs in terms of SYSCLK cycles | |
474 | if (0 == $value$plusargs("delay_between_XIR=%d", delay_between_XIR)) | |
475 | delay_between_XIR = 1000; | |
476 | `PR_NORMAL("system_reset", `NORMAL, "Additional delay per injected BUTTON_XIR_L pulse = %d SYSCLK cycles (+delay_between_XIR)", delay_between_XIR); | |
477 | // Set the maximum number of injected XIRs; 0=>no injected XIRs | |
478 | if (0 == $value$plusargs("max_num_injected_XIR=%d", max_num_injected_XIR)) | |
479 | max_num_injected_XIR = 0; | |
480 | `PR_NORMAL("system_reset", `NORMAL, "Maximum number of injected BUTTON_XIR_L pulse = %d (+max_num_injected_XIR)", max_num_injected_XIR); | |
481 | max_injected_XIR_count_reached = (max_num_injected_XIR == 0); | |
482 | end // initial begin | |
483 | ||
484 | initial begin | |
485 | injected_XIR_count = 0; | |
486 | XIR_pulse = 0; | |
487 | @(negedge sysclk_i); // Wait for first system clock | |
488 | // Generate a XIR pulse at end_XIR_delay | |
489 | forever @(end_XIR_delay) begin | |
490 | @(negedge sysclk_i); // Always assert on negedge: N2 samples on posedge | |
491 | `PR_NORMAL("system_reset", `NORMAL, "Asserting BUTTON_XIR_L"); | |
492 | XIR_pulse <= 1; | |
493 | repeat(XIR_pulse_width) @(negedge sysclk_i); | |
494 | `PR_NORMAL("system_reset", `NORMAL, "Deasserting BUTTON_XIR_L"); | |
495 | XIR_pulse <= 0; | |
496 | injected_XIR_count = injected_XIR_count + 1; | |
497 | if (injected_XIR_count == max_num_injected_XIR) | |
498 | max_injected_XIR_count_reached = 1; | |
499 | end | |
500 | end // initial begin | |
501 | ||
502 | initial begin | |
503 | #1; // Wait for any glitches at time=0 to pass | |
504 | forever @(posedge start_XIR_delay) begin | |
505 | repeat(XIR_delay) @(posedge sysclk_i); | |
506 | -> end_XIR_delay; | |
507 | // Increase the delay for the next time | |
508 | XIR_delay = XIR_delay + delay_between_XIR; | |
509 | end | |
510 | end | |
511 | ||
512 | integer XIR_state, next_XIR_state; | |
513 | initial begin | |
514 | start_XIR_delay = 0; | |
515 | XIR_state = WAIT_FOR_BOOT_CODE_START; | |
516 | next_XIR_state = WAIT_FOR_BOOT_CODE_START; | |
517 | end | |
518 | ||
519 | always @(posedge sysclk_i) begin | |
520 | XIR_state <= next_XIR_state; | |
521 | end | |
522 | ||
523 | always @(XIR_state or XIR_pulse or Not_in_Boot or max_injected_XIR_count_reached) begin | |
524 | case(XIR_state) | |
525 | START_RESET_COUNTDOWN: begin | |
526 | next_XIR_state = WAIT_FOR_RESET_COUNTDOWN; | |
527 | start_XIR_delay = 1; | |
528 | end | |
529 | WAIT_FOR_RESET_COUNTDOWN: begin | |
530 | start_XIR_delay = 0; | |
531 | if (XIR_pulse) | |
532 | next_XIR_state = WAIT_FOR_BOOT_CODE_START; | |
533 | else | |
534 | next_XIR_state = WAIT_FOR_RESET_COUNTDOWN; | |
535 | end | |
536 | WAIT_FOR_BOOT_CODE_START: begin | |
537 | // On 2nd POR, Not_in_Boot will remain asserted until | |
538 | // the first instruction is executed ("bootStart" user event) | |
539 | if (Not_in_Boot) | |
540 | next_XIR_state = WAIT_FOR_BOOT_CODE_START; | |
541 | else | |
542 | next_XIR_state = WAIT_FOR_BOOT_CODE_END; | |
543 | end | |
544 | WAIT_FOR_BOOT_CODE_END: begin | |
545 | if (Not_in_Boot) begin | |
546 | if (max_injected_XIR_count_reached) begin | |
547 | next_XIR_state = NO_MORE_INJECTED_RESETS; | |
548 | end | |
549 | else begin | |
550 | next_XIR_state = START_RESET_COUNTDOWN; | |
551 | end | |
552 | end else begin | |
553 | next_XIR_state = WAIT_FOR_BOOT_CODE_END; | |
554 | end | |
555 | end | |
556 | NO_MORE_INJECTED_RESETS: begin | |
557 | next_XIR_state = NO_MORE_INJECTED_RESETS; | |
558 | end | |
559 | endcase | |
560 | end | |
561 | ||
562 | ||
563 | /* | |
564 | * niu reset ?? why is it hard coded | |
565 | */ | |
566 | initial | |
567 | begin | |
568 | niu_reset_o = 1'b1; | |
569 | #1331844 niu_reset_o = 1'b0; | |
570 | #332800 niu_reset_o = 1'b1; | |
571 | #665600 niu_reset_o = 1'b0; | |
572 | end | |
573 | ||
574 | ||
575 | ||
576 | `ifndef NON_SLAM_VECTORS | |
577 | assign Button_xir_l = ~XIR_pulse; | |
578 | assign Pb_rst_l = (~PB_pulse) & (~PB_RST_from_UserEvent); | |
579 | assign Pwr_on_rst_l = ~POR_pulse_mux; | |
580 | assign Trst_l = trst_l_o; | |
581 | `endif | |
582 | assign Tb_reset = ~POR_pulse_mux; | |
583 | assign niu_reset = niu_reset_o; | |
584 | assign flush_reset_complete = flush_reset_complete_o; | |
585 | /* | |
586 | * hold POR pulse low till we get to first POR | |
587 | */ | |
588 | assign POR_pulse_mux = mono_PWRON_RST_L ? POR_pulse:1'b1; | |
589 | ||
590 | ||
591 | /* | |
592 | * Monitor for expected number of resets and if it has not happened then | |
593 | * print error messages | |
594 | * | |
595 | **** CODE REMOVED AT system_reset.v 1.20 **** | |
596 | */ | |
597 | ||
598 | ||
599 | endmodule |