Subject: RE: Alternative to SvccBindSVcallee/r
From: Kevin Cameron x3251 (Kevin.Cameron@nsc.com)
Date: Tue Nov 19 2002 - 09:35:27 PST
[I forgot to include the reflector when sending this]
> From owner-sv-cc@server.eda.org Tue Nov 12 11:29:14 2002
> From: "Amouroux, John" <john_amouroux@mentorg.com>
>
> Kevin,
>
> This is interesting. I've been thinking of something along these lines too.
> An extension to your idea could be to define a whole structure that gets
> passed in instead of a separate pli handle and context pointer. Then the
> vendors could put in other useful data at compile-time as well (run-time
> would be too slow).
>
> Something like:
>
> typedef struct directc_context_struct
> {
> int context_version /* = 1, to allow for version changes */
> pli_handle pli; /* the pli instance handle */
> char *file_name; /* source file name if HDL caller */
> int line_number; /* source line number */
> void *user_context; /* our beloved user-context pointer */
> } directc_context;
>
> I really don't know if this extra info is useful. My thought is that the
> line number info may be a way to differentiate the places where the directc
> function is called more than once from the same block, as well as allow
> vendors to emit better error messages. But the nicest thing about passing a
> structure is that we can add or change context info without requiring the
> users to change their call site code.
>
> However, the biggest problem I see with this is that if the vendor needs to
> do some elaboration-time initialization to set up the user context data,
> these calls will happen too late, maybe even if they occur within an initial
> block. A complicated way around this would be to always call each and every
> function instance with a special flag at elab-time to allow this
> pre-simulation context set-up.
You can swap your "user_context" pointer to the first field of the struct and
then it overlays my suggestion (if you initialize it to zero).
The reason for not putting the "pli_handle" in the struct but passing it as
the first argument is that the implementation may want to use the ip (instance
pointer) as the PLI handle, and it is likely to be in a register already - also
it is common to all calls so you would be wasting memory.
Line-number could be useful for coverage, if it was only being used for error
reporting I would use a seperate call-back - the ip-handle and the p_cntxt
arguments should be sufficient for the simulator to locate the SV source
line/call-instance (if needed). Since there are possibly multiple calls per
line I would go for:
typedef struct directc_context_struct
{
union {
void *ptr;
int data[2];
double dbl;
} user_context; /* user-context, initialy zero, 64 bits (aligned) */
short context_version; /* = 1, to allow for version changes */
short call_num; /* call on line */
int line_number; /* source line number */
const char *file_name; /* may be null */
} directc_context;
> Another smaller issue is that the C code writer will still have to write
> some type of mapping/hash functions if they want to share one function entry
> point across numerous blocks and still do some instance-specific
> specializations.
>
> My worry is that by the time we do all this, John S's straightforward
> svcBindCallee(r) scheme may actually end up being simpler.
>
> Let's see what the others have to say.
The approach I'm suggesting avoids having to pre-intialize the call, that
simplifies the code but cost marginally in performance since you have to
check on each call for the setup (one test & branch). Calls that are never
made will consume less resource. If we provide an additional mechanism for
locating the user_context slots then you can initialize them if you want
and skip the test - we could add that later, it would look like the svcBind*
calls.
"context_version" could indicate compile time options for extra fields for
supporting coverage & assertions (returned data).
Kev.
> -- John A.
>
> P.S.
> lst_data needs to be static...
No, the only static data is the storage location pointed at by p_cntxt.
> -----Original Message-----
> From: Kevin Cameron x3251 [mailto:Kevin.Cameron@nsc.com]
> Sent: Tuesday, November 12, 2002 10:40 AM
> To: sv-cc@server.eda.org
> Subject: Alternative to SvccBindSVcallee/r
>
> [I don't think this got to the reflector last time I sent it.]
>
> To avoid using a seperate "bind" call, functions requiring context
> can be called as -
>
> <user func name>(<instance handle>,void **c_context,....)
>
> The instance handle can be a PLI handle for call-backs, and c_context
> points at a pointer location in the simulator which is initially zero
> - the user can fill it if desired on the first call for future calls
> (avoids hash-lookup).
>
> e.g.
>
> SV:
> extern "C" context int uf(int);
>
> int x;
>
> always@(clock) x=uf(x);
>
> C:
> int uf(handle ip,void **p_cntxt,int data)
> {
> int *lst_data,
> new_num;
>
> if (!(lst_data = *(int **)p_cntxt)) {
> /* first call only */
> if(!(*p_cntxt = calloc(1,sizeof int)) {
> reportError(ip,"C:uf","Out of memory");
> return -1;
> }
> }
>
> new_num = random_num(*lst_data);
>
> *lst_data = new_num;
>
> return new_num;
> }
>
>
> If you were calling a SystemC class (non-virtual) method it can
> use the ip handle to locate the right "this" on the first call
> and save it in *p_cntxt.
>
> Regards,
> Kev.
----- End Included Message -----
This archive was generated by hypermail 2b28 : Tue Nov 19 2002 - 09:37:55 PST