Skip to content

Refactor signextend #154

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

Merged
merged 15 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from 10 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
32 changes: 18 additions & 14 deletions doc/components/adder.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ROHD-HCL provides a set of adder modules to get the sum from a pair of Logic. So

A ripple carry adder is a digital circuit used for binary addition. It consists of a series of [FullAdder](https://intel.github.io/rohd-hcl/rohd_hcl/FullAdder-class.html)s connected in a chain, with the carry output of each adder linked to the carry input of the next one. Starting from the least significant bit (LSB) to most significant bit (MSB), the adder sequentially adds corresponding bits of two binary numbers.

The [RippleCarryAdder](https://intel.github.io/rohd-hcl/rohd_hcl/RippleCarryAdder-class.html) module in ROHD-HCL accept input `Logic`s a and b as the input pin and the name of the module `name`. Note that the width of the inputs must be the same or a [RohdHclException](https://intel.github.io/rohd-hcl/rohd_hcl/RohdHclException-class.html) will be thrown.
The [adder](https://intel.github.io/rohd-hcl/rohd_hcl/Adder-class.html) module in ROHD-HCL accept input `Logic`s a and b as the input pin and the name of the module `name`. Note that the width of the inputs must be the same or a [RohdHclException](https://intel.github.io/rohd-hcl/rohd_hcl/RohdHclException-class.html) will be thrown.

An example is shown below to add two inputs of signals that have 8-bits of width.

Expand All @@ -23,8 +23,8 @@ final b = Logic(name: 'b', width: 8);
a.put(5);
b.put(5);

final rippleCarryAdder = RippleCarryAdder(a, b);
final sum = rippleCarryAdder.sum;
final adder = adder(a, b);
final sum = adder.sum;
```

## Parallel Prefix Adder
Expand Down Expand Up @@ -68,7 +68,7 @@ Here is an example of instantiating a [OnesComplementAdder](https://intel.githu
b.put(bv);
final carry = Logic();
final adder = OnesComplementAdder(
a, b, carryOut: carry, adderGen: RippleCarryAdder.new,
a, b, carryOut: carry, adderGen: adder.new,
subtract: true);
final mag = adder.sum.value.toInt() + (carry.value.isZero ? 0 : 1));
final out = (adder.sign.value.toInt() == 1 ? -mag : mag);
Expand Down Expand Up @@ -96,7 +96,7 @@ Here is an example of instantiating a [SignMagnitudeAdder](https://intel.github.
b.put(18);
bSign.put(0);

final adder = SignMagnitudeAdder(aSign, a, bSign, b, adderGen: RippleCarryAdder.new,
final adder = SignMagnitudeAdder(aSign, a, bSign, b, adderGen: adder.new,
largestMagnitudeFirst: true);

final sum = adder.sum;
Expand All @@ -112,14 +112,18 @@ The [`CarrySelectCompoundAdder`](https://intel.github.io/rohd-hcl/rohd_hcl/Carry
The delay of the adder is defined by the combination of the sub-adders and the accumulated carry-select chain delay.

The [CarrySelectCompoundAdder](https://intel.github.io/rohd-hcl/rohd_hcl/CarrySelectCompoundAdder-class.html) module in ROHD-HCL accepts input `Logic`s a and b as the input pin and the name of the module `name`. Note that the width of the inputs must be the same or a [RohdHclException](https://intel.github.io/rohd-hcl/rohd_hcl/RohdHclException-class.html) will be thrown.
The compound adder generator provides two alogithms for splitting the adder into adder sub-blocks:

- The [CarrySelectCompoundAdder.splitSelectAdderAlgorithm4Bit](https://intel.github.io/rohd-hcl/rohd_hcl/CarrySelectCompoundAdder/splitSelectAdderAlgorithm4Bit.html) algoritm splits the adder into blocks of 4-bit ripple-carry adders with the first one width adjusted down.
- The [CarrySelectCompoundAdder.splitSelectAdderAlgorithmSingleBlock](https://intel.github.io/rohd-hcl/rohd_hcl/CarrySelectCompoundAdder/splitSelectAdderAlgorithmSingleBlock.html) algorithm generates only one sub=block with the full bitwidth of the adder.
The compound adder forms a select chain around a set of adders specified by:

Input `List<int> Function(int adderFullWidth) widthGen` should be used to specify the custom adder splitting algorithm that returns a list of sub-adders width. The default one is [CarrySelectCompoundAdder.splitSelectAdderAlgorithmSingleBlock](<https://intel.github.io/rohd-hcl/rohd_hcl/CarrySelectCompoundAdder/splitSelectAdderAlgorithmSingleBlock.html>).
- `addergen`: an adder generator functor option to build the block adders with the default being `ParallelPrefixAdder`.

The `adderGen` input selects the type of sub-adder used, with the default being `ParallelPrefixAdder`.
The compound adder generator provides two algorithms for splitting the adder into adder sub-blocks:

- `splitSelectAdderAlgorithmSingleBlock:
- The [CarrySelectCompoundAdder.splitSelectAdderAlgorithm4Bit](https://intel.github.io/rohd-hcl/rohd_hcl/CarrySelectCompoundAdder/splitSelectAdderAlgorithm4Bit.html) algoritm splits the adder into blocks of 4-bit ripple-carry adders with the first one width adjusted down.
- The [CarrySelectCompoundAdder.splitSelectAdderAlgorithmSingleBlock](https://intel.github.io/rohd-hcl/rohd_hcl/CarrySelectCompoundAdder/splitSelectAdderAlgorithmSingleBlock.html) algorithm generates only one sub=block with the full bitwidth of the adder.

- `List<int> Function(int adderFullWidth) widthGen` should be used to specify the custom adder splitting algorithm that returns a list of sub-adders width. The default one is [CarrySelectCompoundAdder.splitSelectAdderAlgorithmSingleBlock](<https://intel.github.io/rohd-hcl/rohd_hcl/CarrySelectCompoundAdder/splitSelectAdderAlgorithmSingleBlock.html>).

An example is shown below to add two inputs of signals that have 8-bits of width.

Expand All @@ -130,10 +134,10 @@ final b = Logic(name: 'b', width: 8);
a.put(5);
b.put(5);

final rippleCarryAdder = CarrySelectCompoundAdder(a, b);
final sum = rippleCarryAdder.sum;
final sum1 = rippleCarryAdder.sum1;
final adder = CarrySelectCompoundAdder(a, b);
final sum = adder.sum;
final sum1 = adder.sum1;

final rippleCarryAdder4BitBlock = CarrySelectCompoundAdder(a, b,
final adder4BitBlock = CarrySelectCompoundAdder(a, b,
widthGen: CarrySelectCompoundAdder.splitSelectAdderAlgorithm4Bit);
```
6 changes: 3 additions & 3 deletions doc/components/floating_point.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Floating-Point Components

Floating-point operations require meticulous precision, and have standards like [IEEE-754](<https://standards.ieee.org/ieee/754/6210/>) which govern them. To support floating-point components, we have created a parallel to [Logic](https://intel.github.io/rohd/rohd/Logic-class.html)/[LogicValue](https://intel.github.io/rohd/rohd/LogicValue-class.html) which are part of [ROHD](<https://intel.github.io/rohd-website/>). Here, [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) is the [Logic](https://pub.dev/documentation/rohd/latest/rohd/Logic-class.html) wire in a component that carries [FloatingPointValue](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointValue-class.html) literal values, a subclass of [LogicValue](https://intel.github.io/rohd/rohd/LogicValue-class.html). An important distinction is that these classes are parameterized to create arbitrary size floating-point values.
Floating-point operations require meticulous precision, and have standards like [IEEE-754](<https://standards.ieee.org/ieee/754/6210/>) which govern them. To support floating-point components, we have created a parallel to [Logic](https://intel.github.io/rohd/rohd/Logic-class.html)/[LogicValue](https://intel.github.io/rohd/rohd/LogicValue-class.html) which are part of [ROHD](<https://intel.github.io/rohd-website/>). Here, [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) is the [Logic](https://intel.github.io/rohd/rohd/Logic-class.html) wire in a component that carries [FloatingPointValue](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointValue-class.html) literal values, a subclass of [LogicValue](https://intel.github.io/rohd/rohd/LogicValue-class.html). An important distinction is that these classes are parameterized to create arbitrary size floating-point values.

## FloatingPointValue

Expand Down Expand Up @@ -34,13 +34,13 @@ Finally, we have a [random value constructor](https://intel.github.io/rohd-hcl/r

## FloatingPoint

The [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) type is a [LogicStructure](https://pub.dev/documentation/rohd/latest/rohd/LogicStructure-class.html) which comprises the [Logic](https://pub.dev/documentation/rohd/latest/rohd/Logic-class.html) bits for the sign, exponent, and mantissa used in hardware floating-point. This type is provided to simplify and abstract the declaration and manipulation of floating-point bits in hardware. This type is parameterized like [FloatingPointValue](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointValue-class.html), for exponent and mantissa width.
The [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) type is a [LogicStructure](https://intel.github.io/rohd/rohd/LogicStructure-class.html) which comprises the [Logic](https://intel.github.io/rohd/rohd/Logic-class.html) bits for the sign, exponent, and mantissa used in hardware floating-point. This type is provided to simplify and abstract the declaration and manipulation of floating-point bits in hardware. This type is parameterized like [FloatingPointValue](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointValue-class.html), for exponent and mantissa width.

Again, like [FloatingPointValue](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointValue-class.html), [FloatingPoint64](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint64-class.html) and [FloatingPoint32](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint32-class.html) subclasses are provided as these are the most common floating-point number types.

## FloatingPointAdder

A very basic [FloatingPointAdderSimple](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointAdderSimple-class.html) component is available which does not perform any rounding. It takes two [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) [LogicStructure](https://pub.dev/documentation/rohd/latest/rohd/LogicStructure-class.html)s and adds them, returning a normalized [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) on the output. An option on input is the type of ['ParallelPrefix'](https://intel.github.io/rohd-hcl/rohd_hcl/ParallelPrefix-class.html) used in the critical internal addition of the mantissas.
A very basic [FloatingPointAdderSimple](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointAdderSimple-class.html) component is available which does not perform any rounding. It takes two [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) [LogicStructure](https://intel.github.io/rohd/rohd/LogicStructure-class.html)s and adds them, returning a normalized [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) on the output. An option on input is the type of ['ParallelPrefix'](https://intel.github.io/rohd-hcl/rohd_hcl/ParallelPrefix-class.html) used in the critical internal addition of the mantissas.

Currently, the [FloatingPointAdderSimple](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointAdderSimple-class.html) is close in accuracy (as it has no rounding) and is not optimized for circuit performance, but only provides the key functionalities of alignment, addition, and normalization. Still, this component is a starting point for more realistic floating-point components that leverage the logical [FloatingPoint](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPoint-class.html) and literal [FloatingPointValue](https://intel.github.io/rohd-hcl/rohd_hcl/FloatingPointValue-class.html) type abstractions.

Expand Down
51 changes: 24 additions & 27 deletions doc/components/multiplier.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Multiplier
# Integer Multiplier

ROHD-HCL provides an abstract `Multiplier` module which multiplies two
ROHD-HCL provides an abstract [Multiplier](https://intel.github.io/rohd-hcl/rohd_hcl/Multiplier-class.html) module which multiplies two
numbers represented as two `Logic`s, potentially of different widths,
treating them as either signed (twos' complement) or unsigned. It
produces the product as a `Logic` with width equal to the sum of the
Expand All @@ -16,7 +16,7 @@ of this abstract `Module`:
- [Compression Tree Multiplier](#compression-tree-multiplier)

An additional kind of abstract module provided is a
`MultiplyAccumulate` module which multiplies two numbers represented
[MultiplierAccumulate](https://intel.github.io/rohd-hcl/rohd_hcl/MultiplyAccumulate-class.html) module which multiplies two numbers represented
as two `Logic`s and adds the result to a third `Logic` with width
equal to the sum of the widths of the main inputs. Similar to the `Multiplier`,
the signs of the operands are either fixed by a parameter,
Expand Down Expand Up @@ -86,23 +86,24 @@ Simulator.endSimulation();

A compression tree multiplier is a digital circuit used for performing
multiplication operations, using Booth encoding to produce addends, a
compression tree for reducing addends to a final pair, and a final
adder generated from a parallel prefix tree option. It is particularly
useful in applications that require high speed multiplication, such as
digital signal processing.
compression tree for reducing addends to a final pair, and a final adder
generated from a parallel prefix tree functor parameter. It is particularly
useful in applications that require high speed and varying width multiplication,
such as digital signal processing.

The parameters of the
`CompressionTreeMultiplier` are:
[CompressionTreeMultiplier](https://intel.github.io/rohd-hcl/rohd_hcl/CompressionTreeMultiplier-class.html) 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).
- `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.
- `signedMultiplicand` parameter: whether the multiplicand (first arg) should be treated as signed (twos' complement) or unsigned.
- `signedMultiplier` parameter: whether the multiplier (second arg) should be treated as signed (twos' 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.
- `seGen` parameter: the type of `PartialProductSignExtension` functor 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 `CompactRectSignExtension` does not). See [Sign Extension Options](./multiplier_components.md#sign-extension-option).
- Signed or unsigned operands:
- `signedMultiplicand` parameter: whether the multiplicand (first arg) should be treated as signed (twos' complement) or unsigned.
- `signedMultiplier` parameter: whether the multiplier (second arg) should be treated as signed (twos' complement) or unsigned.
- Alternatively, it supports runtime control of signage:
- An optional `selectSignedMultiplicand` control signal which allows 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 allows 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, making the multiplier operate in 2 cycles.

Here is an example of use of the `CompressionTreeMultiplier` with one signed input:

Expand Down Expand Up @@ -130,22 +131,18 @@ A compression tree multiply-accumulate is similar to a compress tree
multiplier, but it inserts an additional addend into the compression
tree to allow for accumulation into this third input.

The parameters of the
`CompressionTreeMultiplyAccumulate` are:
The additional parameters of the
[CompressionTreeMultiplyAccumulate](https://intel.github.io/rohd-hcl/rohd_hcl/CompressionTreeMultiplyAccumulate-class.html) over the [CompressionTreeMltiplier](#compression-tree-multiplier) are:

- Two input product terms `a` and `b` which can be different widths
- 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).
- `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`).
- `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 (twos' complement) or unsigned
- `signedAddend` parameter: whether the addend (third arg) should be treated as signed (twos' 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.
- Addend signage:
- `signedAddend` parameter: whether the addend (third arg) should be treated as signed (twos' complement) or unsigned
OR
- An optional `selectSignedAddend` control signal allows 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.

The output width of the `CompressionTreeMultiplier` is the sum of the product term widths plus one to accomodate the additional acccumulate term.

Here is an example of using the `CompressionTreeMultiplyAccumulate` with all inputs as signed:

```dart
Expand Down
Loading