Verilog Pro

SystemVerilog Arrays, Flexible and Synthesizable

In my last article on plain old Verilog Arrays , I discussed their very limited feature set. In comparison, SystemVerilog arrays have greatly expanded capabilities both for writing synthesizable RTL, and for writing non-synthesizable test benches. In this article, we’ll take a look at the synthesizable features of SystemVerilog Arrays we can use when writing design RTL.

Packed vs Unpacked SystemVerilog Arrays

Verilog had only one type of array. SystemVerilog arrays can be either packed or unpacked . Packed array refers to dimensions declared after the type and before the data identifier name. Unpacked array refers to the dimensions declared after the data identifier name.

Packed Arrays

A one-dimensional packed array is also called a vector. Packed array divides a vector into subfields, which can be accessed as array elements. A packed array is guaranteed to be represented as a contiguous set of bits in simulation and synthesis.

Packed arrays can be made of only the single bit data types ( bit , logic , reg ), enumerated types, and other packed arrays and packed structures. This also means you cannot have packed arrays of integer types with predefined widths (e.g. a packed array of byte ).

Unpacked arrays

Unpacked arrays can be made of any data type. Each fixed-size dimension is represented by an address range, such as [0:1023], or a single positive number to specify the size of a fixed-size unpacked array, such as [1024]. The notation [size] is equivalent to [0:size-1].

Indexing and Slicing SystemVerilog Arrays

Verilog arrays could only be accessed one element at a time. In SystemVerilog arrays, you can also select one or more contiguous elements of an array. This is called a slice . An array slice can only apply to one dimension; other dimensions must have single index values in an expression.

Multidimensional Arrays

Multidimensional arrays can be declared with both packed and unpacked dimensions. Creating a multidimensional packed array is analogous to slicing up a continuous vector into multiple dimensions.

When an array has multiple dimensions that can be logically grouped, it is a good idea to use typedef to define the multidimensional array in stages to enhance readability. But notice the order of the dimensions become a little confusing.

SystemVerilog Array Operations

SystemVerilog arrays support many more operations than their traditional Verilog counterparts.

+: and -: Notation

When accessing a range of indices (a slice ) of a SystemVerilog array, you can specify a variable slice by using the [start+:increment width] and [start-:decrement width] notations. They are simpler than needing to calculate the exact start and end indices when selecting a variable slice. The increment/decrement width must be a constant.

Assignments, Copying, and other Operations

SystemVerilog arrays support many more operations than Verilog arrays. The following operations can be performed on both packed and unpacked arrays.

Packed Array Assignment

A SystemVerilog packed array can be assigned at once like a multi-bit vector, or also as an individual element or slice, and more.

Unpacked Array Assignment

All or multiple elements of a SystemVerilog unpacked array can be assigned at once to a list of values. The list can contain values for individual array elements, or a default value for the entire array.

This article described the two new types of SystemVerilog arrays— packed and unpacked —as well as the many new features that can be used to manipulate SystemVerilog arrays. The features described in this article are all synthesizable, so you can safely use them in SystemVerilog based RTL designs to simplify coding. In the next part of the SystemVerilog arrays article, I will discuss more usages of SystemVerilog arrays that can make your SystemVerilog design code even more efficient. Stay tuned!

  • Synthesizing SystemVerilog: Busting the Myth that SystemVerilog is only for Verification
  • 1888-2012 IEEE Standard for SystemVerilog
  • SystemVerilog for Design Second Edition: A Guide to Using SystemVerilog for Hardware Design and Modeling

Sample Source Code

The accompany source code for this article is a toy example module and testbench that illustrates SystemVerilog array capabilities, including using an array as a port, assigning multi-dimensional arrays, and assigning slices of arrays. Download and run it to see how it works!

[lab_subscriber_download_form download_id=11].

Share this:

  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Twitter (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • Click to share on Pocket (Opens in new window)
  • Click to email a link to a friend (Opens in new window)
  • Click to print (Opens in new window)

36 thoughts on “SystemVerilog Arrays, Flexible and Synthesizable”

Really nice article Jason. Makes for a great quick introduction and reference. I have personally found System Verilog arrays as one of the best ways to convert a Verilog user to System Verilog.

Chapter 5 and specifically Fig 5-5 in the System Verilog for Design book are the best: http://read.pudn.com/downloads166/sourcecode/math/758655/Springer%20-%20SystemVerilog%20for%20Design,%202nd%20Edition.pdf

I believe you have a mistake at the article. Regarding: busB = busA[7:6]; // select a 2-vector slice from busA busB = busA[6+:1]; // equivalent to busA[7:6]

but, busA[6+:1] is different from busA[7:6]! busA[6+:1] is actually busA[6:6] and: busA[6+:2] is busA[7:6]

Regards, Tomer

Hi Tomer. Yes you’re correct! I made a typo there, it’s fixed now. Thanks for spotting it!

I don’t see why we need packed/unpacked array for synthesis. FPGA is not limited with a fix size of memory like computer. The compiler should keep only what we need. Compiler will never allocate useless bits, it’s even opposite.

Same for packed and unpacked struct. What is the purpose if not only simulation speed?

Hi Alexis. If your question is why the packed versions are needed, with traditional synthesis tools you need packed arrays/structs/unions to tell the synthesis tool exactly how many bits and how you want to pack a datastructure. FPGA actually does have limited resources, and each additional (unnecessary) bit of a calculation takes up an additional lookup table. Similarly an extra bit in a calculation will require more gates in an ASIC. I wonder if part of the reason came from this desire for hardware engineers to have complete low level control of the synthesis result.

However, I think generally synthesis tools and Verilog/SystemVerilog rules are smart enough to figure out the minimum number of bits you want in a calculation. So you could argue since tools are so smart, why do we still need to specify the packing. I don’t have a good answer, but I think one day (maybe soon) you will be right and we won’t need to specify packed structures anymore.

I see, exactly since the synthesis tools removes the unused bits from the RTL. Then even if I set unpacked array, at the end, the RTL will be as if I chose packed array. Thank you and sorry for my late reply.

Hi May I confirm if there is a typo on this example typedef bit [4:0] bsix; // multiple packed dimensions with typedef bsix [9:0] v5; // equivalent to bit[4:0][9:0] v5

typedef bsix mem_type [0:3]; // array of four unpacked ‘bsix’ elements mem_type ba [0:7]; // array of eight unpacked ‘mem_type’ elements // equivalent to bit[4:0][9:0] ba [0:3][0:7]

Should the last comment be bit[4:0] ba [0:3][0:7] instead of bit[4:0][9:0] ba [0:3][0:7]?

Yes you’re right! Thanks for catching it!

Got it, thanks. By the way, if I have a 3D array, and I want to be able to slice of a 2D portion when accessing it, would you recommend to build a 3D array as “logic [HEIGHT-1:0][WIDTH-1:0] array [DEPTH]” or “logic [WIDTH-1:0] array [DEPTH][HEIGHT]”

For example, I have several submodules that expect a 2D array input, and I plan to connect them by slicing off the 3D array, so just wondering which way is preferred, “logic [HEIGHT-1:0][WIDTH-1:0] array [DEPTH]” or “logic [WIDTH-1:0] array [DEPTH][HEIGHT]”

You can slice a 2D array out of a 3D array with both ways of coding, or even “logic array [width][depth][height]”. The difference is whether you want the 2nd (middle) dimension to be packed (left of array name) or unpacked (right of array name). In your example, since each “element” is only a single bit (logic), it probably doesn’t matter which way you code it; I would actually probably code it as “logic array [width][depth][height]” to clearly show each element is only a single bit. But if you really meant a 2D array of multi-bit vector, then I would use “logic [vector_width-1:0] array [depth][height]” to show that more clearly.

The packed vs unpacked dimensions matter more if you are instead creating multi-dimensional arrays of structs or more complex data types, in which case there may be rules that the data structures must be packed (on the left) for synthesis.

Got it, thanks for sharing 🙂

1- Why do we still need to use [7:0]? We can use `busB = busA[0+:8];` and use directly the number of bits. It avoids using paraneter like `bus[PARAM-1:0]`, better to write `bus[0+=PARAM]`

2- You said `bus[6+:2]` is equivalent to `bus[7:6]` how to use big endianness to get bus[6:7]? I guess it’s not possible.

Sorry, I misread and I simulated. We can’t define logic using +:, you can delete the question.

Hi, I am writing a code in system verilog, and I wondered if there is a way to index an array from 1? Is this correct, and can I access array a from 1 to q_size?

logic a [1:q_size];

Also, unrelated question but I would be glad if you could give me an answer: I generate a queue made of number (q_size) of my blocks, which are connected with signals, so I need a number (q_size) of signals, which I intenteded to define as example above. In generate for loop I map signals to ports this way:

my_module( .my_input(a[i+1]) //i is genvar )

Is this correct, can I work with indexes this way? Thank you VERY MUCH 🙂

Hi Ivana. It is certainly possible to index an array from 1, like what you wrote. Hardware designers generally like to think and code with index starting with 0 for convenience (for example in your code you wouldn’t need a +1 if the index started at 0). Yes you can use a genvar to index into a vector. Your code should work.

Thanks for the awesome blog posts. Arrays with negative indices seem to compile (at least using the Cadence tools). What I am wondering is, do arrays with negative indices actually synthesize?

parameter integer unsigned width = 0; logic [width-1:0] x;

This compile and in SimVision I actually see x[-1:0] in waves. I am curious to know if this is a quirk in the simulator or does this actually synthesize to a two bit logic equivalent?

Thanks, Sami

Hi Sami. Another interesting question 🙂 I have never used a negative index because that goes against the coding guidelines at work, so I don’t know for sure… but I would guess it would work as expected (if your synthesis tool doesn’t complain).

I have a question about the comparison of mixed arrays that I think would fit in here:

consider the following code:

module testModule #( parameter logic [7:0] TP_A = 8’h01, parameter logic [7:0] TP_B = 8’h02, parameter logic [7:0] TP_C = 8’h03, parameter logic [7:0] TP_D = 8’h04 )( input logic clock_104, input logic reset_n, input logic [7:0] sampleData [12:0] output logic [7:0] errorCnt );

logic [7:0] comp0 [12:0]; assign comp0 = ‘{TP_A,TP_B,TP_C,TP_D,TP_A,TP_B,TP_C,TP_D,TP_A,TP_B,TP_A,TP_B,TP_C};

always @(posedge clock_104) begin if (reset_n == 1’b0) errorCnt <= '{default:0}; else begin if (sampleData == {TP_A,TP_B,TP_C,TP_D,TP_A,TP_B,TP_C,TP_D,TP_A,TP_B,TP_A,TP_B,TP_C} ) begin // this generates an error of illegal comparison to unpacked array if (sampleData == comp0 ) begin // this works fine

Why does one if statement work fine and the other one creates an error? Are they not doing the same thing?

Thank you for your help!

Hi Tom. I tried some variations of your experiment.

A pure array literal. This worked. if (sampleData == ‘{8’h00, 8’h00, 8’h00, 8’h00, 8’h00, 8’h00, 8’h00, 8’h00, 8’h00, 8’h00, 8’h00, 8’h00, 8’h00}

Add an apostrophe in front of the array: if (sampleData == ‘{TP_A,TP_B,TP_C,TP_D,TP_A,TP_B,TP_C,TP_D,TP_A,TP_B,TP_A,TP_B,TP_C} )

The simulator (VCS 2014.10) then reported the following error:

Error-[SV-IUAP] Illegal use of assignment pattern design.sv, 22 “(sampleData == ‘{TP_A, TP_B, TP_C, TP_D, TP_A, TP_B, TP_C, TP_D, TP_A, TP_B, TP_A, TP_B, TP_C})” An assignment pattern can only be used in one of the sides of an assignment-like context. Please consider rewriting it using individual array elements.

I suspect the simulator is somehow trying to do two levels of assignments in the error case, and that cannot be done within a comparison? However, I couldn’t find a statement in the LRM that explained why it is not allowed either…

That is a kind of weird. Thank you for taking the time and looking into this. I appreciate it.

is input node [6-1:0] A the same same input node [5:0] A

Hi Mike. Yes that is identical.

Hi Jason, Thank you for the wonderful forum. I have a few queries. How can I check the bit order ( MSB first and LSB last) of a packed array? e.g. input logic[7:0] test1; and output logic [7:0] out1; Would be kind to explain me.

There are several SystemVerilog system tasks that you can use to do that. See section 20.7 Array Querying Functions of the 2012 SystemVerilog LRM. Some examples are:

  • $left shall return the left bound of the dimension. For a packed dimension, this is the index of the most significant element. For a queue or dynamic array dimension, $left shall return 0.
  • $right shall return the right bound of the dimension. For a packed dimension, this is the index of the least significant element. For a queue or dynamic array dimension whose current size is zero, $right shall return –1.
  • For a fixed-size dimension, $increment shall return 1 if $left is greater than or equal to $right and –1 if $left is less than $right. For a queue or dynamic array dimension, $increment shall return –1.
  • $low shall return the same value as $left if $increment returns –1, and the same value as $right if $increment returns 1.
  • $high shall return the same value as $right if $increment returns –1, and the same value as $left if $increment returns 1.
  • $size shall return the number of elements in the dimension, which is equivalent to: $high – $low + 1.

Thank you Jason for your venerated inputs.

I’d like to try this, but not having much luck.. for example, I’ve created an .sv module that declares eight, 16-bit registers:

module test ( output reg [ 15 : 0 ] regTest[ 0 : 7 ] … );

Then in another .sv file, I try to instantiate like this:

wire [15:0]test[0:7]; test test_u0 ( .regTest (test) … );

However the above says an error that it cannot bind.. I’ve tried using the packed syntax, but it doesn’t seem to make any difference.. any suggestion what might be the problem?

Thanks! Ben

Hi Ben. I tried your code out on edaplayground here , and didn’t have any problem. Perhaps something else was causing the issue?

Hi want to extract only columns in packed 2-D array, for eg logic [255:0][299:0] array1 has 256 rows each having 300 bits ; if I wanted to extract 1st column through array slicing operation how do I do it? Like array1[0] gives first row array1[1] gives second row etc ; Thanks a lot

Hi Venkat. The array definition makes extracting one dimension easier than the other, so you should be careful about how you define the array. To accomplish what you want to do, you can write a loop to extract each element that you need and assign that element to a new 256-entry single dimensional array.

Can I include an unpacked array in a struct or an interface? For example, I like to pass an FIFO and some other info of a module to another to snooping. can I have a struct like this: typedef struct packed { logic [5:0] dev_sel; logic [31:0] wr_pending_fifo_dv; logic [31:0] wr_pending_fifo_mem [128]; } dev_wr_fifo_s;

Would an interface have the same elements?

Thanks Agnes

Hi Agnes. If you create an unpacked struct (typedef struct, without the packed keyword), then you can have an unpacked array like the wr_pending_fifo_mem in the structure. However, Design Compiler will not synthesize an unpacked struct. What are you trying to achieve? Putting a FIFO into a struct seems to be a bit of a strange construct.

Always thanks to your post. Again, I hope to ask clarify below comment. /////////////////////////////////////////////////////////////////////////// bit [3:0] [7:0] joe [0:9] // 10 elements of 4 8-bit bytes // (each element packed into 32 bits) typedef bit [4:0] bsix; // multiple packed dimensions with typedef bsix [9:0] v5; // equivalent to bit[4:0][9:0] v5 typedef bsix mem_type [0:3]; // array of four unpacked ‘bsix’ elements mem_type ba [0:7]; // array of eight unpacked ‘mem_type’ elements // equivalent to bit[4:0] ba [0:3][0:7] – thanks Dennis! /////////////////////////////////////////////////////////////////////////// Considering its semantic, I think it needs to be fixed as below. In my previous experience, I was also confused for that. 1. equivalent to bit[4:0][9:0] v5 => equivalent to bit[9:0][4:0] v5 2. equivalent to bit[4:0] ba [0:3][0:7] => equivalent to bit[4:0] ba [0:7][0:3]

Hi Yunsung. I just ran a test to prove it to myself. You’re right! Thanks for correcting this major mistake!

Is accessing to array slices with dynamic indexing but fixed width synthesizable? For example:

// input_byte is a 8 bit logic input // input_index is 3 bit logic input localparam int unsigned FIXED_WIDTH = 8; logic[63:0] data_array; data_array[input_index *FIXED_WIDTH +: FIXED_WIDTH] <= input_byte;

Hi Veli. I think that should be synthesizable. I have written similar code where the LHS is a dynamic index to an array. I have not additionally used a fixed width slice, but I think since the width is a fixed parameter, it shouldn’t be a problem. A dynamic index and a dynamic width, I think would be a problem.

Leave a Comment Cancel reply

Notify me of follow-up comments by email.

Notify me of new posts by email.

This site uses Akismet to reduce spam. Learn how your comment data is processed .

VLSI Verify

SystemVerilog Arrays

An array is a group of variables having the same data type. It can be accessed using an index value. 

An index is a memory address and the array value is stored at that address.

Types of an array

Fixed-size array in systemverilog, single dimensional array.

  • Multidimensional array a. Two-dimensional array. b. Three-dimensional array
  • Packed and Unpacked array in SystemVerilog
  • Dynamic array in SystemVerilog
  • Associative array in SystemVerilog

Array size is fixed throughout the simulation. Its value will be initialized with a ‘0’ value.

single diamentional array

Array assignment

Multidimensional array.

A multidimensional array is also known as an array of an array. In mathematics, we studied matrix, this can be understood as a multidimensional matrix.

Two-dimensional array

2d array

Three-dimensional array

Scalar vs vector.

The data object which does not have a specific range for bit/logic/reg is a scalar.

The data object which has a specific range for bit/logic/reg is a vector.

Packed and Unpacked array

Packed array.

A packed array refers to the dimension mentioned before the variable or object name. This is also known as the vector width .

Memory allocation is always a continuous set of information that is accessed by an array index.

system verilog array assignment

Unpacked array

An unpacked array refers to the dimension mentioned after the variable or object name.

Memory allocation may or may not be a continuous set of information.

unpacked array

Combination of a packed and unpacked array

All arrays mentioned above are types of static arrays .

System Verilog Tutorials

Fpga Insights

Mastering SystemVerilog Arrays: A Comprehensive Guide

Niranjana R

December 27, 2023

Table of Contents

Introduction

Welcome to “Mastering SystemVerilog Arrays: A Comprehensive Guide.” In the realm of hardware design and verification, SystemVerilog stands out as a powerful language, and understanding its array of capabilities is crucial for harnessing its full potential. Arrays in SystemVerilog offer a versatile and efficient way to manage data, making them a fundamental aspect of hardware description and verification languages.

A. Brief Overview of SystemVerilog

SystemVerilog, an extension of Verilog, was developed to address the challenges of modern hardware design and verification. It encompasses features that facilitate concise and readable code, making it a preferred language in the semiconductor industry. The language not only supports traditional hardware description but also incorporates powerful constructs for verification, making it an ideal choice for verification engineers.

B. Importance of Arrays in SystemVerilog

Arrays serve as a cornerstone in SystemVerilog programming, offering a structured and efficient means of handling data. Whether dealing with large datasets, complex algorithms, or dynamic data structures, arrays provide the flexibility needed to navigate the intricacies of hardware design and verification. This guide aims to unravel the intricacies of SystemVerilog arrays, from their basic definitions to advanced usage scenarios.

Now, let’s delve into the fundamental concepts of SystemVerilog arrays, exploring their declaration, initialization, and basic operations.

SystemVerilog Array Basics

A. definition and declaration of arrays.

In SystemVerilog, arrays are variables that can store multiple values of the same data type. Before delving into their usage, it’s essential to understand how to declare them. The syntax for declaring an array involves specifying the data type, array name, and size.

1. Syntax for Array Declaration

2. Data Types Supported for Arrays

SystemVerilog supports a variety of data types for arrays, including built-in types like bit, logic, and user-defined types. This flexibility allows for the creation of arrays tailored to specific design requirements.

B. Initialization of Arrays

Once declared, arrays can be initialized either explicitly or implicitly. Explicit initialization involves specifying values during declaration, while implicit initialization relies on default values.

1. Explicit Initialization

2. Implicit Initialization

Implicit initialization initializes all elements to their default values based on the data type.

Understanding these basic concepts sets the foundation for further exploration into array indexing, slicing, and the dynamic aspects of arrays in SystemVerilog, which we’ll delve into in the next section.

Array Indexing and Slicing

A. understanding array indexing.

Array elements in SystemVerilog are accessed using indices, and it’s crucial to grasp the indexing conventions. SystemVerilog uses zero-based indexing, meaning the first element of an array has an index of 0. For multi-dimensional arrays, indices are specified for each dimension.

1. Zero-Based Indexing

2. Multi-Dimensional Arrays

B. Slicing Techniques

Array slicing allows the extraction of a subset of elements from an array. This can be particularly useful when working with large datasets or when specific portions of an array need to be manipulated.

1. Basic Slicing

2. Advanced Slicing for Multidimensional Arrays

Understanding array indexing and slicing lays the groundwork for exploring dynamic arrays and associative arrays, which offer even greater flexibility in handling data in SystemVerilog. In the following sections, we’ll delve into these advanced array types and their applications.

Dynamic Arrays in SystemVerilog

A. introduction to dynamic arrays.

Dynamic arrays in SystemVerilog provide a flexible alternative to fixed-size arrays. Unlike static arrays, dynamic arrays don’t require a predefined size during declaration, allowing for dynamic allocation and resizing during runtime.

B. Dynamic Array Methods and Functions

1. Using the “new” Keyword

The new keyword is employed to dynamically allocate memory for a dynamic array. This enables the creation of arrays without specifying a fixed size at compile time.

2. Resizing Arrays

Dynamic arrays can be resized during runtime using the $resize system task. This task allows the array to grow or shrink as needed.

Understanding the dynamics of dynamic arrays opens the door to more adaptive data structures in SystemVerilog. However, when it comes to associative arrays, SystemVerilog offers a unique and powerful tool for handling complex data relationships.

Associative Arrays in SystemVerilog

A. definition and purpose of associative arrays.

Associative arrays, also known as “hash” or “unordered” arrays, differ from traditional arrays in that they use keys instead of indices to access elements. This makes them particularly useful for scenarios where the relationship between data points is not strictly sequential.

B. Operations on Associative Arrays

1. Adding and Removing Elements

2. Iterating Through Associative Arrays

As we explore associative arrays, we’ll uncover their usefulness in various applications, from handling configuration data to efficiently managing complex data relationships in verification environments.

In the upcoming sections, we’ll delve into practical array manipulation techniques, including sorting and searching arrays, and showcase real-world examples of SystemVerilog array usage. Understanding these advanced topics will empower you to leverage arrays effectively in your hardware design and verification projects.

SystemVerilog Array Manipulation

A. sorting arrays.

1. Using Built-in Sorting Functions

SystemVerilog provides convenient built-in functions for sorting arrays. The $sort function simplifies the process of arranging elements in ascending or descending order.

2. Implementing Custom Sorting Algorithms

For more complex sorting requirements, custom sorting algorithms can be implemented. Understanding algorithms like quicksort or mergesort allows for tailored solutions.

B. Searching Arrays

1. Linear Search

Linear search is a straightforward method for finding an element in an array. It involves traversing the array sequentially until the target element is located.

2. Binary Search

Binary search is a more efficient search algorithm but requires a sorted array. It involves repeatedly dividing the search range in half until the target is found.

Mastering array manipulation techniques like sorting and searching is crucial for optimizing performance in hardware design and verification scenarios. In the next section, we’ll explore real-world examples of SystemVerilog array usage, demonstrating how these techniques can be applied in practical situations.

Array Usage in Real-world Examples

A. case studies.

1. Verifying Complex Hardware Designs

In the realm of hardware verification, arrays play a pivotal role in managing test vectors, tracking signals, and validating circuit behavior. Consider a scenario where an intricate hardware design involves multiple registers with varying configurations. An array can efficiently store and manipulate these configurations, simplifying the verification process.

2. Handling Testbench Data with Arrays

In a testbench environment, arrays can be instrumental in managing stimulus data, response checking, and coverage tracking. Consider a testbench scenario where different test cases are generated and executed. Arrays can store the test cases and their corresponding expected outcomes, facilitating efficient testbench automation.

By examining these case studies, it becomes evident how SystemVerilog arrays can streamline complex processes in hardware design and verification.

In this comprehensive guide, we have embarked on a journey to master SystemVerilog arrays, unraveling their intricacies and exploring their myriad applications in hardware design and verification. From the fundamental concepts of array declaration, initialization, and indexing to advanced topics like dynamic arrays and associative arrays, we’ve covered the spectrum of array-related features that SystemVerilog offers.

Understanding the power of SystemVerilog arrays is crucial for harnessing the language’s capabilities in handling diverse data structures, managing complex hardware designs, and creating efficient testbenches. The ability to manipulate arrays through sorting, searching, and dynamic allocation provides engineers with the tools needed to optimize performance and streamline their coding practices.

The real-world case studies showcased the practical application of SystemVerilog arrays in scenarios ranging from complex hardware designs with multiple configurations to automated testbenches handling diverse test cases. These examples highlight how arrays can enhance readability, maintainability, and efficiency in real-world projects.

As we conclude this guide, it is essential to emphasize the significance of best practices in SystemVerilog array usage. By optimizing performance, writing readable and maintainable code, and handling large data sets with efficiency, engineers can ensure that their array-based implementations contribute to robust and reliable hardware designs.

Related Articles

VERILOG ARRAY UNDERSTANDING AND IMPLEMENTING ARRAYS IN VERILOG

1 thought on “Mastering SystemVerilog Arrays: A Comprehensive Guide”

What fundamental concepts of SystemVerilog arrays does the article aim to explore, including aspects such as declaration, initialization, and basic operations? regard Telkom University

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed .

PCI Express 3.0 (1)

most recent

system verilog array assignment

Women in Engineering

Purnima kumari sharma, r&d engineer: women in engineering.

system verilog array assignment

Ritika Rao, R&D Engineer: Women in Engineering

system verilog array assignment

Artificial Intelligence

The rise of ai in space: transforming the future of exploration.

system verilog array assignment

The Art of AI: Innovation and Imagination Collide in the World of Creativity

system verilog array assignment

AI-Driven Virtual Influencers Transforming Social Media

system verilog array assignment

Wireless Networking

Wireless networking’s role in the iot revolution, subscribe to get our best viral stories straight into your inbox.

system verilog array assignment

FPGA Insights have a clear mission of supporting students and professionals by creating a valuable repository of FPGA-related knowledge to contribute to the growth and development of the FPGA community and empower individuals to succeed in their projects involving FPGAs FPGA Insights has been producing FPGA/Verilog/VHDL Guides and blogs with the aim of assisting students and professionals across the globe. The mission of FPGA Insights is to continually create a growing number of FPGA blogs and tutorials to aid professionals in their projects.

© 2024 Fpga Insights. All rights reserved

SystemVerilog Dynamic Arrays and Queues

In this post, we talk about the different types of dynamic arrays we can use in SystemVerilog, including normal dynamic arrays and their associated methods , queues and their associated methods and finally associative arrays .

As we talked about in a previous post, we can declare either static or dynamic arrays in SystemVerilog.

When we declare a static array, a fixed amount of  memory is allocated  to the array at  compile time . We have discussed SystemVerilog static arrays in depth in a previous blog post.

In contrast, we can allocate extra memory or resize a dynamic array while a simulation is running. As a result of this, we can only use dynamic arrays in our testbench code and not in synthesizable code.

In the rest of this post we talk about the way we can use dynamic arrays in our SystemVerilog code.

There are actually three different types of dynamic array which we can use in SystemVerilog - dynamic arrays, queues and associative arrays.

We use each of these three types of array to perform a slightly different task in our testbench. We discuss all three of these arrays in more detail int he rest of this post

SystemVerilog Dynamic Arrays

SystemVerilog dynamic arrays are a special class of array which can be resized whilst a simulation is running.

This differentiates them from static arrays which are allocated memory during compile time and have a fixed sized for the duration of a simulation.

This is useful as we may have instances where we don't know exactly how many elements our array will require when we compile our code.

The code snippet below shows how we declare a dynamic array in SystemVerilog.

When we create a dynamic array, we must always declare it as an unpacked type array .

As dynamic arrays are initially empty, we have to use the new keyword to allocate memory to the array before we can use it. We also declare the number of elements in the array when we use the new keyword.

The code example below shows how we would declare a dynamic array and then allocate the memory for 4 elements.

Dynamic Array Methods

Dynamic arrays are slightly more complex to work with than static arrays as we have to manage the size of the array in our code.

As a result of this, a number of methods are included in the SystemVerilog to help us manage dynamic arrays.

We have already seen one of the most important of these methods in the previous section - the new method.

In addition to this, we also commonly use the delete and size methods to manage our dynamic arrays.

Let's take a closer a look at each of these methods in more detail.

  • The new Method

As we have previously seen, we use the new method to allocate memory to our dynamic array.

The code snippet below shows the general syntax we use to call the new method.

The <size> field in this construct is used to specify how many elements there will be in the array.

We use the <values> field to assign values to the array after it has allocated memory. We can exclude this field if we are creating an empty array.

For example, we would use the code shown below to allocate memory for 8 elements in a dynamic array.

We can call the new method as many times as necessary in our code. Each time we call the new method, we effectively create a new array and allocate memory to it.

For example, we might need to replace our array of 8 elements with a new array which has 16 elements. In this case, we would simply call the new method a second time to resize our array.

The code snippet below shows how we would use the new method to do this.

When we use the new method in this way, any contents which were in the old array are deleted. This means that we create an entirely new, empty array when using this method.

However, we can also keep the existing contents of our array when we call the new method.

To do this, we need to pass the existing array to the new method using the <value> field we mentioned before. This will place the contents of the old array at the start of the resized array.

For example, suppose that we had created a dynamic array which consists of 8 elements and assigned some data to it.

If we now wanted to resize the array to 16 elements and keep the existing data, we could do this using the code shown below. This code can also be simulated on eda playground .

  • The delete Method

We use the delete method to remove the entire contents of a dynamic array.

When we call this method, it not only deletes the contents of the dynamic array but also deallocate the memory. In this sense, we can consider the delete method to be roughly equivalent to the free function in C .

The code snippet below shows the general syntax of the delete method.

In this construct, the <name> field is used to identify the dynamic array which we are calling the method on.

The SystemVerilog code below shows how we would use the delete method in practise. This code can also be simulated on eda playground .

  • The size Method

We use the size method to determine how large our dynamic array is at any given time.

When we call this method it returns a value which is equal to the number of elements in an array.

As we can see from this, it performs a similar function to the $size macro which we mentioned in the post on static arrays.

The code snippet below shows the general syntax for this method.

The SystemVerilog code below shows how we would use the size method in practise. This code can also be simulated on eda playground .

SystemVerilog Queues

SystemVerilog queues are a type of array which are automatically resized when we add or remove elements to the array.

The code snippet below shows how we would declare a queue type in SystemVerilog.

In this construct, we use the $ symbol inside of square brackets to indicate that we are creating a queue type.

We use the optional <max_length> field to limit the amount of elements which a queue can have.

However, we often exclude the <max_length> field from our declaration. When we do this, our queue can contain an unlimited amount of elements.

Queues which have an unlimited amount of elements are known as unbounded arrays whilst queues which are declared using the <max_length> field are known as bounded arrays.

When we declare a queue we can initialize it using a comma separated list of values between a pair of curly braces. This is similar to the use of array literals which we discussed in the previous post.

The SystemVerilog code below shows how we declare both a bounded and an unbounded queue. We also initialize both of the example queues with 2 elements.

  • Dynamic Arrays vs Queues

Dynamic arrays and queues actually perform very similar functions in SystemVerilog as they are both allocated memory at run time. As a result of this, we can resize both of these data structures whilst our code is running.

However, we use them for different purposes as they are optimized for slightly different operations.

We use queues when we are only interested in adding or removing elements at the beginning or end of the array.

The reason for this is that dynamic arrays are stored in contiguous memory addresses during simulation. As a result of this, when we resize a dynamic array it is often necessary for the entire array to be moved to a new location in memory.

In contrast, SystemVerilog queues are implemented in a similar way to linked lists in other programming languages.

This means that it is much quicker to add or remove elements to a queue as there is no need to move the existing elements in the array.

We typically use SystemVerilog queues to emulate either FIFO or LIFO type memories. We often see queues used in this way to move transactions between different blocks in a SystemVerilog based testbench.

However, when we want to access elements in the middle of the data structure then dynamic arrays are more efficient

The reason for this is that our simulator must start from either the beginning or end of the queue and loop through the memory until it reaches the required element. Again, this behavior is similar to linked lists in other programming languages.

In contrast, our simulator can directly access any element in dynamic array.

As we can see from this, it is clearly much quicker for our simulator to retrieve data from the middle of a dynamic array as less memory accesses are required.

Queue Methods

SystemVerilog queues are more complex that static arrays due to the fact that they require dynamic memory allocation .

As a result of this, we have a number of in built methods which can use to manipulate the contents of our queue.

This is in contrast to arrays where we can directly access individual elements to manipulate the contents of the array.

Let's take a closer a look at the most important queue methods in SystemVerilog.

  • Push to Queue

When we want to add data to a SystemVerilog queue, we can use either the push_front or the push_back method.

The push_front method inserts the specified data onto the front of the queue whilst the push_back method inserts the data at the end fo the queue.

We can think of the front of the queue as being equivalent to the lowest indexed element of a normal array.

In contrast, when we talk about the back of a queue this is equivalent to the highest indexed element of a normal array type.

The picture below illustrates the concept of push_front and push_back queue methods.

The code snippet below shows the general syntax we use to call the push_front and push_back methods.

In this construct we use the <queue_name> field to identify the queue we are adding data to.

We then use the <value> field to specify the value of the data which we are adding to the queue. We can use either a hard coded value or a variable to add data to our queue.

The SystemVerilog code below shows how we use the push_front and push_back methods in practise. This code can also be simulated on eda playground .

  • Pop From Queue

When we want to get some data from a SystemVerilog queue we use either the pop_front or pop_back methods.

The pop_front method retrieves data from the front of the queue whilst the pop_back method retrieves the data at the end fo the queue.

As with push_front method, the front of the queue is equivalent to the lowest indexed element of a normal array.

In constrast, the back of a queue is equivalent to the highest indexed element of a normal array type.

When we call either of these methods, the required element is removed from the queue and the value of this element is returned by the function.

The picture below illustrates the concept of pop_front and pop_back queue methods.

The code snippet below shows the general syntax we use to call the pop_front and pop_back methods.

In this construct we use the <queue_name> field to identify the queue we are retrieving data from.

The SystemVerilog code below shows how we use the pop_front and pop_back methods in practise. We can also simulate this code on eda playground .

  • Insert and Delete Methods

We can also use the insert and delete methods to add or remove an element in a SystemVerilog queue.

In contrast to the push and pop methods, we use these two methods to add or remove elements at a specific location in the queue.

As a result, we can use these methods to modify elements in the middle of our array.

However, we should be aware that these methods are less efficient than the push and pop methods. In addition, they can also be inefficient in comparison to the equivalent methods in dynamic arrays.

In fact, when we make extensive use of the insert or delete methods this may be a good indication that we should be using a dynamic array instead.

The code snippet below shows the general syntax we use to call the insert and delete methods.

In this construct we use the <queue_name> field to identify the queue which we are modifying.

We use the <value> field to specify the value of the data which we are adding to the queue. We can use either a hard coded value or a variable to add data to our queue.

In the case of the insert method, we use the <index> field to specify where the new element will be inserted in our queue.

In the case of the delete method, we use the <index> field to specify which element of the queue will be removed.

However, we can omit the <index> field when we use the delete method. When we do this, the entire content of our queue will be deleted.

The SystemVerilog code below shows how we use the insert and delete methods in practise. This code can also be simulated on eda playground.

SystemVerilog Associative Arrays

The final type of array which we can use in SystemVerilog is the associative array.

When we declare an associative array, memory for the array is not allocated at compile time and we can resize the array during simulation.

Therefore, associative arrays are very similar to the dynamic arrays which we discussed previously in this post.

However, the way that we index associative arrays is different from the way that we index dynamic arrays.

As we previously saw, we use sequential integers to index different elements of a dynamic array.

In contrast, we can use any value that we want to index the different elements of an associative array in SystemVerilog.

For example, we could use non sequential integers if we wanted to model the contents of a sparsely populated memory.

However, we could also use a string to give a physical name to the indexes in an associative array.

As we can see from this, we can think of associative arrays as being roughly equivalent to key-value pairs in other programming languages.

The SystemVerilog below shows the general syntax we use to declare an associative array.

When we use associative arrays, we must use the same data type for all of the indexes. This means that we can't mix int types and strings, for example.

We use the <key_type> field to declare what data type we will use for the index.

When we use associative arrays in our SystemVerilog code, the simulator has to search for the memory location of each element in the array when we either read or write to it.

As a result of this, associative arrays are less efficient than both static and dynamic arrays. This normally results in slowly execution times for our test benches.

Therefore, we generally prefer to use either a static or dynamic array instead of associative arrays whenever it is possible.

  • Assigning Data to an Associative Array

We can assign values to an associative array using the same techniques which we discussed in the previous post.

However, when we use array literals to we have to specify not only the data which we are assigning but also the value of the index we want associated with that data.

The SystemVerilog code below shows the general syntax we use to assign data to an associative array using array literals.

In this construct, we use the <key> field to set the value of the index in the array. The <data> field is then used to set the value of the data which is written to the array.

We can also use square brackets to access elements in an associative array. The syntax for this is exactly the same as we use for both static and dynamic arrays.

The SystemVerilog code below shows how we use associative arrays in practise. This code can also be simulated on eda playground .

What is the difference between static arrays and dynamic arrays in SystemVerilog?

Static arrays have a fixed number of elements which are determined at compile time. In contrast, dynamic arrays don't have a fixed sized and we can add or remove elements during simulation.

Write the code to declare a dynamic array of int types and allocate the memory for 8 elements

Which method would we use to deallocate the memory of a dynamic array?

We use the delete method to discard the contents of a dynamic array and dellocate any memory associated with it.

Write some code which creates a queue of int types and initializes 3 elements to 0.

When would we use queues instead of dynamic arrays in SystemVerilog? Why would we use queues in this circumstance.

We use queues when we only want to add or remove data from the beginning or end of the array. The reason for this is that it is more efficient to resize queues than it is to resize dynamic arrays. However, it is more efficient to access elements in the middle of a dynamic array.

Write some code which declares an associative array of int types and uses string type indexes.

2 comments on “SystemVerilog Dynamic Arrays and Queues”

nice post !please keep up good work ! Thank you.

In the " insert and delete"section about

// Create a queue with some initial values in it int example_q [$] = { 1, 2 }; // Insert a value into the

the code example is no complete ?

Hi Kaia, Thanks for pointing that out, I have updated the post so that the example is compete now.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Save my name, email, and website in this browser for the next time I comment.

Table of Contents

Sign Up to our Mailing List

Join our mailing list and be the first to hear about our latest FPGA themed articles and tutorials .

Verification Guide

SystemVerilog 2d array

Systemverilog 2d array initialization.

Table of Contents

The two-dimensional array is an array of arrays. The 2D array is organized as matrices which can be represented as the collection of rows and columns.

SystemVerilog 2D array Syntax

Systemverilog 2d array declaration.

The data in a two-dimensional array is stored in a tabular form as shown in the below diagram.

SystemVerilog Multidimensional array

SystemVerilog 2D array initialization

Systemverilog 2d array example.

Simulator Output

system verilog array assignment

SystemVerilog Associative Array

When size of a 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 look-up 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.

Initialization Example

Associative array methods, associative array methods example, dynamic array of associative arrays, dynamic array within each index of an associative array.

DMCA.com Protection Status

IMAGES

  1. SystemVerilog Class Assignment

    system verilog array assignment

  2. System Verilog Session 17 (Arrays

    system verilog array assignment

  3. Systemverilog Dynamic Array

    system verilog array assignment

  4. 😍 Verilog assignment. Conditional Operator. 2019-02-03

    system verilog array assignment

  5. Verilog Continuous Assignment

    system verilog array assignment

  6. Array in System Verilog programming

    system verilog array assignment

VIDEO

  1. System Design Through Verilog Week 8 Assignment Solution NPTEL

  2. System Design Through Verilog Week 7 Assignment Solution NPTEL

  3. System Design Through Verilog Week 2 Assignment Solution NPTEL

  4. System Design Through Verilog NPTEL week 3 Assignment 3

  5. System Design Through Verilog Assignment 5 Week 5 Answers

  6. System Design Through Verilog Assignment 5 Week 5 Answers

COMMENTS

  1. An Introduction to SystemVerilog Arrays

    April 6, 2021 This post of the the first of two which talk about SystemVerilog arrays. In this post, we will talk about static arrays, array assignment, loops and packed vs unpacked arrays. In SystemVerilog, we can write arrays which have either a fixed number of elements or a variable number of elements.

  2. SystemVerilog Arrays

    SystemVerilog offers much flexibility in building complicated data structures through the different types of arrays. Static Arrays Dynamic Arrays Associative Arrays Queues Static Arrays A static array is one whose size is known before compilation time.

  3. Easy way to assign values to an array in Verilog?

    Easy way to assign values to an array in Verilog? - Stack Overflow Easy way to assign values to an array in Verilog? Ask Question Asked 8 years, 9 months ago Modified 9 months ago Viewed 34k times -1 So I'm creating a large FIR filter in Verilog, it has 256 taps. So I need 256 coefficients.

  4. SystemVerilog Arrays, Flexible and Synthesizable

    In SystemVerilog arrays, you can also select one or more contiguous elements of an array. This is called a slice. An array slice can only apply to one dimension; other dimensions must have single index values in an expression. Multidimensional Arrays Multidimensional arrays can be declared with both packed and unpacked dimensions.

  5. SystemVerilog Array Manipulation

    SystemVerilog Array Manipulation Introduction Introduction What is a Testbench? Data Types Introduction to data types New Data types: logic, bit Signed integers, byte Strings Enumeration Arrays Packed Arrays Unpacked Arrays Dynamic Arrays Associative Arrays Array Manipulation Methods Queues Structures User-defined Data Types Control Flow Loops

  6. Verilog Assignments

    There are three basic forms: Procedural Continuous Procedural continuous Legal LHS values An assignment has two parts - right-hand side (RHS) and left-hand side (LHS) with an equal symbol (=) or a less than-equal symbol (<=) in between.

  7. SystemVerilog Arrays

    SystemVerilog Arrays An array is a group of variables having the same data type. It can be accessed using an index value. An index is a memory address and the array value is stored at that address. Types of an array Fixed-size array in SystemVerilog Single dimensional array Multidimensional array a. Two-dimensional array. b. Three-dimensional array

  8. Mastering SystemVerilog Arrays: A Comprehensive Guide

    Welcome to "Mastering SystemVerilog Arrays: A Comprehensive Guide.". In the realm of hardware design and verification, SystemVerilog stands out as a powerful language, and understanding its array of capabilities is crucial for harnessing its full potential. Arrays in SystemVerilog offer a versatile and efficient way to manage data, making ...

  9. fpga

    %p is a pretty-print format that uses an assignment pattern as its format. It is using using a signed decimal format for each number. SystemVerilog has arrays-of-arrays. You have declared an array with two elements, and each element has an array with four elements. %h is an unsigned radix format.

  10. Continuous Assignment and Combinational Logic in SystemVerilog

    This approach is known as explicit continuous assignment. The SystemVerilog code below shows the general syntax for continuous assignment using the assign keyword. assign <variable> = <value>; In this construct, we use the <variable> field to give the name of the signal which we are assigning data to.

  11. SystemVerilog Dynamic Arrays and Queues

    April 17, 2021. In this post, we talk about the different types of dynamic arrays we can use in SystemVerilog, including normal dynamic arrays and their associated methods, queues and their associated methods and finally associative arrays. As we talked about in a previous post, we can declare either static or dynamic arrays in SystemVerilog.

  12. SystemVerilog Multidimensional Arrays

    You can assign three copies of the one array to it. two = ' { 3 { one } }; $display ("two = %p", two); // ' {' {0, 1, 2, 3}, ' {0, 1, 2, 3}, ' {0, 1, 2, 3}} Stepping through MDAs By now you know that my favorite way to step through an array is with a foreach loop.

  13. SystemVerilog Packed Arrays

    SystemVerilog Packed Arrays SystemVerilog Posts Introduction Introduction What is a Testbench? Data Types Introduction to data types New Data types: logic, bit Signed integers, byte Strings Enumeration Arrays Packed Arrays Unpacked Arrays Dynamic Arrays Associative Arrays Array Manipulation Methods Queues Structures User-defined Data Types

  14. Systemverilog Fixedsize Array

    In SystemVerilog vector width/dimensions declared before the object name is referred to as packed array and array size/dimensions declared after the object name is referred to as an unpacked array. A packed array is a mechanism for subdividing a vector into sub-fields which can be conveniently accessed as array elements.

  15. SystemVerilog Arrays

    SystemVerilog Arrays tutorila arrays examples Fixed Size Arrays Packed and Un-Packed Arrays Dynamic Array Associative Array Queues

  16. Usage of tick ( ' ) in array assignments -> packed vs unpacked

    SystemVerilog. systemverilog-Arrays-packedarrays-unpackedarrays, SystemVerilog. dmitryl March 11, 2018, 1:54pm 1. Hi All, On some place in the web I've found the following example: ... See 10.10.1 Unpacked array concatenations compared with array assignment patterns in the 1800-2017 LRM. dmitryl March 11, 2018, 5:34pm 3. In reply ...

  17. SystemVerilog Unpacked Arrays

    An unpacked array is used to refer to dimensions declared after the variable name. Unpacked arrays may be fixed-size arrays, dynamic arrays, associative arrays or queues. ... SystemVerilog Unpacked Arrays. ... byte stack [8]; // depth = 8, 1 byte wide variable initial begin // Assign random values to each slot of the stack foreach (stack[i ...

  18. SystemVerilog 2d array

    Table of Contents Toggle The two-dimensional array is an array of arrays. The 2D array is organized as matrices which can be represented as the collection of rows and columns. SystemVerilog 2D array Syntax data_type array_name [rows] [columns]; SystemVerilog 2D array declaration int array [2:0] [3:0];

  19. SystemVerilog Associative Array

    SystemVerilog Associative Array. When size of a 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 look-up ...

  20. system verilog

    You cannot use an assignment pattern to make assignments to a particular element of an array, packed or unpacked. Assignment patterns must have values for all elements. And you cannot make assignments to non-contiguous elements of an array (usually called a slice ). The best way of handling this is using a foreach loop;