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 pointers handles to structures.

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 forkjoin, forkjoin_any, or forkjoin_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 forkjoin, forkjoin_any, or forkjoin_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 forkjoin, forkjoin_any, or forkjoin_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.