• 沒有找到結果。

Unified Hardware Design, Specification, and Verification Language

6. Data types

6.23 Type operator

6.24.1 Cast operator

A data type can be changed by using a cast ( ' ) operation. The syntax for cast operations is shown in Syntax 6-7.

constant_cast ::= // from A.8.4

casting_type ' ( constant_expression ) cast ::=

casting_type ' ( expression )

casting_type ::= simple_type | constant_primary | signing | string | const // from A.2.2.1 simple_type ::= integer_type | non_integer_type | ps_type_identifier | ps_parameter_identifier

Syntax 6-7—Casting (excerpt from Annex A)

In a static cast, the expression to be cast shall be enclosed in parentheses that are prefixed with the casting type and an apostrophe. If the expression is assignment compatible with the casting type, then the cast shall return the value that a variable of the casting type would hold after being assigned the expression. If the expression is not assignment compatible with the casting type, then if the casting type is an enumerated type, the behavior shall be as described as in 6.19.4, and if the casting type is a bit-stream type, the behavior shall be as described in 6.24.3.

int'(2.0 * 3.0)

shortint'({8'hFA,8'hCE})

Thus, in the following example, if expressions expr_1 and expr_2 are assignment compatible with data types cast_t1 and cast_t2, respectively, then

A = cast_t1'(expr_1) + cast_t2'(expr_2);

is the same as

cast_t1 temp1;

cast_t2 temp2;

temp1 = expr_1;

temp2 = expr_2;

A = temp1 + temp2;

Thus, an implicit cast (e.g., temp1 = expr1), if defined, gives the same results as the corresponding explicit cast (cast_t1'(expr1)).

If the casting type is a constant expression with a positive integral value, the expression in parentheses shall be padded or truncated to the size specified. It shall be an error if the size specified is zero or negative.

Examples:

17'(x - 2)

parameter P = 16;

(P+1)'(x – 2)

The signedness can also be changed.

signed'(x)

The expression inside the cast shall be an integral value when changing the size or signing.

When changing the size, the cast shall return the value that a packed array type with a single [n-1:0]

dimension would hold after being assigned the expression, where n is the cast size. The signedness shall pass through unchanged, i.e., the signedness of the result shall be the self-determined signedness of the expression inside the cast. The array elements shall be of type bit if the expression inside the cast is 2-state, otherwise they shall be of type logic.

When changing the signing, the cast shall return the value that a packed array type with a single [n-1:0]

dimension would hold after being assigned the expression, where n is the number of bits in the expression to be cast ($bits(expression)). The signedness of the result shall be the signedness specified by the cast type. The array elements shall be of type bit if the expression inside the cast is 2-state; otherwise, they shall be of type logic.

NOTE—The $signed() and $unsigned() system functions (see 11.7) return the same results as signed'() and unsigned'(), respectively.

Examples:

logic [7:0] regA;

logic signed [7:0] regS;

regA = unsigned'(-4); // regA = 8'b11111100 regS = signed'(4'b1100); // regS = -4

An expression may be changed to a constant with a const cast.

const'(x)

When casting an expression as a constant, the type of the expression to be cast shall pass through unchanged.

The only effect is to treat the value as though it had been used to define a const variable of the type of the expression.

When casting to a predefined type, the prefix of the cast shall be the predefined type keyword. When casting to a user-defined type, the prefix of the cast shall be the user-defined type identifier.

When a shortreal is converted to an int or to 32 bits using either casting or assignment, its value is rounded (see 6.12). Therefore, the conversion can lose information. To convert a shortreal to its underlying bit representation without a loss of information, use $shortrealtobits as defined in 20.5. To convert from the bit representation of a shortreal value into a shortreal, use $bitstoshortreal as defined in 20.5.

Structures can be converted to bits preserving the bit pattern. In other words, they can be converted back to the same value without any loss of information. When unpacked data are converted to the packed representation, the order of the data in the packed representation is such that the first field in the structure

VERIFICATION LANGUAGE

occupies the MSBs. The effect is the same as a concatenation of the data items (struct fields or array elements) in order. The type of the elements in an unpacked structure or array shall be valid for a packed representation in order to be cast to any other type, whether packed or unpacked.

An explicit cast between packed types is not required because they are implicitly cast as integral values, but a cast can be used by tools to perform stronger type checking.

The following example demonstrates how $bits can be used to obtain the size of a structure in bits (the

$bits system function is discussed in 20.6.2), which facilitates conversion of the structure into a packed array:

typedef struct {

bit isfloat;

union { int i; shortreal f; } n; // anonymous type

} tagged_st; // named structure

typedef bit [$bits(tagged_st) - 1 : 0] tagbits; // tagged_st defined above tagged_st a [7:0]; // unpacked array of structures

tagbits t = tagbits'(a[3]); // convert structure to array of bits a[4] = tagged_st'(t); // convert array of bits back to structure Note that the bit data type loses X values. If these are to be preserved, the logic type should be used instead.

The size of a union in bits is the size of its largest member. The size of a logic in bits is 1.

The functions $itor, $rtoi, $bitstoreal, $realtobits, $signed, and $unsigned can also be used to perform type conversions (see Clause 20).

6.24.2 $cast dynamic casting

The $cast system task can be used to assign values to variables that might not ordinarily be valid because of differing data type. $cast can be called as either a task or a function.

The syntax for $cast is as follows:

function int $cast( singular dest_var, singular source_exp );

or

task $cast( singular dest_var, singular source_exp );

The dest_var is the variable to which the assignment is made.

The source_exp is the expression that is to be assigned to the destination variable.

Use of $cast as either a task or a function determines how invalid assignments are handled.

When called as a task, $cast attempts to assign the source expression to the destination variable. If the assignment is invalid, a run-time error occurs, and the destination variable is left unchanged.

When called as a function, $cast attempts to assign the source expression to the destination variable and returns 1 if the cast is legal. If the cast fails, the function does not make the assignment and returns 0. When called as a function, no run-time error occurs, and the destination variable is left unchanged.

It is important to note that $cast performs a run-time check. No type checking is done by the compiler, except to check that the destination variable and source expression are singulars. The $cast behavior when applied to class handles is described in 8.16.

For example:

typedef enum { red, green, blue, yellow, white, black } Colors;

Colors col;

$cast( col, 2 + 3 );

This example assigns the expression (5 => black) to the enumerated type. Without $cast or a static compile-time cast operation, this type of assignment is illegal.

The following example shows how to use the $cast to check whether an assignment will succeed:

if ( ! $cast( col, 2 + 8 ) ) // 10: invalid cast

$display( "Error in cast" );

Alternatively, the preceding examples can be cast using a static cast operation. For example:

col = Colors'(2 + 3);

However, this is a compile-time cast, i.e, a coercion that always succeeds at run time and does not provide for error checking or warn if the expression lies outside the enumeration values.

Allowing both types of casts gives full control to the user. If users know that certain expressions assigned to an enumerated variable lie within the enumeration values, the faster static compile-time cast can be used. If users need to check if an expression lies within the enumeration values, it is not necessary to write a lengthy case statement manually. The compiler automatically provides that functionality via the $cast function. By providing both types of casts, SystemVerilog enables users to balance the trade-offs of performance and checking associated with each cast type.

NOTE—$cast is similar to the dynamic_cast function available in C++. However, $cast allows users to check whether the operation will succeed, whereas dynamic_cast always raises a C++ exception.