• 沒有找到結果。

tag is 0 for Invalid, 1 for Valid

7.9 Associative array methods

In addition to the indexing operators, several built-in methods are provided, which allow users to analyze and manipulate associative arrays, as well as iterate over its indices or keys.

7.9.1 Num() and size()

The syntax for the num() and size() methods is as follows:

function int num();

function int size();

The num() and size() methods return the number of entries in the associative array. If the array is empty, they return 0.

int imem[int];

imem[ 2'b3 ] = 1;

imem[ 16'hffff ] = 2;

imem[ 4b'1000 ] = 3;

$display( "%0d entries\n", imem.num ); // prints "3 entries"

7.9.2 Delete()

The syntax for the delete() method is as follows:

VERIFICATION LANGUAGE

function void delete( [input index] );

where index is an optional index of the appropriate type for the array in question.

If the index is specified, then the delete() method removes the entry at the specified index. If the entry to be deleted does not exist, the method issues no warning.

If the index is not specified, then the delete() method removes all the elements in the array.

int map[ string ];

map[ "hello" ] = 1;

map[ "sad" ] = 2;

map[ "world" ] = 3;

map.delete( "sad" ); // remove entry whose index is "sad" from "map"

map.delete; // remove all entries from the associative array "map"

7.9.3 Exists()

The syntax for the exists() method is as follows:

function int exists( input index );

where index is an index of the appropriate type for the array in question.

The exists() function checks whether an element exists at the specified index within the given array. It returns 1 if the element exists; otherwise, it returns 0.

if ( map.exists( "hello" )) map[ "hello" ] += 1;

else

map[ "hello" ] = 0;

7.9.4 First()

The syntax for the first() method is as follows:

function int first( ref index );

where index is an index of the appropriate type for the array in question. Associative arrays that specify a wildcard index type shall not be allowed.

The first() method assigns to the given index variable the value of the first (smallest) index in the associative array. It returns 0 if the array is empty; otherwise, it returns 1.

string s;

if ( map.first( s ) )

$display( "First entry is : map[ %s ] = %0d\n", s, map[s] );

7.9.5 Last()

The syntax for the last() method is as follows:

function int last( ref index );

where index is an index of the appropriate type for the array in question. Associative arrays that specify a wildcard index type shall not be allowed.

The last() method assigns to the given index variable the value of the last (largest) index in the associative array. It returns 0 if the array is empty; otherwise, it returns 1.

string s;

if ( map.last( s ) )

$display( "Last entry is : map[ %s ] = %0d\n", s, map[s] );

7.9.6 Next()

The syntax for the next() method is as follows:

function int next( ref index );

where index is an index of the appropriate type for the array in question. Associative arrays that specify a wildcard index type shall not be allowed.

The next() method finds the smallest index whose value is greater than the given index argument.

If there is a next entry, the index variable is assigned the index of the next entry, and the function returns 1.

Otherwise, the index is unchanged, and the function returns 0.

string s;

if ( map.first( s ) ) do

$display( "%s : %d\n", s, map[ s ] );

while ( map.next( s ) );

7.9.7 Prev()

The syntax for the prev() method is as follows:

function int prev( ref index );

where index is an index of the appropriate type for the array in question. Associative arrays that specify a wildcard index type shall not be allowed.

The prev() function finds the largest index whose value is smaller than the given index argument. If there is a previous entry, the index variable is assigned the index of the previous entry, and the function returns 1.

Otherwise, the index is unchanged, and the function returns 0.

string s;

if ( map.last( s ) ) do

$display( "%s : %d\n", s, map[ s ] );

while ( map.prev( s ) );

7.9.8 Arguments to traversal methods

The argument that is passed to any of the four associative array traversal methods first(), last(), next(), and prev() shall be assignment compatible with the index type of the array. If the argument has an integral type that is smaller than the size of the corresponding array index type, then the function returns –1 and shall truncate in order to fit into the argument. For example:

VERIFICATION LANGUAGE

string aa[int];

byte ix;

int status;

aa[ 1000 ] = "a";

status = aa.first( ix );

// status is –1

// ix is 232 (least significant 8 bits of 1000) 7.9.9 Associative array assignment

Associative arrays can be assigned only to another associative array of a compatible type and with the same index type. Other types of arrays cannot be assigned to an associative array, nor can associative arrays be assigned to other types of arrays, whether fixed-size or dynamic.

Assigning an associative array to another associative array causes the target array to be cleared of any existing entries, and then each entry in the source array is copied into the target array.

7.9.10 Associative array arguments

Associative arrays can be passed as arguments only to associative arrays of a compatible type and with the same index type. Other types of arrays, whether fixed-size or dynamic, cannot be passed to subroutines that accept an associative array as an argument. Likewise, associative arrays cannot be passed to subroutines that accept other types of arrays.

Passing an associative array by value causes a local copy of the associative array to be created.

7.9.11 Associative array literals

Associative array literals use the '{index:value} syntax with an optional default index. Like all other arrays, an associative array can be written one entry at a time, or the whole array contents can be replaced using an array literal.

For example:

// an associative array of strings indexed by 2-state integers, // default is "hello".

string words [int] = '{default: "hello"};

// an associative array of 4-state integers indexed by strings, default is –1 integer tab [string] = '{"Peter":20, "Paul":22, "Mary":23, default:-1 };

If a default value is specified, then reading a nonexistent element shall yield the specified default value, and no warning shall be issued. Otherwise, the value specified by Table 7-1 (see 7.4.6) shall be returned.

Defining a default value shall not affect the operation of the associative array methods (see 7.9).

7.10 Queues

A queue is a variable-size, ordered collection of homogeneous elements. A queue supports constant-time access to all its elements as well as constant-time insertion and removal at the beginning or the end of the queue. Each element in a queue is identified by an ordinal number that represents its position within the queue, with 0 representing the first, and $ representing the last. A queue is analogous to a one-dimensional

unpacked array that grows and shrinks automatically. Thus, like arrays, queues can be manipulated using the indexing, concatenation, slicing operator syntax, and equality operators.

Queues are declared using the same syntax as unpacked arrays, but specifying $ as the array size. The maximum size of a queue can be limited by specifying its optional right bound (last index).

Queue values may be written using assignment patterns or unpacked array concatenations (see 10.9, 10.10).

The syntax for declaring queues is shown in Syntax 7-4.

variable_dimension ::= // from A.2.5

unsized_dimension

| unpacked_dimension

| associative_dimension

| queue_dimension

queue_dimension ::= [ $ [ : constant_expression ] ]

Syntax 7-4—Declaration of queue dimension (excerpt from Annex A)

constant_expression shall evaluate to a positive integer value.

For example:

byte q1[$]; // A queue of bytes

string names[$] = { "Bob" }; // A queue of strings with one element integer Q[$] = { 3, 2, 7 }; // An initialized queue of integers

bit q2[$:255]; // A queue whose maximum size is 256 bits The empty array literal {} is used to denote an empty queue. If an initial value is not provided in the declaration, the queue variable is initialized to the empty queue.

7.10.1 Queue operators

Queues shall support the same operations that can be performed on unpacked arrays. In addition, queues shall support the following operations:

— A queue shall resize itself to accommodate any queue value that is written to it, except that its maxi-mum size may be bounded as described in 7.10.

— In a queue slice expression such as Q[a:b], the slice bounds may be arbitrary integral expressions and, in particular, are not required to be constant expressions.

— Queues shall support methods as described in 7.10.2.

Unlike arrays, the empty queue, {}, is a valid queue and the result of some queue operations. The following rules govern queue operators:

— Q[ a : b ] yields a queue with b - a + 1 elements.

— If a > b, then Q[a:b] yields the empty queue {}.

— Q[ n : n ] yields a queue with one item, the one at position n. Thus, Q[ n : n ] === { Q[n] }.

— If n lies outside Q’s range (n < 0 or n > $), then Q[n:n] yields the empty queue {}.

— If either a or b are 4-state expressions containing X or Z values, it yields the empty queue {}.

— Q[ a : b ] where a < 0 is the same as Q[ 0 : b ].

VERIFICATION LANGUAGE

— Q[ a : b ] where b > $ is the same as Q[ a : $ ].

— An invalid index value (i.e., a 4-state expression whose value has one or more x or z bits, or a value that lies outside 0...$) shall cause a read operation to return the value appropriate for a nonexistent array entry of the queue’s element type (as described in Table 7-1 in 7.4.6).

— An invalid index (i.e., a 4-state expression with X’s or Z’s, or a value that lies outside 0...$+1) shall cause a write operation to be ignored and a run-time warning to be issued; however, writing to Q[$+1] is legal.

— A queue declared with a right bound using the syntax [$:N] is known as a bounded queue and shall be limited to have indices not greater than N (its size shall not exceed N+1). The additional rules governing bounded queues are described in 7.10.5.

7.10.2 Queue methods

In addition to the array operators, queues provide several built-in methods. Assume these declarations for the examples that follow:

typedef mytype element_t; // mytype is any legal type for a queue typedef element_t queue_t[$];

element_t e;

queue_t Q;

int i;

7.10.2.1 Size()

The prototype for the size() method is as follows:

function int size();

The size() method returns the number of items in the queue. If the queue is empty, it returns 0.

for ( int j = 0; j < Q.size; j++ ) $display( Q[j] );

7.10.2.2 Insert()

The prototype of the insert() method is as follows:

function void insert(input integer index, input element_t item);

The insert() method inserts the given item at the specified index position.

If the index argument has any bits with unknown (x/z) value, or is negative, or is greater than the current size of the queue, then the method call shall have no effect on the queue and may cause a warning to be issued.

NOTE—The index argument is of type integer rather than int so that x/z values in the caller’s actual argument value can be detected.

7.10.2.3 Delete()

The prototype for the delete() method is as follows:

function void delete( [input integer index] );

where index is an optional index.

If the index is not specified, then the delete() method deletes all the elements in the queue, leaving the queue empty.

If the index is specified, then the delete() method deletes the item at the specified index position. If the index argument has any bits with unknown (x/z) value, or is negative, or is greater than or equal to the current size of the queue, then the method call shall have no effect on the queue and may cause a warning to be issued.

7.10.2.4 Pop_front()

The prototype of the pop_front() method is as follows:

function element_t pop_front();

The pop_front() method removes and returns the first element of the queue.

If this method is called on an empty queue:

— Its return value shall be the same as that obtained by attempting to read a nonexistent array element of the same type as the queue's elements (as described in Table 7-1, in 7.4.6);

— It shall have no effect on the queue and may cause a warning to be issued.

7.10.2.5 Pop_back()

The prototype of the pop_back() method is as follows:

function element_t pop_back();

The pop_back() method removes and returns the last element of the queue.

If this method is called on an empty queue:

— Its return value shall be the same as that obtained by attempting to read a nonexistent array element of the same type as the queue's elements (as described in Table 7-1 in 7.4.6);

— It shall have no effect on the queue and may cause a warning to be issued.

7.10.2.6 Push_front()

The prototype of the push_front() method is as follows:

function void push_front(input element_t item);

The push_front() method inserts the given element at the front of the queue.

7.10.2.7 Push_back()

The prototype of the push_back() method is as follows:

function void push_back(input element_t item);

The push_back() method inserts the given element at the end of the queue.

VERIFICATION LANGUAGE

7.10.3 Persistence of references to elements of a queue

As described in 13.5.2, it is possible for an element of a queue to be passed by reference to a task that continues to hold the reference while other operations are performed on the queue. Some operations on the queue shall cause any such reference to become outdated (as defined in 13.5.2). This subclause defines the situations in which a reference to a queue element shall become outdated.

When any of the queue methods described in 7.10.2 updates a queue, a reference to any existing element that is not deleted by the method shall not become outdated. All elements that are removed from the queue by the method shall become outdated references.

When the target of an assignment is an entire queue, references to any element of the original queue shall become outdated.

As a consequence of this clause, inserting elements in a queue using unpacked array concatenation syntax, as illustrated in the examples in 7.10.4, will cause all references to any element of the existing queue to become outdated. Use of the delete, pop_front, and pop_back methods will outdate any reference to the popped or deleted element, but will leave references to all other elements of the queue unaffected. By contrast, use of the insert, push_back, and push_front methods on a queue can never give rise to outdated references (except that insert or push_front on a bounded queue would cause the highest-numbered element of the queue to be deleted if the new size of the queue were to exceed the queue’s bound).

7.10.4 Updating a queue using assignment and unpacked array concatenation

As described in 7.10, a queue variable may be updated by assignment. Together with unpacked array concatenation, this offers a flexible alternative to the queue methods described in 7.10.2 when performing operations on a queue variable.

The following examples show queue assignment operations that exhibit behaviors similar to those of queue methods. In each case the resulting value of the queue variable shall be the same as if the queue method had been applied, but any reference to elements of the queue will become outdated by the assignment operation (see 7.10.3):

int q[$] = { 2, 4, 8 };

int e, pos;

// assignment // method call yielding the

// // same value in variable q

// ---- //

---q = { ---q, 6 }; // q.push_back(6)

q = { e, q }; // q.push_front(e)

q = q[1:$]; // void'(q.pop_front()) or q.delete(0)

q = q[0:$-1]; // void'(q.pop_back()) or

// q.delete(q.size-1) q = { q[0:pos-1], e, q[pos:$] }; // q.insert(pos, e) q = { q[0:pos], e, q[pos+1:$] }; // q.insert(pos+1, e)

q = {}; // q.delete()

Some useful operations that cannot be implemented as a single queue method call are illustrated in the following examples. As in the preceding examples, assignment to the queue variable outdates any reference to its elements.

q = q[2:$]; // a new queue lacking the first two items q = q[1:$-1]; // a new queue lacking the first and last items

7.10.5 Bounded queues

A bounded queue shall not have an element whose index is higher than the queue’s declared upper bound.

Operations on bounded queues shall behave exactly as if the queue were unbounded except that if, after any operation that writes to a bounded queue variable, that variable has any elements beyond its bound, then all such out-of-bounds elements shall be discarded and a warning shall be issued.

NOTE—Implementations may meet this requirement in any way that achieves the same result. In particular, they are not required to write the out-of-bounds elements before discarding them.