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 00022 typedef class ovm_sequence_base; 00023 00024 typedef class ovm_seq_prod_if; 00025 typedef class ovm_seq_cons_if; 00026 00027 typedef ovm_seq_item_pull_port #(ovm_sequence_item, ovm_sequence_item) ovm_seq_item_prod_if; 00028 00029 00030 class ovm_sequencer #(type REQ = ovm_sequence_item, 00031 type RSP = REQ) extends ovm_sequencer_param_base #(REQ, RSP); 00032 00033 typedef ovm_sequencer #( REQ , RSP) this_type; 00034 bit sequence_item_requested = 0; 00035 bit get_next_item_called = 0; 00036 00037 // Ports 00038 ovm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_export; 00039 ovm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_cons_if; 00040 00041 // Deprecated Members, do not use 00042 ovm_seq_prod_if seq_prod_if; 00043 ovm_seq_cons_if seq_cons_if[string]; 00044 00045 function new (string name, ovm_component parent); 00046 super.new(name, parent); 00047 00048 seq_item_export = new ("seq_item_export", this); 00049 seq_item_cons_if = seq_item_export; 00050 $cast(seq_prod_if, create_component("ovm_seq_prod_if", "seq_prod_if")); 00051 seq_prod_if.print_enabled = 0; 00052 endfunction // new 00053 00054 // return proper type name string 00055 virtual function string get_type_name(); 00056 return "ovm_sequencer"; 00057 endfunction 00058 00059 function void connect(); 00060 super.connect(); 00061 endfunction // void 00062 00063 virtual function void build(); 00064 super.build(); 00065 endfunction // function 00066 00067 function void end_of_elaboration(); 00068 super.end_of_elaboration(); 00069 endfunction // void 00070 00072 // 00073 // Local functions 00074 // 00076 00077 00079 // 00080 // Methods available to Sequencers 00081 // 00083 00084 00086 // 00087 // Methods available to Pull Drivers 00088 // 00090 00091 virtual function void send_request(ovm_sequence_base sequence_ptr, ovm_sequence_item t, bit rerandomize = 0); 00092 if (seq_item_export.size() != 1) 00093 ovm_report_fatal(get_full_name(), "The seq_item_export is not connected, cannot do items."); 00094 super.send_request(sequence_ptr, t, rerandomize); 00095 endfunction 00096 00097 local task select_sequence(); 00098 integer selected_sequence; 00099 00100 // Select a sequence 00101 do begin 00102 wait_for_sequences(); 00103 selected_sequence = choose_next_request(); 00104 if (selected_sequence == -1) begin 00105 wait_for_available_sequence(); 00106 end 00107 end while (selected_sequence == -1); 00108 // issue grant 00109 if (selected_sequence >= 0) begin 00110 set_arbitration_completed(arb_sequence_q[selected_sequence].request_id); 00111 arb_sequence_q.delete(selected_sequence); 00112 m_update_lists(); 00113 end 00114 endtask // select_sequence 00115 00116 task get_next_item(output REQ t); 00117 REQ req_item; 00118 00119 // If a sequence_item has already been requested, then get_next_item() 00120 // should not be called again until item_done() has been called. 00121 00122 if (get_next_item_called == 1) begin 00123 ovm_report_error(get_full_name(), "Get_next_item called twice without item_done or get in between"); 00124 end 00125 00126 if (sequence_item_requested == 0) begin 00127 select_sequence(); 00128 end 00129 00130 // Set flag indicating that the item has been requested to ensure that item_done or get 00131 // is called between requests 00132 sequence_item_requested = 1; 00133 get_next_item_called = 1; 00134 m_req_fifo.peek(t); 00135 endtask // get_next_item 00136 00137 task try_next_item(output REQ t); 00138 wait_for_sequences(); 00139 if (has_do_available() == 0) begin 00140 t = null; 00141 return; 00142 end 00143 get_next_item(t); 00144 endtask // try_next_item 00145 00146 function void item_done(RSP item = null); 00147 REQ t; 00148 00149 // Set flag to allow next get_next_item or peek to get a new sequence_item 00150 sequence_item_requested = 0; 00151 get_next_item_called = 0; 00152 00153 if (m_req_fifo.try_get(t) == 0) begin 00154 ovm_report_fatal(get_full_name(), "Item done reports empty request fifo"); 00155 end else begin 00156 m_wait_for_item_sequence_id = t.get_sequence_id(); 00157 m_wait_for_item_transaction_id = t.get_transaction_id(); 00158 end 00159 00160 if (item != null) begin 00161 seq_item_export.put_response(item); 00162 end 00163 00164 // Missing item_done functionality 00165 00166 // Grant any locks as soon as possible 00167 grant_queued_locks(); 00168 endfunction // void 00169 00170 virtual task put (RSP t); 00171 put_response(t); 00172 endtask // put 00173 00174 task get(output REQ t); 00175 if (sequence_item_requested == 0) begin 00176 select_sequence(); 00177 end 00178 sequence_item_requested = 1; 00179 m_req_fifo.peek(t); 00180 item_done(); 00181 endtask // get 00182 00183 task peek(output REQ t); 00184 00185 if (sequence_item_requested == 0) begin 00186 select_sequence(); 00187 end 00188 00189 // Set flag indicating that the item has been requested to ensure that item_done or get 00190 // is called between requests 00191 sequence_item_requested = 1; 00192 m_req_fifo.peek(t); 00193 endtask // peek 00194 00195 virtual function void m_add_builtin_seqs(bit add_simple = 1); 00196 if(!sequence_ids.exists("ovm_random_sequence")) 00197 add_sequence("ovm_random_sequence"); 00198 if(!sequence_ids.exists("ovm_exhaustive_sequence")) 00199 add_sequence("ovm_exhaustive_sequence"); 00200 if(add_simple == 1) 00201 if(!sequence_ids.exists("ovm_simple_sequence")) 00202 add_sequence("ovm_simple_sequence"); 00203 endfunction 00204 00205 // Backwards Compatibility 00206 function void item_done_trigger(RSP item = null); 00207 item_done(item); 00208 endfunction 00209 00210 function RSP item_done_get_trigger_data(); 00211 return last_rsp(0); 00212 endfunction 00213 00214 virtual function void add_seq_cons_if(string if_name); 00215 $cast(seq_cons_if[if_name], create_component("ovm_seq_cons_if", 00216 {"seq_cons_if[\"", if_name, "\"]"})); 00217 seq_cons_if[if_name].print_enabled = 0; 00218 endfunction 00219 00220 endclass 00221 00222 typedef ovm_sequencer #(ovm_sequence_item) ovm_virtual_sequencer; 00223 00224 // Deprecated Class 00225 class ovm_seq_prod_if extends ovm_component; 00226 00227 string producer_name = "NOT CONNECTED"; 00228 00229 // constructor 00230 function new (string name="", ovm_component parent = null); 00231 super.new(name, parent); 00232 endfunction 00233 00234 // data method do_print 00235 function void do_print (ovm_printer printer); 00236 super.do_print(printer); 00237 printer.print_string("sequence producer", producer_name); 00238 endfunction 00239 00240 // polymorphic create method 00241 function ovm_object create (string name=""); 00242 ovm_seq_prod_if i; i=new(name); 00243 return i; 00244 endfunction 00245 00246 // return proper type name string 00247 virtual function string get_type_name(); 00248 return "ovm_seq_prod_if"; 00249 endfunction 00250 00251 // connect interface method for producer to consumer 00252 function void connect_if(ovm_seq_cons_if seq_if); 00253 ovm_component temp_comp; 00254 $cast(seq_if.consumer_seqr, get_parent()); 00255 temp_comp = seq_if.get_parent(); 00256 producer_name = temp_comp.get_full_name(); 00257 endfunction 00258 00259 // Macro to enable factory creation 00260 `ovm_component_registry(ovm_seq_prod_if, "ovm_seq_prod_if") 00261 00262 endclass 00263 00264 // Deprecated Class 00265 class ovm_seq_cons_if extends ovm_component; 00266 00267 // variable to hold the sequence consumer as an ovm_sequencer if the 00268 // consumer is that type 00269 ovm_sequencer #(ovm_sequence_item) consumer_seqr; 00270 00271 // constructor 00272 function new (string name="", ovm_component parent = null); 00273 super.new(name, parent); 00274 endfunction 00275 00276 // do_print for this object 00277 function void do_print (ovm_printer printer); 00278 super.do_print(printer); 00279 if (consumer_seqr != null) 00280 printer.print_string("sequence consumer", consumer_seqr.get_full_name()); 00281 else 00282 printer.print_string("sequence consumer", "NOT_CONNECTED"); 00283 endfunction 00284 00285 // polymorphic creation 00286 function ovm_object create (string name=""); 00287 ovm_seq_cons_if i; i=new(name); 00288 return i; 00289 endfunction 00290 00291 // get_type_name implementation 00292 virtual function string get_type_name(); 00293 return "ovm_seq_cons_if"; 00294 endfunction 00295 00296 // method to connect this object to an ovm_sequence_prod_if 00297 function void connect_if(ovm_seq_prod_if seq_if); 00298 $cast(consumer_seqr, seq_if.get_parent());; 00299 endfunction 00300 00301 // method to query who the current grabber of the connected sequencer is 00302 function ovm_sequence_base current_grabber(); 00303 return consumer_seqr.current_grabber(); 00304 endfunction 00305 00306 // method to query if the connected sequencer is grabbed 00307 function bit is_grabbed(); 00308 return consumer_seqr.is_grabbed(); 00309 endfunction 00310 00311 // method to start a sequence on the connected sequencer 00312 task start_sequence(ovm_sequence_base this_seq); 00313 consumer_seqr.start_sequence(this_seq); 00314 endtask 00315 00316 // method to grab the connected sequencer 00317 task grab(ovm_sequence_base this_seq); 00318 consumer_seqr.grab(this_seq); 00319 endtask 00320 00321 // method to ungrab the connected sequencer 00322 function void ungrab(ovm_sequence_base this_seq); 00323 consumer_seqr.ungrab(this_seq); 00324 endfunction 00325 00326 // method to query if this interface object is connected 00327 function bit is_connected(); 00328 if (consumer_seqr != null) 00329 return 1; 00330 else 00331 return 0; 00332 endfunction 00333 00334 // method to query whether this interface is connected to a virtual sequencer 00335 // or sequencer 00336 function bit is_virtual_sequencer(); 00337 ovm_virtual_sequencer vseqr; 00338 if (consumer_seqr == null) 00339 ovm_report_fatal("UNCSQR", "Cannot call connected_sequencer_type() on this unconnected interface."); 00340 else if (!$cast(vseqr, consumer_seqr)) 00341 return 0; 00342 else 00343 return 1; 00344 endfunction 00345 00346 // method to get the connecte sequencer's type name 00347 function string get_sequencer_type_name(); 00348 if(consumer_seqr != null) 00349 return consumer_seqr.get_type_name(); 00350 else 00351 return "NOT_CONNECTED"; 00352 endfunction 00353 00354 // Macro to enable factory creation 00355 `ovm_component_registry(ovm_seq_cons_if, "ovm_seq_cons_if") 00356 00357 endclass 00358 00359
![]() 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 |