System Verilog: Associative Arrays

System Verilog: Associative Arrays

Associative array is one of aggregate data types available in system verilog.

We have already discussed about dynamic array, which is useful for dealing with contiguous collection of variables whose number changes dynamically.

When the size of the collection is unknown or the data space is sparse, an associative array is used, which does not have any storage allocated unitil it is used. That means, it is dynamically allocated, but has non-contiguous elements. Associative array's index expression is not restricted to integral expressions, but can be of any type.

Associative array uses key value pairs and it implements a look up table. That is, associative array maintains the entries that have been assigned values and their relative order according to the index data type. The associative array methods available ensure fastest access to all array elements.

Associative arrays can be assigned only to another Associative array of a compatible type and with the same index type.In the same way, associative arrays can be passed as arguments only to associative arrays of a compatible type and with the same index type.

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.

integer name_list [string] = '{"Mohan":60, "Kiran":20, "Savitha":18, 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.

Below example shows associative array declarations and adding elements to the array. The entire array can be displayed using `do while`. Some of the properties of associative arrays which are specified using wildcard index type are also shown below.

  • The ordering is numerical (smallest to largest).
  • Nonintegral index values are illegal and result in an error.
  • A 4-state index value containing X or Z is invalid.
  • Indexing expressions are self-determined and treated as unsigned.
  • A string literal index is automatically cast to a bit vector of equivalent size.
  • It shall not be used in a foreach loop or with an array manipulation method

module assoc_array_check1;

//Declaration int AarrA [*]; //Wildcard index. can be indexed by any integral datatype. int AarrStr [ string ];// String index int AarrB [ integer ];// Integer index bit [15:0] AarrC [*]; integer i; string str;

initial begin

//Default size of an associative array is 0. $display("AarrA default size=%0d",AarrA.num()); $display("AarrB default size=%0d",AarrB.num()); $display("AarrC default size=%0d",AarrC.num()); $display("AarrStr default size=%0d",AarrStr.num());

//Adding elements for AarrA AarrA[1] = 111; AarrA[2'd3] = 333; AarrA[5'b00101] = 555; AarrA[7] = 777;

//AarrA["hello"] = 777; ///Nonintegral index values are illegal and result in an error. // SystemVerilog associative array index overflow, value can't fit in specified index

$display( "AarrA has %0d entries", AarrA.num ); if (AarrA.first(i) ) do $display( "%d : %d", i, AarrA[i] ); while ( AarrA.next(i) ); end endmodule

/* ncsim> run AarrA default size=0 AarrB default size=0 AarrC default size=0 AarrStr default size=0 AarrA has 4 entries 1 : 111 3 : 333 5 : 555 7 : 777 ncsim: *W,RNQUIE: Simulation is complete.

*/

In the above code, you can see that entry is done in different order, but final array elements have been printed from smallest to largest.

If a read operation uses an index that is a 4-state expression with one or more x or z bits, or an attempt is made to read a nonexistent entry, then a warning shall be issued and the nonexistent entry value for the array type shall be returned. A user-specified default shall not issue a warning.If an invalid index is used during a write operation, the write shall be ignored, and a warning shall be issued.

Associative Array Methods num() size(): The num() or size() method returns the number of entries in the associative array. If the array is empty, it returns 0.

module assoc_array_num_size_check;

int AarrB [ integer ];// Integer index integer i;

initial begin

//Adding elements for AarrB AarrB[5] = 500; AarrB[10] = 1000; AarrB[15] = 1500; AarrB[20] = 2000;

$display( "Use num() : AarrB has %0d entries", AarrB.num ); $display( "Use size() : AarrB has %0d entries", AarrB.size );

end endmodule /* ncsim> run Use num() : AarrB has 4 entries Use size() : AarrB has 4 entries ncsim: *W,RNQUIE: Simulation is complete. */

exists() 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.

module assoc_array_exists_check;

int store[ string ]; string str;

initial begin store ["pencil"] = 1; store ["notebook"] = 2; store ["eraser"] = 3; store ["cutter"] = 4;

if (store.exists("eraser") ) do $display( "Before deletion %0s : %0d", str, store[str] ); while ( store.next(str) );

if (store.exists("pencil") )
store.delete( "pencil" ); // remove entry whose index is "pencil" from "store" $display( "After deletion of single entry: store has %0d entries", store.num );

if (store.first(str) ) do $display( "After deletion %0s : %0d", str, store[str] ); while ( store.next(str) );

store.delete; // remove all entries from the associative array "store" if (!store.exists(str)) $display( "After deletion of all entries: store has %0d entries", store.num ); end endmodule /* ncsim> run Before deletion : 0 Before deletion cutter : 4 Before deletion eraser : 3 Before deletion notebook : 2 Before deletion pencil : 1 After deletion of single entry: store has 3 entries After deletion cutter : 4 After deletion eraser : 3 After deletion notebook : 2 After deletion of all entries: store has 0 entries ncsim: *W,RNQUIE: Simulation is complete. */

delete() : The delete() method removes the entry at the specified index. If the index is specified, then the delete() method removes the entry at the specified index. The method does not issue any warning, if the entry to be deleted does not exist. If the index is not specified, then the delete() method removes all the elements in the array.

module assoc_array_delete_check;

int store[ string ]; string str;

initial begin store ["pencil"] = 1; store ["notebook"] = 2; store ["eraser"] = 3; store ["cutter"] = 4;

$display( "store has %0d entries", store.num ); if (store.first(str) ) do $display( "%0s : %0d", str, store[str] ); while ( store.next(str) );

store.delete( "notebook" ); // remove entry whose index is "notebook" from "store" $display( "After deletion of one entry : store has %0d entries", store.num ); if (store.first(str) ) do $display( "After deletion %0s : %0d", str, store[str] ); while ( store.next(str) );

store.delete; // remove all entries from the associative array "store" $display( "After deletion of all entries: store has %0d entries", store.num ); end

endmodule /* ncsim> run store has 4 entries cutter : 4 eraser : 3 notebook : 2 pencil : 1 After deletion of one entry : store has 3 entries After deletion cutter : 4 After deletion eraser : 3 After deletion pencil : 1 After deletion of all entries: store has 0 entries ncsim: *W,RNQUIE: Simulation is complete. */

first() : 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.

next() : 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.

last() : 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.

prev(): 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.

module assoc_array_first_next_last_prev_check;

//Declaration int AarrB [ integer ];// Integer index integer i;

initial begin

//Adding elements for AarrB AarrB[5] = 500; AarrB[10] = 1000; AarrB[15] = 1500; AarrB[20] = 2000;

if (AarrB.first(i) ) do $display( "Use first() and next() for display the asso arr %d : %d", i, AarrB[i] ); while ( AarrB.next(i) ); $display( "--------------------------------------------------------------------"); if (AarrB.last(i) ) do $display( "Use last() and prev() for display the asso arr in reverse order %d : %d", i, AarrB[i] ); while ( AarrB.prev(i) ); end endmodule /* ncsim> run Use first() and next() for display the asso arr 5 : 500 Use first() and next() for display the asso arr 10 : 1000 Use first() and next() for display the asso arr 15 : 1500 Use first() and next() for display the asso arr 20 : 2000

Use last() and prev() for display the asso arr in reverse order 20 : 2000 Use last() and prev() for display the asso arr in reverse order 15 : 1500 Use last() and prev() for display the asso arr in reverse order 10 : 1000 Use last() and prev() for display the asso arr in reverse order 5 : 500 ncsim: *W,RNQUIE: Simulation is complete. */

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.