00001 // $Id: ovm__connector__base_8svh-source.html,v 1.1 2008/10/07 21:54:44 alex.marin Exp $ 00002 //------------------------------------------------------------------------------ 00003 // Copyright 2007-2008 Mentor Graphics Corporation 00004 // Copyright 2007-2008 Cadence Design Systems, Inc. 00005 // All Rights Reserved Worldwide 00006 // 00007 // Licensed under the Apache License, Version 2.0 (the 00008 // "License"); you may not use this file except in 00009 // compliance with the License. You may obtain a copy of 00010 // the License at 00011 // 00012 // http://www.apache.org/licenses/LICENSE-2.0 00013 // 00014 // Unless required by applicable law or agreed to in 00015 // writing, software distributed under the License is 00016 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00017 // CONDITIONS OF ANY KIND, either express or implied. See 00018 // the License for the specific language governing 00019 // permissions and limitations under the License. 00020 //------------------------------------------------------------------------------ 00021 00022 typedef enum { 00023 OVM_PORT , 00024 OVM_EXPORT , 00025 OVM_IMPLEMENTATION 00026 } ovm_port_type_e; 00027 00028 `const string s_connection_error_id = "Connection Error"; 00029 `const string s_connection_debug_id = "Connections Debug"; 00030 00031 00032 //------------------------------------------------------------------------------ 00033 // 00034 // CLASS: ovm_connector_base 00035 // 00036 //------------------------------------------------------------------------------ 00037 // ovm_connector_base stores the detailed connectivity mechanics for 00038 // ovm_*_port and ovm_*_export. 00039 //------------------------------------------------------------------------------ 00040 00041 virtual class ovm_connector_base extends ovm_component; 00042 00043 protected ovm_port_type_e m_port_type; // ie, PORT, EXPORT or IMP 00044 00045 function new( string name, ovm_component parent, 00046 ovm_port_type_e port_type ); 00047 super.new(name, parent ); 00048 m_port_type = port_type; 00049 endfunction 00050 00051 function bit is_port(); 00052 return m_port_type == OVM_PORT; 00053 endfunction 00054 00055 function bit is_export(); 00056 return m_port_type == OVM_EXPORT; 00057 endfunction 00058 00059 function bit is_imp(); 00060 return m_port_type == OVM_IMPLEMENTATION; 00061 endfunction 00062 00063 function string get_type_name(); 00064 //return "ovm_connector_base"; 00065 case( m_port_type ) 00066 OVM_PORT : return "port"; 00067 OVM_EXPORT : return "export"; 00068 OVM_IMPLEMENTATION : return "implementation"; 00069 endcase 00070 endfunction 00071 00072 endclass 00073 00074 00075 00076 //------------------------------------------------------------------------------ 00077 // 00078 // CLASS: ovm_connector #(IF) 00079 // 00080 //------------------------------------------------------------------------------ 00081 00082 class ovm_connector #(type IF=int) extends ovm_connector_base; 00083 00084 typedef ovm_connector #(IF) connector_type; 00085 00086 local int unsigned if_mask; 00087 00088 local ovm_if_container #(IF) m_if_container; 00089 00090 ovm_port_base_base #(IF) port_h; 00091 00092 // Consider port->port->export->export->imp. 00093 // provided_by list points to RHS of "->" 00094 00095 // the provided_by list is list of connectors that "this" uses to 00096 // satisfy its conenctivity requirements 00097 00098 // all the interfaces of all the m_provided_by[i] are copied into 00099 // this.m_if_list 00100 00101 local connector_type m_provided_by[string]; 00102 00103 // Consider port->port->export->export->imp. 00104 // provided_to_list point to LHS of "->" 00105 00106 // the provided_to list is the list of connectors that use "this" to 00107 // satisfy their connectivity requirements 00108 00109 local connector_type m_provided_to[string]; 00110 00111 function new( string name , ovm_component parent , 00112 ovm_port_type_e port_type, 00113 int min_size = 0, int max_size = 1 ); 00114 00115 super.new( name, parent, port_type ); 00116 m_if_container = new(min_size, max_size); 00117 endfunction 00118 00119 //---------------------------------------------------------------------------- 00120 // accessor and convenience functions 00121 //---------------------------------------------------------------------------- 00122 00123 function ovm_if_container #(IF) get_if_container(); 00124 return m_if_container; 00125 endfunction 00126 00127 function int size(); 00128 return m_if_container.size(); 00129 endfunction 00130 00131 function int min_size(); 00132 return m_if_container.min_size(); 00133 endfunction 00134 00135 function int max_size(); 00136 return m_if_container.max_size(); 00137 endfunction 00138 00139 //---------------------------------------------------------------------------- 00140 // connect_to 00141 // 00142 // For new style binding ovm_*_port -> ovm_*_port -> ovm_*_export -> 00143 // to ovm_*_imp 00144 // 00145 //---------------------------------------------------------------------------- 00146 function bit connect_to( input connector_type c ); 00147 string s; 00148 00149 if(!c.m_if_container.add_list(m_if_container)) begin 00150 s = {"Cannot connect to " , c.get_full_name()}; 00151 ovm_report_error( s_connection_error_id , s ); 00152 return 0; 00153 end 00154 00155 // set the value if m_if to the first entry 00156 // in the interface list 00157 c.port_h.set_if(); 00158 00159 //debug_connected_to(); 00160 00161 return 1; 00162 endfunction 00163 00164 //-------------------------------------------------------------------- 00165 // end_of_elaboration 00166 //-------------------------------------------------------------------- 00167 function void end_of_elaboration(); 00168 check_min_connection_size(); 00169 endfunction 00170 00171 //---------------------------------------------------------------------------- 00172 // update_connection_lists 00173 //---------------------------------------------------------------------------- 00174 function void update_connection_lists( input connector_type c ); 00175 m_provided_by[c.get_full_name()] = c; 00176 c.m_provided_to[get_full_name()] = this; 00177 endfunction 00178 00179 00180 //---------------------------------------------------------------------------- 00181 // resolve_bindings 00182 //---------------------------------------------------------------------------- 00183 virtual function void resolve_bindings(); 00184 00185 if(!is_imp() || is_imp() && m_provided_to.num() == 0) 00186 return; 00187 resolve_bindings_all(); 00188 00189 endfunction 00190 00191 00192 //---------------------------------------------------------------------------- 00193 // resolve_bindings_all 00194 //---------------------------------------------------------------------------- 00195 function void resolve_bindings_all(); 00196 connector_type c; 00197 00198 foreach (m_provided_to[s]) begin 00199 c = m_provided_to[s]; 00200 if(connect_to(c)) 00201 c.resolve_bindings_all(); 00202 end 00203 00204 check_min_connection_size(); 00205 00206 endfunction 00207 00208 00209 //-------------------------------------------------------------------- 00210 // check_min_connection_size 00211 //-------------------------------------------------------------------- 00212 00213 function void check_min_connection_size(); 00214 string s; 00215 00216 if( size() < min_size() ) begin 00217 $sformat( s, 00218 "connection count of %0d does not meet required minimum of %0d" , 00219 size(), min_size() ); 00220 ovm_report_error( s_connection_error_id , s ); 00221 end 00222 endfunction 00223 00224 00225 //---------------------------------------------------------------------------- 00226 // add_if 00227 // 00228 // For old style binding eg ovm_*_port -> tlm_*_if or ovm_*_export to 00229 // to tlm_*_if 00230 // 00231 //---------------------------------------------------------------------------- 00232 function bit add_if( IF _if ); 00233 string s; 00234 00235 if(!m_if_container.add_if(_if)) begin 00236 s.itoa(max_size()); 00237 s = {"Maximum number of interfaces (",s,") exceeded"}; 00238 ovm_report_error( s_connection_error_id , s ); 00239 return 0; 00240 end 00241 00242 return 1; 00243 endfunction 00244 00245 //---------------------------------------------------------------------------- 00246 // lookup_indexed_if 00247 // 00248 // For multiport access 00249 // 00250 //---------------------------------------------------------------------------- 00251 function IF lookup_indexed_if( int i = 0 ); 00252 string s; 00253 IF ifc; 00254 ifc = m_if_container.lookup_indexed_if(i); 00255 00256 if(ifc == null) begin 00257 $sformat( s , "Index %0d out of range [0,%0d]" , i , size() ); 00258 ovm_report_warning( s_connection_error_id , s ); 00259 end 00260 return ifc; 00261 endfunction 00262 00263 //---------------------------------------------------------------------------- 00264 // check_types 00265 // 00266 // checks that the connection types are legal 00267 //---------------------------------------------------------------------------- 00268 function bit check_types( connector_type provider ); 00269 00270 string s; 00271 00272 if( is_imp() || ( is_export() && provider.is_port())) begin 00273 00274 s = {"Cannot connect ", get_type_name(), 00275 "s to ", provider.get_type_name(),"s"}; 00276 00277 ovm_report_error( s_connection_error_id , s ); 00278 return 0; 00279 00280 end 00281 00282 return 1; 00283 endfunction 00284 00285 00286 //---------------------------------------------------------------------------- 00287 // check_phase 00288 // 00289 // checks that this connection is being made in the correct phase 00290 //---------------------------------------------------------------------------- 00291 function bit check_phase( connector_type provider ); 00292 00293 string s; 00294 ovm_phase required_phase, actual_phase; 00295 00296 required_phase = get_required_phase(provider); 00297 actual_phase = ovm_top.get_current_phase(); 00298 00299 if( required_phase != actual_phase ) begin 00300 00301 s = {"You have attempted to connect ", get_full_name(), 00302 " to ",provider.get_full_name(), " in phase '", 00303 actual_phase.get_name(),"'" }; 00304 00305 ovm_report_warning( s_connection_error_id , s ); 00306 00307 s = {"You can only connect ", get_type_name(), "s to ", 00308 provider.get_type_name(), "s in phase '", 00309 required_phase.get_name(), "'" }; 00310 00311 ovm_report_error(s_connection_error_id , s ); 00312 return 0; 00313 end 00314 00315 return 1; 00316 endfunction 00317 00318 00319 //---------------------------------------------------------------------------- 00320 // check_relationship 00321 // 00322 // checks that the parent child relationships are correct 00323 //---------------------------------------------------------------------------- 00324 function bit check_relationship( connector_type provider ); 00325 string s; 00326 ovm_component grandparent; 00327 ovm_component provider_grandparent; 00328 00329 if( m_parent == null || provider == null || provider.m_parent == null ) begin 00330 // don't check if we have a parentless analysis port 00331 return 1; 00332 end 00333 00334 grandparent = m_parent.m_parent; 00335 provider_grandparent = provider.m_parent.m_parent; 00336 00337 // don't check if one or both ends are at top-level 00338 if( grandparent == ovm_top || provider_grandparent == ovm_top) 00339 return 1; 00340 00341 // REVIEW: temporarily disabling the check in preparation for 00342 // import/export_connections deprecation 00343 return 1; 00344 00345 // IUS doesn't support a class handle as a case item so use if/else 00346 if ( get_required_phase(provider) == import_connections_ph) 00347 if( grandparent != provider.m_parent ) begin 00348 s = {"connect ( child port -> port ) : ", m_parent.get_full_name(), 00349 " should be a child of %s", provider.m_parent.get_full_name()}; 00350 ovm_report_error( s_connection_error_id , s ); 00351 return 0; 00352 end 00353 00354 else if ( get_required_phase(provider) == connect_ph) 00355 if( grandparent != provider_grandparent ) begin 00356 s = {"connect ( port -> export ) : ", m_parent.get_full_name(), 00357 " should be a sibling of %s", provider.m_parent.get_full_name()}; 00358 ovm_report_error( s_connection_error_id , s ); 00359 return 0; 00360 end 00361 00362 else if ( get_required_phase(provider) == export_connections_ph) 00363 if( m_parent != provider_grandparent ) begin 00364 s = {"connect ( export -> child export ) : ", m_parent.get_full_name(), 00365 " should be a parent of %s", provider.m_parent.get_full_name()}; 00366 ovm_report_error(s_connection_error_id , s ); 00367 return 0; 00368 end 00369 00370 return 1; 00371 endfunction 00372 00373 00374 //---------------------------------------------------------------------------- 00375 // get_required_phase 00376 //---------------------------------------------------------------------------- 00377 local function ovm_phase get_required_phase(ovm_connector_base provider); 00378 00379 if( is_export() && ( provider.is_export() || provider.is_imp())) 00380 return export_connections_ph; 00381 00382 if( is_port() && ( provider.is_export() || provider.is_imp())) 00383 return connect_ph; 00384 00385 if( is_port() && provider.is_port()) 00386 return import_connections_ph; 00387 00388 ovm_report_error(s_connection_error_id, "no valid required phase"); 00389 return null; 00390 00391 endfunction 00392 00393 00394 00395 00396 00397 00398 00399 // Deprecated ... 00400 00401 00402 //---------------------------------------------------------------------------- 00403 // do_display 00404 // 00405 // do_display is virtual in ovm_component. We only print 00406 // anything if display_connectors is true 00407 //---------------------------------------------------------------------------- 00408 function void do_display( int max_level = -1 , 00409 int level = 0 , 00410 bit display_connectors = 0 ); 00411 00412 if( display_connectors ) begin 00413 ovm_report_info("hierarchy debug" , "" , 1000 ); 00414 end 00415 00416 endfunction 00417 00418 00419 //---------------------------------------------------------------------------- 00420 // debug_connected_to 00421 // 00422 // recurses rightwards through the port->port->export->export->imp 00423 // connections, printing out where it has got to and how many 00424 // interfaces are held at each point 00425 //---------------------------------------------------------------------------- 00426 function void debug_connected_to( int level = 0 , 00427 int max_level = -1 ); 00428 string s, nm; 00429 int sz; 00430 connector_type connector; 00431 00432 if( size() > 1 ) begin 00433 00434 if( m_provided_by.num() > 0 ) begin 00435 $sformat( s , "has %0d interfaces from %0d places" , 00436 size() , m_provided_by.num() ); 00437 end 00438 else begin 00439 $sformat( s , "has %0d interfaces" , size() ); 00440 end 00441 00442 ovm_report_info( s_connection_debug_id , s ); 00443 end 00444 00445 foreach( m_provided_by[i] ) begin 00446 connector = m_provided_by[i]; 00447 sz = connector.size(); 00448 nm = connector.get_full_name(); 00449 $sformat( s , " has %0d interface%s provided by %s" , sz, 00450 ( connector.size() == 1 ? "" : "s" ) , nm ); 00451 ovm_report_info("Connections Debug" , s ); 00452 end 00453 00454 /* 00455 if( is_imp() ) begin 00456 $sformat( s , " implemented by %s" , m_parent.get_full_name() ); 00457 ovm_report_info( s_connection_debug_id , s ); 00458 end 00459 */ 00460 00461 if( level == max_level ) begin 00462 return; 00463 end 00464 00465 foreach( m_provided_by[i] ) begin 00466 connector = m_provided_by[i]; 00467 connector.debug_connected_to( level + 1 , max_level ); 00468 end 00469 00470 endfunction 00471 00472 00473 //---------------------------------------------------------------------------- 00474 // debug_provided_to 00475 // 00476 // recurses leftwards through the port->port->export->export->imp 00477 // connections, printing out where it has got to and how many 00478 // interfaces are held at each point 00479 //---------------------------------------------------------------------------- 00480 function void debug_provided_to( int level = 0 , int max_level = -1 ); 00481 string s, nm; 00482 connector_type connector; 00483 00484 if( m_provided_to.num() == 0 ) begin 00485 return; 00486 end 00487 00488 if( size() > 1 ) begin 00489 00490 if( m_provided_to.num() > 1 ) begin 00491 00492 $sformat( s , "provides %0d interfaces to %0d ports/exports" , 00493 size() , m_provided_to.num() ); 00494 00495 end 00496 else begin 00497 $sformat( s , "provides %0d interfaces" , size() ); 00498 end 00499 00500 ovm_report_info( s_connection_debug_id , s ); 00501 end 00502 00503 foreach( m_provided_to[i] ) begin 00504 connector = m_provided_to[i]; 00505 nm = connector.get_full_name(); 00506 $sformat( s , "provides %0d interface%s to %s" , 00507 size() , ( size() == 1 ? "" : "s") , nm ); 00508 00509 ovm_report_info( s_connection_debug_id , s ); 00510 end 00511 00512 if( level == max_level ) begin 00513 return; 00514 end 00515 00516 foreach( m_provided_to[i] ) begin 00517 connector = m_provided_to[i]; 00518 connector.debug_provided_to( level + 1 , max_level ); 00519 end 00520 00521 endfunction 00522 00523 00524 //---------------------------------------------------------------------------- 00525 // add_to_debug_list 00526 // 00527 // This method is purely for GUI debugging purposes. 00528 // 00529 // puts this into correct debug list 00530 // 00531 //---------------------------------------------------------------------------- 00532 local virtual function void add_to_debug_list(); 00533 00534 case( m_port_type ) 00535 OVM_PORT : m_parent.m_ports[get_full_name()] = this; 00536 OVM_EXPORT : m_parent.m_exports[get_full_name()] = this; 00537 OVM_IMPLEMENTATION : m_parent.m_implementations[get_full_name()] = this; 00538 endcase 00539 endfunction 00540 00541 endclass 00542
![]() 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:20:12 2008 |