recurseFinder method

Logic recurseFinder(
  1. List<Logic> seq, [
  2. int depth = 0
])

Recursively find the trailing 1

Implementation

Logic recurseFinder(List<Logic> seq, [int depth = 0]) {
  if (seq.length == 1) {
    return ~seq[0];
  } else if (seq.length == 2) {
    final l = seq[0].named('leftLeafLead_d$depth');
    final r = seq[1].named('rightLeafLead_d$depth');
    final ret = Logic(width: 2, name: 'leaf_d$depth');
    Combinational([
      If.block([
        Iff(l, [
          ret < Const(0, width: 2),
        ]),
        ElseIf(r, [
          ret < [Const(0), Const(1)].swizzle(),
        ]),
        Else([
          ret < [Const(1), Const(0)].swizzle(),
        ]),
      ]),
    ]);
    return ret;
  } else {
    final divisor = (log(seq.length - 1) / log(2)).floor();
    final split = pow(2.0, divisor).toInt();

    final left = recurseFinder(seq.getRange(0, split).toList(), depth + 1);
    var right =
        recurseFinder(seq.getRange(split, seq.length).toList(), depth + 1);
    if (right.width < left.width) {
      right = right.zeroExtend(left.width);
    }
    final l = left[-1].named('leftLead_d$depth');
    final r = right[-1].named('rightLead_d$depth');
    final ret = Logic(width: right.width + 1, name: 'merge_d$depth');
    final rhs = ((right.width > 1)
            ? [Const(0), Const(1), right.slice(-2, 0)]
                .swizzle()
                .named('zo_right_d$depth')
            : [Const(0), Const(1)].swizzle().named('zo_d$depth'))
        .named('right_d$depth');
    Combinational([
      If.block([
        Iff(l & r, [
          ret <
              [Const(1), Const(0, width: right.width)]
                  .swizzle()
                  .named('lr_d$depth'),
        ]),
        ElseIf(~l, [
          ret < [Const(0), left.slice(-1, 0)].swizzle().named('zl_d$depth'),
        ]),
        ElseIf(l, [
          ret < rhs,
        ]),
      ]),
    ]);
    return ret;
  }
}