Mastering Data and Array Query Functions in Verilog and SystemVerilog

In this tutorial, we will dive into data query and array query functions in Verilog and SystemVerilog. You will learn how to utilize various functions to understand the data types, sizes, and dimensions of your variables and arrays in your SystemVerilog designs. Let's get started!

Data Query Functions

$typename: Discovering Variable Types

The $typename function is a handy tool that returns a string representing the resolved type of its argument. It can work with both expressions and data types. Here's a simple example:

module TypeNameExample;
  typedef logic [7:0] ByteType;
  ByteType byteVar;
  
  initial begin
    string typeName = $typename(byteVar);
    $display("Type name: %0s", typeName);
    // Output: "Type name: logic [7:0]"
  end
endmodule

$bits: Counting Required Bits

The $bits function is used to determine the number of bits required to represent an expression or a data type. The return type of this function is an integer. Check out the following example:

module BitsExample;
  logic [15:0] wordVar;
  int wordBits = $bits(wordVar);
  
  initial begin
    $display("Number of bits in wordVar: %0d", wordBits);
    // Output: "Number of bits in wordVar: 16"
  end
endmodule

$isunbounded: Identifying Unbounded Variables

The $isunbounded function checks if a given variable is unbounded (has the value $). It returns 1'b1 (true) if the variable is unbounded or 1'b0 (false) otherwise.

module RangeExample;
  parameter int ParamA = $;
  parameter int ParamB = 42;
  
  initial begin
    $display("ParamA is unbounded: %0b", $isunbounded(ParamA));
    // Output: "ParamA is unbounded: 1"

    $display("ParamB is unbounded: %0b", $isunbounded(ParamB));
    // Output: "ParamB is unbounded: 0"
  end
endmodule

Array Query Functions

Basic Array Query Functions

Verilog and SystemVerilog provides a set of essential array query functions to obtain information about arrays, including their dimensions and sizes. The following functions are available:

  • $left: Returns the left bound of a specified dimension
  • $right: Returns the right bound of a specified dimension
  • $low: Returns the lower bound of a specified dimension
  • $high: Returns the upper bound of a specified dimension
  • $increment: Returns 1 if $left$right and -1 otherwise
  • $size: Returns the size (number of elements) of a specified dimension. The value is equal to $high$low + 1

These functions can be used with an optional dimension argument to specify which dimension the query should target. The value of the dimension starts from 1, beginning with the unpacked dimension, then the packed dimension, going from left to right. If the dimension argument is not provided, it is default to 1.

Here's an example illustrating the use of basic array query functions:

module ArrayQueryExample;
  logic [15:10][1:4] myArray [0:2][5:7];
  // Dimension 1 is [0:2]
  // Dimension 2 is [5:7]
  // Dimension 3 is [15:10]
  // Dimension 4 is [1:4]

  initial begin
    int left2  = $left(myArray, 2);
    int right2 = $right(myArray, 2);
    int low2   = $low(myArray, 2);
    int high2  = $high(myArray, 2);
    int incr2  = $increment(myArray, 2);
    int size2  = $size(myArray, 2);

    int left3  = $left(myArray, 3);
    int right3 = $right(myArray, 3);
    int low3   = $low(myArray, 3);
    int high3  = $high(myArray, 3);
    int incr3  = $increment(myArray, 3);
    int size3  = $size(myArray, 3);

    $display("Dimension 2:");
    $display("  Left: %0d, Right: %0d", left2, right2);
    $display("  Low: %0d, High: %0d", low2, high2);
    $display("  Increment: %0d, Size: %0d", increment2, size2);

    $display("Dimension 3:");
    $display("  Left: %0d, Right: %0d", left3, right3);
    $display("  Low: %0d, High: %0d", low3, high3);
    $display("  Increment: %0d, Size: %0d", increment3, size3);
  end
endmodule

Expected output:

Dimension 2:
  Left: 5, Right: 7
  Low: 5, High: 7
  Increment: -1, Size: 3
Dimension 3:
  Left: 15, Right: 10
  Low: 10, High: 15
  Increment: 1, Size: 6

Array Dimensions Functions

Verilog and SystemVerilog also offers functions to obtain information about the dimensions of an array:

  • $dimensions: Returns the total number of dimensions in an array, including both packed and unpacked, static or dynamic dimensions
  • $unpacked_dimensions: Returns the total number of unpacked dimensions for an array, including static or dynamic dimensions

Here's an example demonstrating the use of array dimensions functions:

module ArrayDimensionsExample;
  logic [7:0][3:0] myArray [0:3][2:5];

  initial begin
    int dimensions = $dimensions(myArray);
    int unpackedDimensions = $unpacked_dimensions(myArray);

    $display("Total dimensions: %0d", dimensions);            // 4
    $display("Unpacked dimensions: %0d", unpackedDimensions); // 2
  end
endmodule

Verilog and SystemVerilog provides an array of powerful query functions that can make working with arrays more efficient and maintainable. By understanding the differences between basic and advanced array query functions, you can access essential information about your arrays, such as dimensions and sizes, without hardcoding values. Keep in mind the best practices and restrictions to ensure that you use these functions effectively in your Verilog and SystemVerilog code.