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: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
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:20:12 2008
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV