Subject: Re: Alternative to SvccBindSVcallee/r
From: Kevin Cameron x3251 (Kevin.Cameron@nsc.com)
Date: Tue Nov 19 2002 - 09:36:56 PST
[forgot to send this to the reflector]
> From owner-sv-cc@server.eda.org Tue Nov 12 15:19:53 2002
>
> Johnny, Kevin,
>
> How would this kind of proposal work for calls
> heading in the other direction, e.g. C-calling-SV?
>
> Thanks and regards,
> Doug
It doesn't address that. Calling C from SV is relatively simple
because C has a well defined calling interface and a common (cross
compiler) model for how structures are laid out in memory, the
linker ties up the SV call with C code by name since there is only
one version of the C code.
For the reverse call (avoiding C++) I would tend towards using a PLI
like call to get a pointer to the SV function in a manner similar to
svcBindCallee, e.g.:
C:
typedef int (*svcFunc)(handle pli_inst,...);
svcFunc svcGetFunc(const char *,const char *,...);
...
static svcFunc top_u1_foo;
static handle top_u1_pli;
...
/* find instance */
top_u1_pli = findInst("top.u1");
/* get task pointer */
top_u1_foo = svcGetFunc(top_u1_pli,"foo",
"integer" /* argument types */,
0);
/* call SV task */
(*top_u1_foo)(top_u1_pli,0xFF);
SV:
export u::foo; // create a C entry point for task foo in module u
...
module u;
task foo (input d);
integer d;
....
endtask
I don't think the C needs to pass a context to the SV since the caller
can save its context in the C environment for subsequent calls back
from SV - the call-stack/thread should be the same - and the SV instance
can save context.
svcGetFunc can use the strings it gets handed to trawl through the DLLs
to find a matching routine in a vendor-specific manner, or generate
an entry-point on-the-fly.
Note: I used the "::" syntax to mirror the C++ <class>::<method> syntax
for referencing the task outside of its module. That implies all instances
are affected; I'd suggest leaving finer control to vendors tools for 3.1.
$root tasks/functions would be available through svcGetFunc with a null
handle.
Kev.
> Amouroux, John wrote:
> > 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.
> >
> > 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.
> >
> > -- John A.
> >
> > P.S.
> > lst_data needs to be static...
> >
> > -----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:25 PST