Re: Alternative to SvccBindSVcallee/r


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