SystemVerilog associative arrays provide an efficient way to store data when the size of the collection is unknown or the data space is sparse. Unlike traditional arrays, associative arrays allocate memory only when data is stored, making them ideal for situations where the exact size cannot be determined in advance. The key benefit of associative arrays is that they allow you to use any data type as the index, unlike regular arrays, which only accept integer indexes.

What is a SystemVerilog Associative Array?

An associative array in SystemVerilog is a dynamic data structure that stores elements with unique keys. These keys can be of any type, not just integers, allowing for flexible indexing. Here’s a simple example of how an associative array is defined and used:

// Syntax for associative array
data_type array_identifier [ index_type ];

In the above code:

  • data_type refers to the type of data stored in the array.
  • index_type is the type of the key used to access the data.

Example: Defining and Initializing Associative Arrays

Below is an example of how you can define and initialize associative arrays in SystemVerilog:

module tb;
    // Defining associative arrays
    int array1 [int];           // Integer array with integer index
    int array2 [string];        // Integer array with string index
    string array3 [string];     // String array with string index

    initial begin
        // Initialize the arrays with values
        array1 = '{ 1 : 22, 6 : 34 };
        array2 = '{ "Ross" : 100, "Joey" : 60 };
        array3 = '{ "Apples" : "Oranges", "Pears" : "44" };

        // Display the arrays
        $display ("array1 = %p", array1);
        $display ("array2 = %p", array2);
        $display ("array3 = %p", array3);
    end
endmodule

Output:

array1 = '{1:22, 6:34}
array2 = '{"Joey":60, "Ross":100}
array3 = '{"Apples":"Oranges", "Pears":"44"}

SystemVerilog Associative Array Functions

SystemVerilog provides several built-in functions to manage and interact with associative arrays. Here are some key functions:

FunctionDescription
num()Returns the number of entries in the array.
size()Returns the size of the array, or 0 if the array is empty.
delete()Deletes the entry at the specified index, or deletes the entire array if no index is provided.
exists()Checks if a specific index exists. Returns 1 if true, 0 otherwise.
first()Assigns the first index to a given variable.
last()Assigns the last index to a given variable.
next()Finds the smallest index greater than the given index.
prev()Finds the largest index smaller than the given index.

Example: Using Associative Array Functions

module tb;
    int fruits_l0 [string];

    initial begin
        // Initialize the array
        fruits_l0 = '{ "apple"  : 4, "orange" : 10, "plum"   : 9, "guava"  : 1 };

        // Display the size and number of elements
        $display ("fruits_l0.size() = %0d", fruits_l0.size());
        $display ("fruits_l0.num() = %0d", fruits_l0.num());

        // Check if "orange" exists in the array
        if (fruits_l0.exists("orange"))
            $display ("Found %0d orange!", fruits_l0["orange"]);

        // Check if "apricots" exists in the array
        if (!fruits_l0.exists("apricots"))
            $display ("Sorry, season for apricots is over...");

        // Display first and last items using first() and last()
        string fruit;
        if (fruits_l0.first(fruit))
            $display ("fruits_l0.first [%s] = %0d", fruit, fruits_l0[fruit]);
        
        if (fruits_l0.last(fruit))
            $display ("fruits_l0.last [%s] = %0d", fruit, fruits_l0[fruit]);

        // Display next and previous items using next() and prev()
        if (fruits_l0.prev(fruit))
            $display ("fruits_l0.prev [%s] = %0d", fruit, fruits_l0[fruit]);
        
        if (fruits_l0.next(fruit))
            $display ("fruits_l0.next [%s] = %0d", fruit, fruits_l0[fruit]);
    end
endmodule

Output:

fruits_l0.size() = 4
fruits_l0.num() = 4
Found 10 orange!
Sorry, season for apricots is over...
fruits_l0.first [apple] = 4
fruits_l0.last [plum] = 9
fruits_l0.prev [guava] = 1
fruits_l0.next [plum] = 9

Working with Dynamic Arrays Inside Associative Arrays

You can also create associative arrays where each element is itself an array. Here’s an example of how to create and initialize a dynamic array inside an associative array.

module tb;
    // Define an associative array with string keys and dynamic array values
    int fruits [] [string];

    initial begin
        // Create a dynamic array with size 2
        fruits = new[2];

        // Initialize associative arrays inside the dynamic array indices
        fruits[0] = '{ "apple" : 1, "grape" : 2 };
        fruits[1] = '{ "melon" : 3, "cherry" : 4 };

        // Iterate through each index of the dynamic array
        foreach (fruits[i])
            foreach (fruits[i][fruit])
                $display ("fruits[%0d][%s] = %0d", i, fruit, fruits[i][fruit]);
    end
endmodule

Output:

fruits[0][apple] = 1
fruits[0][grape] = 2
fruits[1][cherry] = 4
fruits[1][melon] = 3

Using Typedefs with Associative Arrays

In SystemVerilog, you can also create a typedef to represent dynamic arrays inside associative arrays. Below is an example of how to use typedefs to simplify dynamic array management:

typedef int int_da [];

module tb;
    // Define an associative array with string keys and dynamic arrays as values
    int_da fruits [string];

    initial begin
        // For the key "apple", create a dynamic array
        fruits["apple"] = new[2];

        // Initialize the dynamic array with values
        fruits["apple"] = '{ 4, 5 };

        // Display the values of the dynamic array
        foreach (fruits[str1])
            foreach (fruits[str1][i])
                $display ("fruits[%s][%0d] = %0d", str1, i, fruits[str1][i]);
    end
endmodule

Output:

fruits[apple][0] = 4
fruits[apple][1] = 5

Conclusion

SystemVerilog associative arrays are powerful tools for handling dynamic and sparse data. They provide flexibility in how data is stored and accessed. By allowing any data type as the index, associative arrays offer a high degree of flexibility and efficiency. The built-in functions like size(), num(), exists(), and delete() make it easy to manage these arrays, while the ability to nest dynamic arrays within associative arrays further enhances their utility.

Scroll to Top