00001 // $Id: a00249.html,v 1.1 2009/01/07 19:29:49 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_packer.svh" 00023 00024 //----------------------------------------------------------------------------- 00025 // 00026 // ovm_packer 00027 // 00028 //----------------------------------------------------------------------------- 00029 00030 // NOTE: max size limited to BITSTREAM bits parameter (default: 4096) 00031 00032 00033 // index_ok 00034 // -------- 00035 00036 function void ovm_packer::index_error(int index, string id, int sz); 00037 ovm_report_error("PCKIDX", 00038 $psprintf("index %0d for get_%0s too large; valid index range is 0-%0d.", 00039 index,id,((m_packed_size+sz-1)/sz)-1)); 00040 endfunction 00041 00042 00043 // enough_bits 00044 // ----------- 00045 00046 function bit ovm_packer::enough_bits(int needed, string id); 00047 if ((m_packed_size - count) < needed) begin 00048 ovm_report_error("PCKSZ", 00049 $psprintf("%0d bits needed to unpack %0s, yet only %0d available.", 00050 needed, id, (m_packed_size - count))); 00051 return 0; 00052 end 00053 return 1; 00054 endfunction 00055 00056 00057 // get_packed_size 00058 // --------------- 00059 00060 function int ovm_packer::get_packed_size(); 00061 return m_packed_size; 00062 endfunction 00063 00064 00065 // set_packed_size 00066 // --------------- 00067 00068 function void ovm_packer::set_packed_size(); 00069 m_packed_size = count; 00070 count = 0; 00071 endfunction 00072 00073 00074 // reset 00075 // ----- 00076 00077 function void ovm_packer::reset(); 00078 count = 0; 00079 m_bits = 0; 00080 m_packed_size = 0; 00081 endfunction 00082 00083 00084 // get_packed_bits 00085 // --------------- 00086 00087 function ovm_bitstream_t ovm_packer::get_packed_bits(); 00088 //bits = m_bits; 00089 return m_bits; 00090 endfunction 00091 00092 00093 // get_bits 00094 // -------- 00095 00096 function void ovm_packer::get_bits(ref bit unsigned bits[]); 00097 bits = new[m_packed_size]; 00098 for (int i=0;i<m_packed_size;i++) 00099 bits[i] = m_bits[i]; 00100 endfunction 00101 00102 00103 // get_bytes 00104 // --------- 00105 00106 function void ovm_packer::get_bytes(ref byte unsigned bytes[]); 00107 int sz; 00108 byte v; 00109 sz = (m_packed_size+7) / 8; 00110 bytes = new[sz]; 00111 for (int i=0;i<sz;i++) begin 00112 if (i != sz-1) 00113 v = m_bits[ i*8 +: 8 ]; 00114 else 00115 v = m_bits[ i*8 +: 8 ] & ('hFF >> (m_packed_size%8)); 00116 if(big_endian) begin 00117 byte tmp; tmp = v; 00118 for(int j=0; j<8; ++j) v[j] = tmp[7-j]; 00119 end 00120 bytes[i] = v; 00121 end 00122 endfunction 00123 00124 00125 // get_ints 00126 // -------- 00127 00128 function void ovm_packer::get_ints(ref int unsigned ints[]); 00129 int sz, v; 00130 sz = (m_packed_size+31) / 32; 00131 ints = new[sz]; 00132 for (int i=0;i<sz;i++) begin 00133 if (i != sz-1) 00134 v = m_bits[ i*32 +: 32 ]; 00135 else 00136 v = m_bits[ i*32 +: 32 ] & ('hFFFFFFFF >> (m_packed_size%32)); 00137 if(big_endian) begin 00138 int tmp; tmp = v; 00139 for(int j=0; j<32; ++j) v[j] = tmp[31-j]; 00140 end 00141 ints[i] = v; 00142 end 00143 endfunction 00144 00145 00146 // put_bits 00147 // -------- 00148 00149 function void ovm_packer::put_bits (ref bit bitstream []); 00150 00151 int bit_size; 00152 00153 bit_size = bitstream.size(); 00154 00155 if(big_endian) 00156 for (int i=bit_size-1;i>=0;i--) 00157 m_bits[i] = bitstream[i]; 00158 else 00159 for (int i=0;i<bit_size;i++) 00160 m_bits[i] = bitstream[i]; 00161 00162 m_packed_size = bit_size; 00163 count = 0; 00164 00165 endfunction 00166 00167 // put_bytes 00168 // --------- 00169 00170 function void ovm_packer::put_bytes (ref byte unsigned bytestream []); 00171 00172 int byte_size; 00173 int index; 00174 byte unsigned b; 00175 00176 byte_size = bytestream.size(); 00177 index = 0; 00178 for (int i=0;i<byte_size;i++) begin 00179 b = bytestream[i]; 00180 if(big_endian) begin 00181 byte unsigned tb; tb = b; 00182 for(int j=0;j<8;++j) b[j] = tb[7-j]; 00183 end 00184 m_bits[index +:8] = b; 00185 index += 8; 00186 end 00187 00188 m_packed_size = byte_size*8; 00189 count = 0; 00190 endfunction 00191 00192 00193 // put_ints 00194 // -------- 00195 00196 function void ovm_packer::put_ints (ref int unsigned intstream []); 00197 00198 int int_size; 00199 int index; 00200 int unsigned v; 00201 00202 int_size = intstream.size(); 00203 00204 index = 0; 00205 for (int i=0;i<int_size;i++) begin 00206 v = intstream[i]; 00207 if(big_endian) begin 00208 int unsigned tv; tv = v; 00209 for(int j=0;j<32;++j) v[j] = tv[31-j]; 00210 end 00211 m_bits[index +:32] = v; 00212 index += 32; 00213 end 00214 00215 m_packed_size = int_size*32; 00216 count = 0; 00217 endfunction 00218 00219 00220 00221 00222 // get_bit 00223 // ------- 00224 00225 function bit unsigned ovm_packer::get_bit(int unsigned index); 00226 if (index >= m_packed_size) 00227 index_error(index, "bit",1); 00228 return m_bits[index]; 00229 endfunction 00230 00231 00232 // get_byte 00233 // -------- 00234 00235 function byte unsigned ovm_packer::get_byte(int unsigned index); 00236 if (index >= (m_packed_size+7)/8) 00237 index_error(index, "byte",8); 00238 return m_bits[index*8 +: 8]; 00239 endfunction 00240 00241 00242 // get_int 00243 // ------- 00244 00245 function int unsigned ovm_packer::get_int(int unsigned index); 00246 if (index >= (m_packed_size+31)/32) 00247 index_error(index, "int",32); 00248 return m_bits[(index*32) +: 32]; 00249 endfunction 00250 00251 00252 // PACK 00253 00254 00255 // pack_object 00256 // --------- 00257 00258 function void ovm_packer::pack_object(ovm_object value); 00259 00260 if(scope.in_hierarchy(value)) begin 00261 `ifdef INCA 00262 ovm_report_warning("CYCFND", $psprintf("Cycle detected for object @%0d during pack", this)); 00263 `else 00264 ovm_report_warning("CYCFND", $psprintf("Cycle detected during pack")); 00265 `endif 00266 return; 00267 end 00268 00269 if((policy != OVM_REFERENCE) && (value != null) ) begin 00270 if(use_metadata == 1) begin 00271 m_bits[count +: 4] = 1; 00272 count += 4; // to better debug when display packed bits in hexidecimal 00273 end 00274 scope.down(value.get_name(), value); 00275 value.m_field_automation(null, OVM_PACK,""); 00276 value.do_pack(this); 00277 scope.up(value); 00278 end 00279 else if(use_metadata == 1) begin 00280 m_bits[count +: 4] = 0; 00281 count += 4; 00282 end 00283 endfunction 00284 00285 00286 // pack_real 00287 // --------- 00288 00289 function void ovm_packer::pack_real(real value); 00290 pack_field_int($realtobits(value), 64); 00291 endfunction 00292 00293 00294 // pack_time 00295 // --------- 00296 00297 function void ovm_packer::pack_time(time value); 00298 pack_field_int(value, 64); 00299 //m_bits[count +: 64] = value; this overwrites endian adjustments 00300 endfunction 00301 00302 00303 // pack_field 00304 // ---------- 00305 00306 function void ovm_packer::pack_field(ovm_bitstream_t value, int size); 00307 for (int i=0; i<size; i++) 00308 if(big_endian == 1) 00309 m_bits[count+i] = value[size-1-i]; 00310 else 00311 m_bits[count+i] = value[i]; 00312 count += size; 00313 endfunction 00314 00315 00316 // pack_field_int 00317 // -------------- 00318 00319 function void ovm_packer::pack_field_int(logic [63:0] value, int size); 00320 for (int i=0; i<size; i++) 00321 if(big_endian == 1) 00322 m_bits[count+i] = value[size-1-i]; 00323 else 00324 m_bits[count+i] = value[i]; 00325 count += size; 00326 endfunction 00327 00328 00329 // pack_string 00330 // ----------- 00331 00332 function void ovm_packer::pack_string(string value); 00333 byte b; 00334 foreach (value[index]) begin 00335 if(big_endian == 0) 00336 m_bits[count +: 8] = value[index]; 00337 else begin 00338 b = value[index]; 00339 for(int i=0; i<8; ++i) 00340 m_bits[count+i] = b[7-i]; 00341 end 00342 count += 8; 00343 end 00344 if(use_metadata == 1) begin 00345 m_bits[count +: 8] = 0; 00346 count += 8; 00347 end 00348 endfunction 00349 00350 00351 // UNPACK 00352 00353 00354 // is_null 00355 // ------- 00356 00357 function bit ovm_packer::is_null(); 00358 return (m_bits[count+:4]==0); 00359 endfunction 00360 00361 // unpack_object 00362 // ------------- 00363 00364 function void ovm_packer::unpack_object_ext(inout ovm_object value); 00365 unpack_object(value); 00366 endfunction 00367 00368 function void ovm_packer::unpack_object(ovm_object value); 00369 00370 byte is_non_null; is_non_null = 1; 00371 00372 if(scope.in_hierarchy(value)) begin 00373 `ifdef INCA 00374 ovm_report_warning("CYCFND", $psprintf("Cycle detected for object @%0d during unpack", this)); 00375 `else 00376 ovm_report_warning("CYCFND", $psprintf("Cycle detected during unpack", this)); 00377 `endif 00378 return; 00379 end 00380 00381 if(use_metadata == 1) begin 00382 is_non_null = m_bits[count +: 4]; 00383 count+=4; 00384 end 00385 00386 // NOTE: policy is a _pack_ policy, not unpack policy; 00387 // and you can't pack an object by REFERENCE 00388 if (value != null)begin 00389 if (is_non_null > 0) begin 00390 scope.down(value.get_name(), value); 00391 value.m_field_automation(null, OVM_UNPACK,""); 00392 value.do_unpack(this); 00393 scope.up(value); 00394 end 00395 else begin 00396 // TODO: help do_unpack know whether unpacked result would be null 00397 // to avoid new'ing unnecessarily; 00398 // this does not nullify argument; need to pass obj by ref 00399 end 00400 end 00401 else if ((is_non_null != 0) && (value == null)) begin 00402 ovm_report_error("UNPOBJ","can not unpack into null object"); 00403 return; 00404 end 00405 00406 endfunction 00407 00408 00409 // unpack_real 00410 // ----------- 00411 00412 function real ovm_packer::unpack_real(); 00413 if (enough_bits(64,"real")) begin 00414 return $bitstoreal(unpack_field_int(64)); 00415 end 00416 endfunction 00417 00418 00419 // unpack_time 00420 // ----------- 00421 00422 function time ovm_packer::unpack_time(); 00423 if (enough_bits(64,"time")) begin 00424 return unpack_field_int(64); 00425 end 00426 endfunction 00427 00428 00429 // unpack_field 00430 // ------------ 00431 00432 function ovm_bitstream_t ovm_packer::unpack_field(int size); 00433 unpack_field = 'b0; 00434 if (enough_bits(size,"integral")) begin 00435 count += size; 00436 for (int i=0; i<size; i++) 00437 if(big_endian == 1) 00438 unpack_field[i] = m_bits[count-i-1]; 00439 else 00440 unpack_field[i] = m_bits[count-size+i]; 00441 end 00442 endfunction 00443 00444 00445 // unpack_field_int 00446 // ---------------- 00447 00448 function logic[63:0] ovm_packer::unpack_field_int(int size); 00449 unpack_field_int = 'b0; 00450 if (enough_bits(size,"integral")) begin 00451 count += size; 00452 for (int i=0; i<size; i++) 00453 if(big_endian == 1) 00454 unpack_field_int[i] = m_bits[count-i-1]; 00455 else 00456 unpack_field_int[i] = m_bits[count-size+i]; 00457 end 00458 endfunction 00459 00460 00461 // unpack_string 00462 // ------------- 00463 00464 // If num_chars is not -1, then the user only wants to unpack a 00465 // specific number of bytes into the string. 00466 function string ovm_packer::unpack_string(int num_chars=-1); 00467 byte b; 00468 bit is_null_term; // Assumes a null terminated string 00469 int i; i=0; 00470 if(num_chars == -1) is_null_term = 1; 00471 else is_null_term = 0; 00472 00473 while(enough_bits(8,"string") && 00474 ((m_bits[count+:8] != 0) || (is_null_term == 0)) && 00475 ((i<num_chars)||(is_null_term==1)) ) 00476 begin 00477 // silly, because can not append byte/char to string 00478 unpack_string = {unpack_string," "}; 00479 if(big_endian == 0) 00480 unpack_string[i] = m_bits[count +: 8]; 00481 else begin 00482 for(int j=0; j<8; ++j) 00483 b[7-j] = m_bits[count+j]; 00484 unpack_string[i] = b; 00485 end 00486 count += 8; 00487 ++i; 00488 end 00489 if(enough_bits(8,"string")) 00490 count += 8; 00491 endfunction 00492 00493 00494
![]() 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 |