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