Mantis 2106
P1800-2008/D4
6.18, 6.21
NOTE TO EDITOR: Both blue text and underlined greenish text are insertions (problems with Word).
Modify the text in 6.18 User Defined Types
REPLACE
For example:
typedef int
intP;
This can then be instantiated as follows:
intP a, b;
A type can be used before it is defined,
provided it is first identified as a type by an empty typedef:
typedef foo;
foo f = 1;
typedef int
foo;
An empty typedef shall not be allowed with enumeration values.
Enumeration values must be defined before they are used.
User-defined type identifiers have the
same scoping rules as data identifiers, except that hierarchical reference to
type identifiers shall not be allowed. References to type identifiers defined
within an interface through ports are allowed provided they are locally
redefined before being used.
interface intf_i;
typedef
int data_t;
endinterface
module sub(intf_i p);
typedef
p.data_t my_data_t;
my_data_t
data;
// type of 'data' will be int
when connected to interface above
endmodule
User-defined type names must
be used for complex data types in casting (see 6.24),
which only allows simple type names, and as type parameter values when unpacked
array types are used.
Sometimes a user-defined type
needs to be declared before the contents of the type have been defined. This is
of use with user-defined types derived from enum, struct, union, and class. Support for this is provided by the following forms for typedef:
typedef enum type_identifier;
typedef struct type_identifier;
typedef union type_identifier;
typedef class type_identifier;
typedef type_identifier;
While an empty user-defined
type declaration is useful for coupled definitions of classes as shown in 8.25, it cannot be used for coupled definitions of structures because
structures are statically declared and there is no support for pointers to
structures.
The last form shows that the
type of the user-defined type does not have to be defined in the forward
declaration.
The actual type definition of
a forward typedef declaration shall be resolved within the
same local scope or generate block.
Importing a typedef from a package into a local scope can also
resolve a type definition.
WITH
A typedef may be used to give a user defined name to an existing
data type. For example:
typedef int
intP;
This can then be instantiated as follows:
intP a, b;
User-defined data type names must
be used for complex data types in casting (see 6.24), which only allows simple data type names, and
as type parameter values (see 6.20.3) when unpacked array types are
used.
A type can be used before
it is defined, provided it is first identified as a type by an empty typedef:
typedef foo;
foo f = 1;
typedef int foo;
An empty typedef shall not be allowed with enumeration values.
Enumeration values must be defined before they are used.
A type parameter may also be used to declare a type_identifier.
The declaration of a user-defined data type shall precede any reference to its type_identifier. User-defined
data type
identifiers have the same scoping rules as data identifiers, except that
hierarchical reference to type identifiers type_identifiers shall not be
allowed. References to type identifiers defined within an interface through
ports are not
considered hierarchical references and are allowed provided they
are locally redefined before being used.
interface intf_i;
typedef
int data_t;
endinterface
module sub(intf_i p);
typedef
p.data_t my_data_t;
my_data_t
data;
// type of 'data' will be int
when connected to interface above
endmodule
User-defined type names must be
used for complex data types in casting (see 6.24), which only allows simple type names, and as type
parameter values when unpacked array types are used.
Sometimes a user-defined type
needs to be declared before the contents of the type have been defined. This is
of use with user-defined types derived from the basic data types:
enum,
struct,
union, and class. Support for this is provided by the
following forms for a forward typedef:
typedef enum type_identifier;
typedef struct type_identifier;
typedef union type_identifier;
typedef class type_identifier;
typedef type_identifier;
Note: While an empty
user-defined type declaration is useful for coupled definitions of classes as
shown in 8.25, it cannot be used for coupled definitions of structures
because structures are statically declared and there is no support for handles to
structures.pointers
The last form shows that the basic data type
of the user-defined type does not have to be defined in the forward declaration.
The actual data type
definition of a forward typedef declaration shall be resolved within the
same local scope or generate block.
Importing
a typedef from a package into a local scope can also resolve a type definition. It shall be an error if the type_identifier does not resolve to a data
type. It shall be an error if a basic data type was specified by the forward
type declaration and the actual type definition does not conform to the
specified basic data type.
Modify the text in 6.21 Scope and Lifetime
REPLACE
Any data declared outside a
module, interface, task, or function are global in scope (can be used anywhere
after its declaration) and have a static lifetime (exist for the whole
elaboration and simulation time).
Data declared inside a module,
interface or program, but outside a task, process, or
function, are local in scope and static in lifetime (exist for the lifetime of
the module, interface or program). This is roughly equivalent to C static data
declared outside a function, which is local to a file.
Data declared in an automatic
task, function, or block have the lifetime of the call
or activation and a local scope. This is roughly equivalent to a C automatic
variable.
Data declared in a static
task, function, or block default to a static lifetime and a local scope.
Data can be declared in
unnamed blocks as well as in named blocks. These data are visible to the
unnamed block and any nested blocks below it. Hierarchical references cannot be
used to access these data by name.
Tasks and functions can be
declared as automatic,
making all storage within the task or function automatic.
Specific data within a static
task or function can be explicitly declared as automatic. Data declared as automatic have the
lifetime of the call or block and are initialized on each entry to the call or
block (also see 6.7 on variable initialization). The lifetime of a fork…join, fork…join_any, or fork…join_none block shall encompass the execution of all processes spawned by
the block. The lifetime of a scope enclosing any fork block includes the
lifetime of the fork block.
Data can be explicitly
declared as static. Data
declared to be static in an
automatic task, function, or block have a static lifetime and a scope local to
the block. This is like C static data declared within a function.
WITH
Variables declared outside a
module, program, interface, task, or function are local to the compilation unit
and have a static lifetime (exist for the whole simulation). This is roughly
equivalent to C static variables declared outside a function, which are local
to a file. Variables declared inside a module, interface or program, but
outside a task, process, or function, are local in scope and have a static
lifetime.
Variables declared inside a
static task, function, or block are local in scope and
default to a static lifetime. Specific variables within a static task, function,
or block can be explicitly declared as automatic. Such variables have the lifetime of the
call or block and are initialized on each entry to the call or block (also see
6.7 on variable initialization). This is roughly equivalent to a C automatic
variable.
Tasks and functions may be
declared as automatic.
Variables declared in an automatic task, function, or block are local in scope,
default to the lifetime of the call or block and are initialized on each entry
to the call or block (also see 6.7 on variable initialization). An automatic
block is one in which declarations are automatic by default. Specific variables
within an automatic task, function, or block can be explicitly declared as static. Such variables have a static lifetime.
This is roughly equivalent to C static variables declared within a function.
The lifetime of a fork…join, fork…join_any,
or fork…join_none block shall encompass the execution of all
processes spawned by the block. The lifetime of a scope enclosing any fork
block includes the lifetime of the fork block.
A variable declaration shall
precede any simple reference (non-hierarchical) to that variable. Variable
declarations shall precede any statements within a procedural block. Variables
may be declared in unnamed blocks as well as in named blocks. These variables
are visible to the unnamed block and any nested blocks below it. Hierarchical
references shall not be used to access these variables by name.
Any data declared outside a
module, interface, task, or function are global in scope (can be used anywhere
after its declaration) and have a static lifetime (exist for the whole
elaboration and simulation time).
Data declared inside a
module, interface or program, but outside a task, process, or function, are
local in scope and static in lifetime (exist for the lifetime of the module,
interface or program). This is roughly equivalent to C static data declared
outside a function, which is local to a file.
Data declared in an automatic
task, function, or block have the lifetime of the call
or activation and a local scope. This is roughly equivalent to a C automatic
variable.
Data declared in a static
task, function, or block default to a static lifetime and a local scope.
Data can be declared in
unnamed blocks as well as in named blocks. These data are visible to the
unnamed block and any nested blocks below it. Hierarchical references cannot be
used to access these data by name.
Tasks and functions can be
declared as automatic,
making all storage within the task or function automatic.
Specific data within a static
task or function can be explicitly declared as automatic. Data declared as automatic have the
lifetime of the call or block and are initialized on each entry to the call or
block (also see 6.7 on variable initialization). The lifetime of a fork…join, fork…join_any, or fork…join_none block shall encompass the execution of all
processes spawned by the block. The lifetime of a scope enclosing any fork
block includes the lifetime of the fork block.
Data can be explicitly
declared as static.
Data declared to be static in an automatic task, function, or block have a static lifetime and
a scope local to the block. This is like C static data declared within a
function.