Subject: [sv-cc] userdata edits for inclusion in LRM v0.8
From: Warmke, Doug (doug_warmke@mentorg.com)
Date: Thu Mar 27 2003 - 12:01:30 PST
Hi Joao,
As promised here is the email that contains the LRM edits
for managing user data. All edits are in Annex A.
Please feel free to paraphrase or make minor edits
in my suggestions. Or add stuff I forgot in my haste
to get done by 3:00pm EST(!)
One thing I feel a little weird about is that lots of
rules, caveats, and limitations regarding user data
are expressed in comments above the functions. This is
as opposed to having some explanatory regular text
in the LRM. You may want to clean this up as you edit,
or in a later draft of the LRM, for clarity.
*****
In section 8.3, and in the Include File section
at the bottom of the Annex, make the following changes:
0) After the introductory paragraph, add the following paragraph:
There are functions that allow the user to retrieve and
manipulate the current operational scope. It is an error
to use these functions with any C code that is not executing
under a call to a DPI context imported function.
There are also functions that provide users with the power to
set data specific to C models into the SystemVerilog simulator
for later retrieval. These are the "put" and "get" user data
functions, which are similar to facilities provided in VPI and PLI.
The put and get user data functions are flexible and allow for
a number of use models. Users may wish to share user data across
multiple context imported functions defined in the same SV scope.
Users may wish to have unique data storage on a per function basis.
Shared or unique data storage is controllable by a user-defined key.
To achieve shared data storage, a related set of context imported
functions should all use the same userKey. To achieve unique data
storage, a context import function should use a unique key. Note
that it is a requirement on the user that such a key be truly
unique from all other keys that could possibly be used by C code.
This includes completely unknown C code that could be running in
the same simulation. It is suggested that taking addresses of
static C symbols (such as a function pointer, or address of some
static C data) always be done for user key generation. Generating
keys based on arbitrary integers is not a safe practice.
Note that it is never possible to share user data storage across
different contexts. For example, if a Verilog module 'm' declares a
context imported function 'f', and 'm' is instantiated more than once
in the SystemVerilog design, then 'f' will execute under different
values of svScope. No such executing instances of 'f' can share
user data with each other, at least not using the system-provided
user data storage area accessible via svPutUserData().
a) Regarding svGetScope():
After today's meeting, it looks like you need to adjust
the comment about returning NULL if called from the
wrong kind of C code. I would suggest:
"The return value is undefined if this function is called
from anywhere other than inside a context import function."
b) Regarding svSetScope():
Mention that NULL is an illegal input value.
I think we should mention that if svSetScope() is called
early in the program's life, such that a previous scope
has never been active yet, the return value will be
undefined.
c) Regarding svGetScopeFromName():
Stipulate that it will return a NULL value for any
unrecognized scopeName argument.
d) Change svPutUserData() as follows:
/* Store an arbitrary user data pointer for later retrieval
by svGetUserData(). The userKey is generated by the user.
It must be guaranteed by the user to be unique from all
other userKey's for all unique data storage requirements.
It is recommended that the address of a static function or
variable in the user's C code be used as the userKey.
It is illegal to pass in NULL values for either the
scope or userData parameters. It is also an error to
call svPutUserData() with an invalid svScope parameter.
This function returns -1 for all error cases, 0 upon success.
It is suggested that userData values of 0 (NULL) not be used,
otherwise it will be impossible to discern error returns
when calling svGetUserData().
*/
int svPutUserData(const svScope scope, void* userKey, void* userData);
e) Change svGetUserData() as follows:
/* Retrieve an arbitrary user data pointer that was previously
stored by a call to svPutUserData(). See the comment above
svPutUserData() for an explanation of userKey, as well as
restrictions on NULL and illegal svScope and userKey values.
This function returns NULL for all error cases, 0 upon success.
This function also returns NULL in the event that a prior call
to svPutUserData() was never made.
*/
void* svGetUserData(const svScope scope, void* userKey);
[NOTE from DOUG: Do we want to use const void* in the above two functions?
I prefer void*, since it is such a universal symbol in C programming.
I'm not even sure if all the typical compiler special support for void*
works if the formal parameter is of type const void*.]
f) Fix comment alignment above svGetCallerInfo().
For A8.4, Example 1, replace the C Side with the following:
// Define the function and model class on the C++ side:
class MyCModel {
private:
int locallyMapped(int portID); // Does something interesting...
public:
// Constructor
MyCModel(const char* instancePath) {
svScope scope = svGetScopeFromName(instancePath);
// Associate "this" with the corresponding SV scope for
// fast retrieval during runtime.
svPutUserData(scope, (void*)MyCFunc, this);
}
friend int MyCFunc(int portID);
};
// Implementation of context import 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 this function's user data stored in SV scope
MyCModel* me = (MyCModel*)svGetUserData(scope, (void*)MyCFunc);
return me->locallyMapped(portID);
}
This archive was generated by hypermail 2b28 : Thu Mar 27 2003 - 12:02:43 PST