Subject: RE: More on ISSUE 1.7, More on Context Sensitivity Proposals
From: Warmke, Doug (doug_warmke@mentorg.com)
Date: Thu Nov 28 2002 - 10:07:43 PST
John,
You've really dug into some details with your example here.
That's a good thing - nice example.
There are a couple of major issues your example brings to
light that we should discuss independently of this precise topic:
1) Allocation of array and other complex types
2) Layout of array and other complex types
Your example shows an API function called sv_create_array().
This connotes several things to me, such as involvement of the heap,
memory ownership issues, longevity, etc.
I understood from the comments of others in the group that we
wanted to have well understood memory "C layouts" for all SV types.
The compiler or runtime system would be responsible for transforming
those "C layouts" into whatever internal SV representation is used
by that implementation.
The difficulty with this approach occurs with arrays. The "C layout"
for an SV array will be some contiguous storage. If we don't know
how many dimensionss are in the array, and the bounds of each
dimension, there would be no way on the C side to read the
memory layout. Thus, at least three API functions are needed:
int sv_getNumDimensions(arrayHandle);
int sv_getDimensionHiBound(arrayHandle, dimensionNumber);
int sv_getDimsnsionLoBound(arrayHandle, dimensionNumber);
Names subject to cleanup and change, of course.
Better yet, as someone proposed, just use PLI/VPI equivalents
to do this job. Since the idea of dimensioned arrays doesn't
exist yet in PLI/VPI, we should look at adding to those standards
appropriately. (Should be a very constrained modification for now!)
No other SV types have this problem. I would argue that if we do
define C layouts for all SV types, no further special API functions
would need to be generated.
To continue, I would propose changing your example code such that
the C side completely owns the memory for the input array argument
of MySvModule::MySvFunction. C would allocate it and initialize
it how it sees fit. Of course, the C layout conventions would have
to be followed in a way that matches the SV declarations.
Looking forward to hearing other people's inputs on this train of thought.
The results of this discussion will have a large impact on the C side
of our work.
Thanks and regards,
Doug
-----Original Message-----
From: Stickley, John
Sent: Monday, November 25, 2002 9:30 PM
To: sv-cc@server.eda.org
Cc: Michael.Rohleder@motorola.com; Warmke, Doug
Subject: Re: More on ISSUE 1.7, More on Context Sensitivity Proposals
Team,
Michael Rohleder wrote:
Hello Doug,
also thanks a lot for this clarification. I think I have to agree about most
points. My feeling is still that some check/debug mode can be rather useful,
but you are fully correct by pointing out that this can/should be invisible
to the user. As such, it is something that _should_not_ be in the LRM.
From that perspective, any option that is invisible to the user is possible
and acceptable.
I think, I have to admit, you beat me with my own weapons.
Thanks again, this was a very important point.
Regards,
Michael
I also agree with Michael that Doug put things in a good perspective with
his e-mail.
With Solution 3) Can We Remove "A" | "C" ?
I'm not too keen on always requiring pre-processed wrapper macros or
other cumbersome functions if all the user wants to do is fetch values of
simple
scalar data types.
The main purpose of abstract access should be only for access of more
complex
abstract data types as Doug described in solution 3) of in his e-mail.
Simple
scalar direct types should be accessed directly (hence the name !) for all
reasons
stated by Doug below.
And as Michael pointed out, the debug/error check handling should be
considered
orthogonal to the access mechanism by making it a transparent run-time
option.
A corrollary to this then, is that we can probably get rid of the "A" | "C"
specifiers in both the extern and the export declarations.
Outcome of ISSUE 1.7 Affects Context Sensitivity Proposal
I'm particularly interested in the outcome of this issue because I believe
it also ultimately affects the outcome of the context sensitivity issue that
Kevin, Joao, and I have been discussing.
The way I see it is that the whole difference between whether we can
go with a simple static context binding approach as described in my
proposal, or a more complex dynamic binding approach as described
in Kevin's proposal comes down to how we represent types.
And I think that if we adopt solution 3), that we can keep the static
binding
approach.
Recall that the issue that Kevin raised with my static binding proposal
for the C-to-SV direction, is that you cannot use a single "one size fits
all"
C stub function to serve multiple instances of SV functions being called
from C, if the types of those SV function arguments are parametrized.
But I will contend that such parametrization only becomes an issue
for array types with parametrizeable bounds (or derivatives thereof).
And if such types are always represented with the abstract access
method (as Doug's solution 3) states that they do), the same C stub
function can easily be overloaded for different parameter combinations.
Let me give a small example.
SV Code
export MySvModule::MySvFunc "MySvModule_MySvFunc";
module MySvModule;
parameter HiBound = 7;
parameter LoBound = 0;
function MySvFunction
input [HiBound:LoBound] portID;
output [HiBound:LoBound] mappedPortID;
mappedPortID = map[portID];
endfunction
end module
module Top;
MyModule myModule0; // Uses default bounds.
MyModule #(15, 0) myModule1; // Overrides default bounds.
endmodule
C Code
// C Model Constructor
void MyCModel::MyCModel( const char *path, int numElements ){
dSvContext = tf_mipname( path );
dNumElements
}
// C Model Public Method
int MyCModel::MapID( int portID, int numElements ){
sv_handle mappedIDHandle; // Abstract type handle.
int mappedID = 0;
sv_handle portIDHandle = sv_create_array( numElements-1, 0 );
// Fill out input arg for portID;
for( int i=0; i<numElements ){
sv_put_element( portIDHandle, i, portID&1 );
portID >>= 1;
}
MySvModule_MySvFunc( dSvContext, portIDHandle, &mappedIDHandle );
int hiBound = sv_left_bound( mappedID ); // Abstract type accessor
functions
int loBound = sv_right_bound( mappedID );
// Check basic assumptions about SV function data type bounds.
assert( hiBound == numElements-1 );
assert( loBound == 0 );
for( i=loBound; i<=hiBound; i++ ){
(*mappedID) |= sv_get_element( i );
(*mappedID) <<= 1;
}
return mappedID;
}
void System::RunTest(){
MyCModel model0, model1;
model0 = new MyCModel( "top.myModule0" );
model1 = new MyCModel( "top.myModule1" );
int mappedID0 = model0->MapID( 1, 8 ); // Targets module with 8
elements.
int mappedID1 = model1->MapID( 2, 16 ); // Targets module with 16
elements.
}
So basically what this shows is that the same C stub function
MySvModule_MySvFunc can be used for both parametrizations of MySvFunc.
Also, this example shows clearly that the infrastructure can easily
do error checking on the handles for input arguments that are
abstract types. For example it can verify that the portIDHandle denoting
the portID input argument is the proper number of elements
associated with the instance denoted by the given dSvContext.
Can We Remove the context Keyword ?
One final point for C-to-SV calls is that the context keyword itself
is probably no longer required in the export declaration.
This is because all C-to-SV calls are part of some context.
C-to-SV "free functions" are part of root context. We can
follow the convention that the dSvContext handle for root can
be NULL. Or it can be whatever is explicitly returned from
tf_mipname( "$root" ) (which may be vendor specific).
I've attached a revision of my PowerPoint proposal to reflect all the items
discussed herein with examples updated appropriately.
-- johnS
"Warmke, Doug" wrote:
Michael,Thanks for the clarifications.Here is another way to think about
things, which is one of the main reasonsI support solution c).In all current
mixed language products (i.e. Verilog instantiates VHDL entityand VHDL
instantiates Verilog module), there is no API needed by theuser to fetch and
pass data values that cross the language boundary.The system naturally
converts one type system to the other,following certain well-defined and
documented rules.Users really like this approach. They take a little while
to set it up,and once it's running it stays stable for a long time, since
users don'toften mess around with cross-language setups once they areinto
the heat of their verification. Also, the direct mode is easierto read in
user code due to lack of clutter.I don't see too much value in having debug
API functions that fetch andsend data. The functions could catch illegal
attempts at type conversionsat runtime. However, even without such debug
functions, users will quicklybe able to get the cross language data passing
mechanism workingby reading the docs and doing simple experiments.I would
prefer to see our "mixed language" effort here more closelyfollow the mixed
language type conversions I described above,<
This archive was generated by hypermail 2b28 : Thu Nov 28 2002 - 10:08:24 PST