Skip to content

Commit

Permalink
integrated sign extension into PP generation
Browse files Browse the repository at this point in the history
  • Loading branch information
desmonddak committed Aug 10, 2024
1 parent e8b96e8 commit 61521b5
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 78 deletions.
6 changes: 2 additions & 4 deletions lib/src/arithmetic/multiplier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ class CompressionTreeMultiplier extends Multiplier {
], (a, b) => Logic()).runtimeType}') {
final product = addOutput('product', width: a.width + b.width);
final pp =
PartialProductGenerator(a, b, RadixEncoder(radix), signed: signed)
..signExtendCompact();
PartialProductGenerator(a, b, RadixEncoder(radix), signed: signed);
final compressor = ColumnCompressor(pp)..compress();
final adder = ParallelPrefixAdder(
compressor.extractRow(0), compressor.extractRow(1), ppTree);
Expand All @@ -110,8 +109,7 @@ class CompressionTreeMultiplyAccumulate extends MultiplyAccumulate {
'R${radix}_${ppTree.call([Logic()], (a, b) => Logic()).name}') {
final accumulate = addOutput('accumulate', width: a.width + b.width + 1);
final pp =
PartialProductGenerator(a, b, RadixEncoder(radix), signed: signed)
..signExtendCompact();
PartialProductGenerator(a, b, RadixEncoder(radix), signed: signed);

// TODO(desmonddak): This sign extension method for the additional
// addend may only work with signExtendCompact.
Expand Down
33 changes: 32 additions & 1 deletion lib/src/arithmetic/partial_product_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ import 'package:rohd/rohd.dart';
import 'package:rohd_hcl/rohd_hcl.dart';
import 'package:rohd_hcl/src/arithmetic/multiplier_lib.dart';

/// Methods for sign extending the [PartialProductGenerator]
enum SignExtension {
/// No sign extension
none,

/// Brute force sign extend each row to the full width of the product
brute,

/// Extend using stop bits in each row (and an extra row for final sign)
stop,

/// Fold in last row sign bit (Mohanty, B.K., Choubey, A.)
compact,

/// Sign folding that works for rectangular partial products
compactRect
}

/// A class that generates a set of partial products. Essentially a set of
/// shifted rows of [Logic] addends generated by Booth recoding and
/// manipulated by sign extension, before being compressed
Expand Down Expand Up @@ -54,7 +72,8 @@ class PartialProductGenerator {
/// Construct the partial product matrix
PartialProductGenerator(
Logic multiplicand, Logic multiplier, RadixEncoder radixEncoder,
{this.signed = true}) {
{this.signed = true,
SignExtension signExtension = SignExtension.compactRect}) {
encoder = MultiplierEncoder(multiplier, radixEncoder, signed: signed);
selector =
MultiplicandSelector(radixEncoder.radix, multiplicand, signed: signed);
Expand All @@ -68,6 +87,18 @@ class PartialProductGenerator {
'${selector.shift + (signed ? 1 : 0)}');
}
_build();
switch (signExtension) {
case SignExtension.none:
;
case SignExtension.brute:
bruteForceSignExtend();
case SignExtension.stop:
signExtendWithStopBitsRect();
case SignExtension.compact:
signExtendCompact();
case SignExtension.compactRect:
signExtendCompactRect();
}
}

/// Setup the partial products array (partialProducts and rowShift)
Expand Down
19 changes: 6 additions & 13 deletions test/arithmetic/addend_compressor_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import 'package:rohd_hcl/rohd_hcl.dart';
import 'package:rohd_hcl/src/arithmetic/multiplier_lib.dart';
import 'package:test/test.dart';

enum SignExtension { brute, stop, compact }

void testCompressionExhaustive(PartialProductGenerator pp) {
final widthX = pp.selector.multiplicand.width;
final widthY = pp.encoder.multiplier.width;
Expand Down Expand Up @@ -86,17 +84,13 @@ void main() {
final shift = log2Ceil(encoder.radix);
for (var width = shift + 1; width < 2 * shift + 1; width++) {
for (final signExtension in SignExtension.values) {
if (signExtension == SignExtension.none) {
continue;
}
final pp = PartialProductGenerator(Logic(name: 'X', width: width),
Logic(name: 'Y', width: width), encoder,
signed: signed);
switch (signExtension) {
case SignExtension.brute:
pp.bruteForceSignExtend();
case SignExtension.stop:
pp.signExtendWithStopBitsRect();
case SignExtension.compact:
pp.signExtendCompact();
}
signed: signed, signExtension: signExtension);

testCompressionExhaustive(pp);
}
}
Expand Down Expand Up @@ -124,8 +118,7 @@ void main() {
b.put(bB);
const radix = 4;
final encoder = RadixEncoder(radix);
final pp = PartialProductGenerator(a, b, encoder, signed: signed)
..signExtendCompactRect();
final pp = PartialProductGenerator(a, b, encoder, signed: signed);
// Turn on printing by using widthX == 6 (we are fooling the dead code
// checking linter here)
// print(pp);
Expand Down
76 changes: 17 additions & 59 deletions test/arithmetic/multiplier_encoder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import 'package:rohd_hcl/rohd_hcl.dart';
import 'package:rohd_hcl/src/arithmetic/multiplier_lib.dart';
import 'package:test/test.dart';

enum SignExtension { brute, stop, compact, compactRect }

void checkEvaluateExhaustive(PartialProductGenerator pp) {
final widthX = pp.selector.multiplicand.width;
final widthY = pp.encoder.multiplier.width;
Expand Down Expand Up @@ -74,8 +72,7 @@ void main() {
logicX.put(X);
logicY.put(Y);
logicZ.put(Z);
final pp = PartialProductGenerator(logicX, logicY, encoder)
..signExtendCompact();
final pp = PartialProductGenerator(logicX, logicY, encoder);
// Add a row for addend
final l = [
for (var i = 0; i < logicZ.width; i++) logicZ[i],
Expand All @@ -102,19 +99,13 @@ void main() {
final minWidth = shift + (signed ? 1 : 0);
for (var width = minWidth; width < shift * 2 + 1; width++) {
for (final signExtension in SignExtension.values) {
if (signExtension == SignExtension.none) {
continue;
}
final pp = PartialProductGenerator(Logic(name: 'X', width: width),
Logic(name: 'Y', width: width), encoder,
signed: signed);
switch (signExtension) {
case SignExtension.brute:
pp.bruteForceSignExtend();
case SignExtension.stop:
pp.signExtendWithStopBitsRect();
case SignExtension.compact:
pp.signExtendCompact();
case SignExtension.compactRect:
pp.signExtendCompactRect();
}
signed: signed, signExtension: signExtension);

checkEvaluateExhaustive(pp);
}
}
Expand All @@ -132,25 +123,14 @@ void main() {
// Only some sign extension routines have rectangular support
// Commented out rectangular extension routines for speedup
for (final signExtension in [
// SignExtension.brute,
// SignExtension.stop,
SignExtension.brute,
SignExtension.stop,
SignExtension.compactRect
]) {
final pp = PartialProductGenerator(Logic(name: 'X', width: width),
Logic(name: 'Y', width: width + skew), encoder,
signed: signed);

switch (signExtension) {
case SignExtension.brute:
pp.bruteForceSignExtend();
case SignExtension.stop:
pp.signExtendWithStopBitsRect();
case SignExtension.compact:
pp.signExtendCompact();
case SignExtension.compactRect:
pp.signExtendCompactRect();
}
checkEvaluateRandom(pp, 100);
signed: signed, signExtension: signExtension);
checkEvaluateRandom(pp, 20);
}
}
}
Expand Down Expand Up @@ -186,7 +166,6 @@ void main() {

pp.multiplicand.put(X);
pp.multiplier.put(Y);
pp.signExtendCompactRect();
expect(pp.evaluate(), equals(product));
checkEvaluateRandom(pp, 100);
}
Expand All @@ -203,23 +182,13 @@ void main() {
// Only some sign extension routines have rectangular support
// Commented out rectangular extension routines for speedup
for (final signExtension in SignExtension.values) {
{
final pp = PartialProductGenerator(Logic(name: 'X', width: width),
Logic(name: 'Y', width: width + skew), encoder,
signed: signed);

switch (signExtension) {
case SignExtension.brute:
pp.bruteForceSignExtend();
case SignExtension.stop:
pp.signExtendWithStopBitsRect();
case SignExtension.compact:
pp.signExtendCompact();
case SignExtension.compactRect:
pp.signExtendCompactRect();
}
checkEvaluateRandom(pp, 100);
if (signExtension == SignExtension.none) {
continue;
}
final pp = PartialProductGenerator(Logic(name: 'X', width: width),
Logic(name: 'Y', width: width + skew), encoder,
signed: signed, signExtension: signExtension);
checkEvaluateRandom(pp, 100);
}
}
}
Expand All @@ -241,18 +210,7 @@ void main() {
{
final pp = PartialProductGenerator(Logic(name: 'X', width: width),
Logic(name: 'Y', width: width + skew), encoder,
signed: signed);

switch (signExtension) {
case SignExtension.brute:
pp.bruteForceSignExtend();
case SignExtension.stop:
pp.signExtendWithStopBitsRect();
case SignExtension.compact:
pp.signExtendCompact();
case SignExtension.compactRect:
pp.signExtendCompactRect();
}
signed: signed, signExtension: signExtension);
checkEvaluateExhaustive(pp);
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/arithmetic/multiplier_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void main() {
CompressionTreeMultiplier(a, b, 4, KoggeStone.new, signed: true);

Multiplier curryUnsignedMultiplier(Logic a, Logic b) =>
CompressionTreeMultiplier(a, b, 4, KoggeStone.new, signed: true);
CompressionTreeMultiplier(a, b, 4, KoggeStone.new, signed: false);

// Now treat the multiplier as a MAC with a zero input addend [c]
MultiplyAccumulate currySignedMultiplierAsMAC(Logic a, Logic b, Logic c) =>
Expand Down

0 comments on commit 61521b5

Please sign in to comment.