ovm_packer.sv

Go to the documentation of this file.
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
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
Doxygen Version: 1.4.6
Mon Sep 29 14:23:30 2008
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV