Re: DirectC C layer - open arrays and portability - PLEASE READ


Subject: Re: DirectC C layer - open arrays and portability - PLEASE READ
From: Kevin Cameron (Kevin.Cameron@nsc.com)
Date: Tue Jan 14 2003 - 10:31:18 PST


Andrzej Litwiniuk wrote:

> Team,
>
> In the revised version of the C Layer I tried to address Kevin's concerns with the representation of arrays.
> The solution that I came to may be a bit controversial, so I ask you to analyze it kindly.
>
> For your convenience here are the relevant pieces extracted from the doc.
>
> Andrzej
>
> ============================================
>
> Representation of the data
> --------------------------
>
> The following is assumed about the representation of SV data:
>
> a) representation of packed types is implementation dependent
>
> b) basic integer and real data types are represented as defined in LRM 3.3,
> 3.4.2, see also "Data type mapping" below.
>
> c) layout of unpacked structures is same as used by C compiler (LRM 3.7)
>
> d) layout of sized unpacked arrays is same as used by C compiler;
> this includes arrays embedded in structures and the standalone arrays
> (i.e. not embedded in any structure)
>
> Note that this is a restriction imposed on the SV side of the interface!
> Depending on the implementation, a particular array may or may be not
> accepted as an actual argument for the formal argument which is a sized
> array (it will be always accepted for unsized array).
>
> e) layout of the unsized (aka open) standalone unpacked arrays
> is implementation dependent with the following restriction:
> an element of an array must have the same representation as
> individual a value of the same type, with the exception of scalars
> (bit or logic) and packed arrays as a type of an element.
> Hence array's elements other than scalars or packed arrays can be
> accessed via pointers similarly to individual values.
>
> Note that d) actually does not impose any restrictions on how unpacked arrays
> are implemented; it says only that an array that does not satisfy d)
> may not be passed as an actual argument for the formal argument which is
> a sized array; it may be passed, however, for unsized array.
> Therefore, the correctness of an actual argument may be implementation
> dependent. Nevertheless an open array provides implementation independent
> solution. This seems to be a reasonable trade-off.
>
> 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.
>
> If the actual layout of the SV array passed as an argument for an open unpacked
> array is different than C layout, then it will not be posssible to access such
> array as a whole and therefore the address and size of such array will be
> undefined (zero, to be exact).
> Nonetheless the adresses of individual elements of an array will be always
> supported.
>
> /* a pointer to the actual representation of the whole array of any type */
> /* NULL if not in C layout */
> void *svGetArrayPtr(svHandle);
>
> int svSizeOfArray(svHandle); /* total size in bytes or 0 if not in C layout */
>
> Example 4 - open array
> ======================
>
> SV:
> typedef struct { ... } MyType;
>
> extern void foo(input MyType i [], output MyType o []);
>
> MyType source [11:20];
> MyType target [11:20];
>
> foo(source, target);
>
> C:
> #include "svc_bin.h"
>
> typedef struct ... } MyType;
>
> void foo(svHandle hin, svHandle hout)
> {
> int count = svUnpackedLength(hin, 1);
> MyType *s = (MyType *)svGetArrayPtr(hin);
> MyType *d = (MyType *)svGetArrayPtr(hout);
>
> if (s && d) { /* both arrays have C layout */
>
> /* an efficient solution using poiter arithmetics */
> while (count--)
> *d++ = *s++;
>
> /* even more efficient:
> memcpy(d, s, svSizeOfArray(hin));
> */
>

That's OK except you probably need a additional call to indicate data
has changed, but..

>
> } else { /* less efficient yet implementation independent */
>
> int i = svUnpackedLow(hin, 1);
> int j = svUnpackedLow(hout, 1);
> while (i <= svUnpackedHigh(hin, 1)) {
> *(MyType *)svGetArrElemPtr1(hout, j++) =
> *(MyType *)svGetArrElemPtr1(hin, i++);

You can't do that without knowing the size/layout of MyType, it is therefore
not vendor independent. You cannot dereference a vendor specific type in
the user code and have it be portable. You need to return a void pointer/handle
and pass it back for the assignment e.g.:

                    void *ptr = svGetArrElemPtr1(hout, j++);
                    svPutArrElemPtr1(ptr,hin, i++);

If you want to keep copies of data in user space you need to know the size of
the item and/or use malloc/free e.g.:

                    char buff[svSizeOfArrElem1(hout)]; // GNU C
                    bcopy(svGetArrElemPtr1(hout, j++),buff,sizeof(buff));
                    svPutArrElemPtr1(ptr,hin, i++);
            or:
                    void *ptr = svGetCopyArrElemPtr1(hout, j++);
                    svPutArrElemPtr1(ptr,hin, i++);
                    svFree(ptr);

NB: One simulator may have multiple ways of storing the same data.

Kev.

--
National Semiconductor, Tel: (408) 721 3251
2900 Semiconductor Drive, Mail Stop D3-500, Santa Clara, CA 95052-8090



This archive was generated by hypermail 2b28 : Tue Jan 14 2003 - 10:31:18 PST