Section 4.2

LRM-109

Change (change in red):

For the purposes of assignment, a packed array is treated as a vector. Any vector expression can be assigned to any packed array. The packed array bounds of the target packed array do not affect the assignment. A packed array cannot be directly assigned to an unpacked array without an explicit cast.

Section 4.3

LRM-87

Change (change in red):

Out of range index values shall be illegal for both reading from and writing to an array of 2-state variables, such as int. The result of an out of range index value is indeterminate. Implementations shall generate a warning if an out of range index occurs for a read or write operation.

 

The result of reading from an array of 2-state variables, such as int, with an out of range index is indeterminate. Writing to an array with an out of range index performs no operation. Implementations may generate a warning if an out of range index occurs for a read or write operation.

Section 4.4

LRM-100

Change (change in red):

reg [63:0] data;

reg [7:0] byte2;

byte2 = data[23:16]; // an 8-bit part select from data

Section 4.6

LRM-103

Change (change in red):

Dynamic arrays are one-dimensional unpacked arrays whose size can be set or changed at runtime. The space for a dynamic array doesn’t exist until the array is explicitly created at runtime.

Section 4.9

LRM-103

Change (change in red):

Array elements in associative arrays are allocated dynamically; an entry is created the first time it is written. The associative array maintains the entries that have been assigned values and their relative order according to the index data type. Associative arrays elements are unpacked, meaning that other than copying or comparing arrays, you must select an individual element out of the array before using it in most expressions.

Section 4.9.3

LRM-60

Change (change in red):

— A null index is invalid valid.

Section 4.9.7 (New)

LRM-60

Change (change in red):

4.9.7 Other user defined types

 

Example:

 

typedef struct {real R; int I[*];} Unpkt;

int array_name [ Unpkt ];

 

In general, associative arrays that specify an index of any type have the following properties

 

      Declared Indices must have the equality operator defined for its type to be legal. This includes all of the dynamically sized types as legal Index types

      An Index expression that is or contains X or Z in any of its elements is invalid.

      An Index expression that is or contains an empty value or null for any of it elements does not make the Index invalid.

      If the relational operator is defined for the Index type, the ordering is as defined in the preceding sections. If not, the relative ordering of any two entries in such an associative array can vary, even between successive runs of the same tool. However, the relative ordering must remain the same within the same simulation run while no Indices have been added or deleted.

Section 4.14 (New)

LRM-43

Change (change in red):

4.14 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.

 

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

 

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.

 

4.14.1 Queue Operators

 

Queues support the same operations that can be performed on unpacked arrays, and using the same operators and rules except as defined below:

 

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

int p[$];

int e, pos;

 

e = q[0];              // read the first (leftmost) item

e = q[$];              // read the last (rightmost) item

q[0] = e;              // write the first item

p = q;                 // read and write entire queue (copy)

 

q = { q, 6 };          // insert ‘6’ at the end (append 6)

q = { e, q };          // insert ‘e’ at the beginning (prepend e)

 

q = q[1:$];            // delete the first (leftmost) item

q = q[0:$-1];          // delete the last (rightmost) item

q = q[1:$-1];          // delete the first and last items

 

q = {};                // clear the queue (delete all items)

 

q = { q[0:pos-1], e, q[pos,$] };     // insert ‘e’ at position pos

q = { q[0:pos], e, q[pos+1,$] };     // insert ‘e’ after position pos

 

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 ].

 

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

 

      An invalid index value (i.e., a 4-state expression with X's or Z's, or a value that lies outside 0..$) shall cause a read operation (e = Q[n]) to return the default initial value for the type of queue item (as described in Table 4-1).

 

      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. Note that writing to Q[$+1] is legal.

 

NOTE: Queues and dynamic arrays have the same assignment and argument passing semantics.

 

4.14.2 Queue methods

 

In addition to the array operators, queues provide several built-in methods.

 

4.14.2.1 size()

 

The prototype  for the size() method is:

 

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] );

 

4.14.2.2 insert()

 

The prototype of the insert() method is:

 

function void insert(int index, queue_type item);

 

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

¾      Q.insert(i, e) is equivalent to:  Q = {Q[0:i-1], e, Q[i,$]}

 

4.14.2.3 delete()

 

The prototype of the delete() method is:

 

function void delete(int index);

 

The delete() method deletes the item at the specified index position.

¾      Q.delete(i) is equivalent to:  Q = {Q[0:i-1], Q[i+1,$]}

 

4.14.2.4 pop_front()

 

The prototype of the pop_front() method is:

 

function queue_type pop_front();

 

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

¾      e = Q.pop_front() is equivalent to:  e = Q[0]; Q = Q[1,$]

 

4.14.2.5 pop_back()

 

The prototype of the pop_back() method is:

 

function queue_type pop_back();

 

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

¾      e = Q.pop_back() is equivalent to:  e = Q[$]; Q = Q[0,$-1]

 

4.14.2.6 push_front()

 

The prototype of the push_front() method is:

 

function void push_front(queue_type item);

 

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

¾      Q.push_front(e) is equivalent to:  Q = {e, Q}

 

4.14.2.7 push_back()

 

The prototype of the push_back() method is:

 

function void push_back(queue_type item);

 

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

¾      Q.push_back(e) is equivalent to: Q = {Q, e}

Section 4.15 (New)

LRM-43

Change (change in red):

 

4.15 Array Manipulation Methods

 

SystemVerilog provides several built-in methods to facilitate array searching, ordering, and reduction.

 

The general syntax to call these array methods is:

 

array_method_call ::=                                                                       // from Annex A.8.2

array_identifier . method_identifier [ ([ iterator_identifier ] ) ] [ with ( expression ) ]

 

Syntax 4-8—array method call syntax (excerpt from Annex A)

 

The optional with clause accepts an expression enclosed in parenthesis. In contrast, the with clause used by the randomize method (see Section 12.6) accept a set of constraints enclosed in braces.

 

4.15.1 Array Locator Methods

 

Array locator methods operate on any unpacked array, including queues, but their return type is a queue. These locator methods allow searching an array for elements (or their indexes) that satisfy a given expression. Array locator methods traverse the array in an unspecified order. The optional with expression should not include any side effects; if it does, the results are unpredictable.

 

The prototype of these methods is:

 

       function array_type [$] locator_method ( array_type iterator = item );                                    // same type as the array

or

                function int_or_index_type [$] index_locator_method ( array_type iterator = item );           // index type

 

Index locator methods return a queue of  int for all arrays except associative arrays, which return a queue of the same type as the associative index type.

 

If no elements satisfy the given expression or the array is empty (in the case of a queue or dynamic array) then an empty queue is returned, otherwise these methods return a queue containing all items that satisfy the expression. Index locator methods return a queue with the indexes of all items that satisfy the expression. The optional expression specified by the with clause must evaluate to a boolean value.

 

Locator methods iterate over the array elements, which are then used to evaluate the expression specified by the with clause. The iterator argument optionally specifies the name of the variable used by the with expression to designate the element of the array at each iteration. If it is not specified, the name item is used by default. The scope for the iterator name is the with expression.

 

The following locator methods are supported (the with clause is mandatory) :

 

¾      find() returns all the elements satisfying the given expression

 

¾      find_index() returns the indexes of all the elements satisfying the given expression

 

¾      find_first() returns the first element satisfying the given expression

 

¾      find_first_index() returns the index of the first element satisfying the given expression

 

¾      find_last() returns the last element satisfying the given expression

 

¾      find_last_index() returns the index of the last element satisfying the given expression

 

For the following locator methods the with clause (and its expression) can be omitted if the relational operators (<, >, ==) are defined for the element type of the given array. If a with clause is specified, the relational operators (<, >, ==) must be defined for the type of the expression.

 

¾      min() returns the element with the minimum value or whose expression evaluates to a minimum

 

¾      max() returns the element with the maximum value or whose expression evaluates to a maximum

 

¾      unique() returns all elements with unique values or whose expression is unique

 

¾      unique_index() returns the indexes of all elements with unique values or whose expression is unique

 

Examples:

 

       string SA[10], qs[$];

       int IA[*], qi[$];

 

       qi = IA.find( x ) with ( x > 5 );                      // Find all items greater than 5

 

       qi = IA.find_index with ( item == 3 );                 // Find indexes of all items equal to 3

 

      qs = SA.find_first with ( item == “Bob” );      // Find first item equal to Bob

 

                qs = SA.find_last( y ) with ( y == “Henry” );          // Find last item equal to Henry

 

       qi = SA.find_last_index( s ) with ( s > “Z” );         // Find index of last item greater than Z

 

       qi = IA.min;                                           // Find smallest item

 

       qs = SA.max with ( item.atoi );                        // Find string with largest numerical value

 

       qs = SA.unique;                                        // Find all unique strings elements

 

       qs = SA.unique( s ) with ( s.tolower );                // Find all unique strings in lower-case

 

 

4.15.2 Array ordering methods

 

Array ordering methods can reorder the elements of one-dimensional arrays or queues.

 

The general prototype for the ordering methods is:

 

                function void ordering_method ( array_type iterator = item )

 

The following ordering methods are supported:

 

¾      reverse() reverses all the elements of the array (packed or unpacked). Specifying a with clause shall be a compiler error.

 

¾      sort() sorts the unpacked array in ascending order, optionally using the expression in the with clause. The with clause (and its expression) is optional when the relational operators are defined for the array element type.

 

¾      rsort() sorts the unpacked array in descending order, optionally using the expression in the with clause. The with clause (and its expression) is optional when the relational operators are defined for the array element type.

 

¾      shuffle() randomizes the order of the elements in the array. Specifying a with clause shall be a compiler error.

 

Examples:

 

       string s[] = { “hello”, “sad”, “world” };

       s.reverse;                                      // s becomes { “world”, “sad”, “hello” };

 

       logic [4:1] b = 4’bXZ01;

                b.reverse;                                      // b becomes 4’b10ZX

 

       int q[$] = { 4, 5, 3, 1 };

       q.sort;                                         // q becomes { 1, 3, 4, 5 }

      

       struct { byte red, green, blue } c [512];

       c.sort with ( item.red );                       // sort c using the red field only

       c.sort( x ) with ( x.blue << 8 + x.green );     // sort by blue then green

 

 

4.15.3 Array reduction methods

 

Array reduction methods can be applied to any unpacked array to reduce the array to a single value. The expression within the optional with clause can be used to specify the item to use in the reduction.

 

The prototype for these methods is:

 

                function expression_or_array_type  reduction_method ( array_type iterator = item )

 

The method returns a single value of the same type as the array element type or, if specified, the type of the expression in the with clause. The with clause can be omitted if the corresponding arithmetic or boolean reduction operation is defined for the array element type. If a with clause is specified, the corresponding arithmetic or boolean reduction operation must be defined for the type of the expression.

 

The following reduction methods are supported:

 

¾      sum() returns the sum of all the array elements, or if a with clause is specified, returns the sum of the values yielded by evaluating the expression for each array element.

 

¾      product() returns the product of all the array elements, or if a with clause is specified, returns the product of the values yielded by evaluating the expression for each array element.

 

¾      and() returns the bit-wise AND (&) of all the array elements, or if a with clause is specified, returns the bit-wise AND of the values yielded by evaluating the expression for each array element

 

¾      or() returns the bit-wise OR (|) of all the array elements, or if a with clause is specified, returns the bit-wise OR of the values yielded by evaluating the expression for each array element

 

¾      xor() returns the logical XOR (^) of all the array elements, or if a with clause is specified, returns the XOR of the values yielded by evaluating the expression for each array element

 

Examples:

 

       byte b[] = { 1, 2, 3, 4 };

       int y;

 

       y = b.sum ;                       // y becomes 10 => 1 + 2 + 3 + 4

       y = b.product ;                   // y becomes 24 => 1 * 2 * 3 * 4

                y = b.xor with ( item + 4 );      // y becomes 12 => 5 ^ 6 ^ 7 ^ 8

 

4.15.4 Iterator index querying

 

The expressions used by array manipulation methods sometimes need the actual array indexes at each iteration, not just the array element. The index method of an iterator returns the index value of the specified dimension. The prototype of the index method is:

 

            function int_or_index_type index ( int dimension = 1 )

 

The array dimensions are numbered as defined in Section 22-2: The slowest varying is dimension 1. Successively faster varying dimensions have sequentially higher dimension numbers. If the dimension is not specified, the first dimension is used by default

 

The return type of the index method is an int for all array iterator items except associative arrays, which returns an index of the same type as the associative index type.

 

For example:

 

                int  arr[]

       int  mem[9:0][9:0], mem2[9:0][9:0];

       int  q[$];

       ...

 

       // find all items equal to their position (index)

       q = arr.find with ( item == item.index );

 

       // find all items in mem that are greater than corresponding item in mem2

       q = mem.find( x ) with ( x > mem2[x.index(1)][x.index(2)] );