Subject: RE: DirectC: C Layer - another revision
From: Warmke, Doug (doug_warmke@mentorg.com)
Date: Thu Jan 16 2003 - 10:12:37 PST
Andrzej,
Thanks for the clarifications.
Now I understand things much better.
Please see below for some more suggestions.
This is starting to take great shape now.
Regards,
Doug
> -----Original Message-----
> From: Andrzej Litwiniuk [mailto:Andrzej.Litwiniuk@synopsys.com]
> Sent: Thursday, January 16, 2003 9:20 AM
> To: Warmke, Doug
> Cc: sv-cc@eda.org
> Subject: Re: DirectC: C Layer - another revision
>
>
> Doug,
>
> Thanks for your comments. My answers embedded after the
> relevant excerpts.
>
> Andrzej
>
>
>
> > DOUG:
> > There is one other thing that may seem obvious to many of us, but
> > perhaps needs to be added to the LRM text for clarity.
> >
> > That is, there are actually 3 places at which arguments
> appear. (Let's
> > only consider SV-calls-C for simplicity of discussion - same should
> > apply to the other direction.)
> >
> > 1) The C code
> > 2) The declaration site of the external function
> > 3) The call site(s) of the external function
>
> Please recall that the principle "What You Specify Is What
> You Get" guarantees the types (including sizes) of formal
> arguments of external functions for all types but open arrays.
>
> The declaration site (SV) of the external function is
> relevant for all
> the formal arguments but the open arrays.
>
> The call site(s) of the external function is relevant solely
> for the formal
> arguments specified as open arrays.
>
> To be exact, the unsized ranges of open arrays are determined
> at a call site,
> the rest of type information is specified at the external
> declaration. So, if a formal argument is declared as 'bit
> [15:8] b []', then it is the external declaration that
> specifies that formal argument is an unpacked array of packed
> bit array with bounds 15 to 8, while the actual argument used
> at a particular call site defines the bounds for the unpacked
> part for that particular call.
>
> The formal arguments other than open arrays are assumed to
> have sizes as
> specified in the external declaration. The formal arguments
> defined as open
> arrays have the size of the actual arguments.
DOUG: The description you give here is excellent.
You could probably copy it verbatim into your spec.
>
>
> > When you talk about lining up SV l and r bounds with C indexing, I
> > believe that you are referring to the l and r bounds of the
> argument
> > at the declaration site of the external function in SV.
>
> yes, for all arguments but the open arrays
>
> > *Not* the l and r bounds of the actual argument at the call site.
>
> Wrong. In the case of an open array the l and r bounds of the
> =actual= argument
> at the call site are referred to as SV bounds.
DOUG: Yes, understood after your above description.
>
>
>
> > Normal SV rules would apply for mapping call site actual arguments
> > onto the formal arguments at the declaration site.
>
> Yes, but again: for all arguments but open arrays. Actual
> arguments for open arrays are passed as they are.
>
> > Please let me know if my understanding is correct, and if it is,
> > please add such a clarification paragraph somewhere in the intro
> > sections of your document.
>
> Sure, I'll try to add some clarification.
>
>
>
> > > For sized arrays normalized ranges are assumed.
> > > Normalized ranges mean [n-1:0] indexing for the packed part,
> > > and [0:n-1] indexing for the unpacked part of an array.
> > > Therefore a packed array of range [l:r] will be normalized as
> > > [abs(l-r):0], its most significant bit will have a normalized
> > > index abs(l-r), and its least significant bit will have a
> > > normalized index 0.
> > >
> >
> > DOUG: Here is my suggestion for clarification:
> > "Note that the above range mapping from SV to C applies
> > to calls made in both directions, i.e. SV-calls-C and C-calls-SV."
>
> Yes. Thanks.
>
>
> > > "svc_bin.h"
> > > =================
> > >
> > > typedef unsigned int
> > > svBitVec32; /* (a chunk of) packed bit array */
> > >
> > > typedef struct { unsigned int c; unsigned int d;} /* as in VCS */
> > > svLogicVec32; /* (a chunk of) packed logic array */
> > >
> > > /* reference to a standalone packed array */
> > > typedef void* svBitPackedArr;
> > > typedef void* svLogicPackedArr;
> > >
> > > /* functions for translation between simulator's and
> > > canonical representations */
> > >
> > > /* s=source, d=destination, w=width */
> > >
> > > /* actual <-- canonical */
> > > void svPutBitVec32 (svBitPackedArr d, const svBitVec32*
> > > s, int w);
> > > void svPutLogicVec32 (svLogicPackedArr d, const svLogicVec32*
> > > s, int w);
> >
> > DOUG: I can't understand why the svBitPackedArr and
> svLogicPackedArr
> > are not pointer types. Take svBitPackedArr as an example. It is
> > typedef'd to "int".
>
>
> Doug, I guess you must have confused the two definitions, of
> 'svBitPackedArr' and 'svBitVec32'.
> (Does it mean that other users may be equally easy confused
> and we should look for better and less confusing names?)
DOUG: The thing I missed out on is the "typedef to void*" for
those two Arr variables. You are absolutely right. I quickly
looked up the file and saw the typedef's to unsigned int
and the struct with c and d members, then assumed that those
typedefs applied to the Arr's. I should have been more careful,
sorry about that. All comments down the mail are withdrawn!
One thing you might want to think about regarding the name:
At the function declaration site, it is not obvious that
svBitPackedArr and svLogicPackedArr are pointer types.
Neither is it obvious that those are "handle" types.
There are two ways I can think of to clarify this:
1) Change the typedef as follows:
typedef void svBitPackedArr;
typedef void svLogicPackedArr;
Then you could use the * syntax in the function declarations
to make it clear that those are pointer types.
void svPutBitVec32 (svBitPackedArr* d, const svBitVec32* s, int
w);
void svPutLogicVec32 (svLogicPackedArr* d, const svLogicVec32* s, int
w);
The following way is better in my opinion:
2) Change the names of the "Arr" types to have the string "Handle" in
them.
i.e.
typedef void* svBitPackedArrHandle;
typedef void* svLogicPackedArrHandle;
That way the "handle" nature of these API's is clear.
>
> 'svBitVec32' is defined as int, but this is a canonical
> representation of 2-state value.
>
> 'svBitPackedArr' is actually a pointer, typedef'd to "void".
> Similarly, 'svLogicPackedArr' is a pointer, typedef'd to "void".
>
> 'svBitPackedArr' and 'svLogicPackedArr' are opaque pointers
> to the simulator
> specific representation of packed arrays.
>
>
>
> > These functions are intended to work on only one "chunk"
> > of the canonical representation at a time. (We should add
> > a note to that effect in a comment above them).
>
> Nope. These functions are intended to work on the whole
> packed array, not just
> a single chunk at a time.
>
>
> > Now, since
> > the "d" argument of svPutBitVec32 is not a pointer type, how is the
> > caller of the function supposed to get the result? The function
> > returns void and the d argument is a C "input" parameter, passed by
> > value.
>
> "d" argument of svPutBitVec32 =is= a pointer type.
> I believe everything is ok and you just got misled by the
> similarity of the two type names.
>
>
> > > /* functions for bit-select */
> > > /* s=source, d=destination, i=bit-index */
> > >
> > > svScalar svGetSelectBit(const svBitPackedArr s, int i);
> > > svScalar svGetSelectLogic(const svLogicPackedArr s, int i);
> > >
> > > void svPutSelectBit(svBitPackedArr d, int i, scalar s); void
> > > svPutSelectLogic(svLogicPackedArr d, int i, scalar s);
> >
> > DOUG: Same point on how the user should access the results
> > of these functions if d is not passed as a pointer type.
>
> Same explanaition as above: d is a pointer.
>
>
> > > void svPutPartSelectBit(svBitPackedArr d, const
> > > svBitPackedArr s, int i, int w); void
> > > svPutPartSelectLogic(svLogicPackedArr d, const
> > > svLogicPackedArr s, int i, int w);
> >
> > DOUG: Same basic issues on visibility of function result.
>
>
> Same explanaition as previously: d is a pointer.
>
>
>
>
> > > SV:
> > > typedef struct {int a; int b;} pair;
> > > extern void foo(input int i1, pair i2, output logic [63:0] o3);
> > >
> > > C:
> > > #include "svc_bin.h"
> > >
> > > typedef struct {int a; int b;} pair;
> > >
> > > extern void exported_sv_func(int, int *); /* imported from SV */
> > >
> > > void foo(const int i1, const pair *i2, svLogicPackedArr o3)
> >
> > DOUG: The o3 argument is passed by value into C.
>
> o3 is a pointer. So the actual argument (i.e. a packed array)
> is passed
> by a reference.
>
>
> > Thus how can it be changed by the C code?
> > It seems like it should be passed by reference, i.e. as a pointer.
>
> Right. And it is.
>
>
>
> > > {
> > > svLogicVec32 arr[VEC32_NEEDED(64)]; /* 2 chunks needed */
> > > int tab[8];
> > >
> > > printf("%d\n", i1);
> > > arr[1].c = i2->a;
> > > arr[1].d = 0;
> > > arr[2].c = i2->b;
> > > arr[2].d = 0;
> > > svPutLogicVec32 (o3, arr, 64);
> >
> > DOUG: Once again, this function's signature has the d
> argument passed
> > by value. Even if o3 above is a pointer, how could this function
> > influence its value?
>
> d is a pointer.
>
> > In order to really make clear the use of indexing from the
> C side to
> > SV side, I would suggest complicating the o output type with a
> > 1-dimensioned packed part and a 1-dimensioned unpacked part. That
DOUG: Actually I mis-typed here. I meant to type a 2-dimensioned
unpacked part. (Since you have a 2-dimensional packed part in another
example, and it would be good to demonstrate the handling of multi-d
in both the packed and unpacked parts of arrays)
> > would give more clarity to the indexing rules described in
> the intro
> > part of the document.
>
>
> Good idea.
>
>
This archive was generated by hypermail 2b28 : Thu Jan 16 2003 - 10:13:17 PST