VMM OpenSource - sv/std_lib/vmm_env.sv

sv/std_lib/vmm_env.sv expanded source

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