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

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