Skip to content
Merged
5 changes: 4 additions & 1 deletion lib/src/synthesizers/utilities/synth_module_definition.dart
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,10 @@ class SynthModuleDefinition {
...internalSignal.dstConnections
]
.where((e) =>
e.parentModule == module && logicHasPresentSynthLogic(e))
(e.parentModule == module ||
( // in case of sub-module output driving a net
e.parentModule?.parent == module && e.isOutput)) &&
logicHasPresentSynthLogic(e))
.isNotEmpty;

if (anyInternalConnections) {
Expand Down
48 changes: 48 additions & 0 deletions test/sv_gen_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,35 @@ class TieOffPortSub extends Module {
}
}

class OutToInOutTop extends Module {
OutToInOutTop(Logic clk) : super(name: 'out_to_inout_top') {
clk = addInput('clk', clk);
final modWithOut = ModWithOut(clk);
final myNetTop = LogicNet();
myNetTop <= modWithOut.myOut;

addOutput('clkB') <= ModWithInOut(myNetTop).clkB;
}
}

class ModWithOut extends Module {
late final Logic myOut;

ModWithOut(Logic clk) : super(name: 'mod_with_out') {
clk = addInput('clk', clk);
myOut = addOutput('myOut')..gets(~clk);
}
}

class ModWithInOut extends Module {
late final Logic clkB;
ModWithInOut(LogicNet myNet) : super(name: 'mod_with_inout') {
myNet = addInOut('myNet', myNet);

clkB = addOutput('clkB')..gets(myNet);
}
}

void main() {
tearDown(() async {
await Simulator.reset();
Expand Down Expand Up @@ -947,4 +976,23 @@ endmodule : ModWithUselessWireMods'''));
});
}
});

test('out to inout unnamed connection', () async {
// this test makes sure we don't lose an unnamed connection from an output
// to an inout

final mod = OutToInOutTop(Logic());
await mod.build();

final sv = mod.generateSynth();

expect(sv, contains('assign myNet = myOut;'));

final vectors = [
Vector({'clk': 0}, {'clkB': 1}),
Vector({'clk': 1}, {'clkB': 0}),
];
await SimCompare.checkFunctionalVector(mod, vectors);
SimCompare.checkIverilogVector(mod, vectors);
});
}