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 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 Version: 1.4.6 Mon Sep 29 14:23:30 2008 |