diff --git a/lib/sklansky.dart b/lib/sklansky.dart index 9e8a480..be81405 100644 --- a/lib/sklansky.dart +++ b/lib/sklansky.dart @@ -94,9 +94,34 @@ class Adder extends Module { a = addInput('a', a, width: a.width); b = addInput('b', b, width: b.width); final u = ppGen( - List.generate(a.width, (i) => [a[i] & b[i], a[i] ^ b[i]].swizzle() ), + // generate, propagate or generate + List.generate(a.width, (i) => [a[i] & b[i], a[i] | b[i]].swizzle() ), (lhs, rhs) => [rhs[1] | rhs[0] & lhs[1], rhs[0] & lhs[0]].swizzle() ); addOutput('out', width: a.width) <= List.generate(a.width, (i) => (i==0) ? a[i] ^ b[i] : a[i]^b[i]^u.val[i-1][1]).rswizzle(); } +} + +class Incr extends Module { + Logic get out => output('out'); + Incr(Logic inp, ParallelPrefix Function(List, Logic Function(Logic, Logic )) ppGen) { + inp = addInput('inp', inp, width: inp.width); + final u = ppGen( + List.generate(inp.width, (i) => inp[i] ), + (lhs, rhs) => rhs & lhs + ); + addOutput('out', width: inp.width) <= (List.generate(inp.width, (i) => ((i==0) ? ~inp[i] : inp[i]^u.val[i-1])).rswizzle()); + } +} + +class Decr extends Module { + Logic get out => output('out'); + Decr(Logic inp, ParallelPrefix Function(List, Logic Function(Logic, Logic )) ppGen) { + inp = addInput('inp', inp, width: inp.width); + final u = ppGen( + List.generate(inp.width, (i) => ~inp[i] ), + (lhs, rhs) => rhs & lhs + ); + addOutput('out', width: inp.width) <= (List.generate(inp.width, (i) => ((i==0) ? ~inp[i] : inp[i]^u.val[i-1])).rswizzle()); + } } \ No newline at end of file diff --git a/test/sklansky_test.dart b/test/sklansky_test.dart index 1c43565..35410dd 100644 --- a/test/sklansky_test.dart +++ b/test/sklansky_test.dart @@ -1,40 +1,38 @@ import 'package:sklansky/sklansky.dart'; import 'package:rohd/rohd.dart'; import 'package:rohd/src/utilities/simcompare.dart'; +import 'dart:math'; import 'package:test/test.dart'; - void testOrScan(int n, fn) { - - test('or_scan_$n', () async { - var inp = Logic(name: 'inp', width: n); - final mod = fn(inp); - await mod.build(); - - - int computeOrScan(j) { - var result = 0; - var found = false; - for (var i=0; i 0) { + var shaveOff = min(16, nBits); + result = + (result << shaveOff) + BigInt.from(Random().nextInt(1 << shaveOff)); + nBits -= shaveOff; + } + return result; } -void testAdder(int n, fn) { - test('adder_$n', () async { - var a = Logic(name: 'a', width: n); - var b = Logic(name: 'b', width: n); +void testAdderRandom(int n, int nSamples, fn) { + test('adder_$n', () async { + var a = Logic(name: 'a', width: n); + var b = Logic(name: 'b', width: n); - final mod = fn(a, b); - await mod.build(); + final mod = fn(a, b); + await mod.build(); - int computeAdder(aa, bb) { - return (aa + bb) & ((1< OrScan(inp, ppGen)); } @@ -133,7 +207,7 @@ void main() { }); group('priority_encoder', () { - for (var n in [7,8,9]) { + for (var n in [7, 8, 9]) { for (var ppGen in [Ripple.new, Sklansky.new]) { testPriorityEncoder(n, (inp) => PriorityEncoder(inp, ppGen)); } @@ -141,10 +215,34 @@ void main() { }); group('adder', () { - for (var n in [3,4,5]) { + for (var n in [3, 4, 5]) { for (var ppGen in [Ripple.new, Sklansky.new]) { testAdder(n, (a, b) => Adder(a, b, ppGen)); } } }); + + group('adderRandom', () { + for (var n in [650]) { + for (var ppGen in [Ripple.new, Sklansky.new]) { + testAdderRandom(n, 10, (a, b) => Adder(a, b, ppGen)); + } + } + }); + + group('incr', () { + for (var n in [7, 8, 9]) { + for (var ppGen in [Ripple.new, Sklansky.new]) { + testIncr(n, (inp) => Incr(inp, ppGen)); + } + } + }); + + group('decr', () { + for (var n in [7, 8, 9]) { + for (var ppGen in [Ripple.new, Sklansky.new]) { + testDecr(n, (inp) => Decr(inp, ppGen)); + } + } + }); }