Subject: revised DirectC proposal aka "17 items"
From: Andrzej Litwiniuk (Andrzej.Litwiniuk@synopsys.com)
Date: Mon Nov 18 2002 - 20:04:56 PST
SV-CC members:
Attached is the revised DirectC proposal, aka "17 items".
This version incorporates most of the feedback from e-mails
and from the face-to-face meeting; I might, however, have missed
something unintensionally.
The relevant status ["Resolved", "Not resolved", "Needs clarification and
modification of wording"] is given for each item.
Thank you,
Andrzej
Observation:
-----------
There are two facets of the interface: SV side and a foreign language
side.
These two sides can be defined separately; the foreign programming
language and the actual function call protocol and argument passing
mechanism should be transparent to SV.
In other words, there will be two layers of the interface:
SV layer and the outer layer (layer of a foreign language).
This document focuses on SV layer: on the functionality, semantics and
syntax of SV side of the interface.
(0) The foreign programming language should be transparent to SV.
=================================================================
[Status: Needs clarification and modification of wording]
(a) The SV side of the interface should look identically regardless of
what the foreign side of the interface will be eventually decided.
(b) The semantics of the SV side of the interface should be independent of
the foreign side of the interface.
(c) The actual argument passing mechanism generally should be transparent to
SV.
The specifics of the argument passing may be eventually reflected in
tiny modifications of the syntax agreed upon, similarly to VCS DirectC
variations of 'extern', 'extern "C"', 'extern "A"'.
(d) The actual argument passing mechanism(s) and therefore the methods
to access (read/write) formal arguments from the foreign side of the
interface will be specified separately and there are not addressed in
this document.
(1) DirectC interface allows to call foreign functions from SV code.
=================================================================
[Status: Needs clarification and modification of wording]
(a) DirectC interface includes the capability to call non-SV functions
(including void functions,i.e. functions that return no result) from SV
code.
Such functions will be hereinafter refered to as external functions
(xf).
(b) A richer functionality, like the capability to call SV functions and
tasks from a non-SV domain is not addressed in this proposal.
This document neither precludes nor considers such functionality,
leaving it for a future discussion, as a further extension to the
functionality proposed here or for SV 3.2.
(c) For practical reasons, DirectC interface should allow direct calls to
C functions.
(2) External function executes in 0 time.
=================================================================
[Status: Resolved]
(a) External functions are assumed to execute in 0 simulation time.
In other words, no simulation time passes during the execution of xf.
Xf must not contain timing control, directly or indirectly.
(b) This document does not consider calling foreign tasks, i.e. functions
with timing control, either explicit in their code or achieved via
calling SV tasks.
Such functionality is not addressed in this proposal and may be either
precluded or added as a next feature.
Anyway, xf are assumed to be non-blocking (execute in zero time) for
the rest of this document.
(3) The usage of xf is identical as for SV functions and tasks.
=================================================================
[Status: Needs clarification and modification of wording]
Note: only xf calls are considered here, declarations are disccuded in (5).
The usage and syntax for calling xf is identical as for native SV functions
and tasks (see function_call, task_enable in LRM).
The applicable syntax rules are: A.6.4, A.6.9, A.8.2, A.8.4.
Specifically:
(i) xf may have zero or more formal arguments.
(ii) xf may have input, output and inout formal arguments.
(Types of a result and formal args will be discussed later.)
(iii) any xf can be called as a void function, i.e. its call may occur as
a statement, and a result, if any, will be discarded.
(iv) The evaluation order of formal arguments follows general SV rules
(is unspecified).
(4) xf may access only the predictable SV data objects
=================================================================
[Status: Not resolved]
The rationale is that xf calls should not prohibit compiler optimizations
by introducing unpredictability in accessing and/or modifying SV data.
SV compiler must be able to determine which SV data objects may be accessed
(read or written) by a particular xf call.
(a) By default,i.e. unless specially declared, xf may access only those SV
data objects that are explictly passed as actual arguments to a xf call
(must not acces data objects that have been not passed explicitly as
arguments of the particular call)
The above rule does not restrict xf access to non-SV data
(e.g. global C variables).
(b) If specially declared, xf may access other SV data objects
(e.g. via VPI or PLI calls).
(Note that this may also require PLI/acc capabilities to be turned on
for respective modules.)
The rationale for the requirement that xf must be specially declared if
it may access arbitrary SV data is that a call of such xf may need
a special handling.
(c) Additionally, xf may access all those SV data objects that are known
(by whatever means) to be accessible from the outside of SV source code.
This will include exported variables, if SV is enhanced with such
functionality.
(5) Declarations of external functions
=================================================================
[Status: Needs clarification and modification of wording]
Each xf must be declared. Such declaration will be further refered to as
external declarations.
The syntax of an external declaration mimics SV syntax and will be discussed
in (8).
A declared xf will be resolved eventually to a global symbol of the same name
defined outside SV design. Therefore xf names must be unique; no overloading
is allowed for xf.
(a) An external declaration specifies function name, function result
and types and directions of formal arguments.
It may also provide optional names for formal arguments.
Formal arg names serve only as comments and are otherwise meaningless.
An external declaration may also specify additional features, like
access mode ("A"/"C" in VCS DirectC), "purity" ("pure" in VCS DirectC),
capability to access any SV data object, cf. (4b), etc.
(b) Names of xf must follow C convention for names.
The rationale is that they must acceptable by link-editor as legal
global names.
(6) External declarations may occur only in $root scope
=================================================================
[Status: Needs clarification and modification of wording]
(a) External declarations may occur anywhere in $root scope, ie. outside of
modules, interfaces, functions and tasks.
A scope of an external declaration is the whole design.
A name of xf should not classh with any name declared in $root scope.
Alternatively, xf might be allowed to be declared inside any scope.
This approach seems to be more error prone, however, since all external
declarations with the same name have to be resolved eventually to
the same function, even if their declarations differ.
(b) An external declaration of xf need not to precede an invocation of
that xf.
(c) Regular name resolving rules apply to xf.
Therefore local names declared inside a module (or interface) will
obscure xf name; $root.xf_name may be used to resolve to global name.
Note:
Since xf may not be declared inside a module, currently there is no way
to specify xf as a part of a module intended to be a library module.
In Verilog a library module is self-contained in a sense that it does
not refer to non-local definitions other that the other modules.
In SV some new mechanism seems to be needed that would allow to link
definitions referenced in a library module with that module; such
definitions include typedefs, interfaces, external functions.
Such mechanism should also provide means for linking the external code
(in a source or in an object form) with a library module.
(7) Multiple equivalent declarations of xf are allowed
=================================================================
[Status: Resolved]
Xf may have multiple declarations (i.e. declarations with the same function
name) as long as they are all equivalent.
Two declarations are equivalent if they specify the same function result type,
the same number of formal arguments, and for each formal argument respectively,
the same direction and type.
If function features are specified, they must be identical in all declarartions
of that function.
Note:
The above definition of 'equivalence' is vague about ranges of packed
and unpacked structures and arrays (absolute bounds and the slope).
The question is which of the following forms will be considered as
equivalent: [8:1], [1:8], [7{0]. [0:7].
Preferably SV rules should be applied.
I don't think, however, that SV defines any equivalence rules.
We may require the exact match or relax it and require only the same
number of elements (normalized form).
(8) Syntax of an external declaration similar to SV syntax
=================================================================
[Status: Resolved]
The syntax of an external declaration is based on SV syntax for functions
and tasks, with ansi style port list, cf. LRM Section 10.
An external declaration follows SV rules: formal argument direction defaults
to input, direction may be specified for a group of arguments.
Syntax:
-------
external_declaration:
'extern' optional_function_type function_name '(' optional_arg_list ')' ';'
optional_function_type: 'void' | func_result_type
function_name: identifier
optional_arg_list: optional_direction group_of_args optional_groups_of_args
optional_direction: /*empty*/ | direction
direction: 'input' | 'output' | 'inout'
group_of_args: formal_arg | formal_arg ',' group_of_args
formal_arg: formal_arg_type optional_name
optional_name: /*empty*/ | identifier
optional_groups_of_args: /*empty*/
| direction group_of_args optional_groups_of_args
func_result_type and formal_arg_type will be discussed later.
(9) Compatibility and coercion of actual and formal arguments
=================================================================
[Status: Pass to the Basic SV committee]
Arguments passing for xf is ruled by WYSIWYG principle:
What You Specify Is What You Get.
(The possible exceptions for packed and unpacked ranges will be discussed
later.)
If the actual argument does not match exactly the formal one, a temporary
variable of the type specified for the formal arg is created and passed as an
actual arg.
For input and inout args, such temporary is initialized with the value of actual
arg with the appropriate coercion; for the output or inout arg, the value of
the temporary is assigned to the actual arg with the appropriate conversion.
The assignments between a temporary and the actual arg follow general SV rules
for assignments and automatic coercion.
The definition of argument compatibility and coercion rules are left to be
defined by the Basic SV Committee.
(10) XF call should be indistinguishable from SV call.
=================================================================
[Status: Resolved]
(a) xf must not modify the values of its input args
(b) The initial values of formal output args are unspecified and may be
implementation dependent.
(c) For output and inout args the value propagation (i.e. value change
events) happens as if an actual arg was assigned a formal arg
immediately after control returns from xf.
On the SV side of the interface the values of actual arguments for formal input
arguments of xf should not be affected by the callee; the initial values
of formal output arguments of xf are unspecified, and the necessary coercions,
if any, are applied as for assignments.
For the SV side of the interface, the semantics of arguments passing is as
if input args were passed by "copy-in", output args were passed by "copy-out"
and inout args were passed by "copy-in, copy-out".
The terms "copy-in", "copy-out" in the above statement do not impose the actual
implementation, they refer only to "hypothetical assignment".
The actual implementation of argument passing is transparent and irrelevant
to the SV side of the interface. In particular, it is transparent to SV whether
an argument is actually passed "by value" or "by reference" (note that the later
notion does not exist in SV).
The argument passing mechanism must be defined separately and is not
addressed in this document.
Types of formal arguments and function result
----------------------------------------------
Note: Ideally, any SV data type would be allowed.
For practical reasons, the set of supported types may be restricted.
Different classes of types will be discussed separately in (11)-(17).
(11) Simple 2 state types are supported
=================================================================
[Status: Resolved, change of wordings needed]
As the minimum the following types are allowed for function result type
and formal arguments:
(a) bit (scalar)
(b) basic integer 2 state types: byte, char, shortint, int, longint.
(c) non integer types: time, shortreal, real, realtime.
(d) new primitive types, to be introduced to SV: pointer, string
Note: "pointer" and "string" are code names to be replaced by better
names.
Note that 'integer', 'logic', 'reg' have not been included in the above list
because they represent 4 state values.
Similarly, enumeration types may be 4 state and/or of arbitrary size.
These and other types will be discussed later.
(12) New primitive types: pointer, string.
=================================================================
[Status: Resolved, change of wordings needed]
Note: "pointer" and "string" are code names to be replaced by better names.
These types are meant solely for DirectC interface and are intended for passing
values from non-SV domain back into that domain, with ability to store them in
the interim on SV variables.
The size of types 'pointer' and 'string' is platform dependent and should be
transparent to SV.
Types 'pointer' and 'string' do not introduce the dynamic data types into SV and
generally have no interpretation on the SV side.
Therefore only a minimal set of rudimentary features is proposed here.
The proposition to introduce these new types does not preclude full-fledged
pointers, should the committee decide to introduce them into SV.
Type 'pointer' represents a generic opaque pointer, 'string' represent a pointer
to C-like string.
Note that typedef allows to define different pointer types, e.g.:
typedef pointer list;
typedef pointer queue;
The use of the types pointer and string is restricted as follows:
- pointer/string may be used as types of a function result and formal
arguments of external functions as well as SV functions and tasks
or as types of variables
- may not be used as types of module or interface ports
- may not occur in packed structs or unions
Rationale: platform dependent size.
- may be used in assignments (if both sides are of the same type)
and as actual arguments to function/task calls
- 0 (unsized constant zero) may be used as a value compatible with any
pointer or string type
- the only applicable operations for the values of these types are
comparisons !=, == with 0 (unsized constant zero) or other values of
the same type; no arithmetic operations or other relational operators
are allowed on them
- may not be used in explicit or implicit sensitivity lists or
posedge/negedge or in continupos assignments
- the initial value of a variable of type pointer/string is 0 (unsized
constant).
- a string literal, i.e. characters in quotes, e.g. "a text" occuring as
an actual argument for a formal arg of type string is interpreted as
C-style string rather than as SV encoding of a bit vector.
- save/restart capability will preserve the original values of variables
of type pointer/string. User is responsible for the correct handling of
such pointers in his/her foreign code after restart.
Similarly, user is responsible for the correct handling of such pointers
should the foreign language employ a garbage collection.
More on types of result and formal args of xf
----------------------------------------------
Ideally, any SV and C/C++ data type would be allowed.
This would require that every SV data type is mapped upon some type in the
foreign language, and similarly, any C/C++ type is mapped upon some type in SV.
There is no obvious 1-to-1 correspondence between SV data types and C types.
Contrary to popular belief, there are no common types between SV and C
other than basic arithmetic types.
SV inherits from C but is not a superset of C.
Structures defined in C by and large are not valid SV structures.
[VCS DirectC avoids the problem by generating headers that map V types onto
C types, and by restricting function result types.]
Of course, it's possible to define inductively the set of data types that
would be valid and semantically equivalent in both languages.
It would be, however, impractical and confusing.
Commonly, definitions in C are convoluted, refer to #define constants, involve
conditional compilation, differently specify array's size, etc.
SV parser might support full C or C++ syntax, but this will only add the burden.
A type of a formal argument or a function result of xf usually will not be be
useful, if user cannot declare her/his variable of that type (unless a clear
rule is provided for conversion between SV and non-SV types) that could be used
as an actual argument.
(13) No constraints on the implementation of SV specific types
=================================================================
[Status: partly not resolved, partly resolved]
DirectC interface should not impose any constraints on how SV-specific data
types are actually implemented. Optimal representation may be platform
dependent.
(a) the layout of unpacked SV structs should be the same as the layout
used by a C compiler on the corresponding C structs.
Note that this is platform dependent.
(a) The layout of 2- or 4-state vectors (i.e. packed structs and arrays)
is implementation- and platform- dependent.
(14) More types: logic, structs, arrays.
=================================================================
[Status: Needs clarification and modification of wording]
The implementation (representation and layout) of 4 state values, structs
and arrays is irrelevant for SV semantics, but will impact the foreign side
of the interface.
It seems to be desirable to allow complex data types and SV specific data
types for xf functions.
(i) The types allowed in external declarations generally will be SV types,
with some restrictions and with some notational extensions for unsized
arrays, as proposed in (16).
(ii) It will not be possible to import external types or directly use
the type syntax from another language.
(iii) User will be responsible for using in his/her foreign code the types
equivalent to those used in external declaration.
SV implementation may facilitate the mapping of SV types onto foreign types
by generating appropriate function headers.
The following types are allowed - this is the extension to (11) - for formal
arguments of xf:
(a) all types listed in (11a-d)
(b) logic (scalar)
(c) packed 1-dimensional and multi-dimensional vectors of type bit
(d) packed 1-dimensional and multi-dimensional vectors of type logic
(e) unpacked structs
(f) unpacked 1-dimensional and multi-dimensional arrays of the above
types, i.e. of types listed in (14a-e)
Note that 'integer', 'reg' and the enumeration types fall into the above categories.
The types allowed for function results are more restricted and discussed in (17).
It shall be recalled that this proposal does not constitute a complete interface
specification. It solely and merely describes the SV layer of the interface.
Another layer of the interface, transparent to SV and totally absent in this
document, shall specify how actual arguments are passed ("by value" or "by reference"),
how can be accessed from the foreign code ("direct" or "abstract" access),
and how SV specific data types (logic and packed) are represented
or how to translated them to and from some predefined C-like types.
(15) vectors/arrays will be normalized to [n:0]
=================================================================
[Status: Not resolved]
Note: there were some objections to this item, therefore I propose to
reject this rule; I'm keeping it here only for the record.
All vectors/arrays will be normalized to [n:0] regardless of the original range
and increasing or decreasing order of indexing.
For example [1:8], [8:1], [7:0] will be equivalent declarations of the size
of packed a vector or unpacked an array.
(16) Unsized packed and unpacked arrays
=================================================================
[Status: Needs clarification and modification of wording]
For the convenience, the size of the packed dimension or the unpacked
dimension or both dimensions may remain unspecified; such cases will be refered
to as open vectors and open arrays [or better: unsized arrays?].
This will allow to write a generic code good for different sizes.
If a formal argument is specified as an open vector or an open array, then
the actual argument will match the formal one regardless of its dimensions and
sizes of, respectively, its linearized packed or unpacked dimensions.
Formal argument name is required to separate packed and unpacked dimensions
(refered here as a vector and an array).
Here are the examples of types of formal args:
bit
logic
bit [8:1]
logic [0:31]
bit[]
bit [7:0] b8x10 [1:10] // b8x10 is a formal arg name
logic log10 [1:10] // log10 is a formal arg name
logic [31:0] l32x [] // l32x is a formal arg name
logic [] lx3 [3:1] // lx3 is a formal arg name
bit [] an_unsized_array [] // an_unsized_array is a formal arg name
Comment: empty [] denotes open vector or open array.
(17) Only 'small' values for xf result
=================================================================
[Status: Needs clarification and modification of wording]
The data types allowed for external function result are restricted
to the following ones:
(a) any type listed in (11a-d)
(b) logic (scalar)
(c) packed 1-dimensional array of type bit of size n, n<=32,
=================================================================
This archive was generated by hypermail 2b28 : Mon Nov 18 2002 - 20:05:37 PST