BusSubset constructor

BusSubset(
  1. Logic bus,
  2. int startIndex,
  3. int endIndex, {
  4. String name = 'bussubset',
})

Constructs a Module that accesses a subset from bus which ranges from startIndex to endIndex (inclusive of both).

When, bus has a width of '1', startIndex and endIndex are ignored in the generated SystemVerilog.

Implementation

BusSubset(Logic bus, this.startIndex, this.endIndex,
    {super.name = 'bussubset'})
    : _isNet = bus.isNet {
  // If a converted index value is still -ve then it's an Index out of bounds
  // on a Logic Bus
  if (startIndex < 0 || endIndex < 0) {
    throw Exception(
        'Start ($startIndex) and End ($endIndex) must be greater than or '
        'equal to 0.');
  }
  // If the +ve indices are more than Logic bus width, Index out of bounds
  if (endIndex > bus.width - 1 || startIndex > bus.width - 1) {
    throw Exception(
        'Index out of bounds, indices $startIndex and $endIndex must be less'
        ' than ${bus.width}');
  }

  _originalName = Naming.unpreferredName('original_${bus.name}');
  _subsetName =
      Naming.unpreferredName('subset_${endIndex}_${startIndex}_${bus.name}');

  final newWidth = (endIndex - startIndex).abs() + 1;

  if (_isNet) {
    original = addInOut(_originalName, bus, width: bus.width);
    subset =
        LogicNet(width: newWidth, name: _subsetName, naming: Naming.unnamed);
    final internalSubset = addInOut(_subsetName, subset, width: newWidth);

    if (startIndex > endIndex) {
      // reverse case
      for (var i = 0; i < newWidth; i++) {
        internalSubset.quietlyMergeSubsetTo(
          original[startIndex - i] as LogicNet,
          start: endIndex + i,
        );
      }
    } else {
      // normal case
      (original as LogicNet).quietlyMergeSubsetTo(
        internalSubset,
        start: startIndex,
      );
    }
  } else {
    original = addInput(_originalName, bus, width: bus.width);
    subset = addOutput(_subsetName, width: newWidth);

    // so that people can't do a slice assign, not (yet?) implemented
    subset.makeUnassignable(
        reason:
            'The output of a (non-LogicNet) BusSubset ($this) is read-only.');

    _setup();
  }
}