| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: misc_tasks.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 | `include "defines.vh" |
| 36 | |
| 37 | reg [7:0] sim_status; // Simlation status flags. Vera sees this for coverage. |
| 38 | integer junk; |
| 39 | integer PLIerrors; |
| 40 | integer core_cycle_cnt; // Core clock cycle count |
| 41 | integer global_cycle_cnt; // Core clock cycle count |
| 42 | reg [31:0] core_period; // Number of time units per cycle for core clock |
| 43 | reg core_period_change; |
| 44 | reg in_reset; |
| 45 | reg in_por; |
| 46 | reg in_reset_core; // delay start of in_reset for core because clocks take a couple cycles to stop |
| 47 | |
| 48 | |
| 49 | initial |
| 50 | begin |
| 51 | core_cycle_cnt = 0; |
| 52 | global_cycle_cnt = 0; |
| 53 | core_period = 750000; // Default value |
| 54 | core_period_change = 0; |
| 55 | sim_status = 0; |
| 56 | PLIerrors = 0; |
| 57 | last_act_cycle = 0; |
| 58 | |
| 59 | $enable_dispmon_finish(0); // dispmon will not terminate sim |
| 60 | `ifdef RELEASE1 |
| 61 | //`PR_ALWAYS ("top", `ALWAYS, "Running with build CDMS release version: %s", `RELEASE); |
| 62 | `PR_ALWAYS ("top", `ALWAYS, "Running with build CDMS release version: %d.%d", `RELEASE1,`RELEASE2); |
| 63 | `else |
| 64 | `PR_ALWAYS ("top", `ALWAYS, "If you build with -vcs_build_args=+define+RELEASE1=a+RELEASE2=nnn you will see your CDMS release version as: a.nnn"); |
| 65 | `PR_ALWAYS ("top", `ALWAYS, "Running with build CDMS release version: UNKNOWN"); |
| 66 | `endif |
| 67 | `ifndef AXIS_TL |
| 68 | `ifndef PLAYBACK |
| 69 | `ifdef EMBED_SIMS_BUILD_CMD |
| 70 | `PR_ALWAYS ("top", `ALWAYS, "------------BUILD_CMD-----------"); |
| 71 | `EMBED_SIMS_BUILD_CMD |
| 72 | `PR_ALWAYS ("top", `ALWAYS, "---------------------------------\n"); |
| 73 | `endif |
| 74 | `ifdef EMBED_SIMS_BUILD_ARGS |
| 75 | `PR_ALWAYS ("top", `ALWAYS, "------------BUILD_ARGS-----------"); |
| 76 | `EMBED_SIMS_BUILD_ARGS |
| 77 | `PR_ALWAYS ("top", `ALWAYS, "---------------------------------\n"); |
| 78 | `endif |
| 79 | `endif // PLAYBACK |
| 80 | `endif |
| 81 | end |
| 82 | `ifdef GATESIM |
| 83 | initial |
| 84 | begin |
| 85 | repeat (100) @ (posedge `CPU.cmp_gclk_c3_spc0); |
| 86 | $display(); |
| 87 | $display(); |
| 88 | `PR_ALWAYS ("top", `ALWAYS, "!!!!!!!!!!!!!!!!!!!!"); |
| 89 | `PR_ALWAYS ("top", `ALWAYS, "Gate Simulation. You must run -nosas. "); |
| 90 | `PR_ALWAYS ("top", `ALWAYS, " You will get very few messages in vcs.log."); |
| 91 | `PR_ALWAYS ("top", `ALWAYS, "!!!!!!!!!!!!!!!!!!!!"); |
| 92 | $display(); |
| 93 | $display(); |
| 94 | end |
| 95 | `endif |
| 96 | |
| 97 | |
| 98 | `ifdef CORE_BENCH |
| 99 | `ifndef AXIS_TL |
| 100 | `ifndef AXIS |
| 101 | `ifndef PLAYBACK |
| 102 | initial begin |
| 103 | `ifdef FC_BENCH |
| 104 | `ifndef FC_SCAN_BENCH |
| 105 | // FC Bench changes the core clock period based on plusargs |
| 106 | // can be delayed. |
| 107 | @(posedge `CPU.mio_rst_pwron_rst_l); |
| 108 | @(posedge `CPU.cluster_arst_l); |
| 109 | repeat (10) @(posedge `TOP.SYSCLK); |
| 110 | core_period = $rtoi(1000000.0/`TOP.ccu_pll_config.cmpclk) * 1000; |
| 111 | core_period_change = 1; |
| 112 | `endif |
| 113 | `else |
| 114 | #0; |
| 115 | // SPC2,CMP Benches have the same core clock period |
| 116 | core_period = 100; |
| 117 | core_period_change = 1; |
| 118 | `endif |
| 119 | `PR_NORMAL ("top", `NORMAL, "core and regreport clock period: %0d units", core_period); |
| 120 | repeat (10) @(posedge `TOP.SystemClock); |
| 121 | core_period_change = 0; |
| 122 | end |
| 123 | `endif // PLAYBACK |
| 124 | `endif |
| 125 | `endif |
| 126 | `endif |
| 127 | |
| 128 | |
| 129 | `ifdef CORE_BENCH |
| 130 | |
| 131 | // Bench requires free-running clocks. |
| 132 | // Signal delays the clock by 1 to match the clock header implementation that delays gclk->l2clk by 1 |
| 133 | wire bench_gclk; |
| 134 | |
| 135 | // in FC, this cmp clock does not run until/if the CCU is reset. |
| 136 | assign #1 bench_gclk = `CPU.cmp_gclk_c3_spc0; |
| 137 | |
| 138 | // All core,l2 clocks are same period and phase in the core benches. |
| 139 | // So, only 1 signal is needed in the Bench. |
| 140 | // Created separate defines to be used by the nas_car,ldst_sync,int_sync modules |
| 141 | `define BENCH_SPC0_GCLK `TOP.bench_gclk |
| 142 | `define BENCH_SPC1_GCLK `TOP.bench_gclk |
| 143 | `define BENCH_SPC2_GCLK `TOP.bench_gclk |
| 144 | `define BENCH_SPC3_GCLK `TOP.bench_gclk |
| 145 | `define BENCH_SPC4_GCLK `TOP.bench_gclk |
| 146 | `define BENCH_SPC5_GCLK `TOP.bench_gclk |
| 147 | `define BENCH_SPC6_GCLK `TOP.bench_gclk |
| 148 | `define BENCH_SPC7_GCLK `TOP.bench_gclk |
| 149 | `define BENCH_L2T0_GCLK `TOP.bench_gclk |
| 150 | `define BENCH_L2T1_GCLK `TOP.bench_gclk |
| 151 | `define BENCH_L2T2_GCLK `TOP.bench_gclk |
| 152 | `define BENCH_L2T3_GCLK `TOP.bench_gclk |
| 153 | `define BENCH_L2T4_GCLK `TOP.bench_gclk |
| 154 | `define BENCH_L2T5_GCLK `TOP.bench_gclk |
| 155 | `define BENCH_L2T6_GCLK `TOP.bench_gclk |
| 156 | `define BENCH_L2T7_GCLK `TOP.bench_gclk |
| 157 | |
| 158 | `define BENCH_NCU_GCLK `TOP.bench_gclk |
| 159 | |
| 160 | always @ (posedge `CPU.cmp_gclk_c3_spc0) begin |
| 161 | core_cycle_cnt=core_cycle_cnt+1; |
| 162 | end |
| 163 | |
| 164 | `ifndef PLAYBACK |
| 165 | // SystemClock always runs |
| 166 | always @ (posedge `TOP.SystemClock) begin |
| 167 | global_cycle_cnt=global_cycle_cnt+1; |
| 168 | end |
| 169 | `endif // PLAYBACK |
| 170 | |
| 171 | `endif |
| 172 | |
| 173 | `ifndef PLAYBACK |
| 174 | always @(global_cycle_cnt) begin |
| 175 | // Runaway throttle |
| 176 | if (global_cycle_cnt > `PARGS.max_cycle) begin // { |
| 177 | // Note: Do not change this message because regreport parses it for certain words. |
| 178 | `PR_ALWAYS ("top", `ALWAYS, "ERROR: Maximum Simulation Cycles (%0d) Reached.", `PARGS.max_cycle); |
| 179 | `PR_ALWAYS ("top", `ALWAYS, " Use -max_cycle=n to extend, if not runaway simulation"); |
| 180 | junk = incErr(9999); // must exceed users max error setting to force exit. |
| 181 | `BAD_END; |
| 182 | end //} |
| 183 | |
| 184 | `ifndef FC_SCAN_BENCH |
| 185 | `ifndef AXIS_TL |
| 186 | `ifndef GATESIM |
| 187 | // Timeout Check |
| 188 | if ((core_cycle_cnt - `TOP.last_act_cycle) > `PARGS.timeout) begin //{ |
| 189 | // Note: Do not change this message because regreport parses it for certain words. |
| 190 | `PR_ALWAYS ("top", `ALWAYS, "ERROR: All Threads No Activity for %0d Cycles - Global TIMEOUT!", `PARGS.timeout); |
| 191 | `PR_ALWAYS ("top", `ALWAYS, " Use -rtl_timeout=n to extend, if not runaway simulation"); |
| 192 | junk = incErr(9999); // must exceed users max error setting to force exit. |
| 193 | `BAD_END; |
| 194 | end // } |
| 195 | `endif |
| 196 | `endif |
| 197 | `endif |
| 198 | |
| 199 | end // } |
| 200 | `endif // PLAYBACK |
| 201 | |
| 202 | |
| 203 | `ifndef PLAYBACK |
| 204 | always @(`TOP.finished_tids) begin |
| 205 | if (!((`TOP.finished_tids & `PARGS.finish_mask)^`PARGS.finish_mask) && |
| 206 | (core_cycle_cnt > 1)) begin |
| 207 | if (!`PARGS.nas_check_on) begin |
| 208 | `PR_ALWAYS ("top",`ALWAYS,"-------------------------------------------------"); |
| 209 | `PR_ALWAYS ("top",`ALWAYS,"!!!!! !!!!!"); |
| 210 | `PR_ALWAYS ("top",`ALWAYS," Nas Checking was Disabled for this diag."); |
| 211 | `PR_ALWAYS ("top",`ALWAYS,"!!!!! !!!!!"); |
| 212 | `PR_ALWAYS ("top",`ALWAYS,"-------------------------------------------------"); |
| 213 | end |
| 214 | `PR_ALWAYS("top", `ALWAYS, "\nAll Threads Have Finished Due To Reaching The Good Trap Address..."); |
| 215 | good_end; // potential good end |
| 216 | end |
| 217 | end |
| 218 | `endif // PLAYBACK |
| 219 | |
| 220 | |
| 221 | // in_reset indicates that core(s) are not running due to "reset". |
| 222 | // This would be true before the first thread starts and during warm resets. |
| 223 | // in_reset_core - used by core Bench code to reset nas_pipe & tlb_sync. |
| 224 | // delay start because clocks take a couple cycles to stop in the core |
| 225 | |
| 226 | // This code only works in a core Bench (ie SPC2,CMP,FC), not a SAT (ie DMU SAT) |
| 227 | // But, this file (misc_tasks.v) is included in all SATs. |
| 228 | `ifdef CORE_BENCH |
| 229 | |
| 230 | `ifndef FC_SCAN_BENCH |
| 231 | `ifndef AXIS_TL |
| 232 | `ifndef GATESIM |
| 233 | |
| 234 | initial begin |
| 235 | in_por = 1; |
| 236 | in_reset = 1; |
| 237 | in_reset_core = 1; |
| 238 | `ifdef SPC_BENCH |
| 239 | while (|`CPU.ncu_spc0_core_running !== 1) // while X or 0, still waiting |
| 240 | @(posedge |`CPU.ncu_spc0_core_running); // X -> 1 or 0 -> 1 |
| 241 | `else |
| 242 | while (|(`CPU.ncu_spc0_core_running |`CPU.ncu_spc1_core_running | |
| 243 | `CPU.ncu_spc2_core_running |`CPU.ncu_spc3_core_running | |
| 244 | `CPU.ncu_spc4_core_running |`CPU.ncu_spc5_core_running | |
| 245 | `CPU.ncu_spc6_core_running |`CPU.ncu_spc7_core_running) |
| 246 | !== 1) // while X or 0, still waiting |
| 247 | @(posedge |(`CPU.ncu_spc0_core_running |`CPU.ncu_spc1_core_running | |
| 248 | `CPU.ncu_spc2_core_running |`CPU.ncu_spc3_core_running | |
| 249 | `CPU.ncu_spc4_core_running |`CPU.ncu_spc5_core_running | |
| 250 | `CPU.ncu_spc6_core_running |`CPU.ncu_spc7_core_running)) |
| 251 | // X -> 1 or 0 -> 1 |
| 252 | `endif |
| 253 | in_por = 0; |
| 254 | in_reset = 0; |
| 255 | in_reset_core = 0; |
| 256 | |
| 257 | // Warm/Debug reset : |
| 258 | // - Assert in_reset when clocks are stopped and rst_wrm_protect is asserted |
| 259 | // - Negate in_reset when rst_wrm_protect negates |
| 260 | forever begin |
| 261 | // Wait for clock_stop or rst_wmr_protect to change |
| 262 | `ifdef SPC_BENCH |
| 263 | @(`CPU.rst_wmr_protect or `CPU.tcu_spc0_clk_stop); |
| 264 | `else |
| 265 | @(`CPU.rst_wmr_protect or `CPU.tcu_spc0_clk_stop or |
| 266 | `CPU.tcu_spc1_clk_stop or `CPU.tcu_spc2_clk_stop or |
| 267 | `CPU.tcu_spc3_clk_stop or `CPU.tcu_spc4_clk_stop or |
| 268 | `CPU.tcu_spc5_clk_stop or `CPU.tcu_spc6_clk_stop or |
| 269 | `CPU.tcu_spc7_clk_stop or `CPU.rst_tcu_pwron_rst_l); |
| 270 | `endif |
| 271 | if ((`CPU.rst_wmr_protect !== ~`CPU.rst_wmr_protect) |
| 272 | `ifndef SPC_BENCH |
| 273 | || (`CPU.rst_tcu_pwron_rst_l !== `CPU.rst_tcu_pwron_rst_l) |
| 274 | `endif |
| 275 | ) begin // if not X and not z |
| 276 | if (!in_reset) begin // Assertion of in_reset |
| 277 | `ifndef SPC_BENCH |
| 278 | if (`CPU.rst_tcu_pwron_rst_l) //delay only if not POR |
| 279 | `endif |
| 280 | repeat (6) @(posedge `CPU.cmp_gclk_c3_spc0); // Delay for clock stopping. |
| 281 | `ifdef SPC_BENCH |
| 282 | in_reset = `CPU.rst_wmr_protect & `CPU.tcu_spc0_clk_stop; |
| 283 | `else |
| 284 | in_por = ~`CPU.rst_tcu_pwron_rst_l ; |
| 285 | in_reset = ((`CPU.rst_wmr_protect |~`CPU.rst_tcu_pwron_rst_l) & |
| 286 | `CPU.tcu_spc0_clk_stop & `CPU.tcu_spc1_clk_stop & |
| 287 | `CPU.tcu_spc2_clk_stop & `CPU.tcu_spc3_clk_stop & |
| 288 | `CPU.tcu_spc4_clk_stop & `CPU.tcu_spc5_clk_stop & |
| 289 | `CPU.tcu_spc6_clk_stop & `CPU.tcu_spc7_clk_stop ); |
| 290 | `endif |
| 291 | end |
| 292 | else begin // De-assertion of in_reset |
| 293 | // If just wmr, deassert on wmr negation. |
| 294 | // If POR, de-assert on thread startup .. |
| 295 | `ifdef SPC_BENCH |
| 296 | in_reset = `CPU.rst_wmr_protect ; |
| 297 | `else |
| 298 | if (in_por) begin // { |
| 299 | @(posedge |(`CPU.ncu_spc0_core_running |`CPU.ncu_spc1_core_running | |
| 300 | `CPU.ncu_spc2_core_running |`CPU.ncu_spc3_core_running | |
| 301 | `CPU.ncu_spc4_core_running |`CPU.ncu_spc5_core_running | |
| 302 | `CPU.ncu_spc6_core_running |`CPU.ncu_spc7_core_running)) |
| 303 | in_por = 0; |
| 304 | in_reset = 0; |
| 305 | end //} |
| 306 | else |
| 307 | in_reset = `CPU.rst_wmr_protect ; |
| 308 | `endif |
| 309 | end |
| 310 | end |
| 311 | in_reset_core = in_reset_core & in_reset; // deassert on same cycle as in_reset |
| 312 | if (in_reset & !in_reset_core) begin |
| 313 | repeat (5) @(posedge `CPU.cmp_gclk_c3_spc0); |
| 314 | in_reset_core = in_reset ; // assert N cycles after in_reset asserts |
| 315 | end |
| 316 | end |
| 317 | end |
| 318 | `endif |
| 319 | `endif |
| 320 | `endif |
| 321 | `endif |
| 322 | |
| 323 | |
| 324 | task pli_quit; |
| 325 | integer tmp; |
| 326 | begin |
| 327 | `ifndef AXIS_TL |
| 328 | `ifndef PLAYBACK |
| 329 | if (`PARGS.nas_check_on) begin // { |
| 330 | tmp = $sim_send(`PLI_QUIT); |
| 331 | `PARGS.nas_check_on = 0; |
| 332 | end //} |
| 333 | `endif // PLAYBACK |
| 334 | `endif |
| 335 | end |
| 336 | endtask |
| 337 | |
| 338 | //---------------------------------------------------------- |
| 339 | // potential good end, but need to check error status! |
| 340 | task good_end; |
| 341 | reg [31:0] countDown; |
| 342 | reg [31:0] sysclk_period; |
| 343 | reg [16*8:0] miscstr; |
| 344 | reg ssi_diag; |
| 345 | |
| 346 | begin // --axis tbcall_region// { |
| 347 | |
| 348 | `ifndef AXIS_TL |
| 349 | `ifndef PLAYBACK |
| 350 | ssi_diag = 0; |
| 351 | |
| 352 | `ifdef FC_SCAN_BENCH |
| 353 | `else |
| 354 | pli_quit; |
| 355 | `endif |
| 356 | // query the C dispmon code to see if there are any errors |
| 357 | // from Riesling. |
| 358 | $check_num_dispmon_errors(PLIerrors); |
| 359 | `endif // PLAYBACK |
| 360 | `endif |
| 361 | |
| 362 | |
| 363 | // If verilog/Reisling sees errors, print Failed right away. |
| 364 | // Vera may do the same, but two is better than none. |
| 365 | // |
| 366 | // If Verilog sees NO errors, wait some clocks so that |
| 367 | // vera can have time to decide to print a failing message. |
| 368 | // In this case, the following message will never have a chance to happen. |
| 369 | if (!`TOP.error_count && `TOP.warning_count < maxwarning && !PLIerrors) begin |
| 370 | |
| 371 | `ifdef FC_BENCH |
| 372 | `ifndef FC_SCAN_BENCH |
| 373 | `ifndef AXIS_TL |
| 374 | `ifndef PLAYBACK |
| 375 | // wait for any SSI writes to complete. Used in DTM_MODE. |
| 376 | if ($test$plusargs("SSI_STATUS")) begin |
| 377 | if ($value$plusargs("good_trap=%s", miscstr)) begin |
| 378 | if (get_thread_enables(miscstr) > 64'hf000000000) ssi_diag = 1; |
| 379 | end |
| 380 | if ($value$plusargs("bad_trap=%s", miscstr)) begin |
| 381 | if (get_thread_enables(miscstr) > 64'hf000000000) ssi_diag = 1; |
| 382 | end |
| 383 | |
| 384 | if (!ssi_diag) begin |
| 385 | `PR_ALWAYS ("top", `ALWAYS, "\n+SSI_STATUS seen, good_end waiting for SSI idle (could take a while)"); |
| 386 | // prevent a bogus timeout |
| 387 | `PARGS.timeout = `PARGS.timeout + 10000; |
| 388 | countDown = 50; |
| 389 | while (countDown) begin |
| 390 | @(posedge `CPU.ncu_mio_ssi_sck); |
| 391 | if (`CPU.mio_ncu_ssi_miso === 1 || |
| 392 | `CPU.ncu_mio_ssi_mosi === 1) begin |
| 393 | countDown = 50; |
| 394 | end |
| 395 | countDown = countDown - 1; |
| 396 | end |
| 397 | `PR_ALWAYS ("top", `ALWAYS, "+SSI_STATUS seen, good_end is done waiting for SSI idle..."); |
| 398 | end |
| 399 | end |
| 400 | `endif // PLAYBACK |
| 401 | |
| 402 | // for vector collection |
| 403 | if ($test$plusargs("SSI_STATUS") || $test$plusargs("DTM_ENABLED")) begin |
| 404 | core_period = $rtoi(1000000.0/`TOP.ccu_pll_config.cmpclk) * 1000; |
| 405 | core_period_change = 1; |
| 406 | `PR_ALWAYS ("top", `ALWAYS, "\ncore and regreport clock period: %0d units",core_period); |
| 407 | sysclk_period = $rtoi(1000000.0/`TOP.ccu_pll_config.sysclk) * 1000; |
| 408 | `PR_ALWAYS ("top", `ALWAYS, "SYSCLK period is: %0d units",sysclk_period); |
| 409 | sysclk_period = sysclk_period/1000; // fs to ps since $time will be ps |
| 410 | `PR_ALWAYS ("top", `ALWAYS, "SYSCLK count is: %0d\n", $time/sysclk_period); |
| 411 | end |
| 412 | `endif |
| 413 | `endif |
| 414 | `endif |
| 415 | |
| 416 | // Vera needs to see this sim_status! |
| 417 | // Vera might fail and exit before we pass and exit if |
| 418 | // there are Vera errors. Just because verilog |
| 419 | // thinks the end is good, Vera may not agree!!! |
| 420 | `ifndef AXIS_TL |
| 421 | `ifndef PLAYBACK |
| 422 | sim_status[`ASM_PASS] = 1; |
| 423 | // Give Vera some time to fail on its final errors if it wants to. |
| 424 | // Vera has at least 5 clocks to print failed and die if it needs to. |
| 425 | // NEVER do this in the failing case (bad_end)! |
| 426 | repeat (`TOP.wait_cycle_to_kill + 5) @(posedge `CPU.cmp_gclk_c3_spc0); |
| 427 | // Stall here forever if no_verilog_finish is set. |
| 428 | // User sets this when Vera wants to do a delayed exit |
| 429 | // after asm code has finished. |
| 430 | if (`TOP.no_verilog_finish) begin |
| 431 | `PR_ALWAYS ("top", `ALWAYS, "See no_verilog_finish set, simulation will continue until Vera finishes it!"); |
| 432 | while (`TOP.no_verilog_finish) @(posedge `CPU.cmp_gclk_c3_spc0); |
| 433 | end |
| 434 | `endif // PLAYBACK |
| 435 | `endif |
| 436 | // regreport needs "GOOD End". Do not alter. |
| 437 | // Reaching GOOD End does not imply passing. The word PASS shall never |
| 438 | // be printed, ever! That is up to regreport to decide. |
| 439 | `PR_ALWAYS ("top", `ALWAYS, "Diag Reached GOOD End! (pre regreport checking)"); |
| 440 | // will remove following later after sims gets changed |
| 441 | `PR_ALWAYS ("top", `ALWAYS, "regreport will determine if diag has really PASSED"); |
| 442 | |
| 443 | |
| 444 | |
| 445 | |
| 446 | `ifdef FC_BENCH |
| 447 | `ifndef FC_SCAN_BENCH |
| 448 | `ifndef AXIS_TL |
| 449 | `ifndef AXIS |
| 450 | core_period = $rtoi(1000000.0/`TOP.ccu_pll_config.cmpclk) * 1000; |
| 451 | `endif |
| 452 | `endif |
| 453 | `endif |
| 454 | `endif |
| 455 | |
| 456 | `ifndef AXIS_TL |
| 457 | `ifndef AXIS |
| 458 | `PR_ALWAYS ("top", `ALWAYS, "core and regreport clock period: %0d units\n",core_period); |
| 459 | `endif |
| 460 | `endif |
| 461 | |
| 462 | $finish; |
| 463 | |
| 464 | end |
| 465 | else begin |
| 466 | `PR_ALWAYS ("top", `ALWAYS, "good_end is calling bad_end. Had PLI errors, or error_count was not zero. This should be UNUSUAL!"); |
| 467 | bad_end; |
| 468 | end |
| 469 | |
| 470 | end // } |
| 471 | |
| 472 | endtask |
| 473 | |
| 474 | //---------------------------------------------------------- |
| 475 | // Have verilog errors, need to die. |
| 476 | task bad_end; |
| 477 | begin // --axis tbcall_region // { |
| 478 | `ifndef AXIS_TL |
| 479 | `ifndef PLAYBACK |
| 480 | `TOP.bad_end_called = `TOP.bad_end_called + 1; |
| 481 | `ifndef FC_SCAN_BENCH |
| 482 | pli_quit; |
| 483 | `endif |
| 484 | |
| 485 | // query the C dispmon code to see if there are any Riesling errors |
| 486 | $check_num_dispmon_errors(PLIerrors); |
| 487 | if (PLIerrors > `TOP.error_count) begin |
| 488 | //`TOP.error_count = `TOP.error_count + PLIerrors; |
| 489 | `PR_ALWAYS("top", `ALWAYS, "\nRiesling/PLI had ERRORs! (PLIerrors=%0d)\n",PLIerrors); |
| 490 | end |
| 491 | |
| 492 | `PR_ALWAYS ("top", `ALWAYS, "Diag Finished/Failed with ERRORs! (error_count=%0d)",`TOP.error_count); |
| 493 | `PR_ALWAYS ("top", `ALWAYS, "Disabling further checking.\n"); |
| 494 | |
| 495 | `ifdef FC_BENCH |
| 496 | `ifndef FC_SCAN_BENCH |
| 497 | `ifndef AXIS_TL |
| 498 | `ifndef AXIS |
| 499 | core_period = $rtoi(1000000.0/`TOP.ccu_pll_config.cmpclk) * 1000; |
| 500 | core_period_change = 1; |
| 501 | `endif |
| 502 | `endif |
| 503 | `endif |
| 504 | `endif |
| 505 | |
| 506 | `ifndef AXIS_TL |
| 507 | `ifndef AXIS |
| 508 | `PR_ALWAYS ("top", `ALWAYS, "core and regreport clock period: %0d units\n",core_period); |
| 509 | `endif |
| 510 | `endif |
| 511 | |
| 512 | // vera needs to see this |
| 513 | sim_status[`ASM_ERR] = 1; |
| 514 | // if maxerror > 1 we hang now unless $finish. don't know why |
| 515 | // so do this for now. Might be dispmon C code seeing > 1 error. |
| 516 | if (`TOP.maxerror > 1) $finish; |
| 517 | |
| 518 | // Give Vera some time to do stuff. Vera may fail the |
| 519 | // simulation and exit before our wait is up. No big deal. |
| 520 | // We might get two "Diag Finished/Failed with ERRORs!". |
| 521 | // Two is always better than none. |
| 522 | if (`TOP.wait_cycle_to_kill > 4) repeat (`TOP.wait_cycle_to_kill) @(posedge `TOP.SystemClock); |
| 523 | else repeat (5) @(posedge `TOP.SystemClock); |
| 524 | $finish; |
| 525 | `endif // PLAYBACK |
| 526 | `endif |
| 527 | end // } |
| 528 | endtask |
| 529 | |
| 530 | |
| 531 | |
| 532 | |
| 533 | //---------------------------------------------------------- |
| 534 | // |
| 535 | // ALL calls to $random MUST look like this!!! $random(`PARGS.seed) |
| 536 | // |
| 537 | |
| 538 | // this is obsolete, see file plus_args.v to see how seeding is done |
| 539 | // ALL calls to $random MUST look like this!!! $random(`PARGS.seed) |
| 540 | |
| 541 | task set_seed; |
| 542 | input integer seedIn; |
| 543 | begin |
| 544 | $display("Calling set_seed or verilog_set_seed is obsolete. You can stop now."); |
| 545 | // seedin = seedIn; // save seed |
| 546 | // seed = seedIn; |
| 547 | // junk = $random(seedIn); |
| 548 | end |
| 549 | endtask |
| 550 | |
| 551 | //---------------------------------------------------------- |
| 552 | function [39:0] hashpa; |
| 553 | input [39:0] pa; |
| 554 | |
| 555 | begin // { |
| 556 | |
| 557 | hashpa = pa; |
| 558 | hashpa[17:11] = {(pa[32:28]^pa[17:13]),(pa[19:18]^pa[12:11])}; |
| 559 | |
| 560 | end // } |
| 561 | endfunction |
| 562 | |