VMM - std_lib/vmm_env.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
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 
00041    this.notify.configure(GEN_CFG,      vmm_notify::ON_OFF);
00042    this.notify.configure(BUILD,        vmm_notify::ON_OFF);
00043    this.notify.configure(RESET_DUT,    vmm_notify::ON_OFF);
00044    this.notify.configure(CFG_DUT,      vmm_notify::ON_OFF);
00045    this.notify.configure(START,        vmm_notify::ON_OFF);
00046    this.notify.configure(RESTART,      vmm_notify::ON_OFF);
00047    this.notify.configure(WAIT_FOR_END, vmm_notify::ON_OFF);
00048    this.notify.configure(STOP,         vmm_notify::ON_OFF);
00049    this.notify.configure(CLEANUP,      vmm_notify::ON_OFF);
00050    this.notify.configure(REPORT,       vmm_notify::ON_OFF);
00051 
00052    this.reset_rng_state = 0;
00053    this.thread_rng_state_after_new = get_randstate();
00054 
00055    this.soft_restart = 0;
00056    this.soft_restartable = 0;
00057 
00058    this.end_vote = new(name, "End-of-test Consensus");
00059 endfunction: new
00060 
00061 
00062 task vmm_env::run();
00063    if (this.soft_restart || this.step == 0) this.pre_test();
00064 
00065    if (this.step < CLEANUP) this.cleanup();
00066    if (this.step != CLEANUP)
00067       `vmm_fatal(this.log, "Extension of vmm_env::cleanup() did not call super.cleanup().");
00068    this.report();
00069 endtask: run
00070 
00071 
00072 task vmm_env::pre_test();
00073    if (this.step == 0) begin
00074       this.cfg_dut();
00075       if (this.step != CFG_DUT) 
00076          `vmm_fatal(this.log, "Extension of vmm_env::cfg_dut() did not call super.cfg_dut().");
00077 
00078       // Save the seed for the main program thread
00079       this.thread_rng_state_after_pre_test = get_randstate();
00080       // Save the RNG state for the entire environment as built
00081       this.save_rng_state();
00082    
00083       // Make sure the saved seed are the one that are going
00084       // to be used when starting the environment, even if
00085       // some components are manually replaced in the test
00086       this.reset_rng_state = 1;
00087    end
00088    else if (this.step == RESTARTED) begin
00089       this.step = CFG_DUT;
00090    end
00091    else if (this.step <= CFG_DUT) begin
00092       `vmm_fatal(this.log, "vmm_env::pre_test() was not the first simulation step in simulation flow.");
00093    end
00094    else if (this.step > CFG_DUT) begin
00095       `vmm_fatal(this.log, "vmm_env::pre_test() called too late in simulation flow.");
00096    end
00097 
00098    set_randstate(this.thread_rng_state_after_pre_test);
00099    this.soft_restartable = 1;
00100    this.soft_restart = 0;
00101 endtask: pre_test
00102 
00103 
00104 function void vmm_env::gen_cfg();
00105    if (this.soft_restart) begin
00106      `vmm_fatal(this.log, "Cannot run a tests that invokes vmm_env::gen_cfg after a soft restart...");
00107    end
00108 
00109    this.step = GEN_CFG;
00110    this.notify.indicate(GEN_CFG);
00111    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00112       void'(this.log.text("Generating test configuration..."));
00113       this.log.end_msg();
00114    end
00115 endfunction: gen_cfg
00116 
00117 
00118 function void vmm_env::build();
00119    if (this.soft_restart) begin
00120       `vmm_fatal(this.log, "Cannot run a tests that invokes vmm_env::build after a soft restart...");
00121    end
00122 
00123    if (this.step < GEN_CFG) this.gen_cfg();
00124    if (this.step != GEN_CFG) begin
00125       `vmm_fatal(this.log, "Extension of vmm_env::gen_cfg() did not call super.gen_cfg().");
00126    end
00127 
00128    this.step = BUILD;
00129    this.notify.indicate(BUILD);
00130    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00131       void'(this.log.text("Building verification environment..."));
00132       this.log.end_msg();
00133    end
00134 endfunction: build
00135 
00136 
00137 task vmm_env::reset_dut();
00138    if (this.soft_restart) begin
00139       `vmm_fatal(this.log, "Cannot run a tests that invokes vmm_env::cfg_dut_t after a soft restart...");
00140    end
00141 
00142    if (this.step < BUILD) this.build();
00143    if (this.step != BUILD) begin
00144       `vmm_fatal(this.log, "Extension of vmm_env::build() did not call super.build().");
00145    end
00146 
00147    this.step = RESET_DUT;
00148    this.notify.indicate(RESET_DUT);
00149    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00150       void'(this.log.text("Reseting DUT..."));
00151       this.log.end_msg();
00152    end
00153 endtask: reset_dut
00154 
00155 
00156 task vmm_env::cfg_dut();
00157    if (this.soft_restart) begin
00158       `vmm_fatal(this.log, "Cannot run a tests that invokes vmm_env::cfg_dut_t after a soft restart...");
00159    end
00160 
00161    if (this.step < RESET_DUT) this.reset_dut();
00162    if (this.step != RESET_DUT) begin
00163       `vmm_fatal(this.log, "Extension of vmm_env::reset_dut() did not call super.reset_dut().");
00164    end
00165 
00166    this.step = CFG_DUT;
00167    this.notify.indicate(CFG_DUT);
00168    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00169       void'(this.log.text("Configuring..."));
00170       this.log.end_msg();
00171    end
00172 endtask: cfg_dut
00173 
00174 
00175 task vmm_env::start();
00176    if (this.step < CFG_DUT) this.cfg_dut();
00177    if (this.step != CFG_DUT) begin
00178       `vmm_fatal(this.log, "Extension of vmm_env::cfg_dut() did not call super.cfg_dut().");
00179    end
00180 
00181    this.step = START;
00182    this.notify.indicate(START);
00183    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00184       void'(this.log.text("Starting verification environment..."));
00185       this.log.end_msg();
00186    end
00187 
00188    if (this.reset_rng_state) begin
00189       this.restore_rng_state();
00190       this.reset_rng_state = 0;
00191    end
00192    else this.save_rng_state();
00193 endtask: start
00194 
00195 
00196 task vmm_env::wait_for_end();
00197    if (this.step < START) this.start();
00198    if (this.step != START) begin
00199       `vmm_fatal(this.log, "Extension of vmm_env::start() did not call super.start().");
00200    end
00201 
00202    this.step = WAIT_FOR_END;
00203    this.notify.indicate(WAIT_FOR_END);
00204    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00205       void'(this.log.text("Waiting for end of test..."));
00206       this.log.end_msg();
00207    end
00208 endtask: wait_for_end
00209 
00210 
00211 task vmm_env::stop();
00212    if (this.step < WAIT_FOR_END) this.wait_for_end();
00213    if (this.step != WAIT_FOR_END) begin
00214       `vmm_fatal(this.log, "Extension of vmm_env::wait_for_end() did not call super.wait_for_end().");
00215    end
00216 
00217    this.step = STOP;
00218    this.notify.indicate(STOP);
00219    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00220       void'(this.log.text("Stopping verification environment..."));
00221       this.log.end_msg();
00222    end
00223 endtask: stop
00224 
00225 
00226 task vmm_env::cleanup();
00227    if (this.step < STOP) this.stop();
00228    if (this.step != STOP) begin
00229       `vmm_fatal(this.log, "Extension of vmm_env::stop() did not call super.stop().");
00230    end
00231 
00232    this.step = CLEANUP;
00233    this.notify.indicate(CLEANUP);
00234    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00235       void'(this.log.text("Cleaning up..."));
00236       this.log.end_msg();
00237    end
00238 endtask: cleanup
00239 
00240 
00241 task vmm_env::restart(bit reconfig);
00242    if (!reconfig && !this.soft_restartable) begin
00243       `vmm_fatal(this.log, "Cannot soft-restart after test that did not call vmm_env::pre_test().");
00244    end
00245 
00246    if (this.step < CLEANUP) this.cleanup();
00247    if (this.step != CLEANUP) begin
00248       `vmm_fatal(this.log, "Extension of vmm_env::cleanup() did not call super.cleanup().");
00249    end
00250 
00251    this.notify.indicate(RESTART);
00252    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00253       void'(this.log.text("Restarting..."));
00254       this.log.end_msg();
00255    end
00256 
00257    this.notify.reset(START);
00258    this.notify.reset(RESTART);
00259    this.notify.reset(WAIT_FOR_END);
00260    this.notify.reset(STOP);
00261    this.notify.reset(CLEANUP);
00262    this.notify.reset(REPORT);
00263 
00264    if (reconfig) begin
00265       this.step = 0;
00266       this.notify.reset(GEN_CFG);
00267       this.notify.reset(BUILD);
00268       this.notify.reset(RESET_DUT);
00269       this.notify.reset(CFG_DUT);
00270       this.soft_restart = 0;
00271    end
00272    else begin
00273       this.step = RESTARTED;
00274       this.reset_rng_state = 1;
00275       this.soft_restart = 1;
00276    end
00277 
00278    set_randstate(this.thread_rng_state_after_new);
00279 endtask: restart
00280 
00281 
00282 task vmm_env::report();
00283    this.log.report("/./", "/./");
00284    this.notify.indicate(REPORT);
00285 endtask: report
00286 
00287 
00288 function void vmm_env::save_rng_state();
00289    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00290       void'(this.log.text("Saving RNG state information..."));
00291       this.log.end_msg();
00292    end
00293    this.thread_rng_state_before_start = get_randstate();
00294 endfunction: save_rng_state
00295 
00296 
00297 function void vmm_env::restore_rng_state();
00298    if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::TRACE_SEV )) begin
00299       void'(this.log.text("Restoring RNG state information..."));
00300       this.log.end_msg();
00301    end
00302    set_randstate(this.thread_rng_state_before_start);
00303 endfunction: restore_rng_state