00001 //---------------------------------------------------------------------- 00002 // Copyright 2007-2008 Mentor Graphics Corporation 00003 // Copyright 2007-2008 Cadence Design Systems, 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 typedef enum {CREATED, PRE_BODY, BODY, POST_BODY, ENDED, STOPPED, FINISHED} ovm_sequence_state_enum; 00022 00023 class ovm_sequence_base extends ovm_sequence_item; 00024 00025 protected ovm_sequence_state_enum m_sequence_state; 00026 protected bit m_sequence_state_prebody, m_sequence_state_body, m_sequence_state_postbody; 00027 protected bit m_sequence_state_ended, m_sequence_state_stopped; 00028 integer m_next_transaction_id = 1; 00029 local integer m_priority = -1; 00030 event started, ended; 00031 int m_tr_handle; 00032 int m_wait_for_grant_semaphore; 00033 00034 // Each sequencer will assign a sequence id. When a sequence is talking to multiple 00035 // sequencers, each sequence_id is managed seperately 00036 protected integer m_sqr_seq_ids[integer]; 00037 00038 `ifndef INCA 00039 protected process m_sequence_process; 00040 `else 00041 protected bit m_sequence_started = 0; 00042 protected event m_kill_event; 00043 `endif 00044 local bit m_use_response_handler = 0; 00045 00046 //used as an identifier in constraints for a specific type 00047 rand integer unsigned seq_kind; 00048 00049 // For user random selection. This excludes the exhaustive and 00050 // random sequences. 00051 constraint pick_sequence { 00052 (num_sequences() <= 2) || (seq_kind >= 2); 00053 (seq_kind < num_sequences()) || (seq_kind == 0); } 00054 00055 // bits to detect if is_relevant()/wait_for_relevant() are implemented 00056 local bit is_rel_default; 00057 local bit wait_rel_default; 00058 00059 function new (string name = "ovm_sequence", 00060 ovm_sequencer_base sequencer_ptr = null, 00061 ovm_sequence_base parent_seq = null); 00062 static bit issued1=0,issued2=0; 00063 00064 super.new(name); 00065 if (sequencer_ptr != null) begin 00066 if (!issued1) begin 00067 issued1=1; 00068 ovm_report_warning("deprecated", 00069 {"ovm_sequence::new()'s sequencer_ptr argument has been deprecated. ", 00070 "The sequencer is now specified at the time a sequence is started ", 00071 "using the start() task."}); 00072 end 00073 end 00074 if (parent_seq != null) begin 00075 if (!issued2) begin 00076 issued2=1; 00077 ovm_report_warning("deprecated", 00078 {"ovm_sequence::new()'s parent_seq argument has been deprecated. ", 00079 "The parent sequence is now specified at the time a sequence is started ", 00080 "using the start() task."}); 00081 end 00082 end 00083 m_sequence_state_prebody = 0; 00084 m_sequence_state_body = 0; 00085 m_sequence_state_postbody = 0; 00086 m_sequence_state_ended = 0; 00087 m_sequence_state_stopped = 0; 00088 m_sequence_state = CREATED; 00089 m_wait_for_grant_semaphore = 0; 00090 endfunction // new 00091 00092 function ovm_sequence_state_enum get_sequence_state(); 00093 return (m_sequence_state); 00094 endfunction 00095 00096 task wait_for_sequence_state(ovm_sequence_state_enum state); 00097 00098 // Use state bits to ensure triggering even when there are no delta cycles between states 00099 case (state) 00100 PRE_BODY: wait (m_sequence_state_prebody == 1); 00101 BODY: wait (m_sequence_state_body == 1); 00102 POST_BODY: wait (m_sequence_state_postbody == 1); 00103 ENDED: wait (m_sequence_state_ended == 1); 00104 STOPPED: wait (m_sequence_state_stopped == 1); 00105 FINISHED: wait (m_sequence_state == FINISHED); 00106 endcase // case(state) 00107 endtask // wait_for_sequence_state 00108 00109 virtual task start (ovm_sequencer_base sequencer, 00110 ovm_sequence_base parent_sequence = null, 00111 integer this_priority = 100, 00112 bit call_pre_post = 1); 00113 00114 m_parent_sequence = parent_sequence; 00115 m_sequencer = sequencer; 00116 m_priority = this_priority; 00117 endtask // start 00118 00119 function void stop(); 00120 return; 00121 endfunction 00122 00123 virtual task pre_body(); 00124 return; 00125 endtask // pre_body 00126 00127 virtual task post_body(); 00128 return; 00129 endtask // post_body 00130 00131 virtual task pre_do(bit is_item); 00132 return; 00133 endtask // pre_do 00134 00135 virtual task body(); 00136 ovm_report_warning("ovm_sequence_base", "Body definition undefined"); 00137 return; 00138 endtask 00139 00140 virtual function bit is_item(); 00141 return(0); 00142 endfunction 00143 00144 virtual function void mid_do(ovm_sequence_item this_item); 00145 return; 00146 endfunction 00147 00148 virtual function void post_do(ovm_sequence_item this_item); 00149 return; 00150 endfunction 00151 00152 function integer num_sequences(); 00153 if (m_sequencer == null) return (0); 00154 return (m_sequencer.num_sequences()); 00155 endfunction // num_sequences 00156 00157 function integer get_seq_kind(string type_name); 00158 if(m_sequencer) 00159 return m_sequencer.get_seq_kind(type_name); 00160 else 00161 ovm_report_fatal("NULLSQ", $psprintf("%0s sequencer is null.", 00162 get_type_name())); 00163 endfunction 00164 00165 function ovm_sequence_base get_sequence(integer unsigned req_kind); 00166 ovm_sequence_base m_seq; 00167 string m_seq_type; 00168 ovm_factory factory = ovm_factory::get(); 00169 if (req_kind < 0 || req_kind >= m_sequencer.sequences.size()) begin 00170 ovm_report_error("SEQRNG", 00171 $psprintf("Kind arg '%0d' out of range. Need 0-%0d", 00172 req_kind, m_sequencer.sequences.size()-1)); 00173 end 00174 m_seq_type = m_sequencer.sequences[req_kind]; 00175 if (!$cast(m_seq, factory.create_object_by_name(m_seq_type, get_full_name(), m_seq_type))) begin 00176 ovm_report_fatal("FCTSEQ", 00177 $psprintf("Factory can not produce a sequence of type %0s.", 00178 m_seq_type)); 00179 end 00180 m_seq.set_use_sequence_info(1); 00181 return m_seq; 00182 endfunction // ovm_sequence_base 00183 00184 function ovm_sequence_base get_sequence_by_name(string seq_name); 00185 ovm_sequence_base m_seq; 00186 if (!$cast(m_seq, factory.create_object_by_name(seq_name, get_full_name(), seq_name))) begin 00187 ovm_report_fatal("FCTSEQ", 00188 $psprintf("Factory can not produce a sequence of type %0s.", seq_name)); 00189 end 00190 m_seq.set_use_sequence_info(1); 00191 return m_seq; 00192 endfunction // ovm_sequence_base 00193 00194 task do_sequence_kind(integer unsigned req_kind); 00195 string m_seq_type; 00196 ovm_sequence_base m_seq; 00197 ovm_factory factory = ovm_factory::get(); 00198 m_seq_type = m_sequencer.sequences[req_kind]; 00199 if (!$cast(m_seq, factory.create_object_by_name(m_seq_type, get_full_name(), m_seq_type))) begin 00200 ovm_report_fatal("FCTSEQ", 00201 $psprintf("Factory can not produce a sequence of type %0s.", m_seq_type)); 00202 end 00203 m_seq.set_use_sequence_info(1); 00204 m_seq.set_parent_sequence(this); 00205 m_seq.set_sequencer(m_sequencer); 00206 m_seq.set_depth(get_depth() + 1); 00207 m_seq.reseed(); 00208 00209 start_item(m_seq); 00210 assert(m_seq.randomize()) else begin 00211 ovm_report_warning("RNDFLD", "Randomization failed in do_sequence_kind()"); 00212 end 00213 finish_item(m_seq); 00214 endtask // do_sequence_kind 00215 00216 task create_and_start_sequence_by_name(string seq_name); 00217 ovm_sequence_base m_seq; 00218 m_seq = get_sequence_by_name(seq_name); 00219 m_seq.start(m_sequencer, this, this.get_priority(), 0); 00220 endtask 00221 00222 function void set_priority (integer value); 00223 m_priority = value; 00224 endfunction 00225 00226 function integer get_priority(); 00227 return (m_priority); 00228 endfunction // int 00229 00230 // wait_for_relevant 00231 // ----------------- 00232 00233 virtual task wait_for_relevant(); 00234 event e; 00235 wait_rel_default = 1; 00236 if (is_rel_default != wait_rel_default) 00237 ovm_report_fatal("RELMSM", 00238 "is_relevant() was implemented without defining wait_for_relevant()"); 00239 @e; // this is intended to never return 00240 endtask 00241 00242 // is_relevant 00243 // ----------- 00244 00245 virtual function bit is_relevant(); 00246 is_rel_default = 1; 00247 return 1; 00248 endfunction 00249 00250 function bit is_blocked(); 00251 return(m_sequencer.is_blocked(this)); 00252 endfunction // bit 00253 00254 task lock(ovm_sequencer_base sequencer = null); 00255 if (sequencer == null) begin 00256 assert (m_sequencer != null) else begin 00257 ovm_report_fatal("ISRELVNT", "Null m_sequencer reference"); 00258 end 00259 m_sequencer.lock(this); 00260 end 00261 else begin 00262 sequencer.lock(this); 00263 end 00264 endtask // grab 00265 00266 task grab(ovm_sequencer_base sequencer = null); 00267 if (sequencer == null) begin 00268 assert (m_sequencer != null) else begin 00269 ovm_report_fatal("GRAB", "Null m_sequencer reference"); 00270 end 00271 m_sequencer.lock(this); 00272 end 00273 else begin 00274 sequencer.lock(this); 00275 end 00276 endtask // grab 00277 00278 function void unlock(ovm_sequencer_base sequencer = null); 00279 if (sequencer == null) begin 00280 assert (m_sequencer != null) else begin 00281 ovm_report_fatal("UNLOCK", "Null m_sequencer reference"); 00282 end 00283 m_sequencer.unlock(this); 00284 end else begin 00285 sequencer.unlock(this); 00286 end 00287 endfunction 00288 00289 function void ungrab(ovm_sequencer_base sequencer = null); 00290 unlock(sequencer); 00291 endfunction // void 00292 00293 virtual function void put_response (ovm_sequence_item response_item); 00294 return; 00295 endfunction // put_response 00296 00297 virtual task m_start_item(ovm_sequencer_base sequencer_ptr, ovm_sequence_item sequence_ptr, 00298 integer set_priority = -1); 00299 return; 00300 endtask 00301 00302 virtual task m_finish_item(ovm_sequencer_base sequencer_ptr, 00303 ovm_sequence_item sequence_ptr, 00304 integer set_priority = -1); 00305 ovm_sequence_base seq_base_ptr; 00306 00307 assert($cast(seq_base_ptr, sequence_ptr)) else begin 00308 ovm_report_fatal("SEQMFINISH", "Failure to cast sequence item"); 00309 end 00310 if (set_priority == -1) 00311 begin 00312 if (get_priority() < 0) 00313 begin 00314 start(sequencer_ptr, seq_base_ptr, 100, 0); 00315 end 00316 else 00317 begin 00318 start(sequencer_ptr, seq_base_ptr, get_priority(), 0); 00319 end 00320 end 00321 else 00322 begin 00323 start(sequencer_ptr, seq_base_ptr, set_priority, 0); 00324 end 00325 endtask 00326 00327 virtual task wait_for_grant(integer item_priority = -1, bit lock_request = 0); 00328 assert (m_sequencer != null) else begin 00329 ovm_report_fatal("WAITGRANT", "Null m_sequencer reference"); 00330 end 00331 m_sequencer.wait_for_grant(this, item_priority, lock_request); 00332 endtask // wait_for_grant 00333 00334 virtual function void send_request(ovm_sequence_item request, bit rerandomize = 0); 00335 assert (m_sequencer != null) else begin 00336 ovm_report_fatal("SENDREQ", "Null m_sequencer reference"); 00337 end 00338 m_sequencer.send_request(this, request, rerandomize); 00339 endfunction 00340 00341 virtual task wait_for_item_done(integer transaction_id = -1); 00342 assert (m_sequencer != null) else begin 00343 ovm_report_fatal("WAITITEMDONE", "Null m_sequencer reference"); 00344 end 00345 m_sequencer.wait_for_item_done(this, transaction_id); 00346 endtask // wait_for_item_done 00347 00348 virtual function void set_sequencer(ovm_sequencer_base sequencer); 00349 m_sequencer = sequencer; 00350 endfunction // void 00351 00352 virtual function ovm_sequencer_base get_sequencer(); 00353 return(m_sequencer); 00354 endfunction // ovm_sequencer_base 00355 00356 function void m_kill(); 00357 `ifndef INCA 00358 if (m_sequence_process != null) begin 00359 m_sequence_process.kill; 00360 m_sequence_process = null; 00361 end 00362 `else 00363 ->m_kill_event; 00364 m_sequence_started=0; 00365 `endif 00366 m_sequence_state = STOPPED; 00367 m_sequence_state_stopped = 1; 00368 endfunction // void 00369 00370 function void kill(); 00371 `ifndef INCA 00372 if (m_sequence_process != null) begin 00373 `else 00374 if (m_sequence_started != 0) begin 00375 `endif 00376 // If we are not connected to a sequencer, then issue 00377 // kill locally. 00378 if (m_sequencer == null) begin 00379 m_kill(); 00380 return; 00381 end 00382 // If we are attached to a sequencer, then the sequencer 00383 // will clear out queues, and then kill this sequence 00384 m_sequencer.kill_sequence(this); 00385 return; 00386 end 00387 endfunction // void 00388 00389 function void use_response_handler(bit enable); 00390 m_use_response_handler = enable; 00391 endfunction // void 00392 00393 function bit get_use_response_handler(); 00394 return(m_use_response_handler); 00395 endfunction // bit 00396 00397 virtual function void response_handler(ovm_sequence_item response); 00398 return; 00399 endfunction // response_handler 00400 00401 protected function ovm_sequence_item create_item(ovm_object_wrapper type_var, 00402 ovm_sequencer_base l_sequencer, string name); 00403 00404 ovm_factory f_ = ovm_factory::get(); 00405 $cast(create_item, f_.create_object_by_type( type_var, this.get_full_name(), name )); 00406 00407 create_item.set_use_sequence_info(1); 00408 create_item.set_parent_sequence(this); 00409 create_item.set_sequencer(l_sequencer); 00410 create_item.set_depth(get_depth() + 1); 00411 create_item.reseed(); 00412 00413 endfunction // ovm_sequence_item 00414 00415 function integer m_get_sqr_sequence_id(integer sequencer_id, bit update_sequence_id); 00416 if (m_sqr_seq_ids.exists(sequencer_id)) begin 00417 if (update_sequence_id == 1) begin 00418 set_sequence_id(m_sqr_seq_ids[sequencer_id]); 00419 end 00420 return(m_sqr_seq_ids[sequencer_id]); 00421 end 00422 else begin 00423 if (update_sequence_id == 1) begin 00424 set_sequence_id(-1); 00425 end 00426 return(-1); 00427 end 00428 endfunction 00429 00430 function void m_set_sqr_sequence_id(integer sequencer_id, integer sequence_id); 00431 m_sqr_seq_ids[sequencer_id] = sequence_id; 00432 set_sequence_id(sequence_id); 00433 endfunction // void 00434 00436 // 00437 // OVM Layered stimulus backward compatibility 00438 // 00440 00441 function integer get_id(); 00442 return (get_sequence_id()); 00443 endfunction // get_id 00444 00445 function ovm_sequence_base get_parent_scenario(); 00446 return (m_parent_sequence); 00447 endfunction // ovm_sequence_base 00448 00449 virtual task pre_apply(); 00450 return; 00451 endtask 00452 00453 virtual task mid_apply(); 00454 return; 00455 endtask 00456 00457 virtual task post_apply(); 00458 return; 00459 endtask // post_apply 00460 00461 endclass 00462
![]() Intelligent Design Verification Project: OVM, Revision: 2.0.1 |
Copyright (c) 2008 Intelligent Design Verification. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included here: http://www.intelligentdv.com/licenses/fdl.txt |
![]() Doxygen Version: 1.5.5 Wed Jan 7 19:27:18 2009 |