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