diff --git a/lib/src/synthesizers/netlist/netlist_synthesizer.dart b/lib/src/synthesizers/netlist/netlist_synthesizer.dart index ceacb6ff8..4cf15ca45 100644 --- a/lib/src/synthesizers/netlist/netlist_synthesizer.dart +++ b/lib/src/synthesizers/netlist/netlist_synthesizer.dart @@ -967,7 +967,7 @@ class NetlistSynthesizer extends Synthesizer { final netnames = translation.netnames; // -- Structural validation ------------------------------------------- - NetlistValidation.validate(ports, cells, module.name, netnames: netnames); + NetlistValidation.validate(ports, cells, module.name); return NetlistSynthesisResult(module, getInstanceTypeOfModule, ports: ports, cells: cells, netnames: netnames, attributes: attr); diff --git a/lib/src/synthesizers/netlist/netlist_validation.dart b/lib/src/synthesizers/netlist/netlist_validation.dart index f2c8a6b87..81d571be3 100644 --- a/lib/src/synthesizers/netlist/netlist_validation.dart +++ b/lib/src/synthesizers/netlist/netlist_validation.dart @@ -51,9 +51,8 @@ class NetlistValidation { static void validate( Map> ports, Map> cells, - String moduleName, { - Map? netnames, - }) { + String moduleName, + ) { final issues = []; final driversByBit = _driversByBit(ports, cells); @@ -70,33 +69,6 @@ class NetlistValidation { )); } - if (netnames != null) { - for (final entry in netnames.entries) { - final netname = entry.value; - if (netname is! Map) { - continue; - } - final logicType = netname['logic_type']; - if (logicType is! Map || - (logicType['arrayDims'] is! List && logicType['fields'] is! List)) { - continue; - } - final bits = (netname['bits'] as List?)?.whereType() ?? const []; - final aggregateDrivers = { - for (final bit in bits) ...driversByBit[bit] ?? const [], - }; - if (aggregateDrivers.length <= 1) { - continue; - } - issues.add(NetlistValidationIssue( - 'aggregate net "${entry.key}" is reached from multiple drivers: ' - '${aggregateDrivers.join(', ')}', - netname: entry.key, - drivers: aggregateDrivers.toList(), - )); - } - } - if (issues.isNotEmpty) { throw NetlistValidationException(moduleName, issues); } diff --git a/test/netlist_synthesizer_test.dart b/test/netlist_synthesizer_test.dart index 59cbdda3b..15390de66 100644 --- a/test/netlist_synthesizer_test.dart +++ b/test/netlist_synthesizer_test.dart @@ -2119,7 +2119,7 @@ void main() { ); }); - test('struct aggregate netnames cannot span multiple drivers', () { + test('struct aggregate netnames allow disjoint field drivers', () { final ports = >{}; final cells = >{ 'first_driver': { @@ -2145,30 +2145,42 @@ void main() { }, }, }; - final netnames = { - 'values': { - 'bits': [ - ...List.generate(8, (index) => 200 + index), - ...List.generate(8, (index) => 400 + index), - ], - 'logic_type': { - 'typeName': 'PairStructure', - 'fields': [ - {'name': 'first', 'width': 8}, - {'name': 'second', 'width': 8}, - ], + expect( + () => NetlistValidation.validate(ports, cells, 'struct_module'), + returnsNormally, + ); + }); + + test('structured netnames reject overlapping field drivers', () { + final ports = >{}; + final cells = >{ + 'first_driver': { + 'type': r'$buf', + 'port_directions': {'A': 'input', 'Y': 'output'}, + 'connections': { + 'A': [100, 101], + 'Y': [200, 201], + }, + }, + 'second_driver': { + 'type': r'$buf', + 'port_directions': {'A': 'input', 'Y': 'output'}, + 'connections': { + 'A': [102, 103], + 'Y': [201, 202], }, }, }; expect( - () => NetlistValidation.validate( - ports, - cells, - 'struct_module', - netnames: netnames, + () => NetlistValidation.validate(ports, cells, 'struct_module'), + throwsA( + isA().having( + (error) => error.issues.map((issue) => issue.wireBit), + 'overlapping wire bit', + contains(201), + ), ), - throwsA(isA()), ); });