Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: sys_reset.vr | |
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 | #include <vera_defines.vrh> | |
36 | #include "std_display_class.vrh" | |
37 | #include "ucb___packet.vrh" | |
38 | #include "rst_defines.vri" | |
39 | #include "tcu_top.vri" | |
40 | // #include "ccu_top.vri" // @@UPDATE@@ This file should be split and included as reg_top.vri | |
41 | #include "reg_top.vri" | |
42 | #include "rst_top.vri" | |
43 | ||
44 | #include "tcu_tasks.vrh" | |
45 | #include "sys_registers.vrh" | |
46 | ||
47 | #include "ucb_top.vri" | |
48 | #include "ucb_monitor.vrh" | |
49 | ||
50 | class SystemReset { | |
51 | string dispmonScope; | |
52 | ||
53 | sc__port sc_port; | |
54 | rst__port rst_port; | |
55 | SystemTap dft; | |
56 | SystemRegs resetSource; // Physical RST register | |
57 | SystemRegs resetGenerate; // Physical RST register | |
58 | SystemRegs resetStatus; // Physical RST register | |
59 | SystemRegs resetSubsystem; // Physical RST register | |
60 | SystemRegs resetLocktime; // Physical RST register | |
61 | SystemRegs resetNiutime; // Physical RST register | |
62 | SystemRegs resetCcutime; // Physical RST register | |
63 | SystemRegs resetProptime; // Physical RST register | |
64 | SystemRegs resetFee; // Physical RST register | |
65 | UCB_port ucb_port; | |
66 | UCB_monitor ucb_monitor; | |
67 | ||
68 | StandardDisplay dbg; | |
69 | integer clkgenBegin; | |
70 | integer clkgenEnd; | |
71 | integer clkenStartBegin; | |
72 | integer clkenStartEnd; | |
73 | integer clkenStopBegin; | |
74 | integer clkenStopEnd; | |
75 | integer rst_attribs[RST_LOCK_ATTRIB_COUNT+1][RST_LOCK_ATTRIB_FIELD_COUNT+1] = RST_LOCK; | |
76 | integer refCycleCnt; | |
77 | integer resetSeqTimeout; // timeout of reset seq not progressing (in sysclk cycs) | |
78 | bit [63:0] temp_reg_val_holder; | |
79 | rand integer pwron_assrt_time; // Number of cycles to assign the PWRON_RST pin | |
80 | ||
81 | constraint pwron{ | |
82 | pwron_assrt_time in { 1 : 30 }; | |
83 | } | |
84 | ||
85 | task new(StandardDisplay dbgIn, SystemTap dftIn) { | |
86 | dispmonScope = "rst"; | |
87 | sc_port = sc_bind; | |
88 | rst_port = rst_bind; | |
89 | dbg = dbgIn; | |
90 | dft = dftIn; | |
91 | ||
92 | if (get_plus_arg(CHECK, "rst_resetSeqTimeout=")) | |
93 | resetSeqTimeout = get_plus_arg(NUM, "rst_resetSeqTimeout="); | |
94 | else | |
95 | resetSeqTimeout = TEST_RST_SEQUENCE_TIME; | |
96 | ||
97 | dbg.dispmon(dispmonScope, MON_INFO, "$Id: sys_reset.vr,v 1.6 2007/07/28 20:36:17 drp Exp $"); | |
98 | resetGenerate = new(dbg,dft,"RST_ASI_RESET_GEN_REG" | |
99 | , RST_ASI_RESET_GEN_REG, RST_ASI_RESET_GEN_DEF, RST_ASI_RESET_GEN_MASK, creg_bind_rgen); | |
100 | resetStatus = new(dbg,dft,"RST_ASI_RESET_STAT_REG" | |
101 | , RST_ASI_RESET_STAT_REG, RST_ASI_RESET_STAT_DEF, RST_ASI_RESET_STAT_MASK, creg_bind_rstat); | |
102 | resetSource = new(dbg,dft,"RST_ASI_RESET_SOURCE_REG" | |
103 | , RST_ASI_RESET_SOURCE_REG, RST_ASI_RESET_SOURCE_DEF, RST_ASI_RESET_SOURCE_MASK, creg_bind_rsrc); | |
104 | resetSubsystem = new(dbg,dft,"RST_ASI_RESET_SSYS_REG" | |
105 | , RST_ASI_RESET_SSYS_REG, RST_ASI_RESET_SSYS_DEF, RST_ASI_RESET_SSYS_MASK, creg_bind_rssys); | |
106 | resetLocktime = new(dbg,dft,"RST_ASI_LOCK_TIME_REG" | |
107 | , RST_ASI_LOCK_TIME_REG, RST_ASI_LOCK_TIME_DEF, RST_ASI_LOCK_TIME_MASK, creg_bind_locktime); | |
108 | resetNiutime = new(dbg,dft,"RST_ASI_NIU_TIME_REG" | |
109 | , RST_ASI_NIU_TIME_REG, RST_ASI_NIU_TIME_DEF, RST_ASI_NIU_TIME_MASK, creg_bind_niutime); | |
110 | resetCcutime = new(dbg,dft,"RST_ASI_CCU_TIME_REG" | |
111 | , RST_ASI_CCU_TIME_REG, RST_ASI_CCU_TIME_DEF, RST_ASI_CCU_TIME_MASK, creg_bind_ccutime); | |
112 | resetProptime = new(dbg,dft,"RST_ASI_PROP_TIME_REG" | |
113 | , RST_ASI_PROP_TIME_REG, RST_ASI_PROP_TIME_DEF, RST_ASI_PROP_TIME_MASK, creg_bind_proptime); | |
114 | resetFee = new(dbg,dft,"RST_ASI_RESET_FEE_REG" | |
115 | , RST_ASI_RESET_FEE_REG, RST_ASI_RESET_FEE_DEF, RST_ASI_RESET_FEE_MASK, creg_bind_rfee); | |
116 | void = randomize(); | |
117 | ||
118 | ucb_port = rst_ucb_mon_bind; | |
119 | if (get_plus_arg(CHECK, "rst_noUcbMon")) | |
120 | dbg.dispmon(dispmonScope, MON_ALWAYS, "warning: UCB monitor is disable"); | |
121 | else | |
122 | ucb_monitor = new("rst_ucb_mon", dbg, ucb_port, 4, 8'h89 , 1); // Instantiate and start the monitor | |
123 | ||
124 | // dft.stop_port.$rst_tcu_flush_req = 1'b0; // @@UPDATE@@ remove when flush connect to RST | |
125 | // FC regression failing for PEU because vera driving these inputs to RST | |
126 | #ifndef FC_BENCH // could not drive package pins becoz vera drives it | |
127 | #ifdef TCU_SAT | |
128 | rst_port.$l2t0_rst_fatal_error = 1'b0 async ; | |
129 | rst_port.$l2t1_rst_fatal_error = 1'b0 async ; | |
130 | rst_port.$l2t2_rst_fatal_error = 1'b0 async ; | |
131 | rst_port.$l2t3_rst_fatal_error = 1'b0 async ; | |
132 | rst_port.$l2t4_rst_fatal_error = 1'b0 async ; | |
133 | rst_port.$l2t5_rst_fatal_error = 1'b0 async ; | |
134 | rst_port.$l2t6_rst_fatal_error = 1'b0 async ; | |
135 | rst_port.$l2t7_rst_fatal_error = 1'b0 async ; | |
136 | rst_port.$ncu_rst_fatal_error = 1'b0 async ; | |
137 | #endif | |
138 | // sc_port.$por_ = 1'b0 soft async ; // asked for assert from time 0 | |
139 | sc_port.$por_ = 1'bx soft async ; | |
140 | sc_port.$pb_xir_ = 1'bx soft async ; | |
141 | sc_port.$pb_rst_ = 1'bx soft async ; | |
142 | #endif // FC_BENCH ndef | |
143 | ||
144 | //// Start another process, count the reference clocks | |
145 | fork { | |
146 | while(1) { | |
147 | @(posedge sc_port.$clk); | |
148 | // @@UPDATE@@ This might change -csr | |
149 | if (sc_port.$por_in_ == 1'b0) { | |
150 | refCycleCnt = 0; | |
151 | } else { | |
152 | refCycleCnt++; | |
153 | } | |
154 | } | |
155 | } join none | |
156 | } | |
157 | ||
158 | //------------------ Knobs will be initialized in :/verif/diag files --------------------- | |
159 | task runRstSequence() { | |
160 | integer pllreset_cyc_cnt; // number of sys clks that PWRON_RST_L is asserted | |
161 | integer pllreset_min_cycs = 0; // minimum time required to reset pll | |
162 | integer async_delay; | |
163 | dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("PWRON_RST_L assert time is %d pll_sys_clkp cycles", pwron_assrt_time)); | |
164 | sc_port.$pb_xir_ = 1'bx; | |
165 | sc_port.$pb_rst_ = 1'bx; | |
166 | sc_port.$por_ = 1'bx; | |
167 | repeat (10) @(negedge sc_port.$clk); | |
168 | sc_port.$por_ = 1'b0; // PRM 1.2 section 13.9.1 step 1 | |
169 | dft.TapDrive_trst_n(1'b0); // PRM 1.2 section 13.9.1 step 1 | |
170 | pllreset_cyc_cnt = get_cycle(sc_port.$clk); | |
171 | dft.TapDrive_tms(1'b1); // PRM 1.2 section 13.9.1 step 4 | |
172 | sc_port.$pb_xir_ = 1'b1; // Define the XIR & PB now since it matters | |
173 | sc_port.$pb_rst_ = 1'b1; | |
174 | repeat (5) @(negedge sc_port.$clk); | |
175 | dft.TapDrive_trst_n(1'b1); // PRM 1.2 section 13.9.1 step 5 | |
176 | repeat (5) dft.toggleDutTck(); // PRM 1.2 section 13.9.1 step 6 | |
177 | if (get_plus_arg(CHECK, "pllreset_time=")) { | |
178 | pllreset_min_cycs = get_plus_arg(NUM, "pllreset_time="); | |
179 | pllreset_cyc_cnt = get_cycle(sc_port.$clk) - pllreset_cyc_cnt; | |
180 | pllreset_cyc_cnt = pllreset_min_cycs - pllreset_cyc_cnt; | |
181 | if (pllreset_cyc_cnt > 0) | |
182 | repeat (pllreset_cyc_cnt) @(posedge sc_port.$clk); // wait to meet min cycs | |
183 | } | |
184 | else | |
185 | repeat (pwron_assrt_time) @(negedge sc_port.$clk); | |
186 | // async_delay = urandom_range(7499, 0); | |
187 | // dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("PWRON_RST_L deasert asyncdelay is %d ps", async_delay)); | |
188 | // delay(async_delay) ; | |
189 | sc_port.$por_ = 1'b1 ; // Service processor deasserts | |
190 | wait_unpark_thread(); | |
191 | } | |
192 | ||
193 | task runRstSequenceJtpor() { | |
194 | dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("PWRON_RST_L assert time is %d pll_sys_clkp cycles", pwron_assrt_time)); | |
195 | repeat (5) @(posedge sc_port.$clk); | |
196 | sc_port.$por_ = 1'b0; | |
197 | sc_port.$pb_rst_ = 1'b0; // PRM 1.2 section 13.9.1 step 1 | |
198 | dft.TapDrive_trst_n(1'b0); // According to PRM 11.9.1 09/21/2004 | |
199 | @(posedge sc_port.$clk); | |
200 | @(posedge sc_port.$clk); | |
201 | dft.TapDrive_tms(1'b1); // PRM 1.2 section 13.9.1 step 4 | |
202 | sc_port.$pb_xir_ = 1'b1; // Define the XIR & PB now since it matters | |
203 | sc_port.$pb_rst_ = 1'b1; | |
204 | repeat (5) @(posedge sc_port.$clk); | |
205 | dft.TapDrive_trst_n(1'b1); // PRM 1.2 section 13.9.1 step 5 | |
206 | repeat (5) dft.toggleDutTck(); // PRM 1.2 section 13.9.1 step 6 | |
207 | repeat (1) @(posedge sc_port.$clk); | |
208 | //repeat (pwron_assrt_time) @(posedge sc_port.$clk); | |
209 | sc_port.$por_ = 1'b1; // Service processor deasserts | |
210 | // repeat (2) @(posedge sc_port.$clk); | |
211 | ||
212 | wait_for_por2(); | |
213 | } | |
214 | ||
215 | ||
216 | //------------------ Update Reset Registers Expected Value --------------------- | |
217 | task expectedResetUpdate(integer reset_type) { | |
218 | // Update the Shadow Status registers (RST spec v.0.92) | |
219 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_POR_S] = resetStatus.asiVeraValue[RST_ASI_RESET_STAT_POR]; | |
220 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_WMR_S] = resetStatus.asiVeraValue[RST_ASI_RESET_STAT_WMR]; | |
221 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_FREQ_S] = resetStatus.asiVeraValue[RST_ASI_RESET_STAT_FREQ]; | |
222 | ||
223 | case ( reset_type ) { | |
224 | RST_ASI_RESET_STAT_POR: { | |
225 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_POR] = 1'b1; | |
226 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_WMR] = 1'b0; | |
227 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_FREQ] = 1'b0; | |
228 | } | |
229 | RST_ASI_RESET_STAT_WMR: { | |
230 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_POR] = 1'b0; | |
231 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_WMR] = 1'b1; | |
232 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_FREQ] = 1'b0; | |
233 | } | |
234 | RST_ASI_RESET_STAT_FREQ: { | |
235 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_POR] = 1'b0; | |
236 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_WMR] = 1'b1; | |
237 | resetStatus.asiVeraValue[RST_ASI_RESET_STAT_FREQ] = 1'b1; | |
238 | } | |
239 | default: dbg.dispmon(dispmonScope, MON_ERR, psprintf("Unrecognized reset type (%s) for RESET_STAT_REG", reset_type)); | |
240 | } | |
241 | } | |
242 | ||
243 | //------------------ Update Reset Registers Expected Value --------------------- | |
244 | task check_resetStatReg(string bitfield) { | |
245 | if(bitfield == "WMR"){ | |
246 | expectedResetUpdate(RST_ASI_RESET_STAT_WMR); | |
247 | } | |
248 | else if(bitfield == "POR"){ | |
249 | expectedResetUpdate(RST_ASI_RESET_STAT_POR); | |
250 | } | |
251 | else if (bitfield == "FREQ"){ | |
252 | expectedResetUpdate(RST_ASI_RESET_STAT_FREQ); | |
253 | } | |
254 | else{ | |
255 | dbg.dispmon(dispmonScope, MON_ERR, psprintf("ERROR: Wrong argument to task check_resetStatReg - %s ", bitfield)); | |
256 | return; | |
257 | } | |
258 | resetStatus.printCurrentRegister(); //Fetch asiCurrentValue | |
259 | resetStatus.printCheckRegister(resetStatus.asiVeraValue , resetStatus.asiCurrentValue); | |
260 | }// End of check_resetStatReg | |
261 | ||
262 | // Task to cause a simple POR reset with PWRON_RST_L pin. 02/20/05 | |
263 | task POR_reset() { | |
264 | runRstSequence(); | |
265 | }// End of POR_reset | |
266 | ||
267 | // Task to cause a WMR reset with PB_RST_L pin. 03/01/05 | |
268 | task WMR_PB_RST() { | |
269 | // Initiate warm reset through PB_RST_L pin | |
270 | dbg.dispmon(dispmonScope, MON_ALWAYS, "Assert PB_RST_L pin"); | |
271 | repeat (5) @(posedge sc_port.$clk); | |
272 | sc_port.$pb_rst_ = 1'b0; | |
273 | repeat (urandom_range(20, 2)) @(posedge sc_port.$clk); | |
274 | delay(urandom_range(7499, 0)); | |
275 | sc_port.$pb_rst_ = 1'b1 async; | |
276 | wait_unpark_thread(); | |
277 | repeat (20) @(posedge sc_port.$clk); | |
278 | }// End of WMR_PB_RST | |
279 | ||
280 | // Task to cause a WMR reset with L2t_error signal pins. 03/01/05 | |
281 | task gen_fatal_error(string error_type) { | |
282 | reg [63:0] fee_reg_data = 64'd0; | |
283 | sc_port.$pb_rst_ = 1'b1; | |
284 | sc_port.$por_ = 1'b1; | |
285 | sc_port.$pb_xir_ = 1'b1; | |
286 | if (error_type == "L2T_ERR"){ | |
287 | dbg.dispmon(dispmonScope, MON_ALWAYS, "Generate L2t fatal error"); | |
288 | fee_reg_data[8] = random(); | |
289 | fee_reg_data[9] = random(); | |
290 | fee_reg_data[10] = random(); | |
291 | fee_reg_data[11] = random(); | |
292 | fee_reg_data[12] = random(); | |
293 | fee_reg_data[13] = random(); | |
294 | fee_reg_data[14] = random(); | |
295 | fee_reg_data[15] = random(); | |
296 | if (fee_reg_data == 64'd0){ | |
297 | fee_reg_data[8] = 1'b1; | |
298 | } | |
299 | resetFee.ucbWrite(fee_reg_data); | |
300 | void = resetFee.ucbRead(); | |
301 | repeat (5) @(posedge rst_port.$clk_iol2clk); | |
302 | ||
303 | rst_port.$l2t0_rst_fatal_error = fee_reg_data[8] async ; | |
304 | rst_port.$l2t1_rst_fatal_error = fee_reg_data[9] async ; | |
305 | rst_port.$l2t2_rst_fatal_error = fee_reg_data[10] async ; | |
306 | rst_port.$l2t3_rst_fatal_error = fee_reg_data[11] async ; | |
307 | rst_port.$l2t4_rst_fatal_error = fee_reg_data[12] async ; | |
308 | rst_port.$l2t5_rst_fatal_error = fee_reg_data[13] async ; | |
309 | rst_port.$l2t6_rst_fatal_error = fee_reg_data[14] async ; | |
310 | rst_port.$l2t7_rst_fatal_error = fee_reg_data[15] async ; | |
311 | repeat (1) @(posedge rst_port.$clk_iol2clk); | |
312 | rst_port.$l2t0_rst_fatal_error = 1'b0 async ; | |
313 | rst_port.$l2t1_rst_fatal_error = 1'b0 async ; | |
314 | rst_port.$l2t2_rst_fatal_error = 1'b0 async ; | |
315 | rst_port.$l2t3_rst_fatal_error = 1'b0 async ; | |
316 | rst_port.$l2t4_rst_fatal_error = 1'b0 async ; | |
317 | rst_port.$l2t5_rst_fatal_error = 1'b0 async ; | |
318 | rst_port.$l2t6_rst_fatal_error = 1'b0 async ; | |
319 | rst_port.$l2t7_rst_fatal_error = 1'b0 async ; | |
320 | } | |
321 | else if(error_type == "NCU_ERR") { | |
322 | dbg.dispmon(dispmonScope, MON_ALWAYS, "Generate NCU fatal error"); | |
323 | repeat (5) @(posedge rst_port.$clk_iol2clk); | |
324 | rst_port.$ncu_rst_fatal_error = 1'b1 async; | |
325 | repeat (1) @(posedge rst_port.$clk_iol2clk); | |
326 | rst_port.$ncu_rst_fatal_error = 1'b0 async; | |
327 | } | |
328 | else { | |
329 | dbg.dispmon(dispmonScope, MON_ERR, "ERROR: Did not specify the type of fatal error to generate"); | |
330 | } | |
331 | wait_unpark_thread(); | |
332 | ||
333 | // For L2 error check weather FEE register is reset to all zeros | |
334 | fee_reg_data = resetFee.ucbRead() & resetFee.asiWriteableMask; | |
335 | if (fee_reg_data != 64'd0) | |
336 | { | |
337 | dbg.dispmon(dispmonScope, MON_ERR, "ERROR: RESET_FEE register is not reset after warm reset"); | |
338 | dbg.dispmon(dispmonScope, MON_ERR, psprintf("FEE REG is': 0x%64h", fee_reg_data)); | |
339 | } | |
340 | }// End of WMR_L2t_error | |
341 | ||
342 | // Task to cause XIR reset through the BUTTON_XIR_L pin | |
343 | task XIR_reset() { | |
344 | dbg.dispmon(dispmonScope, MON_ALWAYS, "Assert XIR reset"); | |
345 | sc_port.$pb_rst_ = 1'b1; | |
346 | sc_port.$por_ = 1'b1; | |
347 | sc_port.$pb_xir_ = 1'b0; | |
348 | fork | |
349 | { | |
350 | repeat (urandom_range(20, 2)) @(posedge sc_port.$clk); | |
351 | delay(urandom_range(7499, 0)); | |
352 | sc_port.$pb_xir_ = 1'b1 async; | |
353 | } | |
354 | join none | |
355 | wait_xir_reset(); | |
356 | repeat (20) @(posedge sc_port.$clk); | |
357 | }// End of XIR_reset | |
358 | ||
359 | // Task for software generated resets, excercice RESET_GEN register and SSYS reg | |
360 | task software_gen_reset(string rst_type) | |
361 | { | |
362 | bit reset_timeout; //To have smart timeout than default timeout- 03/03/05 | |
363 | ||
364 | dbg.dispmon(dispmonScope, MON_ALWAYS, psprintf("%s S/W Reset gen", rst_type)); | |
365 | if (rst_type == "WMR_GEN"){ | |
366 | resetGenerate.printCurrentRegister(); | |
367 | resetGenerate.ucbWrite(64'd1); | |
368 | } else | |
369 | if (rst_type == "XIR_GEN"){ | |
370 | resetGenerate.printCurrentRegister(); | |
371 | resetGenerate.ucbWrite(64'd2 ); | |
372 | } else | |
373 | if (rst_type == "DBR_GEN"){ | |
374 | resetGenerate.printCurrentRegister(); | |
375 | resetGenerate.ucbWrite(64'd8 ); | |
376 | } else | |
377 | if (rst_type == "SSYS_DMU_PEU"){ | |
378 | resetSubsystem.printCurrentRegister(); | |
379 | resetSubsystem.ucbWrite(64'd2 ); | |
380 | } else | |
381 | if (rst_type == "SSYS_NIU"){ | |
382 | resetSubsystem.printCurrentRegister(); | |
383 | resetSubsystem.ucbWrite(64'd1 ); | |
384 | } else | |
385 | dbg.dispmon(dispmonScope, MON_ERR, psprintf("Unrecognized s/w reset to generate for %s in RESET_GEN_REG", rst_type)); | |
386 | ||
387 | if((rst_type == "WMR_GEN") || (rst_type == "DBR_GEN") ){ | |
388 | wait_unpark_thread(); | |
389 | } | |
390 | else { | |
391 | reset_timeout = 1'b0; | |
392 | fork | |
393 | { | |
394 | if(rst_type == "XIR_GEN"){ | |
395 | @(posedge rst_port.$ncu_rst_xir_done async); | |
396 | } | |
397 | else if(rst_type == "SSYS_DMU_PEU"){ | |
398 | @(negedge rst_port.$rst_dmu_peu_wmr_ ); | |
399 | repeat (50) @(posedge sc_port.$clk async); | |
400 | } | |
401 | else if(rst_type == "SSYS_NIU"){ | |
402 | @(negedge rst_port.$rst_niu_wmr_ ); | |
403 | repeat (50) @(posedge sc_port.$clk async); | |
404 | } | |
405 | reset_timeout = 1'b0; | |
406 | } | |
407 | { | |
408 | repeat (resetSeqTimeout) @(posedge sc_port.$clk); | |
409 | reset_timeout = 1'b1; | |
410 | } | |
411 | join any | |
412 | terminate; | |
413 | if(reset_timeout) | |
414 | { | |
415 | dbg.dispmon(dispmonScope, MON_ERR, psprintf("ERROR: TIMEOUT for %s reset, failed to generate reset ", rst_type)); | |
416 | } | |
417 | } | |
418 | repeat (50) @(posedge sc_port.$clk); | |
419 | ||
420 | } // End of software_gen_reset | |
421 | ||
422 | // This task tests that source register is correctly updated and also clears the field in order to simulate the s/w behaviour | |
423 | task check_resetSourceReg(string bitfield) { | |
424 | integer bitPosition = 2; | |
425 | reg [63:0] expectedVal = 64'd0; | |
426 | resetSource.printCurrentRegister(); // Update the currentValue variable in the class | |
427 | if( bitfield == "WMR_GEN") | |
428 | bitPosition = 0; | |
429 | else if( bitfield == "XIR_GEN") | |
430 | bitPosition = 1; | |
431 | else if( bitfield == "DBR_GEN") | |
432 | bitPosition = 3; | |
433 | else if( bitfield == "PWRON_RST") | |
434 | bitPosition = 4; | |
435 | else if( bitfield == "PB_RST") | |
436 | bitPosition = 5; | |
437 | else if( bitfield == "PB_XIR") | |
438 | bitPosition = 6; | |
439 | else if( bitfield == "NCU_FATAL") | |
440 | bitPosition = 7; | |
441 | else if( bitfield == "L2T_FATAL"){ | |
442 | temp_reg_val_holder = resetSource.asiCurrentValue & 64'h000000000000ff00; | |
443 | if((resetSource.asiCurrentValue & 64'h000000000000ff00) > 64'd0){ | |
444 | dbg.dispmon(dispmonScope, MON_INFO, psprintf(" Source register is correctly updated for field %s", bitfield)); | |
445 | resetSource.ucbWrite(resetSource.asiWriteableMask); | |
446 | } | |
447 | else | |
448 | dbg.dispmon(dispmonScope, MON_ERR, psprintf("ERROR: Source register not set for bit %s ", bitfield)); | |
449 | return; | |
450 | }else | |
451 | dbg.dispmon(dispmonScope, MON_ERR, psprintf("ERROR: Wrong argument to task check_resetSourceReg - %s ", bitfield)); | |
452 | ||
453 | expectedVal[bitPosition] = 1'b1; | |
454 | // if(resetSource.asiCurrentValue[bitPosition] == 1'b1) | |
455 | if((resetSource.asiWriteableMask & resetSource.asiCurrentValue) == expectedVal) | |
456 | dbg.dispmon(dispmonScope, MON_INFO, psprintf(" Source register is correctly updated for field %s", bitfield)); | |
457 | ||
458 | else | |
459 | dbg.dispmon(dispmonScope, MON_ERR, psprintf("ERROR: Source register NOT correctly updated for reset %s", bitfield)); | |
460 | ||
461 | resetSource.ucbWrite(resetSource.asiWriteableMask); | |
462 | void = resetSource.ucbRead(); // Dumy read to ensure write completed | |
463 | } // End of checkSourceReg | |
464 | ||
465 | //Wait for unpark_thread | |
466 | task wait_unpark_thread(){ | |
467 | integer counter = 0; | |
468 | bit unpark_done = 0; | |
469 | ||
470 | dbg.dispmon(dispmonScope, MON_ALWAYS, "Waiting for unpark_thread "); | |
471 | fork { | |
472 | fork | |
473 | { | |
474 | @(posedge rst_port.$rst_ncu_unpark_thread); | |
475 | dbg.dispmon(dispmonScope, MON_ALWAYS, "unpark_thread asserted"); | |
476 | unpark_done = 1; | |
477 | } | |
478 | { | |
479 | while (!unpark_done) { | |
480 | @(posedge sc_port.$clk); | |
481 | counter++; | |
482 | if (counter == 1000) { | |
483 | counter = 0; | |
484 | dbg.dispmon(dispmonScope, MON_ALWAYS, "Complete 1000 cycle wait"); | |
485 | } | |
486 | } | |
487 | } | |
488 | { | |
489 | repeat (resetSeqTimeout) @(posedge sc_port.$clk); | |
490 | dbg.dispmon(dispmonScope, MON_ERR, "ERROR: TIMEOUT for task wait_unpark_thread "); | |
491 | exit(1); | |
492 | } | |
493 | join any | |
494 | terminate; | |
495 | }join all | |
496 | }//End of wait_unpark_thread | |
497 | ||
498 | ||
499 | ||
500 | //Wait for por2 | |
501 | task wait_for_por2(){ | |
502 | integer counter = 0; | |
503 | bit por2_start = 0; | |
504 | ||
505 | dbg.dispmon(dispmonScope, MON_ALWAYS, "Waiting for por2 "); | |
506 | fork { | |
507 | fork | |
508 | { | |
509 | @(posedge rst_port.$rst_tcu_flush_init_req); | |
510 | dbg.dispmon(dispmonScope, MON_ALWAYS, "por2"); | |
511 | por2_start = 1; | |
512 | } | |
513 | { | |
514 | while (!por2_start) { | |
515 | @(posedge sc_port.$clk); | |
516 | counter++; | |
517 | if (counter == 1000) { | |
518 | counter = 0; | |
519 | dbg.dispmon(dispmonScope, MON_ALWAYS, "Complete 1000 cycle wait"); | |
520 | } | |
521 | } | |
522 | } | |
523 | { | |
524 | repeat (resetSeqTimeout) @(posedge sc_port.$clk); | |
525 | dbg.dispmon(dispmonScope, MON_ERR, "ERROR: TIMEOUT for task wait_unpark_thread "); | |
526 | exit(1); | |
527 | } | |
528 | join any | |
529 | terminate; | |
530 | }join all | |
531 | }//End of wait_por2 | |
532 | ||
533 | ||
534 | ||
535 | //Wait for xir_reset | |
536 | task wait_xir_reset(){ | |
537 | fork { | |
538 | fork | |
539 | { | |
540 | @(posedge rst_port.$ncu_rst_xir_done); | |
541 | } | |
542 | { | |
543 | repeat (resetSeqTimeout) @(posedge sc_port.$clk); | |
544 | dbg.dispmon(dispmonScope, MON_ERR, "ERROR: TIMEOUT for task wait_xir_reset "); | |
545 | exit(1); | |
546 | } | |
547 | join any | |
548 | terminate; | |
549 | }join all | |
550 | }//End of wait_xir_reset | |
551 | } // End of sys_reset |