MultiplicandSelector constructor

MultiplicandSelector(
  1. int radix,
  2. Logic multiplicand, {
  3. Logic? selectSigned,
  4. bool signed = false,
})

Generate required multiples of multiplicand

Implementation

MultiplicandSelector(this.radix, this.multiplicand,
    {Logic? selectSigned, bool signed = false})
    : shift = log2Ceil(radix) {
  if (signed && (selectSigned != null)) {
    throw RohdHclException('sign reconfiguration requires signed=false');
  }
  if (radix > 16) {
    throw RohdHclException('Radices beyond 16 are not yet supported');
  }
  final width = multiplicand.width + shift;
  final numMultiples = radix ~/ 2;
  multiples = LogicArray([numMultiples], width);
  final Logic extendedMultiplicand;
  if (selectSigned == null) {
    extendedMultiplicand = signed
        ? multiplicand.signExtend(width)
        : multiplicand.zeroExtend(width);
  } else {
    final len = multiplicand.width;
    final sign = multiplicand[len - 1];
    final extension = [
      for (var i = len; i < width; i++) mux(selectSigned, sign, Const(0))
    ];
    extendedMultiplicand = (multiplicand.elements + extension).rswizzle();
  }

  for (var pos = 0; pos < numMultiples; pos++) {
    final ratio = pos + 1;
    multiples.elements[pos] <=
        switch (ratio) {
          1 => extendedMultiplicand,
          2 => extendedMultiplicand << 1,
          3 => (extendedMultiplicand << 2) - extendedMultiplicand,
          4 => extendedMultiplicand << 2,
          5 => (extendedMultiplicand << 2) + extendedMultiplicand,
          6 => (extendedMultiplicand << 3) - (extendedMultiplicand << 1),
          7 => (extendedMultiplicand << 3) - extendedMultiplicand,
          8 => extendedMultiplicand << 3,
          _ => throw RohdHclException('Radix is beyond 16')
        };
  }
}