Re: DirectC C layer - open arrays and portability


Subject: Re: DirectC C layer - open arrays and portability
From: Kevin Cameron x3251 (Kevin.Cameron@nsc.com)
Date: Wed Jan 15 2003 - 09:40:27 PST


> From Andrzej.Litwiniuk@synopsys.com Tue Jan 14 18:37:33 2003
>
> Kevin's comments followed by my answers or comments.
>
> Andrzej

And mine again...

> > > 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));
> > > */
> > >
> > KEVIN:
> > That's OK except you probably need a additional call to indicate data
> > has changed, but..
>
> Nope. SV side must assume for each output or inout argument, that the value
> may change and is responsible for detecting such a change.

We discussed that before, it's extremely inefficient to keep copies of data
so that you can tell what changed. There should be a mechanism to inform the
simulator if there is a change.
 
>
> > > } 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++);
> >
> > KEVIN:
> > You can't do that without knowing the size/layout of MyType,
>
> You are absolutely right. That's why C code in this example contains
> the definition of the structure MyType.
>
>
>
> > it is therefore
> > not vendor independent. You cannot dereference a vendor specific type in
> > the user code and have it be portable.
>
> Right. So in the worst case scenario the above code will be only source-level
> compatible, cf. example 2.
> Note however, that this may happen only when SV specific types are mixed with
> C compatible types, e.g. when packed arrays are embedded in structures.
> When types are not mixed yet vendor specific types are used (packed arrays),
> portability (i.e. binary level compatibility) may be achieved by using
> the canonical representation.
> See the following example (derived from example 4):

If the API is to be portable there should be no definition of MyType. That
code would only work if all simulators have the same size for MyType, if
one simulator happens to use a smaller size and contiguous elements, the
writes will overlap and corrupt data.

> SV:
> extern void foo(input bit [63:0] i [], output bit [63:0] o []);
>
> bit [63:0] source [11:20];
> bit [63:0] target [11:20];
>
> foo(source, target);
>
>
> C:
> #include "svc_bin.h"
>
> void foo(const svHandle hin, svHandle hout)
> {
> svBitVec32 arr[VEC32_NEEDED(64)]; /* canonical repr. */
>
> int i = svLow(hin, 1);
> int j = svLow(hout, 1);
>
> while (i <= svHigh(hin, 1)) {
> svGetBitArrElem1Vec32(arr, hin, i++);
> svPutBitArrElem1Vec32(hout, arr, j++);
> }
> }
>
>
> > KEVIN:
> > 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++);
>
> Instead of that, I may go thru canonical representation, as in the example
> above.

Like I said above, you can't use the canonical form unless the data is the
same size in all simulators.
 
> > KEVIN:
> > 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.:
>
> - unless the size is statically known.
>

But you can't know that in an implementation independent manner unless you
are doing a copy-in/copy-out to realign the data.

>
> > KEVIN:
> >
> > 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.

Kev.



This archive was generated by hypermail 2b28 : Wed Jan 15 2003 - 09:41:08 PST