diff --git a/test/arithmetic/addend_compressor_test.dart b/test/arithmetic/addend_compressor_test.dart new file mode 100644 index 000000000..b48da59d2 --- /dev/null +++ b/test/arithmetic/addend_compressor_test.dart @@ -0,0 +1,106 @@ +// Copyright (C) 2023-2024 Intel Corporation +// SPDX-License-Identifier: BSD-3-Clause +// +// compressor_test.dart +// Tests for the select interface of Booth encoding +// +// 2024 June 04 +// Author: Desmond Kirkpatrick + +import 'dart:io'; +import 'dart:math'; +import 'package:rohd/rohd.dart'; +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; + + final compressor = ColumnCompressor(pp); + + final limitX = pow(2, widthX); + final limitY = pow(2, widthY); + for (var i = 0; i < limitX; i++) { + for (var j = 0; j < limitY; j++) { + final X = pp.signed + ? BigInt.from(i).toSigned(widthX) + : BigInt.from(i).toUnsigned(widthX); + final Y = pp.signed + ? BigInt.from(j).toSigned(widthY) + : BigInt.from(j).toUnsigned(widthY); + final product = X * Y; + + pp.multiplicand.put(X); + pp.multiplier.put(Y); + final value = pp.evaluate(); + expect(value, equals(product), + reason: 'Fail: $i($X) * $j($Y): $value ' + 'vs expected $product' + '\n$pp'); + final evaluateValue = compressor.evaluate(); + if (evaluateValue != product) { + stdout + ..write('Fail: $i($X)[$widthX] * $j($Y)[$widthY]: $evaluateValue ' + 'vs expected $product\n') + ..write(pp); + } + compressor.compress(); + final compressedValue = compressor.evaluate(); + expect(compressedValue, equals(product), + reason: 'Fail: $i($X)[$widthX] * $j($Y)[$widthY]: $compressedValue ' + 'vs expected $product' + '\n$pp'); + final compressedLogicValue = compressor.evaluate(logic: true); + expect(compressedLogicValue, equals(product), + reason: + 'Fail: $i($X)[$widthX] * $j($Y)[$widthY]: $compressedLogicValue ' + 'vs expected $product' + '\n$pp'); + + final a = compressor.extractRow(0); + final b = compressor.extractRow(1); + final adder = ParallelPrefixAdder(a, b, KoggeStone.new); + final adderValue = + adder.out.value.toBigInt().toSigned(compressor.columns.length); + expect(adderValue, equals(product), + reason: 'Fail: $i($X)[$widthX] * $j($Y)[$widthY]: ' + '$adderValue vs expected $product' + '\n$pp'); + } + } +} + +void main() { + test('exhaustive compression evaluate: square radix-4, all SignExtension', + () async { + stdout.write('\n'); + + for (final signed in [false, true]) { + for (var radix = 4; radix < 32; radix *= 2) { + final encoder = RadixEncoder(2); + // stdout.write('encoding with radix=$radix\n'); + final shift = log2Ceil(encoder.radix); + for (var width = shift + 1; width < 2 * shift + 1; width++) { + for (final signExtension in SignExtension.values) { + 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(); + } + testCompressionExhaustive(pp); + } + } + } + } + }); +} diff --git a/test/arithmetic/compressor_test.dart b/test/arithmetic/compressor_test.dart deleted file mode 100644 index f991367f2..000000000 --- a/test/arithmetic/compressor_test.dart +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2023-2024 Intel Corporation -// SPDX-License-Identifier: BSD-3-Clause -// -// compressor_test.dart -// Tests for the select interface of Booth encoding -// -// 2024 June 04 -// Author: Desmond Kirkpatrick - -import 'dart:io'; -import 'dart:math'; - -import 'package:rohd/rohd.dart'; -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; - - final compressor = ColumnCompressor(pp); - - final limitX = pow(2, widthX); - final limitY = pow(2, widthY); - for (var i = 0; i < limitX; i++) { - for (var j = 0; j < limitY; j++) { - final X = BigInt.from(i).toSigned(widthX); - final Y = BigInt.from(j).toSigned(widthY); - final product = X * Y; - - pp.multiplicand.put(X); - pp.multiplier.put(Y); - // stdout.write('$i($X) * $j($Y): should be $product\n'); - if (pp.evaluate() != product) { - stdout - ..write('Fail: $i($X) * $j($Y): ${pp.evaluate()} ' - 'vs expected $product\n') - ..write(pp); - } - expect(pp.evaluate(), equals(product)); - final evaluateValue = compressor.evaluate(); - if (evaluateValue != product) { - stdout - ..write('Fail: $i($X)[$widthX] * $j($Y)[$widthY]: $evaluateValue ' - 'vs expected $product\n') - ..write(pp); - } - compressor.compress(); - final compressedValue = compressor.evaluate(); - if (compressedValue != product) { - stdout - ..write('Fail: $i($X)[$widthX] * $j($Y)[$widthY]: $compressedValue ' - 'vs expected $product\n') - ..write(pp); - } - expect(compressedValue, equals(product)); - final compressedLogicValue = compressor.evaluate(logic: true); - if (compressedLogicValue != product) { - stdout - ..write( - 'Fail: $i($X)[$widthX] * $j($Y)[$widthY]: $compressedLogicValue ' - 'vs expected $product\n') - ..write(pp); - } - expect(compressedLogicValue, equals(product)); - - final a = compressor.extractRow(0); - final b = compressor.extractRow(1); - final adder = ParallelPrefixAdder(a, b, KoggeStone.new); - final adderValue = - adder.out.value.toBigInt().toSigned(compressor.columns.length); - if (adderValue != product) { - stdout - ..write('Fail: $i($X)[$widthX] * $j($Y)[$widthY]: $adderValue ' - 'vs expected $product\n') - ..write(pp); - } - expect(adderValue, equals(product)); - } - } -} - -void main() { - test('exhaustive compression evaluate: square radix-4, all SignExtension', - () async { - stdout.write('\n'); - - for (var radix = 4; radix < 8; radix *= 2) { - final encoder = RadixEncoder(2); - // stdout.write('encoding with radix=$radix\n'); - final shift = log2Ceil(encoder.radix); - for (var width = shift + 1; width < shift + 2; width++) { - // stdout.write('\tTesting width=$width\n'); - for (final signExtension in SignExtension.values) { - final pp = PartialProductGenerator(Logic(name: 'X', width: width), - Logic(name: 'Y', width: width), encoder); - switch (signExtension) { - case SignExtension.brute: - pp.bruteForceSignExtend(); - case SignExtension.stop: - // pp.signExtendWithStopBitsRect(); - case SignExtension.compact: - pp.signExtendCompact(); - } - // stdout.write('\tTesting extension=$signExtension\n'); - testCompressionExhaustive(pp); - } - } - } - }); -} diff --git a/test/arithmetic/multiplier_encoder_test.dart b/test/arithmetic/multiplier_encoder_test.dart index a08adf19c..ecf9bd448 100644 --- a/test/arithmetic/multiplier_encoder_test.dart +++ b/test/arithmetic/multiplier_encoder_test.dart @@ -29,7 +29,9 @@ void checkEvaluateExhaustive(PartialProductGenerator pp) { final Y = pp.signed ? j.toSigned(widthY) : j.toUnsigned(widthY); pp.multiplicand.put(X); pp.multiplier.put(Y); - expect(pp.evaluate(), equals(X * Y)); + final value = pp.evaluate(); + expect(value, equals(X * Y), + reason: '$X * $Y = $value should be ${X * Y}'); } } } @@ -45,7 +47,8 @@ void checkEvaluateRandom(PartialProductGenerator pp, int nSamples) { final Y = pp.signed ? rY.toSigned(widthY) : rY; pp.multiplicand.put(X); pp.multiplier.put(Y); - expect(pp.evaluate(), equals(X * Y)); + final value = pp.evaluate(); + expect(value, equals(X * Y), reason: '$X * $Y = $value should be ${X * Y}'); } } @@ -73,15 +76,14 @@ void main() { logicX.put(X); logicY.put(Y); logicZ.put(Z); - final pp = PartialProductGenerator(logicX, logicY, encoder); - // ignore: cascade_invocations - pp.signExtendCompact(); + final pp = PartialProductGenerator(logicX, logicY, encoder) + ..signExtendCompact(); // Add a row for addend - final l = [for (var i = 0; i < logicZ.width; i++) logicZ[i]]; - // ignore: cascade_invocations - l - ..add(Const(0)) // ~Sign in our sign extension form - ..add(Const(1)); + final l = [ + for (var i = 0; i < logicZ.width; i++) logicZ[i], + Const(0), + Const(1) + ]; pp.partialProducts.add(l); pp.rowShift.add(0); @@ -100,7 +102,6 @@ void main() { for (final signed in [false, true]) { for (var radix = 4; radix < 8; radix *= 2) { final encoder = RadixEncoder(radix); - // stdout.write('encoding with radix=$radix\n'); final shift = log2Ceil(encoder.radix); for (var width = shift + 1; width < shift * 2 + 1; width++) { for (final signExtension in SignExtension.values) {