Skip to content

Commit

Permalink
Fix bug where shuffled array assignments were incorrectly collapsed i…
Browse files Browse the repository at this point in the history
…n generated SV (#504)
  • Loading branch information
mkorbel1 authored Aug 7, 2024
1 parent d41029e commit 9910774
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
30 changes: 27 additions & 3 deletions lib/src/synthesizers/systemverilog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1218,8 +1218,8 @@ class _SynthModuleDefinition {
final srcArray = src.parentArray;
final dstArray = dst.parentArray;

assert(srcArray.logics.length == 1, 'should be 1');
assert(dstArray.logics.length == 1, 'should be 1');
assert(srcArray.logics.length == 1, 'should be 1 name for the array');
assert(dstArray.logics.length == 1, 'should be 1 name for the array');

if (srcArray.logics.first.elements.length !=
dstArray.logics.first.elements.length ||
Expand All @@ -1236,7 +1236,31 @@ class _SynthModuleDefinition {

for (final MapEntry(key: (srcArray, dstArray), value: arrAssignments)
in groupedAssignments.entries) {
if (arrAssignments.length == srcArray.logics.first.elements.length) {
assert(
srcArray.logics.first.elements.length ==
dstArray.logics.first.elements.length,
'should be equal lengths of elements in both arrays by now');

// first requirement is that all elements have been assigned
var shouldMerge =
arrAssignments.length == srcArray.logics.first.elements.length;

if (shouldMerge) {
// only check each element if the lengths match
for (final arrAssignment in arrAssignments) {
final arrAssignmentSrc =
(arrAssignment.src as _SynthLogicArrayElement).logic;
final arrAssignmentDst =
(arrAssignment.dst as _SynthLogicArrayElement).logic;

if (arrAssignmentSrc.arrayIndex! != arrAssignmentDst.arrayIndex!) {
shouldMerge = false;
break;
}
}
}

if (shouldMerge) {
reducedAssignments.add(_SynthAssignment(srcArray, dstArray));
} else {
reducedAssignments.addAll(arrAssignments);
Expand Down
26 changes: 26 additions & 0 deletions test/array_collapsing_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ class ArrayModule extends Module {
}
}

class ArrayWithShuffledAssignment extends Module {
ArrayWithShuffledAssignment(LogicArray a) {
final inpA = addInputArray('a', a, dimensions: a.dimensions);
final outB = addOutputArray('b', dimensions: a.dimensions);

for (var i = 0; i < a.dimensions.first; i++) {
outB.elements[i] <= inpA.elements[a.dimensions.first - i - 1];
}
}
}

class ArrayModuleWithNetIntermediates extends Module {
ArrayModuleWithNetIntermediates(LogicArray a, LogicArray b) {
a = addInOutArray('a', a,
Expand Down Expand Up @@ -69,6 +80,21 @@ void main() {
SimCompare.checkIverilogVector(mod, vectors);
});

test('array assignment non-collapsing with shuffled assignment', () async {
final mod = ArrayWithShuffledAssignment(LogicArray([4], 1));
await mod.build();

final sv = mod.generateSynth();
expect(sv, contains('assign b[0] = a[3];'));
expect(sv, contains('assign b[3] = a[0];'));

final vectors = [
Vector({'a': LogicValue.of('01xz')}, {'b': LogicValue.of('zx10')}),
];
await SimCompare.checkFunctionalVector(mod, vectors);
SimCompare.checkIverilogVector(mod, vectors);
});

test('array nets with intermediate collapse with unpacked', () async {
final mod = ArrayModuleWithNetIntermediates(
LogicArray([3, 3], 1, numUnpackedDimensions: 2),
Expand Down

0 comments on commit 9910774

Please sign in to comment.