diff --git a/lib/src/synthesizers/systemverilog.dart b/lib/src/synthesizers/systemverilog.dart index d4d8569ff..562c8c1d3 100644 --- a/lib/src/synthesizers/systemverilog.dart +++ b/lib/src/synthesizers/systemverilog.dart @@ -7,6 +7,7 @@ // 2021 August 26 // Author: Max Korbel +import 'package:collection/collection.dart'; import 'package:rohd/rohd.dart'; import 'package:rohd/src/collections/traverseable_collection.dart'; import 'package:rohd/src/utilities/uniquifier.dart'; @@ -152,28 +153,28 @@ class _SystemVerilogSynthesisResult extends SynthesisResult { List _verilogInputs() { final declarations = _synthModuleDefinition.inputs + .sorted((a, b) => a.name.compareTo(b.name)) .map((sig) => 'input logic ${sig.definitionName()}') - .toList(growable: false) - ..sort(); + .toList(growable: false); return declarations; } List _verilogOutputs() { final declarations = _synthModuleDefinition.outputs + .sorted((a, b) => a.name.compareTo(b.name)) .map((sig) => 'output logic ${sig.definitionName()}') - .toList(growable: false) - ..sort(); + .toList(growable: false); return declarations; } String _verilogInternalNets() { final declarations = []; - for (final sig in _synthModuleDefinition.internalNets) { + for (final sig in _synthModuleDefinition.internalNets + .sorted((a, b) => a.name.compareTo(b.name))) { if (sig.needsDeclaration) { declarations.add('logic ${sig.definitionName()};'); } } - declarations.sort(); return declarations.join('\n'); } diff --git a/test/sv_gen_test.dart b/test/sv_gen_test.dart index bba16778e..e4503ec7d 100644 --- a/test/sv_gen_test.dart +++ b/test/sv_gen_test.dart @@ -31,21 +31,53 @@ class AlphabeticalModule extends Module { } } +class AlphabeticalWidthsModule extends Module { + AlphabeticalWidthsModule() { + final l = addInput('l', Logic(width: 4), width: 4); + final a = addInput('a', Logic(width: 3), width: 3); + final w = addInput('w', Logic(width: 2), width: 2); + + final o = Logic(name: 'o', width: 4); + final c = Logic(name: 'c', width: 3); + final y = Logic(name: 'y', width: 2); + + c <= a & a; + o <= l | l; + y <= w ^ w; + + addOutput('m', width: 4) <= o + o; + addOutput('x', width: 2) <= y + y; + addOutput('b', width: 3) <= c + c; + } +} + void main() { + void checkSignalDeclarationOrder(String sv, List signalNames) { + final expected = + signalNames.map((e) => RegExp(r'logic\s*\[?[:\d\s]*]?\s*' + e)); + final indices = expected.map(sv.indexOf); + expect(indices.isSorted((a, b) => a.compareTo(b)), isTrue, + reason: 'Expected order $signalNames, but indices were $indices'); + } + test('input, output, and internal signals are sorted', () async { final mod = AlphabeticalModule(); await mod.build(); final sv = mod.generateSynth(); - void checkSignalDeclarationOrder(List signalNames) { - final expected = signalNames.map((e) => 'logic $e'); - final indices = expected.map(sv.indexOf); - expect(indices.isSorted((a, b) => a.compareTo(b)), isTrue, - reason: 'Expected order $expected, but indices were $indices'); - } + checkSignalDeclarationOrder(sv, ['a', 'l', 'w']); + checkSignalDeclarationOrder(sv, ['b', 'm', 'x']); + checkSignalDeclarationOrder(sv, ['c', 'o', 'y']); + }); + + test('input, output, and internal signals are sorted (different widths)', + () async { + final mod = AlphabeticalWidthsModule(); + await mod.build(); + final sv = mod.generateSynth(); - checkSignalDeclarationOrder(['a', 'l', 'w']); - checkSignalDeclarationOrder(['b', 'm', 'x']); - checkSignalDeclarationOrder(['c', 'o', 'y']); + checkSignalDeclarationOrder(sv, ['a', 'l', 'w']); + checkSignalDeclarationOrder(sv, ['b', 'm', 'x']); + checkSignalDeclarationOrder(sv, ['c', 'o', 'y']); }); }