ovm_sequence_base.svh

Go to the documentation of this file.
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
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
Doxygen Version: 1.5.5
Wed Jan 7 19:27:18 2009
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV