00001 //
00002 // -------------------------------------------------------------
00003 // Copyright 2004-2008 Synopsys, Inc.
00004 // All Rights Reserved Worldwide
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the
00007 // "License"); you may not use this file except in
00008 // compliance with the License. You may obtain a copy of
00009 // the License at
00010 //
00011 // http://www.apache.org/licenses/LICENSE-2.0
00012 //
00013 // Unless required by applicable law or agreed to in
00014 // writing, software distributed under the License is
00015 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00016 // CONDITIONS OF ANY KIND, either express or implied. See
00017 // the License for the specific language governing
00018 // permissions and limitations under the License.
00019 // -------------------------------------------------------------
00020 //
00021
00022
00023 function vmm_env::new(string name = "Verif Env"
00024 `VMM_ENV_BASE_NEW_EXTERN_ARGS);
00025 int initial_seed;
00026
00027 `ifdef VMM_ENV_BASE_NEW_CALL
00028 super.new(`VMM_ENV_BASE_NEW_CALL);
00029 `endif
00030
00031 this.log = new(name, "");
00032
00033 if ($value$plusargs("ntb_random_seed=%d", initial_seed)) begin
00034 `vmm_note(this.log, `vmm_sformatf("Initial random seed is %0d", initial_seed));
00035 end
00036
00037 this.step = 0;
00038
00039 this.notify = new(this.log);
00040 `ifdef VMM_OBJECT
00041 this.notify.set_parent(this);
00042 `endif
00043
00044 void'(this.notify.configure(GEN_CFG, vmm_notify::ON_OFF));
00045 void'(this.notify.configure(BUILD, vmm_notify::ON_OFF));
00046 void'(this.notify.configure(RESET_DUT, vmm_notify::ON_OFF));
00047 void'(this.notify.configure(CFG_DUT, vmm_notify::ON_OFF));
00048 void'(this.notify.configure(START, vmm_notify::ON_OFF));
00049 void'(this.notify.configure(RESTART, vmm_notify::ON_OFF));
00050 void'(this.notify.configure(WAIT_FOR_END, vmm_notify::ON_OFF));
00051 void'(this.notify.configure(STOP, vmm_notify::ON_OFF));
00052 void'(this.notify.configure(CLEANUP, vmm_notify::ON_OFF));
00053 void'(this.notify.configure(REPORT, vmm_notify::ON_OFF));
00054
00055 this.reset_rng_state = 0;
00056 this.thread_rng_state_after_new = get_randstate();
00057
00058 this.soft_restart = 0;
00059 this.soft_restartable = 0;
00060
00061 this.end_vote = new(name, "End-of-test Consensus");
00062 `ifdef VMM_OBJECT
00063 this.end_vote.set_parent(this);
00064 `endif
00065 endfunction: new
00066
00067
00068 function string vmm_env::psdisplay(string prefix = "");
00069 $sformat(psdisplay, "%sEnvironment %s(%s): ", prefix,
00070 this.log.get_name(), this.log.get_instance());
00071 return psdisplay;
00072 endfunction
00073
00074
00075 task vmm_env::run();
00076 if (this.step == 0 ||
00077 this.step == RESTARTED) this.pre_test();
00078
00079 if (this.step < CLEANUP) this.cleanup();
00080 if (this.step != CLEANUP) begin
00081 `vmm_fatal(this.log, "Extension of vmm_env::cleanup() did not call super.cleanup().");
00082 end
00083 this.report();
00084 endtask: run
00085
00086
00087 task vmm_env::reset_env(restart_e kind);
00088 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00089 void'(this.log.text({"Resetting environment (", kind.name(), ")..."}));
00090 this.log.end_msg();
00091 end
00092 endtask: reset_env
00093
00094
00095 task vmm_env::power_on_reset();
00096 this.hw_reset();
00097 endtask: power_on_reset
00098
00099
00100 task vmm_env::hw_reset();
00101 endtask: hw_reset
00102
00103
00104 task vmm_env::power_up();
00105 // All ON by default
00106 endtask: power_up
00107
00108
00109 task vmm_env::pre_test();
00110 if (this.step == 0) begin
00111 this.cfg_dut();
00112 if (this.step != CFG_DUT)
00113 `vmm_fatal(this.log, "Extension of vmm_env::cfg_dut() did not call super.cfg_dut().");
00114
00115 // Save the seed for the main program thread
00116 this.thread_rng_state_after_pre_test = get_randstate();
00117 // Save the RNG state for the entire environment as built
00118 this.save_rng_state();
00119
00120 // Make sure the saved seed are the one that are going
00121 // to be used when starting the environment, even if
00122 // some components are manually replaced in the test
00123 this.reset_rng_state = 1;
00124 end
00125 else if (this.step == RESTARTED) begin
00126 this.step = CFG_DUT;
00127 end
00128 else if (this.step <= CFG_DUT) begin
00129 `vmm_fatal(this.log, "vmm_env::pre_test() was not the first simulation step in simulation flow.");
00130 end
00131 else if (this.step > CFG_DUT) begin
00132 `vmm_fatal(this.log, "vmm_env::pre_test() called too late in simulation flow.");
00133 end
00134
00135 set_randstate(this.thread_rng_state_after_pre_test);
00136 this.soft_restartable = 1;
00137 this.soft_restart = 0;
00138 endtask: pre_test
00139
00140
00141 function void vmm_env::gen_cfg();
00142 if (this.soft_restart) begin
00143 `vmm_fatal(this.log, "Cannot run a tests that invokes vmm_env::gen_cfg after a soft restart...");
00144 end
00145
00146 this.step = GEN_CFG;
00147 this.notify.indicate(GEN_CFG);
00148 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00149 void'(this.log.text("Generating test configuration..."));
00150 this.log.end_msg();
00151 end
00152 endfunction: gen_cfg
00153
00154
00155 function void vmm_env::build();
00156 if (this.soft_restart) begin
00157 `vmm_fatal(this.log, "Cannot run a tests that invokes vmm_env::build after a soft restart...");
00158 end
00159
00160 if (this.step < GEN_CFG) this.gen_cfg();
00161 if (this.step != GEN_CFG) begin
00162 `vmm_fatal(this.log, "Extension of vmm_env::gen_cfg() did not call super.gen_cfg().");
00163 end
00164
00165 this.step = BUILD;
00166 this.notify.indicate(BUILD);
00167 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00168 void'(this.log.text("Building verification environment..."));
00169 this.log.end_msg();
00170 end
00171 endfunction: build
00172
00173
00174 task vmm_env::reset_dut();
00175 if (this.soft_restart) begin
00176 `vmm_fatal(this.log, "Cannot run a tests that invokes vmm_env::cfg_dut_t after a soft restart...");
00177 end
00178
00179 if (_vmm_opts.get_bit("help", "Displays a list of all VMM run-time options queried so far")) begin
00180 _vmm_opts.get_help();
00181 $finish;
00182 end
00183
00184 if (this.step < BUILD) this.build();
00185 if (this.step != BUILD) begin
00186 `vmm_fatal(this.log, "Extension of vmm_env::build() did not call super.build().");
00187 end
00188
00189 this.step = RESET_DUT;
00190 this.notify.indicate(RESET_DUT);
00191 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00192 void'(this.log.text("Reseting DUT..."));
00193 this.log.end_msg();
00194 end
00195 this.power_on_reset();
00196 endtask: reset_dut
00197
00198
00199 task vmm_env::cfg_dut();
00200 if (this.soft_restart) begin
00201 `vmm_fatal(this.log, "Cannot run a tests that invokes vmm_env::cfg_dut_t after a soft restart...");
00202 end
00203
00204 if (this.step < RESET_DUT) this.reset_dut();
00205 if (this.step != RESET_DUT) begin
00206 `vmm_fatal(this.log, "Extension of vmm_env::reset_dut() did not call super.reset_dut().");
00207 end
00208
00209 this.step = CFG_DUT;
00210 this.notify.indicate(CFG_DUT);
00211 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00212 void'(this.log.text("Configuring..."));
00213 this.log.end_msg();
00214 end
00215 this.power_up();
00216 endtask: cfg_dut
00217
00218
00219 task vmm_env::start();
00220 if (this.step < CFG_DUT) this.cfg_dut();
00221 if (this.step != CFG_DUT) begin
00222 `vmm_fatal(this.log, "Extension of vmm_env::cfg_dut() did not call super.cfg_dut().");
00223 end
00224
00225 this.step = START;
00226 this.notify.indicate(START);
00227 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00228 void'(this.log.text("Starting verification environment..."));
00229 this.log.end_msg();
00230 end
00231
00232 if (this.reset_rng_state) begin
00233 this.restore_rng_state();
00234 this.reset_rng_state = 0;
00235 end
00236 else this.save_rng_state();
00237 endtask: start
00238
00239
00240 task vmm_env::wait_for_end();
00241 if (this.step < START) this.start();
00242 if (this.step != START) begin
00243 `vmm_fatal(this.log, "Extension of vmm_env::start() did not call super.start().");
00244 end
00245
00246 this.step = WAIT_FOR_END;
00247 this.notify.indicate(WAIT_FOR_END);
00248 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00249 void'(this.log.text("Waiting for end of test..."));
00250 this.log.end_msg();
00251 end
00252 endtask: wait_for_end
00253
00254
00255 task vmm_env::stop();
00256 if (this.step < WAIT_FOR_END) this.wait_for_end();
00257 if (this.step != WAIT_FOR_END) begin
00258 `vmm_fatal(this.log, "Extension of vmm_env::wait_for_end() did not call super.wait_for_end().");
00259 end
00260
00261 this.step = STOP;
00262 this.notify.indicate(STOP);
00263 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00264 void'(this.log.text("Stopping verification environment..."));
00265 this.log.end_msg();
00266 end
00267 endtask: stop
00268
00269
00270 task vmm_env::cleanup();
00271 if (this.step < STOP) this.stop();
00272 if (this.step != STOP) begin
00273 `vmm_fatal(this.log, "Extension of vmm_env::stop() did not call super.stop().");
00274 end
00275
00276 this.step = CLEANUP;
00277 this.notify.indicate(CLEANUP);
00278 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00279 void'(this.log.text("Cleaning up..."));
00280 this.log.end_msg();
00281 end
00282 endtask: cleanup
00283
00284
00285 task vmm_env::restart(bit reconfig = 0);
00286 if (!reconfig && !this.soft_restartable) begin
00287 `vmm_fatal(this.log, "Cannot soft-restart after test that did not call vmm_env::pre_test().");
00288 end
00289
00290 this.reset_env((reconfig) ? HARD : SOFT);
00291
00292 // Only go to the end-of-test on SOFT or HARD restart
00293 if (this.step < CLEANUP) this.cleanup();
00294 if (this.step != CLEANUP) begin
00295 `vmm_fatal(this.log, "Extension of vmm_env::cleanup() did not call super.cleanup().");
00296 end
00297
00298 this.notify.indicate(RESTART);
00299 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00300 void'(this.log.text("Restarting..."));
00301 this.log.end_msg();
00302 end
00303
00304 this.notify.reset(START);
00305 this.notify.reset(RESTART);
00306 this.notify.reset(WAIT_FOR_END);
00307 this.notify.reset(STOP);
00308 this.notify.reset(CLEANUP);
00309 this.notify.reset(REPORT);
00310
00311 if (reconfig) begin
00312 this.step = 0;
00313 this.notify.reset(GEN_CFG);
00314 this.notify.reset(BUILD);
00315 this.notify.reset(RESET_DUT);
00316 this.notify.reset(CFG_DUT);
00317 this.soft_restart = 0;
00318 // Kill all sub-threads
00319 disable fork;
00320 end
00321 else begin
00322 this.step = RESTARTED;
00323 this.reset_rng_state = 1;
00324 this.soft_restart = 1;
00325 end
00326
00327 set_randstate(this.thread_rng_state_after_new);
00328 endtask: restart
00329
00330
00331 task vmm_env::restart_test();
00332 this.reset_env(FIRM);
00333
00334 this.notify.indicate(RESTART);
00335 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00336 void'(this.log.text("Restarting test..."));
00337 this.log.end_msg();
00338 end
00339
00340 this.notify.reset(RESET_DUT);
00341 this.notify.reset(CFG_DUT);
00342 this.notify.reset(START);
00343 this.notify.reset(RESTART);
00344 this.notify.reset(WAIT_FOR_END);
00345 this.notify.reset(STOP);
00346 this.notify.reset(CLEANUP);
00347 this.notify.reset(REPORT);
00348
00349 this.step = BUILD;
00350 endtask: restart_test
00351
00352
00353 task vmm_env::report();
00354 this.log.report("/./", "/./");
00355 this.notify.indicate(REPORT);
00356 endtask: report
00357
00358
00359 function void vmm_env::save_rng_state();
00360 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00361 void'(this.log.text("Saving RNG state information..."));
00362 this.log.end_msg();
00363 end
00364 this.thread_rng_state_before_start = get_randstate();
00365 endfunction: save_rng_state
00366
00367
00368 function void vmm_env::restore_rng_state();
00369 if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00370 void'(this.log.text("Restoring RNG state information..."));
00371 this.log.end_msg();
00372 end
00373 set_randstate(this.thread_rng_state_before_start);
00374 endfunction: restore_rng_state
00375
00376
00377 function string vmm_env::do_psdisplay(string prefix = "");
00378 this.__vmm_done_user = 0;
00379 endfunction
00380
00381
00382 task vmm_env::do_vote();
00383 this.__vmm_done_user = 0;
00384 endtask
00385
00386
00387 task vmm_env::do_start();
00388 this.__vmm_done_user = 0;
00389 endtask
00390
00391
00392 task vmm_env::do_stop();
00393 this.__vmm_done_user = 0;
00394 endtask
00395
00396
00397 task vmm_env::do_reset(vmm_env::restart_e kind);
00398 this.__vmm_done_user = 0;
00399 endtask