LogicArray constructor

LogicArray(
  1. List<int> dimensions,
  2. int elementWidth, {
  3. String? name,
  4. int numUnpackedDimensions = 0,
  5. Naming? naming,
})

Creates an array with specified dimensions and elementWidth named name.

Setting the numUnpackedDimensions gives a hint to Synthesizers about the intent for declaration of signals. By default, all dimensions are packed, but if the value is set to more than 0, then the outer-most dimensions (first in dimensions) will become unpacked. It must be less than or equal to the length of dimensions. Modifying it will have no impact on simulation functionality or behavior. In SystemVerilog, there are some differences in access patterns for packed vs. unpacked arrays.

Implementation

factory LogicArray(List<int> dimensions, int elementWidth,
    {String? name, int numUnpackedDimensions = 0, Naming? naming}) {
  if (dimensions.isEmpty) {
    throw LogicConstructionException(
        'Arrays must have at least 1 dimension.');
  }

  if (numUnpackedDimensions > dimensions.length) {
    throw LogicConstructionException(
        'Cannot unpack more than all of the dimensions.');
  }

  // calculate the next layer's dimensions
  final nextDimensions = dimensions.length == 1
      ? null
      : UnmodifiableListView(
          dimensions.getRange(1, dimensions.length).toList(growable: false));

  // if the total width will eventually be 0, then force element width to 0
  if (elementWidth != 0 && dimensions.reduce((a, b) => a * b) == 0) {
    elementWidth = 0;
  }

  return LogicArray._(
    List.generate(
        dimensions.first,
        (index) => (dimensions.length == 1
            ? Logic(
                width: elementWidth,
                naming: Naming.renameable,
              )
            : LogicArray(
                nextDimensions!,
                elementWidth,
                numUnpackedDimensions: max(0, numUnpackedDimensions - 1),
                name: '${name}_$index',
              ))
          .._arrayIndex = index,
        growable: false),
    dimensions: UnmodifiableListView(dimensions),
    elementWidth: elementWidth,
    numUnpackedDimensions: numUnpackedDimensions,
    name: name,
    naming: naming,
  );
}