SystemVerlog Associative Array

Associative array in SystemVerilog offers a flexible and memory-efficient way to store data. These arrays represent an extension of dynamic arrays, associative arrays do not immediately allocate memory when declared. Instead, memory is allocated dynamically as data is inserted. The key feature of associative arrays is their ability to accept a wide range of data types as indices, including strings, making them highly advantageous in certain scenarios.

 

Associative arrays are a special type of dynamic array in SystemVerilog. Unlike dynamic arrays, the memory for associative arrays is not allocated immediately upon declaration. Instead, memory is allocated as data is stored, resulting in a more memory-efficient approach. However, this on-demand memory allocation can lead to slightly slower performance compared to dynamic arrays.

 

Associative arrays can be thought of as collections of key-value pairs. The index (key) is used to access the associated value. The key can have various data types, such as strings or integers.

 

Syntax of Associative Arrays

 

 

When declaring an associative array, the syntax is similar to that of dynamic arrays. The key’s data type should be specified within square brackets. 

Data_type <array_name>[index_type];

where:

 data_type, which is the array items’ data type.

array name is the associative array’s name.

index_type: The data type to be used as an index, or *: This denotes that any integral expression of any size can be used to index the array.

 

int arr[string]; // Associative array with a string key and an integer value

string arr2[int]; // Associative array with an integer key and a string value

 

Example

module city_population();
    int city_population[string];
    string city;

    initial begin
        // Storing population data in the associative array
        city_population = {"New York": 8537673, "Los Angeles": 3976322, "Chicago": 2704958};
        
        // Displaying the entire city population data
        $display("City Populations = %p", city_population);

        // Accessing the population of a specific city (e.g., New York)
        $display("Population of New York = %0d", city_population["New York"]);

        // Adding a new city along with its population to the array
        city_population["Houston"] = 2303482;

        // Displaying the updated city population data
        $display("City Populations (Updated) = %p", city_population);

        // Check if a particular city exists in the array
        city = "Los Angeles";
        if (city_population.exists(city))
            $display("%s exists in the city population data.", city);
        else
            $display("%s does not exist in the city population data.", city);
    end
endmodule

Output:

City Populations = '{"Chicago":2704958, "Los Angeles":3976322, "New York":8537673} 
Population of New York = 8537673
City Populations (Updated) = '{"Chicago":2704958, "Houston":2303482, "Los Angeles":3976322, "New York":8537673} 
Los Angeles exists in the city population data.
           V C S   S i m u l a t i o n   R e p o r t

Advantages of Associative Arrays

 

Associative arrays are particularly useful when modeling memories in a test bench. Memories often consist of a large number of elements, and if dynamic arrays are used, memory is allocated immediately upon array definition, which can lead to potential system failures. Associative arrays allocate memory only when values are stored, making them a more efficient choice for modeling memories.

 

Associative Array Methods

 

SystemVerilog provides several built-in methods for manipulating associative arrays:

 

num():                    Returns the number of entries stored in the associative array.

size():                    Also returns the number of values stored in the associative array and  returns 0 for an                                  empty array.

delete([key]):        Deletes the value associated with the specified key. If no key is provided, it deletes the                          entire array.

 exists(key):            Checks whether a value is associated with the given key and returns 0  if no value is                                  present.

first(ref key):           Assigns the key variable with the first key of the associative array. If the array is                                           empty, it returns 0.

 last(ref key):            Assigns t he key variable with the last key of the associative array. If the array is                                           empty, it returns 0.

 next(ref key):          Assign the key variable with the key that comes after the specified key. If the array is                                 empty or the specified key is the last, it returns 0.

 prev(ref key):          Assigns the key variable with the key that comes just before the specified key. If the                                   array is empty or the specified key is the first, it returns 0.

 

These methods allow you to manage and access data within associative arrays efficiently.

 

Let’s apply some of these methods to the associative array we declared earlier:    

module student_scores();
    int scores[string];
    string studentName;

    initial begin
        // Initializing the associative array with student scores
        scores = {"Alice": 95, "Bob": 82, "Charlie": 75, "David": 88, "Eve": 91};

        // Displaying the entire student scores
        $display("Student Scores = %p", scores);

        // Accessing the score of a specific student (e.g., Bob)
        $display("Score of Bob = %0d", scores["Bob"]);

        // Adding a new student along with their score to the array
        scores["Frank"] = 79;

        // Displaying the updated student scores
        $display("Student Scores (Updated) = %p", scores);

        // Check if a particular student exists in the array
        studentName = "David";
        if (scores.exists(studentName))
            $display("%s exists in the student scores data.", studentName);
        else
            $display("%s does not exist in the student scores data.", studentName);

        // Get the first and last student name stored in the array
        if (scores.first(studentName))
            $display("First student found is = %s", studentName);

        if (scores.last(studentName))
            $display("Last student found is = %s", studentName);

        // Get the student name stored before the last one
        if (scores.prev(studentName))
            $display("Student previous to the last student found is = %s", studentName);

        // Get the student name stored after the last one
        if (scores.next(studentName))
            $display("Student next to the last student found is = %s", studentName);
        else
            $display("Either no student found or this is the last student");

        // Delete the array
        scores.delete();
        $display("Number of students after deleting = %0d", scores.num());
    end
endmodule

Output:

Student Scores = '{"Alice":95, "Bob":82, "Charlie":75, "David":88, "Eve":91} 
Score of Bob = 82
Student Scores (Updated) = '{"Alice":95, "Bob":82, "Charlie":75, "David":88, "Eve":91, "Frank":79} 
David exists in the student scores data.
First student found is = Alice
Last student found is = Frank
Student previous to the last student found is = Eve
Student next to the last student found is = Frank
Number of students after deleting = 0
           V C S   S i m u l a t i o n   R e p o r t
module employee_details();
    string employee_info[string][string];
    string department;
    string employeeName;

    initial begin
        // Employee information stored in an associative array
        employee_info = {"HR": {}, "Engineering": {}};
        
        // Adding employee details within each department
        employee_info["HR"]["John"] = "HR Manager";
        employee_info["HR"]["Alice"] = "HR Coordinator";
        employee_info["Engineering"]["Bob"] = "Software Engineer";
        employee_info["Engineering"]["Eve"] = "Hardware Engineer";

        // Displaying the employee details within each department
        foreach (employee_info[department]) begin
            $display("Employees in %s department:", department);
            foreach (employee_info[department][employeeName]) begin
                $display("%s is %s", employeeName, employee_info[department][employeeName]);
            end
        end
    end
endmodule

Output:

# run -all
# Employees in Engineering department:
# Bob is Software Engineer
# Eve is Hardware Engineer
# Employees in HR department:
# Alice is HR Coordinator
# John is HR Manager
# exit

Associative Array inside Associative Array

 

Let’s imagine a scenario where we need to store information about different employees within various departments. Each department may have multiple employees, and each employee might have various details associated with them. For this case, we can use an associative array within an associative array structure.

module employee_details();
    string employee_info[string][string];
    string department;
    string employeeName;

    initial begin
        // Employee information stored in an associative array
        employee_info = '{"HR": {}, "Engineering": {}}';
        
        // Adding employee details within each department
        employee_info["HR"]["John"] = "HR Manager";
        employee_info["HR"]["Alice"] = "HR Coordinator";
        employee_info["Engineering"]["Bob"] = "Software Engineer";
        employee_info["Engineering"]["Eve"] = "Hardware Engineer";

        // Displaying the employee details within each department
        foreach (employee_info[department]) begin
            $display("Employees in %s department:", department);
            foreach (employee_info[department][employeeName]) begin
                $display("%s is %s", employeeName, employee_info[department][employeeName]);
            end
        end
    end
endmodule

Output:

# run -all
# Employees in Engineering department:
# Bob is Software Engineer
# Eve is Hardware Engineer
# Employees in HR department:
# Alice is HR Coordinator
# John is HR Manager

Associative Array inside Dynamic Array

module students_subjects_marks();
    int marks [][string];
    string subject;
    string studentName;

    initial begin
        // Initializing a dynamic array to manage students' subject marks
        marks = new [3];
        
        // Assigning marks for different subjects to different students
        marks[0] = {"Physics": 85, "Maths": 90};
        marks[1] = {"Chemistry": 78, "Biology": 82, "English": 88};
        marks[2] = {"Computer Science": 92, "Robotics": 87};

        // Displaying the marks for each subject taken by each student
        foreach (marks[i]) begin
            $display("Marks for Student %0d:", i + 1);
            foreach (marks[i][subject]) begin
                $display("%s: %0d", subject, marks[i][subject]);
            end
        end

        //  retrieving the first subject for the first student
        if (marks[0].first(subject))
            $display("First subject of Student 1 is: %s", subject);
    end
endmodule

Output:


# run -all
# Marks for Student 1:
# Maths: 90
# Physics: 85
# Marks for Student 2:
# Biology: 82
# Chemistry: 78
# English: 88
# Marks for Student 3:
# Computer Science: 92
# Robotics: 87
# First subject of Student 1 is: Maths

dynamic array inside associative array

module courses_students_enrollment();
    string students_enrollment[string][];
    string courseName;
    string studentName;

    initial begin
        // Initializing an associative array to manage course enrollments
        students_enrollment = {};
        
        // Enrolling students in different courses
        students_enrollment["Maths"] = {"Alice", "Bob", "Charlie"};
        students_enrollment["Physics"] = {"David", "Eve"};
        students_enrollment["Chemistry"] = {"Frank", "Grace", "Hannah", "Ivy"};

        // Displaying the list of students enrolled in each course
        foreach (students_enrollment[courseName]) begin
            $display("Students enrolled in the %s course:", courseName);
            foreach (students_enrollment[courseName][studentName]) begin
                $display(studentName);
            end
        end

       
    end
endmodule

Output:

# run -all
# Students enrolled in the Chemistry course:
#           0
#           1
#           2
#           3
# Students enrolled in the Maths course:
#           0
#           1
#           2
# Students enrolled in the Physics course:
#           0
#           1
# exit
Scroll to Top