blob: ba5a9b275e7cfe1d24fc1dbdcffa11226bb67d3d [file] [log] [blame]
// $Id: ovm_packer.svh,v 1.15 2010/03/12 20:52:36 jlrose Exp $
//------------------------------------------------------------------------------
// Copyright 2007-2009 Mentor Graphics Corporation
// Copyright 2007-2009 Cadence Design Systems, Inc.
// All Rights Reserved Worldwide
//
// Licensed under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in
// writing, software distributed under the License is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See
// the License for the specific language governing
// permissions and limitations under the License.
//------------------------------------------------------------------------------
`ifndef OVM_PACKER_SVH
`define OVM_PACKER_SVH
//------------------------------------------------------------------------------
// CLASS: ovm_packer
//
// The ovm_packer class provides a policy object for packing and unpacking
// ovm_objects. The policies determine how packing and unpacking should be done.
// Packing an object causes the object to be placed into a bit (byte or int)
// array. If the `ovm_field_* macro are used to implement pack and unpack,
// by default no metadata information is stored for the packing of dynamic
// objects (strings, arrays, class objects).
//
//-------------------------------------------------------------------------------
// Maximum bytes for the packer array.
`ifndef OVM_PACKER_MAX_BYTES
`define OVM_PACKER_MAX_BYTES OVM_STREAMBITS
`endif
typedef bit signed [(`OVM_PACKER_MAX_BYTES*8)-1:0] ovm_pack_bitstream_t;
class ovm_packer;
//----------------//
// Group: Packing //
//----------------//
// Function: pack_field
//
// Packs an integral value (less than or equal to 4096 bits) into the
// packed array. ~size~ is the number of bits of ~value~ to pack.
extern virtual function void pack_field (ovm_bitstream_t value, int size);
// Function: pack_field_int
//
// Packs the integral value (less than or equal to 64 bits) into the
// pack array. The ~size~ is the number of bits to pack, usually obtained by
// ~$bits~. This optimized version of <pack_field> is useful for sizes up
// to 64 bits.
extern virtual function void pack_field_int (logic[63:0] value, int size);
// Function: pack_string
//
// Packs a string value into the pack array.
//
// When the metadata flag is set, the packed string is terminated by a null
// character to mark the end of the string.
//
// This is useful for mixed language communication where unpacking may occur
// outside of SystemVerilog OVM.
extern virtual function void pack_string (string value);
// Function: pack_time
//
// Packs a time ~value~ as 64 bits into the pack array.
extern virtual function void pack_time (time value);
// Function: pack_real
//
// Packs a real ~value~ as 64 bits into the pack array.
//
// The real ~value~ is converted to a 6-bit scalar value using the function
// $real2bits before it is packed into the array.
extern virtual function void pack_real (real value);
// Function: pack_object
//
// Packs an object value into the pack array.
//
// A 4-bit header is inserted ahead of the string to indicate the number of
// bits that was packed. If a null object was packed, then this header will
// be 0.
//
// This is useful for mixed-language communication where unpacking may occur
// outside of SystemVerilog OVM.
extern virtual function void pack_object (ovm_object value);
//------------------//
// Group: Unpacking //
//------------------//
// Function: is_null
//
// This method is used during unpack operations to peek at the next 4-bit
// chunk of the pack data and determine if it is 0.
//
// If the next four bits are all 0, then the return value is a 1; otherwise
// it is 0.
//
// This is useful when unpacking objects, to decide whether a new object
// needs to be allocated or not.
extern virtual function bit is_null ();
// Function: unpack_field_int
//
// Unpacks bits from the pack array and returns the bit-stream that was
// unpacked.
//
// ~size~ is the number of bits to unpack; the maximum is 64 bits.
// This is a more efficient variant than unpack_field when unpacking into
// smaller vectors.
extern virtual function logic[63:0] unpack_field_int (int size);
// Function: unpack_field
//
// Unpacks bits from the pack array and returns the bit-stream that was
// unpacked. ~size~ is the number of bits to unpack; the maximum is 4096 bits.
extern virtual function ovm_bitstream_t unpack_field (int size);
// Function: unpack_string
//
// Unpacks a string.
//
// num_chars bytes are unpacked into a string. If num_chars is -1 then
// unpacking stops on at the first null character that is encountered.
extern virtual function string unpack_string (int num_chars=-1);
// Function: unpack_time
//
// Unpacks the next 64 bits of the pack array and places them into a
// time variable.
extern virtual function time unpack_time ();
// Function: unpack_real
//
// Unpacks the next 64 bits of the pack array and places them into a
// real variable.
//
// The 64 bits of packed data are converted to a real using the $bits2real
// system function.
extern virtual function real unpack_real ();
// Function: unpack_object
//
// Unpacks an object and stores the result into ~value~.
//
// ~value~ must be an allocated object that has enough space for the data
// being unpacked. The first four bits of packed data are used to determine
// if a null object was packed into the array.
//
// The <is_null> function can be used to peek at the next four bits in
// the pack array before calling this method.
extern virtual function void unpack_object (ovm_object value);
// Function: get_packed_size
//
// Returns the number of bits that were packed.
extern virtual function int get_packed_size();
//------------------//
// Group: Variables //
//------------------//
// Variable: physical
//
// This bit provides a filtering mechanism for fields.
//
// The <abstract> and physical settings allow an object to distinguish between
// two different classes of fields. It is up to you, in the
// <ovm_object::do_pack> and <ovm_object::do_unpack> methods, to test the
// setting of this field if you want to use it as a filter.
bit physical = 1;
// Variable: abstract
//
// This bit provides a filtering mechanism for fields.
//
// The abstract and physical settings allow an object to distinguish between
// two different classes of fields. It is up to you, in the
// <ovm_object::do_pack> and <ovm_object::do_unpack> routines, to test the
// setting of this field if you want to use it as a filter.
bit abstract = 0;
// Variable: use_metadata
//
// This flag indicates whether to encode metadata when packing dynamic data,
// or to decode metadata when unpacking. Implementations of <do_pack> and
// <do_unpack> should regard this bit when performing their respective
// operation. When set, metadata should be encoded as follows:
//
// - For strings, pack an additional null byte after the string is packed.
//
// - For objects, pack 4 bits prior to packing the object itself. Use 4'b0000
// to indicate the object being packed is null, otherwise pack 4'b0001 (the
// remaining 3 bits are reserved).
//
// - For queues, dynamic arrays, and associative arrays, pack 32 bits
// indicating the size of the array prior to to packing individual elements.
bit use_metadata = 0;
// Variable: big_endian
//
// This bit determines the order that integral data is packed (using
// <pack_field>, <pack_field_int>, <pack_time>, or <pack_real>) and how the
// data is unpacked from the pack array (using <unpack_field>,
// <unpack_field_int>, <unpack_time>, or <unpack_real>). When the bit is set,
// data is associated msb to lsb; otherwise, it is associated lsb to msb.
//
// The following code illustrates how data can be associated msb to lsb and
// lsb to msb:
//
//| class mydata extends ovm_object;
//|
//| logic[15:0] value = 'h1234;
//|
//| function void do_pack (ovm_packer packer);
//| packer.pack_field_int(value, 16);
//| endfunction
//|
//| function void do_unpack (ovm_packer packer);
//| value = packer.unpack_field_int(16);
//| endfunction
//| endclass
//|
//| mydata d = new;
//| bit bits[];
//|
//| initial begin
//| d.pack(bits); // 'b0001001000110100
//| ovm_default_packer.big_endian = 0;
//| d.pack(bits); // 'b0010110001001000
//| end
bit big_endian = 1;
// variables and methods primarily for internal use
static bit bitstream[]; // local bits for (un)pack_bytes
static bit fabitstream[]; // field automation bits for (un)pack_bytes
int count = 0; // used to count the number of packed bits
ovm_scope_stack scope= new;
bit reverse_order = 0; //flip the bit order around
byte byte_size = 8; //set up bytesize for endianess
int word_size = 16; //set up worksize for endianess
bit nopack = 0; //only count packable bits
ovm_recursion_policy_enum policy = OVM_DEFAULT_POLICY;
ovm_pack_bitstream_t m_bits = 0;
int m_packed_size = 0;
extern virtual function void unpack_object_ext (inout ovm_object value);
extern virtual function ovm_pack_bitstream_t get_packed_bits ();
extern virtual function bit unsigned get_bit (int unsigned index);
extern virtual function byte unsigned get_byte (int unsigned index);
extern virtual function int unsigned get_int (int unsigned index);
extern virtual function void get_bits (ref bit unsigned bits[]);
extern virtual function void get_bytes(ref byte unsigned bytes[]);
extern virtual function void get_ints (ref int unsigned ints[]);
extern virtual function void put_bits (ref bit unsigned bitstream[]);
extern virtual function void put_bytes(ref byte unsigned bytestream[]);
extern virtual function void put_ints (ref int unsigned intstream[]);
extern virtual function void set_packed_size();
extern function void index_error(int index, string id, int sz);
extern function bit enough_bits(int needed, string id);
extern function void reset();
endclass
`endif // OVM_PACKER_SVH