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