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