Subject: Re: DirectC: C Layer - another revision
From: Andrzej Litwiniuk (Andrzej.Litwiniuk@synopsys.com)
Date: Thu Jan 16 2003 - 09:20:13 PST
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.
> 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.
> 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?)
'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 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 - 09:21:03 PST