CarrySaveMultiplier constructor

CarrySaveMultiplier(
  1. Logic a,
  2. Logic b, {
  3. required Logic clk,
  4. required Logic reset,
  5. required bool signed,
  6. String name = 'carry_save_multiplier',
})

Construct a CarrySaveMultiplier that multiply input a and input b.

Implementation

CarrySaveMultiplier(super.a, super.b,
    {required Logic clk,
    required Logic reset,
    required super.signed,
    super.name = 'carry_save_multiplier'}) {
  if (a.width != b.width) {
    throw RohdHclException('inputs of a and b should have same width.');
  }
  clk = addInput('clk', clk);
  reset = addInput('reset', reset);

  final product = addOutput('product', width: a.width + b.width + 1);

  _sum = List.generate(a.width * 2, (index) => Logic(name: 'sum_$index'));
  _carry = List.generate(a.width * 2, (index) => Logic(name: 'carry_$index'));

  final rCarryA = Logic(name: 'rcarry_a', width: a.width);
  final rCarryB = Logic(name: 'rcarry_b', width: b.width);

  _pipeline = Pipeline(
    clk,
    stages: [
      ...List.generate(
        b.width,
        (row) => (p) {
          final columnAdder = <Conditional>[];
          final maxIndexA = (a.width - 1) + row;

          for (var column = maxIndexA; column >= row; column--) {
            final fullAdder = FullAdder(
                a: column == maxIndexA || row == 0
                    ? Const(0)
                    : p.get(_sum[column]),
                b: p.get(a)[column - row] & p.get(b)[row],
                carryIn: row == 0 ? Const(0) : p.get(_carry[column - 1]));

            columnAdder
              ..add(p.get(_carry[column]) < fullAdder.carryOut)
              ..add(p.get(_sum[column]) < fullAdder.sum);
          }

          return columnAdder;
        },
      ),
      (p) => [
            p.get(rCarryA) <
                <Logic>[
                  Const(0),
                  ...List.generate(a.width - 1,
                      (index) => p.get(_sum[(a.width + b.width - 2) - index]))
                ].swizzle(),
            p.get(rCarryB) <
                <Logic>[
                  ...List.generate(
                      a.width,
                      (index) =>
                          p.get(_carry[(a.width + b.width - 2) - index]))
                ].swizzle()
          ],
    ],
    reset: reset,
    resetValues: {product: Const(0)},
  );

  final nBitAdder = RippleCarryAdder(
    _pipeline.get(rCarryA),
    _pipeline.get(rCarryB),
  );

  product <=
      <Logic>[
        ...List.generate(
          a.width + 1,
          (index) => nBitAdder.sum[(a.width) - index],
        ),
        ...List.generate(
          a.width,
          (index) => _pipeline.get(_sum[a.width - index - 1]),
        )
      ].swizzle();
}