Re: [sv-cc] LRM modifications for svGet/PutUserData proposal


Subject: Re: [sv-cc] LRM modifications for svGet/PutUserData proposal
From: Stickley, John (john_stickley@mentorg.com)
Date: Tue Mar 25 2003 - 22:21:52 PST


Doug,

Warmke, Doug wrote:
> Hi John,
>
> Real nice work hammering out a compromise here.
> I have a couple of corrections to make in the example.
> Please see below.
>
> Regards,
> Doug
>
> > -----Original Message-----
> > From: Stickley, John
> > Sent: Tuesday, March 25, 2003 2:07 PM
> > To: sv-cc@server.eda.org
> > Subject: [sv-cc] LRM modifications for svGet/PutUserData proposal
> >
> >
> > Team,
> >
> > In the interest of expediency and ease of insertion, I've
> > tried to frame Francoise's proposal in the form that can
> > be inserted directly into Joao's draft of the LRM.
> >
> > Note to Joao: There are a number of errors in the example
> > in section A.8.4. Please supersede with my version where those
> > errors have been corrected (and where the new get/putUserData()
> > usage is demonstrated). Also, what is missing is an
> > example of invoking an exported function after setting
> > svPutScope(). I can provide an extension to the existing
> > example that shows this if you wish.
> >
> > Here are the required updates to the LRM.
> >
> > ---------------------- cut here ----------------------
> >
> > A.8.3 Working with DPI context functions in C code
> >
> > [...]
> >
> > /* Return a unique ID that can be used as a key to store user
> > data in a given module scope. */
> > int svGetUserDataIdForScope(const svScope scope);
> >
> > /* Set arbitrary user data pointer into specified instance scope */
> > void svPutUserData(const svScope scope, int userDataId, void*
> > userData);
> >
> > /* Retrieve arbitrary user data from specified instance scope */
> > void* svGetUserData(const svScope scope, int userDataId );
> >
> > [...]
> >
> > New section
> > | | | | |
> > V V V V V
> >
> > A.8.3.1 Associating User Data with Module Contexts
> >
> > The DPI allows association of multiple user defined data
> > pointers with module instances by allocating unique ID's
> > that can serve has keys to identify each distinct user
> > data pointer to be associated with a given module instance.
> >
> > The user data pointer is of type void * and is never
> > interpreted by the SV infrastructure - only by the user
> > application.
> >
> > The svGetUserDataIdForScope() function can be called at
> > initialization time to request unique IDs that can be
> > used to identify user data pointers to be associated
> > with a given module scope.
> >
> > The returned ID can be stored in a place known to the
> > C code (most likely a static or global variable) and
> > later be frequently referenced during run-time when
> > svGetUserData() is called to retrieve user data
> > pointers inside imported C functions that are called
> > from SystemVerilog.
> >
> > The functions svPutUserData() and svGetuserData() each
> > require a module scope handle and a user data ID argument.
> >
> > ID=0 is reserved to denote the NULL or invalid ID. This
> > allows a variable used to store an ID to be conveniently
> > tested for validity.
> >
> > A.8.4 Example 1 - Using DPI context functions
> >
> > SV Side:
> >
> > [...]
> >
> > C Side:
>
> DOUG: [Admittedly minor nitpick]
> We should use consistent whitespace here.
> The examples all use K&R whitespace, such as
> if (condition) {
> doSomething();
> }
>
> In this code, there are a few tidbits like:
> if( condition ){
> doSomething();
> }
>
> Let's clean those up in the LRM so all is consistent.

johnS:
No problem - I can fix this. Hard to break old habits !

>
> >
> > // Define the function and model class on the C++ side:
> > class MyCModel {
> > private:
> > static int dUserDataId;
> > int locallyMapped(int portID); // Does something
> > interesting...
> >
> > public:
> > // Constructor
> > MyCModel(const char* instancePath) {
> > svScope scope = svGetScopeByName(instancePath);
> >
> > // Allocate a unique ID to be used as key to associate
> > // user data with module scope. Skip this step if ID
> > // has already been assigned.
> > if( dUserDataId != 0 )
> > dUserDataId = svGetUserDataIdForScope( scope );
> >
> > // Associate "this" with SV scope (avoids a hash in C++
> code)
> > svPutUserData(scope, this);
> DOUG: You forgot to use the new second argument to this function.
> Should be:
> svPutUserData(scope, dUserDataId, this);

johnS:
You are right. Thank-you.

>
> Further, I'm not exactly clear on why you are using the static class
> member rather than a normal class member. It doesn't seem to be
> reasonable, considering that this is not a static class. If there
> is more than one instance of this class, the different constructors
> will overwrite each other's user data with different "this" pointers.
> The final constructed class instance will dominate the others.
>

johnS:
Your confusion is certainly justified and is the key reason
I still am not completely comfortable with this interface
- mainly because I think users will be equally confused about
the subtlety of the requirement for static storage of the user ID.

So let me try to explain. The ID itself cannot be stored in
the user's instance of the C model. This is because the ID
must be used inside an imported function to fetch the
user's C model instance in the first place (using svGetUserData()).

The thing probably causing most of your confusion however
is that there's a flaw in passing the svScope into
svGetUserDataIdForScope().

I just sent out an e-mail explaining that this function needs
to take moduleName rather than scope handle. This allows
you to obtain a single unique ID that is usable with *all*
instances of that module.

Which leads to the issue of why a static is used. By storing
the ID as a static in the C model, the imported function
can fetch the access ID before actually having the C model
(a.k.a. user data) pointer. This is why static storage is
required here.

It works but I fear it is non-intuitive. However, it does
addess Andrzej's and Joao's concern about the overhead of
having to set up a current function scope object each time
an imported function is called which my proposal of
yesterday would have required. With the ID scheme you avoid
this. The only thing that has to be set up is the current
module scope.

> Please see if you think I have misunderstood something, and if not,
> please double-check your intentions. If you do intend to demonstrate
> using static class data to represent a "shared user data", then I
> think the comments or text surrounding the example should express
> the intention in English language.
>
> Other than this confusion (quite possibly my own!), great job here.
>
> Regards,
> Doug
>
> > }
> >
> > friend int MyCFunc(int portID);
> > };
> >
> > int MyCModel::dUserDataId = 0;
> >
> > // Implementation of external context function callable in SV
> > int MyCFunc(int portID) {
> > // Retrieve SV module instance scope (i.e. this function's
> context).
> > svScope scope = svGetScope();
> >
> > // Retrieve and make use of user data stored in SV scope
> > MyCModel* me = (MyCModel*)svGetUserData( scope, dUserDataId );
> >
> > return me->locallyMapped(portID);
> > }
> >
> >
                                                            __
                        ______ | \
______________________/ \__ / \
                                 \ H Dome ___/ |
John Stickley E | a __ ___/ / \____
Principal Engineer l | l | \ /
Verification Solutions Group | f | \/ ____
Mentor Graphics Corp. - MED C \ -- / /
17 E. Cedar Place a \ __/ / /
Ramsey, NJ 07446 p | / ___/
                                  | / /
mailto:John_Stickley@mentor.com \ /
Phone: (201)818-2585 \ /
                                    ---------



This archive was generated by hypermail 2b28 : Tue Mar 25 2003 - 22:24:01 PST