ovm_sequence.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 virtual class ovm_sequence #(type REQ = ovm_sequence_item,
00022                              type RSP = REQ) extends ovm_sequence_base;
00023 
00024 typedef ovm_sequencer_param_base #(REQ, RSP) sequencer_t;
00025 
00026 sequencer_t        param_sequencer;
00027 REQ                req;
00028 RSP                rsp;
00029 local RSP          response_queue[$];
00030 protected integer      response_queue_depth = 8;
00031 protected bit          response_queue_error_report_disabled = 0;
00032 
00033   function new (string name = "ovm_sequence", 
00034                 ovm_sequencer_base sequencer_ptr = null, 
00035                 ovm_sequence_base parent_seq = null);
00036     static bit issued1=0,issued2=0;
00037     super.new(name);
00038     if (sequencer_ptr != null) begin
00039       if (!issued1) begin
00040         issued1=1;
00041         ovm_report_warning("deprecated",
00042           {"ovm_sequence::new()'s sequencer_ptr argument has been deprecated. ",
00043           "The sequencer is now specified at the time a sequence is started ",
00044           "using the start() task."});
00045       end
00046       m_sequencer = sequencer_ptr;
00047     end
00048     if (parent_seq != null) begin
00049       if (!issued2) begin
00050         issued2=1;
00051         ovm_report_warning("deprecated",
00052           {"ovm_sequence::new()'s parent_seq argument has been deprecated. ",
00053           "The parent sequence is now specified at the time a sequence is started ",
00054           "using the start() task."});
00055       end
00056       m_parent_sequence = parent_seq;
00057     end
00058   endfunction // new
00059 
00060   function void do_print (ovm_printer printer);
00061     super.do_print(printer);
00062     printer.print_object("req", req);
00063     printer.print_object("rsp", rsp);
00064   endfunction
00065 
00066   virtual task start (ovm_sequencer_base sequencer,
00067               ovm_sequence_base parent_sequence = null,
00068               integer this_priority = 100,
00069               bit call_pre_post = 1);
00070 
00071     m_sequence_state_prebody  = 0;
00072     m_sequence_state_body     = 0;
00073     m_sequence_state_postbody = 0;
00074     m_sequence_state_ended    = 0;
00075     m_sequence_state_stopped  = 0;
00076 
00077     super.start(sequencer, parent_sequence, this_priority, call_pre_post);
00078     m_set_p_sequencer();
00079 
00080     if (m_sequencer != null) begin
00081       if (m_sequencer.recording_detail != OVM_NONE) begin
00082         if (m_parent_sequence == null) begin
00083           m_tr_handle = m_sequencer.begin_tr(this, get_name());
00084         end else begin
00085           m_tr_handle = m_sequencer.begin_child_tr(this, m_parent_sequence.m_tr_handle, 
00086                                                    get_root_sequence_name());
00087         end
00088       end
00089     end
00090 
00091     // Ensure that the sequence_id is intialized in case this sequence has been stopped previously
00092     set_sequence_id(-1);
00093     // Remove all sqr_seq_ids
00094     m_sqr_seq_ids.delete();
00095 
00096     ->started;
00097     
00098     if (call_pre_post == 1) begin
00099       m_sequence_state = PRE_BODY;
00100       m_sequence_state_prebody = 1;
00101       #0;   // Allow external waiter to be activated
00102       this.pre_body();
00103     end
00104 
00105     if (parent_sequence != null) begin
00106       parent_sequence.pre_do(0);
00107       parent_sequence.mid_do(this);
00108     end
00109 
00110     m_sequence_state = BODY;
00111     m_sequence_state_body = 1;
00112     #0;   // Allow external waiter to be activated
00113     
00114 `ifndef INCA
00115     
00116     fork
00117       begin
00118         m_sequence_process = process::self();
00119         body();
00120         m_sequence_state_ended = 1;
00121         m_sequence_state = ENDED;
00122         #0;   // Allow external waiter to be activated
00123       end
00124     join
00125     
00126 `else
00127     
00128     fork //wrap the fork/join_any to only effect this block
00129       begin
00130         fork
00131           begin
00132             body();
00133             m_sequence_state_ended = 1;
00134             m_sequence_state = ENDED;
00135           end
00136           begin
00137             m_sequence_started = 1;
00138             @(m_kill_event or m_sequence_state==ENDED);
00139           end
00140         join_any
00141         if(m_sequence_state!=ENDED) begin
00142           disable fork;
00143         end
00144         else
00145           #0;   // Allow external waiter to be activated
00146       end
00147     join
00148         
00149 `endif
00150         
00151     if (parent_sequence != null) begin
00152       parent_sequence.post_do(this);
00153     end
00154 
00155     if (call_pre_post == 1) begin
00156       m_sequence_state = POST_BODY;
00157       m_sequence_state_postbody = 1;
00158       #0;   // Allow external waiter to be activated
00159       post_body();
00160     end
00161 
00162     ->ended;
00163     m_sequence_state = FINISHED;
00164 
00165     if (m_sequencer != null) begin      
00166       if (m_sequencer.recording_detail != OVM_NONE) begin
00167         m_sequencer.end_tr(this);
00168       end
00169     end
00170 
00171     // Clean up any sequencer queues after exiting
00172     if (m_sequencer != null) begin
00173       m_sequencer.sequence_exiting(this);
00174     end
00175   endtask // start
00176 
00177   function void send_request(ovm_sequence_item request, bit rerandomize = 0);
00178     REQ m_request;
00179     
00180     assert (m_sequencer != null) else begin
00181       ovm_report_fatal("SSENDREQ", "Null m_sequencer reference");
00182     end
00183     assert ($cast(m_request, request)) else begin
00184       ovm_report_fatal("SSENDREQ", "Failure to cast ovm_sequence_item to request");
00185     end
00186     m_sequencer.send_request(this, m_request, rerandomize);
00187   endfunction // void
00188 
00189   function REQ get_current_item();
00190     assert($cast(param_sequencer, m_sequencer));
00191     return (param_sequencer.get_current_item());
00192   endfunction // REQ
00193 
00194   task get_response(output RSP response, input integer transaction_id = -1);
00195     integer queue_size, i;
00196 
00197     if (response_queue.size() == 0) begin
00198       wait (response_queue.size() != 0);
00199     end
00200 
00201     if (transaction_id == -1) begin
00202       response = response_queue.pop_front();
00203       return;
00204     end
00205 
00206     forever begin
00207       queue_size = response_queue.size();
00208       for (i = 0; i < queue_size; i++) begin
00209         if (response_queue[i].get_transaction_id() == transaction_id) 
00210           begin
00211             response = response_queue[i];
00212             response_queue.delete(i);
00213             return;
00214           end
00215       end
00216       wait (response_queue.size() != queue_size);
00217     end
00218   endtask // get_response
00219 
00220   virtual function void put_response(ovm_sequence_item response_item);
00221     RSP response;
00222 
00223     assert($cast(response, response_item)) else begin
00224       ovm_report_fatal("PUTRSP", "Failure to cast response in put_response");
00225     end
00226     if ((response_queue_depth == -1) ||
00227         (response_queue.size() < response_queue_depth)) begin
00228       response_queue.push_back(response);
00229       return;
00230     end
00231     if (response_queue_error_report_disabled == 0) begin
00232       ovm_report_error(get_full_name(), "Response queue overflow, response was dropped");
00233     end
00234   endfunction // put_response
00235 
00236   virtual function void set_sequencer(ovm_sequencer_base sequencer);
00237     m_sequencer = sequencer;
00238     m_set_p_sequencer();
00239   endfunction // void
00240 
00242   //
00243   // function void set_response_queue_error_report_disabled(bit value);
00244   //
00245   // By default, if the response_queue overflows, an error is reported.
00246   //
00247   // The response_queue will overflow if more responses are sent to
00248   // this sequence from the driver than get_response() calls are made.
00249   //
00250   // The error may be disabled by calling 
00251   //   set_response_queue_error_report_disabled(1).
00252   //
00253   // The error may be enabled by calling 
00254   //   set_response_queue_error_report_disabled(0).
00255   //
00257 
00258   function void set_response_queue_error_report_disabled(bit value);
00259     response_queue_error_report_disabled = value;
00260     endfunction
00261 
00263   //
00264   // function bit get_response_queue_error_report_disabled();
00265   //
00266   // The current value of the response_queue_error_report_disabled
00267   // bit may be examined with this method.
00268   //
00269   // When this bit is 0 (default value), error reports are generated
00270   // if the response queue overflows.
00271   //
00272   // When this bit is 1, no error reports are generated
00273   //
00275 
00276   function bit get_response_queue_error_report_disabled();
00277     return(response_queue_error_report_disabled);
00278   endfunction // bit
00279 
00281   //
00282   //  function void set_response_queue_depth(integer value);
00283   //
00284   //  The default maximum depth of the response queue is 8.  This
00285   //  method is used to change the maximum depth of the response
00286   //  queue.
00287   //
00288   //  Setting the response_queue_depth to -1 indicates an arbitrarily
00289   //  deep response queue.  No checking is done
00290   //
00292 
00293   function void set_response_queue_depth(integer value);
00294     response_queue_depth = value;
00295   endfunction  
00296 
00298   //
00299   //  function integer get_response_queue_depth();
00300   //
00301   //  This method returns the current response_queue_depth
00302   //
00304 
00305   function integer get_response_queue_depth();
00306     return(response_queue_depth);
00307   endfunction  
00308 
00309 endclass

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