ovm_sequencer.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 
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
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
Doxygen Version: 1.5.5
Wed Jan 7 19:27:18 2009
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV