A LogicArray is a type of LogicStructure that mirrors multi-dimensional arrays in hardware languages like SystemVerilog. In ROHD, the LogicArray type inherits a lot of functionality from LogicStructure, so it can behave like a Logic where it makes sense or be individually referenced in other places.

LogicArrays can be constructed easily using the constructor:

// A 1D array with ten 8-bit elements.
LogicArray([10], 8);

// A 4x3 2D array, with four arrays, each with three 2-bit elements.
LogicArray([4, 3], 2, name: 'array4x3');

// A 5x5x5 3D array, with 125 total elements, each 128 bits.
LogicArray([5, 5, 5], 128);

As long as the total width of a LogicArray and another type of Logic (including Logic, LogicStructure, and another LogicArray) are the same, assignments and bitwise operations will work in per-element order. This means you can assign two LogicArrays of different dimensions to each other as long as the total width matches.

Unpacked arraysPermalink

In SystemVerilog, there is a concept of “packed” vs. “unpacked” arrays which have different use cases and capabilities. In ROHD, all arrays act the same and you get the best of both worlds. You can indicate when constructing a LogicArray that some number of the dimensions should be “unpacked” as a hint to Synthesizers. Marking an array with a non-zero numUnpackedDimensions, for example, will make that many of the dimensions “unpacked” in generated SystemVerilog signal declarations.

// A 4x3 2D array, with four arrays, each with three 2-bit elements.
// The first dimension (4) will be unpacked.
LogicArray(
  [4, 3],
  2,
  name: 'array4x3w1unpacked',
  numUnpackedDimensions: 1,
);

Array portsPermalink

You can declare ports of Modules as being arrays (including with some dimensions “unpacked”) using addInputArray and addOutputArray. Note that these do not automatically do validation that the dimensions, element width, number of unpacked dimensions, etc. are equal between the port and the original signal. As long as the overall width matches, the assignment will be clean.

Array ports in generated SystemVerilog will match dimensions (including unpacked) as specified when the port is created.

Elements of arraysPermalink

To iterate through or access elements of a LogicArray (or bits of a simple Logic), use elements. Using the normal [n] accessors will return the nth bit regardless for LogicArray and Logic to maintain API consistency.

Index-based Selection in an ArrayPermalink

The selectIndex and selectFrom methods are used to select a value from a LogicArray or from a list of Logic elements based on an index. These methods are useful for creating dynamic selection logic in hardware design. They can be used in 2 ways as shown below.

1. Using a LogicArray typePermalink

final arrayA = LogicArray([4], 8, name: 'arrayA'); // A 1D array with four 8-bit element
final id = Logic(name: 'id', width: 3);

selectIndexValueArrayA <= arrayA.elements.selectIndex(id, defaultValue: defaultValue);
selectFromValueArrayA <= id.selectFrom(arrayA.elements, defaultValue: defaultValue);

An example code is given to demonstrate a usage of selectIndex and selectFrom for logic arrays. Please see code here: logic_array.dart

2. Using a list of Logic elementsPermalink

final inputA = Logic(name: 'inputA', width: 8);
final inputB = Logic(name: 'inputB', width: 8);
final inputC = Logic(name: 'inputC', width: 8);
final listA = <Logic>[inputA, inputB, inputC];

final id = Logic(name: 'id', width: 3);

selectIndexValueListA <= listA.selectIndex(id, defaultValue: defaultValue);
selectFromValueListA <= id.selectFrom(listA, defaultValue: defaultValue);

Updated: