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