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