Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full set of sign variants (signed/unsigned/selected) for multiplier operands #144

Merged
merged 5 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions doc/components/multiplier.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,14 @@ digital signal processing.
The parameters of the
`CompressionTreeMultiplier` are:

- Two input terms `a` and `b` which can be different widths
- The radix used for Booth encoding (2, 4, 8, and 16 are currently supported)
- The type of `ParallelPrefix` tree used in the final `ParallelPrefixAdder` (optional)
- `signed` parameter: whether the operands should be treated as signed (2s complement) or unsigned
- Two input terms `a` and `b` which can be different widths.
- The radix used for Booth encoding (2, 4, 8, and 16 are currently supported).
- The type of `ParallelPrefix` tree used in the final `ParallelPrefixAdder` (optional).
- `ppGen` parameter: the type of `PartialProductGenerator` to use which has derived classes for different styles of sign extension. In some cases this adds an extra row to hold a sign bit.
- An optional `selectSigned` control signal which overrides the `signed` configuration allowing for runtime control of signed or unsigned operation with the same hardware. `signed` must be false if using this control signal.
- `signedMultiplicand` parameter: whether the multiplicand (first arg) should be treated as signed (2s complement) or unsigned.
- `signedMultiplier` parameter: whether the multiplier (second arg) should be treated as signed (2s complement) or unsigned.
- An optional `selectSignedMultiplicand` control signal which overrides the `signedMultiplicand` parameter allowing for runtime control of signed or unsigned operation with the same hardware. `signedMultiplicand` must be false if using this control signal.
- An optional `selectSignedMultiplier` control signal which overrides the `signedMultiplier` parameter allowing for runtime control of signed or unsigned operation with the same hardware. `signedMultiplier` must be false if using this control signal.
- An optional `clk`, as well as `enable` and `reset` that are used to add a pipestage in the `ColumnCompressor` to allow for pipelined operation.

Here is an example of use of the `CompressionTreeMultiplier`:
Expand Down Expand Up @@ -123,9 +125,13 @@ The parameters of the
- The accumulate input term `c` which must have width as sum of the two operand widths + 1.
- The radix used for Booth encoding (2, 4, 8, and 16 are currently supported)
- The type of `ParallelPrefix` tree used in the final `ParallelPrefixAdder` (default Kogge-Stone).
- `signed` parameter: whether the operands should be treated as signed (2s complement) or unsigned
- `ppGen` parameter: the type of `PartialProductGenerator` to use which has derived classes for different styles of sign extension. In some cases this adds an extra row to hold a sign bit (default `PartialProductGeneratorCompactRectSignExtension`).
- An optional `selectSigned` control signal which overrides the `signed` configuration allowing for runtime control of signed or unsigned operation with the same hardware. `signed` must be false if using this control signal.
- `signedMultiplicand` parameter: whether the multiplicand (first arg) should be treated as signed (2s complement) or unsigned
- `signedMultiplier` parameter: whether the multiplier (second arg) should be treated as signed (2s complement) or unsigned
- `signedAddend` parameter: whether the addend (third arg) should be treated as signed (2s complement) or unsigned
- An optional `selectSignedMultiplicand` control signal which overrides the `signedMultiplicand` parameter allowing for runtime control of signed or unsigned operation with the same hardware. `signedMultiplicand` must be false if using this control signal.
- An optional `selectSignedMultiplier` control signal which overrides the `signedMultiplier` parameter allowing for runtime control of signed or unsigned operation with the same hardware. `signedMultiplier` must be false if using this control signal.
- An optional `selectSignedAddend` control signal which overrides the `signedAddend` parameter allowing for runtime control of signed or unsigned operation with the same hardware. `signedAddend` must be false if using this control signal.
- An optional `clk`, as well as `enable` and `reset` that are used to add a pipestage in the `ColumnCompressor` to allow for pipelined operation.

Here is an example of using the `CompressionTreeMultiplyAccumulate`:
Expand Down
4 changes: 2 additions & 2 deletions lib/src/arithmetic/carry_save_mutiplier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class CarrySaveMultiplier extends Multiplier {
CarrySaveMultiplier(super.a, super.b,
{required Logic clk,
required Logic reset,
required super.signed,
super.name = 'carry_save_multiplier'}) {
super.name = 'carry_save_multiplier'})
: super(signedMultiplicand: false, signedMultiplier: false) {
if (a.width != b.width) {
throw RohdHclException('inputs of a and b should have same width.');
}
Expand Down
6 changes: 2 additions & 4 deletions lib/src/arithmetic/evaluate_partial_product.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@ extension EvaluateLivePartialProduct on PartialProductGenerator {
}
}
final sum = LogicValue.ofBigInt(accum, maxW).toBigInt();
return signed
return isSignedMultiplicand() | isSignedMultiplier()
? sum.toSigned(maxW)
: (selectSigned != null && !selectSigned!.value.isZero)
? sum.toSigned(maxW)
: sum;
: sum;
}

/// Print out the partial product matrix
Expand Down
27 changes: 18 additions & 9 deletions lib/src/arithmetic/multiplicand_selector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import 'package:rohd_hcl/rohd_hcl.dart';

/// A class accessing the multiples of the multiplicand at a position
class MultiplicandSelector {
/// radix of the selector
/// The radix of the selector
int radix;

/// The bit shift of the selector (typically overlaps 1)
Expand All @@ -21,17 +21,25 @@ class MultiplicandSelector {
/// New width of partial products generated from the multiplicand
int get width => multiplicand.width + shift - 1;

/// Access the multiplicand
/// The base multiplicand from which to generate multiples to select.
Logic multiplicand = Logic();

/// Place to store multiples of the multiplicand
/// Place to store [multiples] of the [multiplicand] (e.g. *1, *2, *-1, *-2..)
late LogicArray multiples;

/// Generate required multiples of multiplicand
/// Build a [MultiplicandSelector] generationg required [multiples] of
/// [multiplicand] to [select] using a [RadixEncoder] argument.
///
/// [multiplicand] is base multiplicand multiplied by Booth encodings of
/// the [RadixEncoder] during [select].
///
/// [signedMultiplicand] generates a fixed signed selector versus using
/// [selectSignedMultiplicand] which is a runtime sign selection [Logic]
/// in which case [signedMultiplicand] must be false.
MultiplicandSelector(this.radix, this.multiplicand,
{Logic? selectSigned, bool signed = false})
{Logic? selectSignedMultiplicand, bool signedMultiplicand = false})
: shift = log2Ceil(radix) {
if (signed && (selectSigned != null)) {
if (signedMultiplicand && (selectSignedMultiplicand != null)) {
throw RohdHclException('sign reconfiguration requires signed=false');
}
if (radix > 16) {
Expand All @@ -41,15 +49,16 @@ class MultiplicandSelector {
final numMultiples = radix ~/ 2;
multiples = LogicArray([numMultiples], width);
final Logic extendedMultiplicand;
if (selectSigned == null) {
extendedMultiplicand = signed
if (selectSignedMultiplicand == null) {
extendedMultiplicand = signedMultiplicand
? 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))
for (var i = len; i < width; i++)
mux(selectSignedMultiplicand, sign, Const(0))
];
extendedMultiplicand = (multiplicand.elements + extension).rswizzle();
}
Expand Down
Loading