Array methods

Array Locator Methods

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[$];
// Find all items greater than 5
qi = IA.find( x ) with ( x > 5 );
// Find indexes of all items equal to 3
qi = IA.find_index with ( item == 3 );
// Find the first item equal to Bob
qs = SA.find_first with ( item == "Bob" );
// Find the last item equal to Henry
qs = SA.find_last( y ) with ( y == "Henry" );
// Find the index of the last item greater than Z
qi = SA.find_last_index( s ) with ( s > "Z" );
// Find the smallest item
qi = IA.min;
// Find the string with a largest numerical value
qs = SA.max with ( item.atoi );
// Find all unique strings elements
qs = SA.unique;
// Find all unique strings in lower-case
qs = SA.unique( s ) with ( s.tolower );

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", "good", "morning" };
s.reverse; // s becomes { "morning", "good", "hello" };
logic [4:1] a = 4’bXZ01;
a.reverse; // a 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

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 bitwise 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

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 slowest variation 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[$];
//Finds all items equal to their position (index)
q = arr.find with ( item == item.index );
//Finds all items in mem that are greater than the corresponding item in mem2
q = mem.find( x ) with ( x > mem2[x.index(1)][x.index(2)] );

<< Previous | Next >>

Associative arrays

When the size of the collection is unknown or the data space is sparse, an associative array is a better option. Associative arrays do not have any storage allocated until it is used, and the index expression is not restricted to integral expressions but can be of any type.
An associative array implements a lookup table of the elements of its declared type. The data type to be used as an index serves as the lookup key, and imposes an ordering.

The syntax to declare an associative array is:

data_type array_id [ index_type ];

where:

  • data_type is the data type of the array elements. Can be any type allowed for fixed-size arrays.
  • array_id is the name of the array being declared.
  • index_type is the data type to be used as an index, or *. If * is specified, then the array is indexed by any

integral expression of arbitrary size. An index type restricts the indexing expressions to a particular type.

Examples of associative array declarations are:

integer i_array[*]; // associative array of integer (unspecified index)
bit [20:0] array_b[string]; // associative array of 21-bit vector, indexed by string
event ev_array[myClass]; // associative array of event indexed by class myClass

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

Wildcard index type

Example: int array_name [*];

Associative arrays that specify a wildcard index type have the following properties:

  • The array can be indexed by any integral data type. Since the indices can be of different sizes, the same numerical value can have multiple representations, each of a different size. SystemVerilog resolves this ambiguity by detecting the number of leading zeros and computing a unique length and representation for every value.
  • Non-integral index types are illegal and result in a type check error.
  • A 4-state Index containing X or Z is invalid.
  • Indices are unsigned.
  • Indexing expressions are self-determined; signed indices are not sign extended.
  • A string literal index is auto-cast to a bit-vector of equivalent size.
  • The ordering is numerical (smallest to largest).

String index

Example: int array_name [ string ];

Associative arrays that specify a string index have the following properties:

  • Indices can be strings or string literals of any length. Other types are illegal and shall result in a type check error.
  • An empty string “” index is valid.
  • The ordering is lexicographical (lesser to greater).

Class index

Example: int array_name [ some_Class ];

Associative arrays that specify a class index have the following properties:

  • Indices can be objects of that particular type or derived from that type. Any other type is illegal and shall result in a type check error.
  • A null index is valid.
  • The ordering is deterministic but arbitrary.

Integer (or int) index

Example: int array_name [ integer ];

Associative arrays that specify an integer index have the following properties:

  • Indices can be any integral expression.
  • Indices are signed.
  • A 4-state index containing X or Z is invalid.
  • Indices smaller than integer are sign extended to 32 bits.
  • Indices larger than integer are truncated to 32 bits.
  • The ordering is signed numerical.

Signed packed array

Example: typedef bit signed [4:1] Nibble;

int array_name [ Nibble ];

Associative arrays that specify a signed packed array index have the following properties:

  • Indices can be any integral expression.
  • Indices are signed.
  • Indices smaller than the size of the index type are sign extended.
  • Indices larger than the size of the index type are truncated to the size of the index type.
  • The ordering is signed numerical.

Unsigned packed array or packed struct

Example: typedef bit [4:1] Nibble;

int array_name [ Nibble ];

Associative arrays that specify an unsigned packed array index have the following properties:

  • Indices can be any integral expression.
  • Indices are unsigned.
  • A 4-state Index containing X or Z is invalid.
  • Indices smaller than the size of the index type are zero filled.
  • Indices larger than the size of the index type are truncated to the size of the index type.
  • The ordering is numerical

Associative array methods

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

num()

The syntax for the num() method is:
function int num();

The num() method returns the number of entries in the associative array. If the array is empty, it returns 0.

int imem[*];
imem[ 2’b3 ] = 1;
imem[ 16’hffff ] = 2;
imem[ 4b’1000 ] = 3;
$display( "%0d entries\n", imem.num );
// prints “3 entries”

delete()

The syntax for the delete() method is:
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”

exists()

The syntax for the exists() method is:
function int exists( input index );

Where index is an index of the appropriate type for the array in question. The exists() function checks if 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;

first()

The syntax for the first() method is:
function int first( ref index );

Where index is an index of the appropriate type for the array in question. 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, and 1 otherwise.

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

last()

The syntax for the last() method is:
function int last( ref index );

Where index is an index of the appropriate type for the array in question. 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, and 1 otherwise.

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

next()

The syntax for the next() method is:
function int next( ref index );

Where index is an index of the appropriate type for the array in question. The next() method finds the entry whose index is greater than the given index. 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 ) );

prev()

The syntax for the prev() method is:
function int prev( ref index );

Where index is an index of the appropriate type for the array in question. The prev() function finds the entry whose index is smaller than the given index. 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 ) );

If the argument passed to any of the four associative array traversal methods first, last, next, and prev are smaller than the size of the corresponding index, then the function returns –1 and shall copy only as much data as can fit into the argument. For example:

string aa[*];
byte ix;
int status;
aa[ 1000 ] = "a";
status = aa.first( ix );

// status is –1
// ix is 232 (least significant 8 bits of 1000)

<< Previous | Next >>