Subject: Re: DirectC C-Layer: open arrays and abstract access - revised
From: Francoise Martinolle (fm@cadence.com)
Date: Thu Jan 09 2003 - 16:03:28 PST
My comments and question embedded in blue.
At 11:48 AM 1/8/2003 -0500, Andrzej Litwiniuk wrote:
>Team,
>
>Here is the revised/corrected version of the abstract access to open vectors.
>
>Modifications:
> - fixed typos ("U" replaced with "int" in function headers)
> - prefix "svc"
> - redundant functions eliminated (variants of "get pointer")
> - new function "int svcSizeOfArray(svcHandle);"
> - corrected declaration "void foo(input MyType i [][])" in Example 3.
>
>
>Regards,
>Andrzej I. Litwiniuk
>
>
>
> ============================================================
> DirectC C layer - open (unsized) arrays and abstract access
> ============================================================
>
>
>Overview
>========
>
>All open arrays, packed (i.e. vectors) and unpacked (i.e. arrays per se)
>will be passed by handle and accessed mainly via accessory functions (abstract
>access).
>
>Abstract access for open arrays will allow inquires about the dimensions
>and the original boundaries of SV actual argument and will allow to access
>the elements of an open array using the same range of indices as in SV.
>
>The programmer will always have a choice, whether to specify a formal
>argument as a sized array or as an open (unsized) array.
>
>In the former case all indices will be normalized on the C side (i.e. 0
>and up)
>and the programmer is assumed to know the size of an array.
>Programmer is also assumed to be capable of figuring out how the ranges of
>the actual argument will map onto C-style ranges.
>Hint: programmers may decide to stick to [n:0]name[0:k] style ranges in SV.
>
>In the later case, i.e. open array, the abstract access mode will be used,
>what would facilitate SV-style of indexing with the original boundaries of
>the actual argument, all this for the price of some overhead.
>
>Note that this provides some degree of flexibility and allows programmer
>to control the trade-off of performance vs. convenience.
>If a formal argument is specified as a sized array, then it will be passed
>by reference, with no overhead, and will be directly accessible as a normalized
>array.
>If a formal argument is specified as a open (unsized) array, then it will be
>passed by handle, with some overhead, and will be accessible mostly
>indirectly,
>again with some overhead, although with the original boundaries.
>
>
>Unsized formal arguments
>========================
>
>For input, output and inout arguments that are declared as open array,
>the corresponding formal argument in C will be of type svcHandle.
>
>Type svcHandle denotes an opaque pointer to a descriptor generated by SV
>compiler for an actual argument. Descriptor will provide comprehensive
>information about an actual argument. The internal structure of a descriptor
>is implementation dependent and fully irrelevant to the user.
>
>Limitations
>===========
>
>The unpacked part of an open array may be multidimensional.
>The packed part, however, is restricted to a single dimension.
>
>Note that any packed data type in SV is eventually equivalent to
>a one-dimensional packed array. Hence the above limitation is practically
>not restrictive.
>
>Open array querying functions
>=============================
>
>These functions are modelled upon SV array querying functions, with
>the same semantics:
>
>/* h= handle to open array, d=dimension */
>
>/* For unpacked part */
>int svcUnpackedLeft(svcHandle h, int d);
>int svcUnpackedRight(svcHandle h, int d);
>int svcUnpackedLow(svcHandle h, int d);
>int svcUnpackedHigh(svcHandle h, int d);
>int svcUnpackedIncrement(svcHandle h, int d); What does this function do?
>int svcUnpackedLength(svcHandle h, int d); Does this function returns the
>width of a given
>dimension? basically high - low +1?
Did you think about have a single function doing the queries for the entire
open array
and returning the information in a single data structure rather than having
distinct functions?
The reason for this being that the C user code may need it all anyway.
example:
int svcOpenArrayData(svcHandle, svcDim_p dimdata);
where svcDim_p is a pointer to list of structures svcDim describing the
array dimensions
from right most range to left most range. That way there is no limitation
on the topology
of the open array.
struct svcDim{
int high, low, left, right, length;
svcDim_p next;
}
>int svcUnpackedDimensions(svcHandle h);
>
>/* For 1-dimensional packed part */
>int svcPackedLeft(svcHandle h);
>int svcPackedRight(svcHandle h);
>int svcPackedLow(svcHandle h);
>int svcPackedHigh(svcHandle h);
>int svcPackedIncrement(svcHandle h);
>int svcPackedLength(svcHandle h);
I don't see the need for both unpacked and packed queries functions, you
could make it so that if the dimension is 0, then the query could be
relative to the packed range.
>(Would you prefer more intuitive names for 'Unpacked', say, "svcArr*"?)
>
>
>Open array access functions
>=============================
>
>Similarly to sized arrays, there are functions for copying data between
>the simulator representation and the canonical representation.
>
>It will be also possible to get the actual address of SV data object
>or of an individual element of an unpacked array.
>This may be useful for the simulator-specific tuning of the application.
>
>Depending on the type of an element of an unpacked array, different access
>methods are used:
>- packed arrays ('bit' or 'logic') are accessed via copying to or from
> the canonical representation
>- scalars (1-bit value of type 'bit' or 'logic') are accessed directly
>- other types of values (e.g. structures) are accessed via generic pointers;
> a library function calculates an address and the user should provide
> the appropriate casting
>- all types but scalars may be accessed via pointers, as described above
>
>SV allows arbitrary dimensions and hence an arbitrary number of indices.
>To facilitate this, a variable argument list functions will be used.
>For the sake of performance the specialized versions of all indexing
>functions
>are provided for 1, 2 and 3 indices.
>
>
>Access via canonical representation
>-----------------------------------
>
>This group of functions is meant for accessing elements which are packed
>arrays ('bit' or 'logic').
>
>The following functions will copy a single vector from a canonical
>representation to an element of an open array or other way round.
>
>Element of an array is identified by indices bound by the ranges of the
>actual argument. In other words, original SV values are used for indexing.
The other alternative is to use a flat offset to the beginning of the array
rather than the SV
indices. The problem of the offset is that the user must calculate it; this
may be easy
in the case of array of bits and logic but more difficult in the general
array case.
I don't particular disagree with the multiple functions for 1, 2, 3, and
var dimensions,
but I wanted to bring the other alternative.
>/* functions for translation between simulator's and canonical
> representations */
>
>/* s=source, d=destination */
>
>/* actual <-- canonical */
>void svcPutBitArrElemVec32 (svcHandle d, svcBitVec32* s, int indx1, ...);
>void svcPutBitArrElem1Vec32(svcHandle d, svcBitVec32* s, int indx1);
>void svcPutBitArrElem2Vec32(svcHandle d, svcBitVec32* s, int indx1, int
>indx2);
>void svcPutBitArrElem3Vec32(svcHandle d, svcBitVec32* s,
> U indx1, int indx2, int indx3);
>
>void svcPutLogicArrElemVec32 (svcHandle d, svcLogicVec32* s, int indx1, ...);
>void svcPutLogicArrElem1Vec32(svcHandle d, svcLogicVec32* s, int indx1);
>void svcPutLogicArrElem2Vec32(svcHandle d, svcLogicVec32* s, int indx1,
>int indx2);
>void svcPutLogicArrElem3Vec32(svcHandle d, svcLogicVec32* s,
> U indx1, int indx2, int
> indx3);
>
>/* canonical <-- actual */
>void svcGetBitArrElemVec32 (svcBitVec32* d, svcHandle s, int indx1, ...);
>void svcGetBitArrElem1Vec32(svcBitVec32* d, svcHandle s, int indx1);
>void svcGetBitArrElem2Vec32(svcBitVec32* d, svcHandle s, int indx1, int
>indx2);
>void svcGetBitArrElem3Vec32(svcBitVec32* d, svcHandle s,
> U indx1, int indx2, int indx3);
>
>void svcGetLogicArrElemVec32 (svcLogicVec32* d, svcHandle s, int indx1, ...);
>void svcGetLogicArrElem1Vec32(svcLogicVec32* d, svcHandle s, int indx1);
>void svcGetLogicArrElem2Vec32(svcLogicVec32* d, svcHandle s, int indx1,
>int indx2);
>void svcGetLogicArrElem3Vec32(svcLogicVec32* d, svcHandle s,
> U indx1,U indx2, int
> indx3);
>
>The above functions copy the whole array in either direction. User is
>responsible for providing the correct width and for allocating an array in
>the canonical
>representation.
I don't see the width specified as a parameter! Is it missing?
>Access to scalars ('bit' and 'logic')
>-------------------------------------
>
>Another group of functions is needed for scalars (i.e. when an element
>of an array is a simple scalar, 'bit' or 'logic':
You missed some U in this part.
>svcBit svcGetBitArrElem (svcHandle s, int indx1, ...);
>svcBit svcGetBitArrElem (svcHandle s, int indx1);
>svcBit svcGetBitArrElem (svcHandle s, int indx1, int indx2);
>svcBit svcGetBitArrElem (svcHandle s, int indx1,U indx2, int indx3);
>
>svcLogic svcGetLogicArrElem(svcHandle s, int indx1, ...);
>svcLogic svcGetLogicArrElem(svcHandle s, int indx1);
>svcLogic svcGetLogicArrElem(svcHandle s, int indx1, int indx2);
>svcLogic svcGetLogicArrElem(svcHandle s, int indx1,U indx2, int indx3);
>
>void svcPutLogicArrElem(svcHandle d, svcBit value, int indx1, ...);
>void svcPutLogicArrElem(svcHandle d, svcBit value, int indx1);
>void svcPutLogicArrElem(svcHandle d, svcBit value, int indx1, int indx2);
>void svcPutLogicArrElem(svcHandle d, svcBit value, int indx1,U indx2,
>int indx3);
>
>void svcPutBitArrElem (svcHandle d, svcLogic value, int indx1, ...);
>void svcPutBitArrElem (svcHandle d, svcLogic value, int indx1);
>void svcPutBitArrElem (svcHandle d, svcLogic value, int indx1, int indx2);
>void svcPutBitArrElem (svcHandle d, svcLogic value, int indx1,U indx2,
>int indx3);
>
>
>Access to the actual representation
>-----------------------------------
>
>The following functions provide an actual address of the whole array or
>of its individual element. These functions will be used for accessing
>elements of the arrays of types compatible with C.
>
>These functions will be also usefull for the vendors, because
>they provide access to the actual representation for all types of arrays.
>
>/* a pointer to the actual representation of the whole array of any type */
>void *svcGetArrayPtr(svcHandle);
>
>Note that no specific representation of an array is assumed here, hence
>a generic pointer void *.
How do you use the generic pointer void * which is returned. How do you
traverse the
actual representation?
Let's assume that we have an open array of SV unpacked structures ? How do
I retrieve the value of one element of that array?
>int svcSizeOfArray(svcHandle); /* total size in bytes */
How is the size function useful?
>/* Return a pointer to an element of the array
> or NULL if index outside the range or null pointer */
>
>void *svcGetArrElemPtr(svcHandle, int indx1, ...);
>
> /* specialized versions for 1-, 2- and 3-dimensional arrays: */
>void *svcGetArrElemPtr1(svcHandle, int indx1);
>void *svcGetArrElemPtr2(svcHandle, int indx1, int indx2);
>void *svcGetArrElemPtr3(svcHandle, int indx1, int indx2, int indx3);
>
>
>Access to array elements of other types
>---------------------------------------
>
>If array's elements are of a type compatible with C, then there is no need
>to use the canonical representation. In such situations the elements will
>be accessed via pointers, i.e. the actual address of an element will be
>computed first and then used to access the desired element.
>
>
>Example 3 - open array,
>======================
>
>SV:
> typedef struct {int i; ... } MyType;
>
> extern void foo(input MyType i [][]);
> // 2-dimensional unsized unpacked array of MyType
>
> MyType a_10x5 [11:20][6:2];
> MyType a_64x8 [64:1][-1:-8];
>
> foo(a_10x5);
> foo(a_64x8);
>
>
>C:
> #include "svcerilog.h"
>
> typedef struct {int i; ... } MyType;
>
> void foo(svcHandle h)
> {
> MyType my_value;
> int i, j;
> int lo1 = svcUnpackedLow(h, 1);
> int hi1 = svcUnpackedHigh(h, 1);
> int lo2 = svcUnpackedLow(h, 2);
> int hi2 = svcUnpackedHigh(h, 2);
>
> for (i = lo1; i <= hi1; i++) {
> for (j = lo2; j <= hi2; j++) {
>
> my_value = *(MyType *)svcGetArrElemPtr2(h, i, j);
> ...
> *(MyType *)svcGetArrElemPtr2(h, i, j) = my_value;
> ...
> }
> ...
> }
> }
>
>
>
>
>==============================================================================
>Andrzej I. Litwiniuk, PhD Principal Engineer VCS R&D
>Synopsys, Inc TEL: (508) 263-8056
>154 Crane Meadow Road, Suite 300, FAX: (508) 263-8069
>Marlboro, MA 01752, USA
>==============================================================================
This archive was generated by hypermail 2b28 : Thu Jan 09 2003 - 16:04:21 PST