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 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
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
Doxygen Version: 1.4.6
Mon Sep 29 14:23:30 2008
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV