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 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 Version: 1.5.5 Wed Jan 7 19:27:18 2009 |