00001 // $Id: a00241.html,v 1.1 2009/01/07 19:29:48 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 `include "base/ovm_misc.svh" 00023 00024 // Create a seed which is based off of the ius seed which can be used to seed 00025 // srandom processes but will change if the command line seed setting is 00026 // changed. 00027 00028 int unsigned ovm_global_random_seed = $urandom; 00029 00030 // This map is a seed map that can be used to update seeds. The update 00031 // is done automatically by the seed hashing routine. The seed_table_lookup 00032 // uses an instance name lookup and the seed_table inside a given map 00033 // uses a type name for the lookup. 00034 00035 class ovm_seed_map; 00036 int unsigned seed_table [string]; 00037 endclass 00038 ovm_seed_map ovm_random_seed_table_lookup [string]; 00039 00040 // 00041 // ovm_instance_scope; 00042 // 00043 // A function that returns the scope that the urm library lives in, either 00044 // an instance, a module, or a package. 00045 00046 function string ovm_instance_scope(); 00047 byte c; 00048 int pos; 00049 //first time through the scope is null and we need to calculate, afterwards it 00050 //is correctly set. 00051 00052 if(ovm_instance_scope != "") 00053 return ovm_instance_scope; 00054 00055 $swrite(ovm_instance_scope, "%m"); 00056 //remove the extraneous .ovm_instance_scope piece or ::ovm_instance_scope 00057 pos = ovm_instance_scope.len()-1; 00058 c = ovm_instance_scope[pos]; 00059 while(pos && (c != ".") && (c != ":")) 00060 c = ovm_instance_scope[--pos]; 00061 assert(pos != 0); 00062 ovm_instance_scope = ovm_instance_scope.substr(0,pos); 00063 endfunction 00064 00065 00066 // 00067 // ovm_oneway_hash 00068 // 00069 // A one-way hash function that is useful for creating srandom seeds. An 00070 // unsigned int value is generated from the string input. An initial seed can 00071 // be used to seed the hash, if not supplied the ovm_global_random_seed 00072 // value is used. Uses a CRC like functionality to minimize collisions. 00073 00074 parameter OVM_STR_CRC_POLYNOMIAL = 32'h04c11db6; 00075 function int unsigned ovm_oneway_hash ( string string_in, int unsigned seed=0 ); 00076 bit msb; 00077 bit [7:0] current_byte; 00078 bit [31:0] crc1; 00079 00080 if(!seed) seed = ovm_global_random_seed; 00081 ovm_oneway_hash = seed; 00082 00083 crc1 = 32'hffffffff; 00084 for (int _byte=0; _byte < string_in.len(); _byte++) begin 00085 current_byte = string_in[_byte]; 00086 if (current_byte == 0) break; 00087 for (int _bit=0; _bit < 8; _bit++) begin 00088 msb = crc1[31]; 00089 crc1 <<= 1; 00090 if (msb ^ current_byte[_bit]) begin 00091 crc1 ^= OVM_STR_CRC_POLYNOMIAL; 00092 crc1[0] = 1; 00093 end 00094 end 00095 end 00096 ovm_oneway_hash += ~{crc1[7:0], crc1[15:8], crc1[23:16], crc1[31:24]}; 00097 00098 endfunction 00099 00100 // 00101 // ovm_create_random_seed 00102 // 00103 // Creates a random seed and updates the seed map so that if the same string 00104 // is used again, a new value will be generated. The inst_id is used to hash 00105 // by instance name and get a map of type name hashes which the type_id uses 00106 // for it's lookup. 00107 00108 function int unsigned ovm_create_random_seed ( string type_id, string inst_id="" ); 00109 ovm_seed_map seed_map; 00110 00111 if(inst_id == "") 00112 inst_id = "__global__"; 00113 00114 if(!ovm_random_seed_table_lookup.exists(inst_id)) 00115 ovm_random_seed_table_lookup[inst_id] = new; 00116 seed_map = ovm_random_seed_table_lookup[inst_id]; 00117 00118 type_id = {ovm_instance_scope(),type_id}; 00119 00120 if(!seed_map.seed_table.exists(type_id)) begin 00121 seed_map.seed_table[type_id] = ovm_oneway_hash ({type_id,"::",inst_id}, ovm_global_random_seed); 00122 end 00123 00124 //can't just increment, otherwise too much chance for collision, so 00125 //randomize the seed using the last seed as the seed value. Check if 00126 //the seed has been used before and if so increment it. 00127 seed_map.seed_table[type_id] = $urandom(seed_map.seed_table[type_id]); 00128 00129 return seed_map.seed_table[type_id]; 00130 endfunction 00131 00132 00133 //---------------------------------------------------------------------------- 00134 // 00135 // CLASS: ovm_scope_stack 00136 // 00137 //---------------------------------------------------------------------------- 00138 00139 // depth 00140 // ----- 00141 00142 function int ovm_scope_stack::depth(); 00143 return m_stack.size(); 00144 endfunction 00145 00146 00147 // scope 00148 // ----- 00149 00150 function string ovm_scope_stack::get(); 00151 return m_scope; 00152 endfunction 00153 00154 00155 // scope_arg 00156 // --------- 00157 00158 function string ovm_scope_stack::get_arg(); 00159 return m_scope_arg; 00160 endfunction 00161 00162 00163 // set_scope 00164 // --------- 00165 00166 function void ovm_scope_stack::set (string s, ovm_object obj); 00167 ovm_void v; v=obj; 00168 m_scope_arg = s; 00169 m_scope = s; 00170 00171 // When no arg delete() is supported for queues, can just call m_stack.delete(). 00172 while(m_stack.size()) void'(m_stack.pop_front()); 00173 00174 m_stack.push_back(v); 00175 if(v!=null) begin 00176 m_object_map[v] = 1; 00177 end 00178 endfunction 00179 00180 00181 // down 00182 // ---- 00183 00184 function void ovm_scope_stack::down (string s, ovm_object obj); 00185 ovm_void v; v=obj; 00186 if(m_scope == "") 00187 m_scope = s; 00188 else if(s.len()) begin 00189 if(s[0] == "[") 00190 m_scope = {m_scope,s}; 00191 else 00192 m_scope = {m_scope,".",s}; 00193 end 00194 m_scope_arg=m_scope; 00195 if(v!=null) begin 00196 m_object_map[v] = 1; 00197 end 00198 m_stack.push_back(v); 00199 endfunction 00200 00201 00202 // down_element 00203 // ------------ 00204 00205 function void ovm_scope_stack::down_element (int element, ovm_object obj); 00206 string tmp_value_str; 00207 ovm_void v; v=obj; 00208 tmp_value_str.itoa(element); 00209 00210 m_scope = {m_scope, "[", tmp_value_str, "]"}; 00211 m_scope_arg=m_scope; 00212 m_stack.push_back(v); 00213 if(v!=null) 00214 m_object_map[v] = 1; 00215 endfunction 00216 00217 // current 00218 // ------- 00219 00220 function ovm_object ovm_scope_stack::current (); 00221 ovm_void v; 00222 if(m_stack.size()) begin 00223 v = m_stack[m_stack.size()-1]; 00224 $cast(current, v); 00225 end 00226 else 00227 return null; 00228 endfunction 00229 00230 // up 00231 // -- 00232 00233 function void ovm_scope_stack::up (ovm_object obj, byte separator ="."); 00234 string tmp_value_str; 00235 int last_dot; 00236 if(!m_scope.len()) begin 00237 // When no arg delete() is supported for associative arrays, can just call 00238 // m_object_map.delete(). 00239 foreach(m_object_map[i]) m_object_map.delete(i); 00240 // When no arg delete() is supported for queues, can just call m_stack.delete(). 00241 while(m_stack.size()) void'(m_stack.pop_front()); 00242 return; 00243 end 00244 //Find the last scope separator 00245 for(last_dot = m_scope.len()-1; last_dot != 0; --last_dot) 00246 if(m_scope[last_dot] == separator) break; 00247 00248 if(!last_dot) 00249 m_scope = ""; 00250 00251 tmp_value_str = ""; 00252 for(int i=0; i<last_dot; ++i) begin 00253 tmp_value_str = {tmp_value_str, " "}; 00254 tmp_value_str[i] = m_scope[i]; 00255 end 00256 m_scope = tmp_value_str; 00257 void'(m_stack.pop_back()); 00258 if(m_stack.size() == 0) 00259 m_scope = ""; 00260 00261 m_scope_arg = m_scope; 00262 m_object_map.delete(obj); 00263 endfunction 00264 00265 00266 // up_element 00267 // ---------- 00268 00269 function void ovm_scope_stack::up_element (ovm_object obj); 00270 up(obj, "["); 00271 endfunction 00272 00273 00274 // set_arg 00275 // ------- 00276 00277 function void ovm_scope_stack::set_arg (string arg); 00278 if(m_scope == "") 00279 m_scope_arg = arg; 00280 else if(arg[0] == "[") 00281 m_scope_arg = {m_scope, arg}; 00282 else 00283 m_scope_arg = {m_scope, ".", arg}; 00284 endfunction 00285 00286 00287 // set_arg_element 00288 // --------------- 00289 00290 function void ovm_scope_stack::set_arg_element (string arg, int ele); 00291 string tmp_value_str; 00292 tmp_value_str.itoa(ele); 00293 if(m_scope == "") 00294 m_scope_arg = {arg, "[", tmp_value_str, "]"}; 00295 else 00296 m_scope_arg = {m_scope, ".", arg, "[", tmp_value_str, "]"}; 00297 endfunction 00298 00299 function void ovm_scope_stack::unset_arg (string arg); 00300 int s, sa; 00301 s=m_scope_arg.len(); 00302 sa=arg.len(); 00303 if(m_scope_arg[s-1] == "]" && arg[sa-1] != "]") 00304 s--; 00305 if(s<sa) return; 00306 while(sa>=0) begin 00307 if(m_scope_arg[s] != arg[sa]) return; 00308 s--; sa--; 00309 end 00310 if(m_scope_arg[s] == ".") 00311 s--; 00312 else if(m_scope_arg[s] == "[" && m_scope_arg[m_scope_arg.len()-1]=="]") 00313 s--; 00314 m_scope_arg = m_scope_arg.substr(0,s); 00315 endfunction 00316 00317 // in_hierarchy 00318 // ------------ 00319 00320 function bit ovm_scope_stack::in_hierarchy (ovm_object obj); 00321 ovm_void v; v = obj; 00322 if (!m_object_map.exists(v)) return 0; 00323 return m_object_map[v]; 00324 endfunction 00325 00326 // ovm_leaf_scope 00327 // -------------- 00328 function string ovm_leaf_scope (string full_name, byte scope_separator = "."); 00329 byte bracket_match; 00330 int pos; 00331 int bmatches; 00332 00333 bmatches = 0; 00334 case(scope_separator) 00335 "[": bracket_match = "]"; 00336 "(": bracket_match = ")"; 00337 "<": bracket_match = ">"; 00338 "{": bracket_match = "}"; 00339 default: bracket_match = ""; 00340 endcase 00341 00342 //Only use bracket matching if the input string has the end match 00343 if(bracket_match != "" && bracket_match != full_name[full_name.len()-1]) 00344 bracket_match = ""; 00345 00346 for(pos=full_name.len()-1; pos!=0; --pos) begin 00347 if(full_name[pos] == bracket_match) bmatches++; 00348 else if(full_name[pos] == scope_separator) begin 00349 bmatches--; 00350 if(!bmatches || (bracket_match == "")) break; 00351 end 00352 end 00353 if(pos) begin 00354 if(scope_separator != ".") pos--; 00355 ovm_leaf_scope = full_name.substr(pos+1,full_name.len()-1); 00356 end 00357 else begin 00358 ovm_leaf_scope = full_name; 00359 end 00360 endfunction 00361 00362 00363 // OVM does not provide any kind of recording functionality, but provides hooks 00364 // when a component/object may need such a hook. 00365 00366 00367 `ifndef OVM_RECORD_INTERFACE 00368 `define OVM_RECORD_INTERFACE 00369 00370 // ovm_create_fiber 00371 // ---------------- 00372 00373 function integer ovm_create_fiber (string name, 00374 string t, 00375 string scope); 00376 return 0; 00377 endfunction 00378 00379 // ovm_set_index_attribute_by_name 00380 // ------------------------------- 00381 00382 function void ovm_set_index_attribute_by_name (integer txh, 00383 string nm, 00384 int index, 00385 logic [1023:0] value, 00386 string radix, 00387 integer numbits=32); 00388 return; 00389 endfunction 00390 00391 00392 // ovm_set_attribute_by_name 00393 // ------------------------- 00394 00395 function void ovm_set_attribute_by_name (integer txh, 00396 string nm, 00397 logic [1023:0] value, 00398 string radix, 00399 integer numbits=0); 00400 return; 00401 endfunction 00402 00403 00404 // ovm_check_handle_kind 00405 // --------------------- 00406 00407 function integer ovm_check_handle_kind (string htype, integer handle); 00408 return 1; 00409 endfunction 00410 00411 00412 // ovm_begin_transaction 00413 // --------------- 00414 00415 function integer ovm_begin_transaction(string txtype, 00416 integer stream, 00417 string nm 00418 , string label="", 00419 string desc="", 00420 time begin_time=0 00421 ); 00422 00423 return 0; 00424 endfunction 00425 00426 00427 // ovm_end_transaction 00428 // ------------------- 00429 00430 function void ovm_end_transaction (integer handle 00431 , time end_time=0 00432 ); 00433 return; 00434 endfunction 00435 00436 00437 // ovm_link_transaction 00438 // -------------------- 00439 00440 function void ovm_link_transaction(integer h1, integer h2, 00441 string relation=""); 00442 return; 00443 endfunction 00444 00445 00446 00447 // ovm_free_transaction_handle 00448 // --------------------------- 00449 00450 function void ovm_free_transaction_handle(integer handle); 00451 return; 00452 endfunction 00453 00454 `endif // OVM_RECORD_INTERFACE 00455 00456 // The following functions check to see if a string is representing an array 00457 // index, and if so, what the index is. 00458 00459 function int ovm_get_array_index_int(string arg, output bit is_wildcard); 00460 int i; 00461 ovm_get_array_index_int = 0; 00462 is_wildcard = 1; 00463 i = arg.len() - 1; 00464 if(arg[i] == "]") 00465 while(i > 0 && (arg[i] != "[")) begin 00466 --i; 00467 if((arg[i] == "*") || (arg[i] == "?")) i=0; 00468 else if((arg[i] < "0") || (arg[i] > "9") && (arg[i] != "[")) begin 00469 ovm_get_array_index_int = -1; //illegal integral index 00470 i=0; 00471 end 00472 end 00473 else begin 00474 is_wildcard = 0; 00475 return 0; 00476 end 00477 00478 if(i>0) begin 00479 arg = arg.substr(i+1, arg.len()-2); 00480 ovm_get_array_index_int = arg.atoi(); 00481 is_wildcard = 0; 00482 end 00483 endfunction 00484 00485 function string ovm_get_array_index_string(string arg, output bit is_wildcard); 00486 int i; 00487 ovm_get_array_index_string = ""; 00488 is_wildcard = 1; 00489 i = arg.len() - 1; 00490 if(arg[i] == "]") 00491 while(i > 0 && (arg[i] != "[")) begin 00492 if((arg[i] == "*") || (arg[i] == "?")) i=0; 00493 --i; 00494 end 00495 if(i>0) begin 00496 ovm_get_array_index_string = arg.substr(i+1, arg.len()-2); 00497 is_wildcard = 0; 00498 end 00499 endfunction 00500 00501 function bit ovm_is_array(string arg); 00502 int last; 00503 ovm_is_array = 0; 00504 last = arg.len()-1; 00505 if(arg[last] == "]") ovm_is_array = 1; 00506 endfunction 00507 00508
![]() 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 |