Section 22.2 (New)

LRM-111

Add after 22.1 (change in red):

22.2 Elaboration-time typeof Function

 

type_function ::=                                                                                                                 // not in Annex A

  $typeof ( expression )

| $typeof ( data_type )

 

Syntax 22-1—typeof function syntax (not in Annex A)

 

The $typeof system function returns a type derived from its argument. The data type returned by the $typeof system function may be used to assign or override a type parameter, or in a comparison with another $typeof, evaluated during elaboration.

When called with an expression as its argument, $typeof returns a type that represents the self-determined type result of the expression. The expression’s return type is determined during elaboration but never evaluated. The expression shall not contain any hierarchical identifiers or references to elements of dynamic objects. In all contexts, $typeof together with its argument can be used in any place an elaboration constant is required.

 

When used in a comparison, equality (==) or case equality is true if the operands are type equivalent. (See section 5.8 Type Equivalency).

 

For example:

 

bit [12:0] A_bus, B_bus;

parameter type bus_t = $typeof(A_bus);

generate

    case ($typeof(but_t))

$typeof(bit[12:0]): addfixed_int #(bus_t) (A_bus,B_bus);

$typeof(real): add_float #($typeof(A_bus)) (A_bus,B_bus);

endcase

endgenerate

 

The actual value returned by $typeof is not visible to the user and is not defined.

Section 22.3 (New)

LRM-111

Add after new 22.2 (change in red):

22.2 Typename Function

typename_function ::=                                                                                        // not in Annex A

  $typename ( expression )

| $typename ( data_type )

Syntax 22-2—typename function syntax (not in Annex A)

 

The $typename system function returns a string that represents the resolved type of its argument.

 

The return string is constructed in the following steps:

1.         A typedef that creates an equivalent type is resolved back to built-in or user defined types.

2.        The default signing is removed, even if present explicitly in the source

3.        System generated names are created for anonymous structs, unions and enums.

4.        A ‘$’ is used as the placeholder for the name of anonymous unpacked array

5.        Actual encoded values are appended with numeration labels.

6.        User defined type names are prefixed with their defining package or scope namespace.

7.        Array ranges are represented as unsized decimal numbers.

8.        Whitespace in the source is removed and a single space is added to separate identifiers and keywords from each other.

 

This process is similar to the way that type equality is computed, except that array ranges and built-in equivalent types are not normalized in the generated string. Thus $typename can be used in string comparisons for stricter type-checking of arrays than $typeof.

 

When called with an expression as its argument, $typename returns a string that represents the self-determined type result of the expression. The expression’s return type is determined during elaboration but never evaluated. When used as an eleboration time constant, the expression shall not contain any hierarchical identifiers or references to elements of dynamic objects.

 

// source code                  // $typename would return

typedef bit node;               // “bit”

node signed [2:0] X;            // “bit signed[2:0]”

int signed Y;                         // “int”

package A;

  enum {A,B,C=99} X;            // “enum{A=32’d0,B=32’d1,C=’32bX}A::e$1”

  typedef bit [9:1’b1] word     // “A::bit[9:1]”

endpackage : A

import A:.*;

module top;

  typedef struct {node A,B;} AB_t;

  AB_t AB[10];                  // “struct{bit A;bit B;}top.AB_t$[0:9]”

...

endmodule

Section 22.2

LRM-111

Change existing 22.2 (change in red):

size_function ::=                                                                                   // not in Annex A

  $bits ( expression )

| $bits ( type_identifier )

Syntax 22-1—Size function syntax (not in Annex A)

 

The $bits system function returns the number of bits required to hold a value an expression as a bit stream. See section 3.16 bit-stream cast for a definition of legal types. A 4-state value counts as one bit. Given the declaration:

 

logic [31:0] foo;

 

Then $bits(foo) shall return 32, even if a software tool the implementation uses more than 32-bits of storage to represent the 4-state values. Given the declaration:

 

typedef struct {

logic valid;

    bit [8:1] data;

} MyType;

 

The expression $bits(MyType) shall return 9, the number of data bits needed by a variable of type MyType.

 

The $bits function can be used as an elaboration-time constant when used on fixed sized types; hence, it can be used in the declaration of other types or variables.

 

typedef bit[$bits(MyType):1] MyBits;//same as typedef bit [9:1] MyBits;

MyBits b;

 

Variable b can be used to hold the bit pattern of a variable of type MyType without loss of information.

 

The $bits system function returns logic X when called with a dynamically sized type that is currently empty. It is an error to use the $bits system function directly with a dynamically sized type identifier.

Section 22.4

LRM-111

Change existing 22.4 (change in red):

 

array_query_functions ::=                                                                                                  // not in Annex A

                array_dimension_function ( array_identifier [ , dimension_expression ] )

                | array_dimension_function ( type_identifier [ , dimension_expression ] )

                | $dimensions ( array_identifier )

                | $dimensions ( type_identifier )

 

array_dimension_function ::=

                  $left

                | $right

                | $low

                | $high

                | $increment

              | $length $size

 

dimension_expression ::= expression

Syntax 22-2—Array querying function syntax (not in Annex A)

 

SystemVerilog provides new system functions to return information about a particular dimension of an array variable or type. The default for the optional dimension expression is 1. The array dimension can specify any fixed sized index (packed or unpacked), or any dynamically sized index (dynamic, associative, or queue).

 

      $left shall return the left bound (msb) of the dimension

 

      $right shall return the right bound (lsb) of the dimension

 

      $low shall return the minimum of $left and $right of the dimension

 

      $high shall return the maximum of $left and $right of the dimension

 

      $increment shall return 1 if $left is greater than or equal to $right, and -1 if $left is less than $right

 

      $length $size shall return the number of elements in the dimension, which is equivalent to $high - $low + 1

 

      $dimensions shall return the number of dimensions in the array, or 0 for a singular object

 

The dimensions of an array shall be numbered as follows: The slowest varying dimension (packed or unpacked) is dimension 1. Successively faster varying dimensions have sequentially higher dimension numbers. For instance:  Intermediate type definitions are expanded first before numbering the dimensions.

 

For example:

// Dimension numbers

//    3    4       1    2

reg [3:0][2:1] n [1:5][2:8];

typedef reg [3:0][2:1] packed_reg;

packed_reg n[1:5][2:8]; // same dimensions as in the lines above

 

For an integer or bit type, only dimension 1 is defined. For a fixed sized integer type (integer, shortint, longint, and byte), dimension 1 is pre-defined. For an integer N declared without a range specifier, its bounds are assumed to be [$bits(N)-1:0].

 

If an out-of-range dimension is specified, these functions shall return a logic X.

 

When used on a dynamic array or queue dimension, these functions return information about the current state of the array. If the dimension is currently empty, these functions shall return a logic X. It is an error to use these functions directly on a dynamically sized type identifier.

 

Use on associative array dimensions is restricted to index types with integral values. With integral indexes, these functions shall return:

 

      $left shall return 0

 

      $right shall return the highest possible index value

 

      $low shall return the lowest currently allocated index value

 

      $high shall return the largest currently allocated index value

 

      $increment shall return -1

 

      $size shall return the number of elements currently allocated

 

If the array identifier is a fixed sized array, these query functions can be used as a constant function and passed as a parameter before elaboration. These query functions can also be used on fixed sized type identifiers in which case it is always treated as a constant function.

 

Given the declaration below:

 

typedef logic [16:1] Word;

Word Ram[0:9];

 

The following system functions return 16:

 

$size(Word)

$size(Ram,2)

Section 22.7

LRM-105

Change Syntax 22-5(change in red):

assert_boolean_functions ::=            // not in Annex A

  insert_function ( expression ) ;

| $insetz ( expression, expression [ { , expression } ] ) ;

 

assert_function ::=

  $onehot

| $onehot0

| $inset

| $isunknown

LRM-105

Change (change in red):

               

$insetz returns true if the first expression is equal to at least one other expression argument. Comparison is performed using casez semantics, so Z or ? bits are treated as don’t-cares.

Section 22.12

LRM-79

Change (change in red):

22.12 $readmemb and $readmemh

$readmemb and $readmemh are extended to unpacked arrays of packed data. In such cases, they treat each packed element as the vector equivalent and perform the normal operation. $readmemb and $readmemh are not defined for packed arrays or unpacked arrays of unpacked data.

 

22.12.1 Reading packed data

$readmemb and $readmemh are extended to unpacked arrays of packed data, associative arrays of packed data, and dynamic arrays of packed data. In such cases, the system tasks treat each packed element as the vector equivalent and perform the normal operation.
 
When working with associative arrays, indexes must be of integral types. 
 

22.12.2 Reading 2-state types

$readmemb and $readmemh are extended to packed data of 2-state type, such as int or enumerated types.  For 2-state integer types, reading proceeds the same as for conventional Verilog reg types (e.g. integer), with the exception that X or Z data is converted to 0.  For enumerated types, the file data represents the ordinal value of the enumerated type. (Cross-reference LRM section 3.10)  If an enumeration ordinal is out of range for a given type, then an error shall be issued and no further reading shall take place.
 

22.13 $writememb and $writememh

SystemVerilog introduces system tasks $writememb and $writememh:
 
$writememb("file_name", memory_name[, start_addr[, finish_addr]]); 
$writememh("file_name", memory_name[, start_addr[, finish_addr]]); 
 
$writememb and $writememh are used to dump memory contents to files that are readable by $readmemb and $readmemh, respectively. If "file_name" exists at the time $writememb or $writememh is called, the file will be overwritten (.i.e. there is no append mode).
 
22.13.1 Writing packed data
$writememb and $writememh treat packed data identically to $readmemb and $readmemh.  See section 22.12.1.
 
22.13.2 Writing 2-state types
$writememb and $writememh can write out data corresponding to unpacked arrays of 2-state types, such as int or enumerated types. For enumerated types, values in the file correspond to the ordinal values of the enumerated type. (X-ref LRM section 3.10).
 
22.13.3 Writing addresses to output file
When $writememb and $writememh write out data corresponding to unpacked or dynamic arrays, address specifiers (@-words) shall not be written to the output file.
 
When $writememb and $writememh write out data corresponding to associative arrays, address specifiers shall be written to the output file.
 
22.14 File format considerations for multi-dimensional unpacked arrays
In SystemVerilog, $readmemb, $readmemh, $writememb and $writememh can work with multi-dimensional unpacked arrays.
 
The file contents are organized in row-major order, with each dimension's entries ranging from low to high address. This is backward compatible with plain Verilog memories.
 
In this organization, the lowest dimension (i.e. the rightmost dimension in the array declaration) varies the most rapidly. There is a hierarchical sense to the file data. The higher dimensions contain words of lower-dimension data, sorted in row-major order.  Each successive lower dimension is entirely enclosed as part of higher dimension words.
 
As an example of file format organization, here is the layout of a file representing words for a memory declared
 
reg [31:0] mem [0:2][0:4][5:8];
 
In the example word contents, wzyx,
 
z corresponds to words of the [0:2] dimension
y corresponds to words of the [0:4] dimension
x corresponds to words of the [5:8] dimension
 
w005 w006 w007 w008
w015 w016 w017 w018
w025 w026 w027 w028
w035 w036 w037 w038
w045 w046 w047 w048
w105 w106 w107 w108
w115 w116 w117 w118
w125 w126 w127 w128
w135 w136 w137 w138
w145 w146 w147 w148
w205 w206 w207 w208
w215 w216 w217 w218
w225 w226 w227 w228
w235 w236 w237 w238
w245 w246 w247 w248
 
Note that the diagram would be identical if one or more of the unpacked dimension declarations were reversed, as in
 
reg [31:0] mem [2:0][0:4][8:5]
 
Address entries in the file exclusively address the highest dimension's words. In the above case, address entries in the file could look something as follows:
 
@0 w005 w006 w007 w008
       w015 w016 w017 w018
       w025 w026 w027 w028
       w035 w036 w037 w038
       w045 w046 w047 w048
@1 w105 w106 w107 w108
       w115 w116 w117 w118
       w125 w126 w127 w128
       w135 w136 w137 w138
       w145 w146 w147 w148
@2 w205 w206 w207 w208
       w215 w216 w217 w218
       w225 w226 w227 w228
       w235 w236 w237 w238
       w245 w246 w247 w248
 
When $readmemh or $readmemb is given a file without address entries, all data is read assuming that each dimension has complete data.  i.e. each word in each dimension will be initialized with the appropriate value from the file. If the file contains incomplete data, the read operation will stop at the last initialized word, and any remaining array words or subwords will be left unchanged.
 
When $readmemh or $readmemb is given a file with address entries, initialization of the specified highest dimension words is done.  If the file contains insufficient words to completely fill a highest dimension word, then the remaining subwords are left unchanged.
 
22.15 System task arguments for multi-dimensional unpacked arrays
The $readmemb, $readmemh, $writememb, and $writememh signatures are shown below:
 
$readmemb("file_name", memory_name[, start_addr[, finish_addr]]);
$readmemh("file_name", memory_name[, start_addr[, finish_addr]]);
$writememb("file_name", memory_name[, start_addr[, finish_addr]]);
$writememh("file_name", memory_name[, start_addr[, finish_addr]]);
 
memory_name can be an unpacked array, or a partially indexed multi- dimensional unpacked array that resolves to a lesser-dimensioned  unpacked array.
 
Higher order dimensions must be specified with an index, rather than a complete or partial dimension range.  The lowest dimension (i.e. the rightmost specified dimension in the identifier) can be specified with slice syntax.  See section 4.4 for details on legal array indexing in SystemVerilog.
 
The start_addr and finish_addr arguments apply to the addresses of the unpacked array selected by memory_name. This address range represents the highest dimension of data in the file_name.
 
When slice syntax is used in the memory_name argument, any start_addr and finish_addr arguments must fall within the bounds of the slice's range.
 
The direction of the highest dimension's file entries is given by the relative magnitudes of start_addr and finish_addr, as is the case in 1364-2001.