Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
6 changes: 4 additions & 2 deletions doc/components/adder.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@ The compound adder forms a select chain around a set of adders specified by:
- `adderGen`: an adder generator functor option to build the block adders with the default being a closure returning a functor returning `ParallelPrefixAdder`. This functor has the signature: This functor has the signature:

```dart
(Logic a, Logic b, {Logic? carryIn, Logic? subtractIn, String name = ''})=> Adder
(Logic a, Logic b, {Logic? carryIn, dynamic subtract, String name = ''})=> Adder
```

Note that the subtract input can either be a `bool` or a `Logic` signal to enable static subtraction or dynamic control of subtraction.

- `splitSelectAdderAlgorithmSingleBlock:
- The `CarrySelectCompoundAdder.splitSelectAdderAlgorithmNBit` algorithm splits the adder into blocks of n-bit 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 bit-width of the adder.
Expand Down Expand Up @@ -151,7 +153,7 @@ ROHD-HCL has an implementation of a `CompoundAdder` that uses a `OnesComplement`

By providing `outputCarryOut` and/or `outputCarryOutP1` settings, the outputs `carryOut` and `carryOutP1` are provided which also ensures the adder does not convert to 2s complement but instead does the efficient 1s complement subtract (or add) and provides the end-around carry as an output. Otherwise, the adder will add back the end-around carry to the result to convert back to 2s complement. A `sign` and `signP1` is also output for the result.

Both Logic control `subtractIn` and boolean control `subtract` are provided for enabling subtraction either by control signal or by a hard configuration (no signal control).
Both `Logic` control and boolean control are provided via the `subtract` option for enabling subtraction.

```dart
final adder = CarrySelectOnesComplementCompoundAdder(a, b,
Expand Down
7 changes: 4 additions & 3 deletions doc/components/multiplier.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ The parameters of the
- 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.
- As booleans, these parameters satically configure the multiplier to support signed opernads. Alternatively the multiplier supports runtime control of signage by passing a `Logic` signal instead and control logic will be added to support signed or unsigned operands.
- Note that these parameters are optional and can be specified as:
- `null`: default behavior is unsigned.
- `bool`: statically configure the component to treat operand as unsigned.
- `Logic`: specify a `Logic` control signal to dynamically treat operand as signed or unsigned.
- 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 @@ -135,8 +138,6 @@ The additional parameters of the
- The accumulate input term `c` which must have width as sum of the two operand widths + 1.
- Addend signage:
- `signedAddend` parameter: whether the addend (third argument) 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 accommodate the additional accumulate term.
Expand Down
45 changes: 45 additions & 0 deletions doc/components/static_or_dynamic_configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Static or Dynamic Component Configuration

Features of a hardware component may be selectable either at generation time or controllable by a hardware signal. In the former case, we can statically configure the generator to generate the logic needed to support that feature set by the parameter. In the latter case we would generate the logic for the feature as well as control logic to enable or disable the feature.

An example use of this is in specifying signed operands in ROHD-HCL multipliers where we pass in a parameter during construction:

```dart
dynamic signedMultiplicand,
...
```

Internally, we can convert this dynamic to either a boolean or a Logic depending on what was passed in, and perform the appropriate logic generation for either statically configurating signed-multiplicand operation, or adding the Logic provided as an input for controlling signed-multiplicand operation as a hardware feature. This will enforce that the parameter is either not provided (null), a boolean, or a `Logic` control signal for the feature.

Inside a component, we can interpret and check the type of the parameter passed in:

```dart
final signedMultiplicandParameter = StaticOrLogicParameter.ofDynamic(signedMultiplicand);
```

We can check if it is a hardware control signal:

```dart
if (signedMultiplicandParameter.dynamicConfig != null)
```

If not dynamically configurable, we can then grab the static boolean:

```dart
final doSignedMultiplicand = signedMultiplicandParameter.staticConfig;
```

Since this is an input parameter with potentially a control `Logic` signal, the signal would have to be added as an input to a module. The API for `StaticOrDynamicParameter` adds the input and creates a new copy by cloning with the current module as an argument (taking care of ensuring the internal signal of the Module is used) for passing to submodules:

```dart
class MyModule extends Module {
MyModule({dynamic hardwareFeatureOne}) {
// Make sure to pass the signal of the current module's added input and
// not the signal from outside to the submodule.
final submodule = MySubModule(hardwareFeature.clone(this));
}
}

final hardwareFeatureOn = Const(1);
final myModule = MyModule(hardwareFeatureOne: hardwareFeatureOn);
```
2 changes: 1 addition & 1 deletion lib/rohd_hcl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export 'src/serialization/serialization.dart';
export 'src/shift_register.dart';
export 'src/signed_shifter.dart';
export 'src/sort.dart';
export 'src/static_or_runtime_parameter.dart';
export 'src/static_or_dynamic_parameter.dart';
export 'src/summation/summation.dart';
export 'src/toggle_gate.dart';
export 'src/utils.dart';
38 changes: 17 additions & 21 deletions lib/src/arithmetic/compound_adder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class CarrySelectCompoundAdder extends CompoundAdder {

/// Default adder functor to use.
static Adder _defaultBlockAdder(Logic a, Logic b,
{Logic? carryIn, Logic? subtractIn, String name = ''}) =>
{Logic? carryIn, dynamic subtract, String name = ''}) =>
ParallelPrefixAdder(a, b, carryIn: carryIn, name: name);

/// Constructs a [CarrySelectCompoundAdder].
Expand All @@ -120,7 +120,7 @@ class CarrySelectCompoundAdder extends CompoundAdder {
Logic? subtractIn,
super.carryIn,
Adder Function(Logic a, Logic b,
{Logic? carryIn, Logic? subtractIn, String name})
{Logic? carryIn, dynamic subtract, String name})
adderGen = _defaultBlockAdder,
List<int> Function(int) widthGen = splitSelectAdderAlgorithmSingleBlock,
super.name = 'cs_compound_adder',
Expand Down Expand Up @@ -159,10 +159,10 @@ class CarrySelectCompoundAdder extends CompoundAdder {
// Build sub adders for carryIn=0 and carryIn=1
final fullAdder0 = adderGen(a.getRange(blockStartIdx, blockEnd),
b.getRange(blockStartIdx, blockEnd),
subtractIn: subtractIn, carryIn: Const(0), name: 'block0_$i');
subtract: subtractIn, carryIn: Const(0), name: 'block0_$i');
final fullAdder1 = adderGen(a.getRange(blockStartIdx, blockEnd),
b.getRange(blockStartIdx, blockEnd),
subtractIn: subtractIn, carryIn: Const(1), name: 'block1_$i');
subtract: subtractIn, carryIn: Const(1), name: 'block1_$i');
sum0Ary <=
((i == 0)
? fullAdder0.sum
Expand Down Expand Up @@ -220,32 +220,31 @@ class CarrySelectOnesComplementCompoundAdder extends CompoundAdder {

/// Subtraction controlled by an optional logic [subtractIn]
@protected
late final Logic? subtractIn;
late final StaticOrDynamicParameter subtractIn;

/// Constructs a [CarrySelectCompoundAdder] using a set of
/// [OnesComplementAdder] in a carry-select configuration. Adds (or subtracts)
/// [a] and [b] to produce [sum] and [sumP1] (sum plus 1).
/// - [adderGen] is the adder generator [Function] inside the
/// [OnesComplementAdder].
/// - [subtractIn] is an optional [Logic] control for subtraction.
/// - [subtract] is a boolean control for subtraction. It must be
/// `false`(default) if a [subtractIn] [Logic] is provided.
/// - [adderGen] is the adder used inside the [OnesComplementAdder].
/// - The optional [subtract] parameter configures the adder to subtract [b]
/// from [a] statically using a `bool` to indicate a ssubtraction (default
/// is `false`, or addition) or dynamically with a 1-bit [Logic] input.
/// Passing something other null, `bool`, or [Logic] will result in a throw.
/// - [generateCarryOut] set to `true` will create output [carryOut] and
/// employ the ones-complement optimization of not adding '1' to convert
/// back to 2s complement during subtraction on the [sum].
/// - [generateCarryOutP1] set to `true` will create output [carryOutP1] and
/// employ the ones-complement optimization of not adding '1' to convert
/// back to 2s complement during subtraction on the [sumP1].
/// - [widthGen] is a [Function] which produces a list for splitting the adder
/// - [widthGen] is a function which produces a list for splitting the adder
/// for the carry-select chain. The default is
/// [CarrySelectCompoundAdder.splitSelectAdderAlgorithmSingleBlock],
CarrySelectOnesComplementCompoundAdder(super.a, super.b,
{Adder Function(Logic, Logic, {Logic? carryIn}) adderGen =
NativeAdder.new,
Logic? subtractIn,
bool generateCarryOut = false,
bool generateCarryOutP1 = false,
bool subtract = false,
dynamic subtract,
List<int> Function(int) widthGen =
CarrySelectCompoundAdder.splitSelectAdderAlgorithmSingleBlock,
super.name,
Expand All @@ -255,9 +254,7 @@ class CarrySelectOnesComplementCompoundAdder extends CompoundAdder {
: super(
definitionName: definitionName ??
'CarrySelectOnesComplementCompoundAdder_W${a.width}') {
subtractIn = (subtractIn != null)
? addInput('subtractIn', subtractIn, width: subtractIn.width)
: null;
subtractIn = StaticOrDynamicParameter.ofDynamic(subtract).clone(this);

if (generateCarryOut) {
addOutput('carryOut');
Expand All @@ -266,19 +263,18 @@ class CarrySelectOnesComplementCompoundAdder extends CompoundAdder {
addOutput('carryOutP1');
}

final doSubtract = subtractIn ?? (subtract ? Const(subtract) : Const(0));
final doSubtract = subtractIn.getLogic(this);

final csadder = CarrySelectCompoundAdder(a, b,
widthGen: widthGen,
subtractIn: subtractIn,
adderGen: (a, b, {carryIn, subtractIn, name = 'ones_complement'}) =>
subtractIn: doSubtract,
adderGen: (a, b, {carryIn, subtract, name = 'ones_complement'}) =>
OnesComplementAdder(a, b,
adderGen: adderGen,
carryIn: carryIn,
generateEndAroundCarry: true,
subtract: subtract,
chainable: true,
subtractIn: subtractIn));
subtract: subtract));

addOutput('sign') <= mux(doSubtract, ~csadder.sum[-1], Const(0));
addOutput('signP1') <= mux(doSubtract, ~csadder.sumP1[-1], Const(0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class FloatingPointAdderDualPath<FpTypeIn extends FloatingPoint,

final significandAdderRPath = CarrySelectOnesComplementCompoundAdder(
largeOperandFlopped, smallerOperandRPathFlopped,
subtractIn: effectiveSubtractionFlopped,
subtract: effectiveSubtractionFlopped,
generateCarryOut: true,
generateCarryOutP1: true,
adderGen: adderGen,
Expand Down Expand Up @@ -307,7 +307,7 @@ class FloatingPointAdderDualPath<FpTypeIn extends FloatingPoint,
// here?
final significandSubtractorNPath = OnesComplementAdder(
largeOperand, smallOperandNPath,
subtractIn: effectiveSubtraction,
subtract: effectiveSubtraction,
adderGen: adderGen,
name: 'npath_significand_sub');

Expand Down Expand Up @@ -340,7 +340,7 @@ class FloatingPointAdderDualPath<FpTypeIn extends FloatingPoint,

final expCalcNPath = OnesComplementAdder(
largerExpFlopped, leadOneNPath.zeroExtend(exponentWidth),
subtractIn: Const(1), adderGen: adderGen, name: 'npath_expcalc');
subtract: Const(1), adderGen: adderGen, name: 'npath_expcalc');

final preExpNPath =
expCalcNPath.sum.slice(exponentWidth - 1, 0).named('preExpNpath');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class FloatingPointAdderSinglePath<FpTypeIn extends FloatingPoint,
largeNarrowMantissa, smallNarrowMantissa,
generateCarryOut: true,
generateCarryOutP1: true,
subtractIn: effectiveSubtraction,
subtract: effectiveSubtraction,
widthGen: widthGen,
adderGen: adderGen);

Expand Down
Loading