blob: a0d1cadac795cfbec134a1fc436e5055a9774486 [file] [log] [blame]
//----------------------------------------------------------------------
// Copyright 2018 Qualcomm, Inc.
// Copyright 2018 Cadence Design Systems, Inc.
// Copyright 2018 NVIDIA Corporation
// Copyright 2018 Cisco 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 UVM_PACKER_DEFINES_SVH
`define UVM_PACKER_DEFINES_SVH
//------------------------------------------------------------------------------
//
// MACROS for uvm_packer usage
//
// Provides a set of packing/unpacking macros that will call appropriate methods
// inside of a uvm_packer object.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Group -- NODOCS -- Packing Macros
//
// The packing macros assist users who implement the <uvm_object::do_pack>
// method. They help ensure that the pack operation is the exact inverse of the
// unpack operation. See also <Unpacking Macros>.
//
//| virtual function void do_pack(uvm_packer packer);
//| `uvm_pack_int(cmd)
//| `uvm_pack_int(addr)
//| `uvm_pack_array(data)
//| endfunction
//
// The 'N' versions of these macros take a explicit size argument, which must
// be compile-time constant value greater than 0.
//------------------------------------------------------------------------------
//--------------------------------
// Group -- NODOCS -- Packing - With Size Info
//--------------------------------
// Macro -- NODOCS -- `uvm_pack_intN
//
// Pack an integral variable.
//
//| `uvm_pack_intN(VAR,SIZE)
//
// Group: Packing Macros
//
// The packing macros are implemented as described in section B.2.4 of the
// 1800.2 specification.
//
// The Accellera implementation adds an additional ~PACKER~ argument to
// these macros with a default value of 'packer'. This allows the macros
// to be used in environments with alternative packer names.
//
// For example, <`uvm_pack_intN> is defined in the LRM as
// | `define uvm_pack_intN(VAR,SIZE)
//
// Whereas the implementation is
// | `define uvm_pack_intN(VAR,SIZE,PACKER=packer)
//
// This allows for usage such as
// | function void pack_foo( uvm_packer other_packer );
// | `uvm_pack_intN(foo, 32, other_packer)
// | endfunction : pack_foo
//
// @uvm-contrib This API is being considered for potential contribution to 1800.2
// @uvm-ieee 1800.2-2017 auto B.2.4.1
`define uvm_pack_intN(VAR,SIZE,PACKER=packer) \
begin \
bit __array[]; \
{ << bit { __array}} = VAR; \
__array = new [SIZE] (__array); \
PACKER.pack_bits(__array, SIZE); \
end
// @uvm-ieee 1800.2-2017 auto B.2.4.2
`define uvm_pack_enumN(VAR,SIZE,PACKER=packer) \
`uvm_pack_intN(VAR,SIZE,PACKER)
// @uvm-ieee 1800.2-2017 auto B.2.4.3
`define uvm_pack_sarrayN(VAR,SIZE,PACKER=packer) \
begin \
foreach (VAR `` [index]) \
`uvm_pack_intN(VAR[index],SIZE,PACKER) \
end
// @uvm-ieee 1800.2-2017 auto B.2.4.4
`define uvm_pack_arrayN(VAR,SIZE,PACKER=packer) \
begin \
`uvm_pack_intN(VAR.size(),32,PACKER) \
`uvm_pack_sarrayN(VAR,SIZE,PACKER) \
end
// @uvm-ieee 1800.2-2017 auto B.2.4.5
`define uvm_pack_queueN(VAR,SIZE,PACKER=packer) \
`uvm_pack_arrayN(VAR,SIZE,PACKER)
//------------------------------
// Group -- NODOCS -- Packing - No Size Info
//------------------------------
// @uvm-ieee 1800.2-2017 auto B.2.4.6
`define uvm_pack_int(VAR,PACKER=packer) \
`uvm_pack_intN(VAR,$bits(VAR),PACKER)
// uvm_pack_object
`define uvm_pack_object(VAR,PACKER=packer) \
PACKER.pack_object_with_meta(VAR);
// @uvm-ieee 1800.2-2017 auto B.2.4.7
`define uvm_pack_enum(VAR,PACKER=packer) \
`uvm_pack_enumN(VAR,$bits(VAR),PACKER)
// @uvm-ieee 1800.2-2017 auto B.2.4.8
`define uvm_pack_string(VAR,PACKER=packer) \
PACKER.pack_string(VAR);
// @uvm-ieee 1800.2-2017 auto B.2.4.9
`define uvm_pack_real(VAR,PACKER=packer) \
PACKER.pack_real(VAR);
// @uvm-ieee 1800.2-2017 auto B.2.4.10
`define uvm_pack_sarray(VAR,PACKER=packer) \
`uvm_pack_sarrayN(VAR,$bits(VAR[0]),PACKER)
// @uvm-ieee 1800.2-2017 auto B.2.4.11
`define uvm_pack_array(VAR,PACKER=packer) \
`uvm_pack_arrayN(VAR,$bits(VAR[0]),PACKER)
`define uvm_pack_da(VAR,PACKER=packer) \
`uvm_pack_array(VAR,PACKER)
// @uvm-ieee 1800.2-2017 auto B.2.4.12
`define uvm_pack_queue(VAR,PACKER=packer) \
`uvm_pack_queueN(VAR,$bits(VAR[0]),PACKER)
//------------------------------------------------------------------------------
// Group -- NODOCS -- Unpacking Macros
//
// The unpacking macros assist users who implement the <uvm_object::do_unpack>
// method. They help ensure that the unpack operation is the exact inverse of
// the pack operation. See also <Packing Macros>.
//
//| virtual function void do_unpack(uvm_packer packer);
//| `uvm_unpack_enum(cmd,cmd_t)
//| `uvm_unpack_int(addr)
//| `uvm_unpack_array(data)
//| endfunction
//
// The 'N' versions of these macros take a explicit size argument, which must
// be a compile-time constant value greater than 0.
//------------------------------------------------------------------------------
//----------------------------------
// Group -- NODOCS -- Unpacking - With Size Info
//----------------------------------
// @uvm-ieee 1800.2-2017 auto B.2.5.1
`define uvm_unpack_intN(VAR,SIZE,PACKER=packer) \
begin \
bit __array[] = new [SIZE]; \
PACKER.unpack_bits(__array, SIZE); \
__array = new [$bits(VAR)] (__array); \
VAR = { << bit { __array }}; \
end
// @uvm-ieee 1800.2-2017 auto B.2.5.2
`define uvm_unpack_enumN(VAR,SIZE,TYPE,PACKER=packer) \
begin \
bit __array[] = new [SIZE]; \
PACKER.unpack_bits(__array, SIZE); \
__array = new [$bits(VAR)] (__array); \
VAR = TYPE'({ << bit { __array }}); \
end
// @uvm-ieee 1800.2-2017 auto B.2.5.3
`define uvm_unpack_sarrayN(VAR,SIZE,PACKER=packer) \
begin \
foreach (VAR `` [i]) \
`uvm_unpack_intN(VAR``[i], SIZE, PACKER) \
end
// @uvm-ieee 1800.2-2017 auto B.2.5.4
`define uvm_unpack_arrayN(VAR,SIZE,PACKER=packer) \
begin \
int sz__; \
`uvm_unpack_intN(sz__,32,PACKER) \
VAR = new[sz__]; \
`uvm_unpack_sarrayN(VAR,SIZE,PACKER) \
end
// @uvm-ieee 1800.2-2017 auto B.2.5.5
`define uvm_unpack_queueN(VAR,SIZE,PACKER=packer) \
begin \
int sz__; \
`uvm_unpack_intN(sz__,32,PACKER) \
while (VAR.size() > sz__) \
void'(VAR.pop_back()); \
for (int i=0; i<sz__; i++) \
`uvm_unpack_intN(VAR[i],SIZE,PACKER) \
end
//--------------------------------
// Group -- NODOCS -- Unpacking - No Size Info
//--------------------------------
// @uvm-ieee 1800.2-2017 auto B.2.5.6
`define uvm_unpack_int(VAR,PACKER=packer) \
`uvm_unpack_intN(VAR,$bits(VAR),PACKER)
// uvm_unpack_object
`define uvm_unpack_object(VAR,PACKER=packer) \
begin \
uvm_object __ref = VAR; \
PACKER.unpack_object_with_meta(__ref); \
if ((__ref != VAR) && !$cast(VAR,__ref)) begin \
`uvm_fatal("UVM/UNPACK_EXT/OBJ_CAST_FAILED", \
{"Could not cast object of type '", __ref.get_type_name(), \
"' into '", `"LVALUE`"}) \
end \
end
// @uvm-ieee 1800.2-2017 auto B.2.5.7
`define uvm_unpack_enum(VAR,TYPE,PACKER=packer) \
`uvm_unpack_enumN(VAR,$bits(VAR),TYPE,PACKER)
// @uvm-ieee 1800.2-2017 auto B.2.5.8
`define uvm_unpack_string(VAR,PACKER=packer) \
VAR = PACKER.unpack_string();
// @uvm-ieee 1800.2-2017 auto B.2.5.9
`define uvm_unpack_real(VAR,PACKER=packer) \
VAR = PACKER.unpack_real();
// @uvm-ieee 1800.2-2017 auto B.2.5.10
`define uvm_unpack_sarray(VAR,PACKER=packer) \
`uvm_unpack_sarrayN(VAR,$bits(VAR[0]),PACKER)
// @uvm-ieee 1800.2-2017 auto B.2.5.11
`define uvm_unpack_array(VAR,PACKER=packer) \
`uvm_unpack_arrayN(VAR,$bits(VAR[0]),PACKER)
// Implementation artifact. Simplifies field macros.
`define uvm_unpack_da(VAR,PACKER=packer) \
`uvm_unpack_array(VAR,PACKER)
// @uvm-ieee 1800.2-2017 auto B.2.5.12
`define uvm_unpack_queue(VAR,PACKER=packer) \
`uvm_unpack_queueN(VAR,$bits(VAR[0]),PACKER)
//--
`define uvm_pack_aa_int_intN(VAR, SIZE, PACKER=packer) \
begin \
`uvm_pack_intN(VAR.num(), 32, PACKER) \
if (VAR.num()) begin \
`uvm_pack_intN(SIZE, 32, PACKER) \
foreach(VAR[i]) begin \
`uvm_pack_intN(i, SIZE, PACKER) \
`uvm_pack_int(VAR[i],PACKER) \
end \
end \
end
`define uvm_unpack_aa_int_intN(VAR, SIZE, PACKER=packer) \
begin \
int __num__; \
`uvm_unpack_intN(__num__, 32, PACKER) \
if (__num__ == 0) \
VAR.delete(); \
else begin \
bit[SIZE-1:0] __index__; \
int __sz__; \
`uvm_unpack_intN(__sz__, 32, PACKER) \
if (SIZE != __sz__) \
`uvm_error("UVM/UNPACK/AA_INT_SZ", $sformatf("Unpack size '%0d' different from pack size '%0d'", \
SIZE, \
__sz__)) \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_intN(__index__, SIZE, PACKER) \
`uvm_unpack_int(VAR[__index__], PACKER) \
end \
end \
end
//--
`define uvm_pack_aa_object_intN(VAR, SIZE, PACKER=packer) \
begin \
PACKER.pack_field_int(VAR.num(), 32); \
if (VAR.num()) begin \
PACKER.pack_field_int(SIZE, 32); \
foreach(VAR[i]) begin \
`uvm_pack_intN(i, SIZE, PACKER) \
`uvm_pack_object(VAR[i], PACKER) \
end \
end \
end
`define uvm_unpack_aa_object_intN(VAR, SIZE, PACKER=packer) \
begin \
int __num__; \
`uvm_unpack_intN(__num__, 32, PACKER) \
if (__num__ == 0) \
VAR.delete(); \
else begin \
bit[SIZE-1:0] __index__; \
int __sz__; \
`uvm_unpack_intN(__sz__, 32, PACKER) \
if (SIZE != __sz__) \
`uvm_error("UVM/UNPACK/AA_INT_SZ", $sformatf("Size '%d' insufficient to store '%d' bits", \
SIZE, \
__sz__)) \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_intN(__index__, __sz__, PACKER) \
`uvm_unpack_object(VAR[__index__],PACKER) \
end \
end \
end
//--
`define uvm_pack_aa_string_intN(VAR, SIZE, PACKER=packer) \
begin \
PACKER.pack_field_int(VAR.num(), 32); \
if (VAR.num()) begin \
PACKER.pack_field_int(SIZE, 32); \
foreach(VAR[i]) begin \
`uvm_pack_intN(i, SIZE, PACKER) \
`uvm_pack_string(VAR[i], PACKER) \
end \
end \
end
`define uvm_unpack_aa_string_intN(VAR, SIZE, PACKER=packer) \
begin \
int __num__; \
`uvm_unpack_intN(__num__, 32, PACKER) \
if (__num__ == 0) \
VAR.delete(); \
else begin \
bit[SIZE-1:0] __index__; \
int __sz__; \
`uvm_unpack_intN(__sz__, 32, PACKER) \
if (SIZE != __sz__) \
`uvm_error("UVM/UNPACK/AA_INT_SZ", $sformatf("Size '%d' insufficient to store '%d' bits", \
SIZE, \
__sz__)) \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_intN(__index__, __sz__, PACKER) \
`uvm_unpack_string(VAR[__index__], PACKER) \
end \
end \
end
//--
`define uvm_pack_aa_object_string(VAR, PACKER=packer) \
begin \
PACKER.pack_field_int(VAR.num(), 32); \
if (VAR.num()) begin \
foreach(VAR[i]) begin \
`uvm_pack_string(i, PACKER) \
`uvm_pack_object(VAR[i], PACKER) \
end \
end \
end
`define uvm_unpack_aa_object_string(VAR, PACKER=packer) \
begin \
int __num__ = PACKER.unpack_field_int(32); \
if (__num__ == 0) \
VAR.delete(); \
else begin \
string __index__; \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_string(__index__, PACKER) \
`uvm_unpack_object(VAR[__index__], PACKER) \
end \
end \
end
//--
`define uvm_pack_aa_int_string(VAR, PACKER=packer) \
begin \
PACKER.pack_field_int(VAR.num(), 32); \
if (VAR.num()) begin \
foreach(VAR[i]) begin \
`uvm_pack_string(i, PACKER) \
`uvm_pack_int(VAR[i], PACKER) \
end \
end \
end
`define uvm_unpack_aa_int_string(VAR, PACKER=packer) \
begin \
int __num__ = PACKER.unpack_field_int(32); \
if (__num__ == 0) \
VAR.delete(); \
else begin \
string __index__; \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_string(__index__, PACKER) \
`uvm_unpack_int(VAR[__index__], PACKER) \
end \
end \
end
//--
`define uvm_pack_aa_string_string(VAR, PACKER=packer) \
begin \
PACKER.pack_field_int(VAR.num(), 32); \
if (VAR.num()) begin \
foreach(VAR[i]) begin \
`uvm_pack_string(i, PACKER) \
`uvm_pack_string(VAR[i], PACKER) \
end \
end \
end
`define uvm_unpack_aa_string_string(VAR, PACKER=packer) \
begin \
int __num__ = PACKER.unpack_field_int(32); \
if (__num__ == 0) \
VAR.delete(); \
else begin \
string __index__; \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_string(__index__, PACKER) \
`uvm_unpack_string(VAR[__index__], PACKER) \
end \
end \
end
//--
`define uvm_pack_aa_int_enum(VAR, TYPE, PACKER=packer) \
begin \
PACKER.pack_field_int(VAR.num(), 32); \
if (VAR.num()) begin \
foreach(VAR[i]) begin \
`uvm_pack_enum(i, PACKER) \
`uvm_pack_int(VAR[i], PACKER) \
end \
end \
end
`define uvm_unpack_aa_int_enum(VAR, TYPE, PACKER=packer) \
begin \
int __num__ = PACKER.unpack_field_int(32); \
if (__num__ == 0) \
VAR.delete(); \
else begin \
TYPE __index__; \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_enum(__index__, TYPE, PACKER) \
`uvm_unpack_int(VAR[__index__], PACKER) \
end \
end \
end
//--
`define uvm_pack_aa_object_enum(VAR, TYPE, PACKER=packer) \
begin \
PACKER.pack_field_int(VAR.num(), 32); \
if (VAR.num()) begin \
foreach(VAR[i]) begin \
`uvm_pack_enum(i, PACKER) \
`uvm_pack_object(VAR[i], PACKER) \
end \
end \
end
`define uvm_unpack_aa_object_enum(VAR, TYPE, PACKER=packer) \
begin \
int __num__ = PACKER.unpack_field_int(32); \
if (__num__ == 0) \
VAR.delete(); \
else begin \
TYPE __index__; \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_enum(__index__, TYPE, PACKER) \
`uvm_unpack_object(VAR[__index__], PACKER) \
end \
end \
end
//--
`define uvm_pack_aa_string_enum(VAR, TYPE, PACKER=packer) \
begin \
PACKER.pack_field_int(VAR.num(), 32); \
if (VAR.num()) begin \
foreach(VAR[i]) begin \
`uvm_pack_intN(i, SIZE, PACKER) \
`uvm_pack_string(VAR[i], PACKER) \
end \
end \
end
`define uvm_unpack_aa_string_enum(VAR, TYPE, PACKER=packer) \
begin \
int __num__ = PACKER.unpack_field_int(32); \
if (__num__ == 0) \
VAR.delete(); \
else begin \
TYPE __index__; \
for (int __i__ = 0; __i__ < __num__; __i__++) begin \
`uvm_unpack_enum(__index__, TYPE, PACKER) \
`uvm_unpack_string(VAR[__index__], PACKER) \
end \
end \
end
//--
`define uvm_pack_sarray_real(VAR, PACKER=packer) \
foreach(VAR[index]) \
`uvm_pack_real(VAR[index], PACKER)
`define m_uvm_pack_qda_real(VAR, PACKER=packer) \
`uvm_pack_intN(VAR.size(), 32, PACKER) \
`uvm_pack_sarray_real(VAR, PACKER)
`define uvm_pack_queue_real(VAR, PACKER=packer) \
`m_uvm_pack_qda_real(VAR, PACKER)
`define uvm_pack_da_real(VAR, PACKER=packer) \
`m_uvm_pack_qda_real(VAR, PACKER)
`define uvm_unpack_sarray_real(VAR, PACKER=packer) \
foreach(VAR[index]) \
`uvm_unpack_real(VAR[index], PACKER)
`define uvm_unpack_da_real(VAR, PACKER=packer) \
begin \
int tmp_size__; \
`uvm_unpack_intN(tmp_size__, 32, PACKER) \
VAR = new [tmp_size__]; \
`uvm_unpack_sarray_real(VAR, PACKER) \
end
`define uvm_unpack_queue_real(VAR, PACKER=packer) \
begin \
int tmp_size__; \
`uvm_unpack_intN(tmp_size__, 32, PACKER) \
while (VAR.size() > tmp_size__) \
void'(VAR.pop_back()); \
for (int i = 0; i < tmp_size__; i++) \
`uvm_unpack_real(VAR[i], PACKER) \
end
`endif // `ifndef UVM_PACKER_DEFINES_SVH