1- // Copyright (C) 2021-2025 Intel Corporation
1+ // Copyright (C) 2021-2026 Intel Corporation
22// SPDX-License-Identifier: BSD-3-Clause
33//
44// systemverilog_synth_module_definition.dart
@@ -19,7 +19,7 @@ class SystemVerilogSynthModuleDefinition extends SynthModuleDefinition {
1919 @override
2020 void process () {
2121 _replaceNetConnections ();
22- _collapseChainableModules ();
22+ _collapseMarkedChainableModules ();
2323 _replaceInOutConnectionInlineableModules ();
2424 }
2525
@@ -30,34 +30,41 @@ class SystemVerilogSynthModuleDefinition extends SynthModuleDefinition {
3030 /// Creates a new [_NetConnect] module to synthesize assignment between two
3131 /// [LogicNet] s.
3232 SystemVerilogSynthSubModuleInstantiation _addNetConnect (
33- SynthLogic dst, SynthLogic src) {
33+ SynthLogic dst,
34+ SynthLogic src,
35+ ) {
3436 // make an (unconnected) module representing the assignment
35- final netConnect =
36- _NetConnect (LogicNet (width: dst.width), LogicNet (width: src.width));
37+ final netConnect = _NetConnect (
38+ LogicNet (width: dst.width),
39+ LogicNet (width: src.width),
40+ );
3741
3842 // instantiate the module within the definition
3943 final netConnectSynthSubModInst =
4044 (getSynthSubModuleInstantiation (netConnect)
4145 as SystemVerilogSynthSubModuleInstantiation )
42-
4346 // map inouts to the appropriate `_SynthLogic`s
4447 ..setInOutMapping (_NetConnect .n0Name, dst)
4548 ..setInOutMapping (_NetConnect .n1Name, src);
4649
4750 // notify the `SynthBuilder` that it needs declaration
4851 supportingModules.add (netConnect);
4952
53+ netConnectSynthSubModInst.pickName (module);
54+
5055 return netConnectSynthSubModInst;
5156 }
5257
53- /// Replace all [assignments] between two [LogicNet] s with a [_NetConnect] .
58+ /// Builds [_NetConnect] instances for [LogicNet] assignments .
5459 void _replaceNetConnections () {
5560 final reducedAssignments = < SynthAssignment > [];
5661
5762 for (final assignment in assignments) {
5863 if (assignment.src.isNet && assignment.dst.isNet) {
59- assert (assignment is ! PartialSynthAssignment ,
60- 'Net connections should not be partial assignments.' );
64+ assert (
65+ assignment is ! PartialSynthAssignment ,
66+ 'Net connections should not be partial assignments.' ,
67+ );
6168
6269 _addNetConnect (assignment.dst, assignment.src);
6370 } else {
@@ -73,106 +80,19 @@ class SystemVerilogSynthModuleDefinition extends SynthModuleDefinition {
7380 }
7481 }
7582
76- /// Collapses chainable, inlineable modules.
77- void _collapseChainableModules () {
83+ /// Collapses chainable, inlineable modules after naming .
84+ void _collapseMarkedChainableModules () {
7885 // collapse multiple lines of in-line assignments into one where they are
7986 // unnamed one-liners
8087 // for example, be capable of creating lines like:
8188 // assign x = a & b & c & _d_and_e
8289 // assign _d_and_e = d & e
8390 // assign y = _d_and_e
8491
85- // Also feed collapsed chained modules into other modules
86- // Need to consider order of operations in systemverilog or else add ()
87- // everywhere! (for now add the parentheses)
88-
89- // Algorithm:
90- // - find submodule instantiations that are inlineable
91- // - filter to those who only output as input to one other module
92- // - pass an override to the submodule instantiation that the corresponding
93- // input should map to the output of another submodule instantiation
94- // do not collapse if signal feeds to multiple inputs of other modules
95-
96- final inlineableSubmoduleInstantiations = module.subModules
97- .whereType <InlineSystemVerilog >()
98- .map ((m) => getSynthSubModuleInstantiation (m)
99- as SystemVerilogSynthSubModuleInstantiation );
100-
101- // number of times each signal name is used by any module
102- final signalUsage = < SynthLogic , int > {};
103-
104- for (final subModuleInstantiation in subModuleInstantiations) {
105- for (final inSynthLogic in [
106- ...subModuleInstantiation.inputMapping.values,
107- ...subModuleInstantiation.inOutMapping.values
108- ]) {
109- if (inputs.contains (inSynthLogic) || inOuts.contains (inSynthLogic)) {
110- // dont worry about inputs to THIS module
111- continue ;
112- }
113-
114- subModuleInstantiation as SystemVerilogSynthSubModuleInstantiation ;
115-
116- if (subModuleInstantiation.inlineResultLogic == inSynthLogic) {
117- // don't worry about the result signal
118- continue ;
119- }
120-
121- signalUsage.update (
122- inSynthLogic,
123- (value) => value + 1 ,
124- ifAbsent: () => 1 ,
125- );
126- }
127- }
128-
129- final singleUseSignals = < SynthLogic > {};
130- signalUsage.forEach ((signal, signalUsageCount) {
131- // don't collapse if:
132- // - used more than once
133- // - inline modules for preferred names
134- if (signalUsageCount == 1 && signal.mergeable) {
135- singleUseSignals.add (signal);
136- }
137- });
138-
139- // partial assignments are a special case, count as a usage
140- for (final partialAssignment
141- in assignments.whereType <PartialSynthAssignment >()) {
142- singleUseSignals.remove (partialAssignment.src);
143- }
144-
145- final singleUsageInlineableSubmoduleInstantiations =
146- inlineableSubmoduleInstantiations.where ((subModuleInstantiation) {
147- // inlineable modules have only 1 result signal
148- final resultSynthLogic = subModuleInstantiation.inlineResultLogic! ;
149-
150- return singleUseSignals.contains (resultSynthLogic) &&
151-
152- // don't inline modules if they were cleared from instantiation
153- subModuleInstantiation.needsInstantiation;
154- });
155-
156- // remove any inlineability for those that want no expressions
157- for (final instantiation in subModuleInstantiations) {
158- final subModule = instantiation.module;
159- if (subModule is SystemVerilog ) {
160- singleUseSignals.removeAll (subModule.expressionlessInputs.map ((e) =>
161- instantiation.inputMapping[e] ?? instantiation.inOutMapping[e]));
162- }
163- // ignore: deprecated_member_use_from_same_package
164- else if (subModule is CustomSystemVerilog ) {
165- singleUseSignals.removeAll (subModule.expressionlessInputs.map ((e) =>
166- instantiation.inputMapping[e] ?? instantiation.inOutMapping[e]));
167- }
168- }
169-
17092 final synthLogicToInlineableSynthSubmoduleMap =
17193 < SynthLogic , SystemVerilogSynthSubModuleInstantiation > {};
172- for (final subModuleInstantiation
173- in singleUsageInlineableSubmoduleInstantiations) {
174- (subModuleInstantiation.module as InlineSystemVerilog ).resultSignalName;
175-
94+ for (final subModuleInstantiation in chainableModulesToCollapse
95+ .cast <SystemVerilogSynthSubModuleInstantiation >()) {
17696 // inlineable modules have only 1 result signal
17797 final resultSynthLogic = subModuleInstantiation.inlineResultLogic! ;
17898
@@ -189,8 +109,10 @@ class SystemVerilogSynthModuleDefinition extends SynthModuleDefinition {
189109 for (final subModuleInstantiation in subModuleInstantiations) {
190110 subModuleInstantiation as SystemVerilogSynthSubModuleInstantiation ;
191111
192- subModuleInstantiation.synthLogicToInlineableSynthSubmoduleMap =
193- synthLogicToInlineableSynthSubmoduleMap;
112+ subModuleInstantiation.synthLogicToInlineableSynthSubmoduleMap = {
113+ ...? subModuleInstantiation.synthLogicToInlineableSynthSubmoduleMap,
114+ ...synthLogicToInlineableSynthSubmoduleMap,
115+ };
194116 }
195117 }
196118
@@ -199,11 +121,12 @@ class SystemVerilogSynthModuleDefinition extends SynthModuleDefinition {
199121 /// [_NetConnect] assignment instead of a normal assignment.
200122 void _replaceInOutConnectionInlineableModules () {
201123 for (final subModuleInstantiation in subModuleInstantiations.toList ().where (
202- (e) =>
203- e.module is InlineSystemVerilog &&
204- e.needsInstantiation &&
205- e.outputMapping.isEmpty &&
206- e.inOutMapping.isNotEmpty)) {
124+ (e) =>
125+ e.module is InlineSystemVerilog &&
126+ e.needsInstantiation &&
127+ e.outputMapping.isEmpty &&
128+ e.inOutMapping.isNotEmpty,
129+ )) {
207130 // algorithm:
208131 // - mark module as not needing declaration
209132 // - add a net_connect
@@ -225,8 +148,10 @@ class SystemVerilogSynthModuleDefinition extends SynthModuleDefinition {
225148 parentSynthModuleDefinition: this ,
226149 );
227150
228- final netConnectSynthSubmod = _addNetConnect (subModResult, dummy)
229- ..synthLogicToInlineableSynthSubmoduleMap ?? = {};
151+ final netConnectSynthSubmod = _addNetConnect (
152+ subModResult,
153+ dummy,
154+ )..synthLogicToInlineableSynthSubmoduleMap ?? = {};
230155
231156 netConnectSynthSubmod.synthLogicToInlineableSynthSubmoduleMap! [dummy] =
232157 subModuleInstantiation;
@@ -260,19 +185,21 @@ class _NetConnect extends Module with SystemVerilog {
260185 _NetConnect (LogicNet n0, LogicNet n1)
261186 : assert (n0.width == n1.width, 'Widths must be equal.' ),
262187 width = n0.width,
263- super (
264- definitionName: _definitionName,
265- name: _definitionName,
266- ) {
188+ super (definitionName: _definitionName, name: _definitionName) {
267189 n0 = addInOut (n0Name, n0, width: width);
268190 n1 = addInOut (n1Name, n1, width: width);
269191 }
270192
271193 @override
272194 String instantiationVerilog (
273- String instanceType, String instanceName, Map <String , String > ports) {
274- assert (instanceType == _definitionName,
275- 'Instance type selected should match the definition name.' );
195+ String instanceType,
196+ String instanceName,
197+ Map <String , String > ports,
198+ ) {
199+ assert (
200+ instanceType == _definitionName,
201+ 'Instance type selected should match the definition name.' ,
202+ );
276203 return '$instanceType '
277204 ' #(.WIDTH($width ))'
278205 ' $instanceName '
0 commit comments