Repository: intel/rohd
Pull request #498 (2024-07-29 22:22:41)

Do not generate SystemVerilog parameter syntax when there are 0 parameters
<!-- Please make sure you check out the contribution guidelines before submitting a pull request! -->

## Description & Motivation

This is a bug fix for when parameter arguments in custom-generated SystemVerilog have provided parameter information (either instantiation or definition), but the list/map is empty (but non-null).  It is illegal SystemVerilog syntax to generate something like `#( )`, but that's what was being generated.  The fix is to look for `null` OR empty conditions.

## Related Issue(s)

N/A

## Testing

Added a new test that covers both instantiation and definition empty parameter scenarios.

## Backwards-compatibility

> Is this a breaking change that will not be backwards-compatible? If yes, how so?

No

## Documentation

> Does the change require any updates to documentation? If so, where? Are they included?

No



Patch:
diff --git a/lib/src/synthesizers/systemverilog.dart b/lib/src/synthesizers/systemverilog.dart
index 47a065b8..7395b552 100644
--- a/lib/src/synthesizers/systemverilog.dart
+++ b/lib/src/synthesizers/systemverilog.dart
@@ -102,7 +102,7 @@ class SystemVerilogSynthesizer extends Synthesizer {
     final connectionsStr = connections.join(',');
 
     var parameterString = '';
-    if (parameters != null) {
+    if (parameters != null && parameters.isNotEmpty) {
       final parameterContents =
           parameters.entries.map((e) => '.${e.key}(${e.value})').join(',');
       parameterString = '#($parameterContents)';
@@ -485,7 +485,7 @@ class _SystemVerilogSynthesisResult extends SynthesisResult {
   String? _verilogParameters(Module module) {
     if (module is SystemVerilog) {
       final defParams = module.definitionParameters;
-      if (defParams == null) {
+      if (defParams == null || defParams.isEmpty) {
         return null;
       }
 


Test patch:
diff --git a/test/sv_param_passthrough_test.dart b/test/sv_param_passthrough_test.dart
index a92b000b..e7b0876d 100644
--- a/test/sv_param_passthrough_test.dart
+++ b/test/sv_param_passthrough_test.dart
@@ -114,6 +114,35 @@ class LeafNodeExternal extends ModWithParamPassthrough {
   String? definitionVerilog(String definitionType) => '';
 }
 
+class TopForEmptyParams extends ModWithParamPassthrough {
+  Logic get b => output('b');
+  TopForEmptyParams(Logic a,
+      {super.definitionName = 'top_for_empty',
+      super.instantiationParameters = const {},
+      super.name = 'top'})
+      : super([]) {
+    a = addInput('a', a, width: 8);
+    addOutput('b', width: 8);
+    b <= LeafNodeExternalEmptyParams(a).b;
+  }
+}
+
+class LeafNodeExternalEmptyParams extends ModWithParamPassthrough {
+  Logic get b => output('b');
+  LeafNodeExternalEmptyParams(Logic a,
+      {super.definitionName = 'leaf_node',
+      super.instantiationParameters = const {},
+      super.name = 'leaf'})
+      : super([]) {
+    a = addInput('a', a, width: 8);
+    addOutput('b', width: 8);
+  }
+
+  // leaf node should not generate any SV, like external
+  @override
+  String? definitionVerilog(String definitionType) => '';
+}
+
 void main() {
   test('passthrough params custom system verilog', () async {
     final mod = Top(Logic(width: 8));
@@ -128,4 +157,12 @@ void main() {
       'test/sv_param_passthrough.sv', // include external SV
     ]);
   });
+
+  test('empty params does include param # in generated system verilog',
+      () async {
+    final mod = TopForEmptyParams(Logic(width: 8));
+    await mod.build();
+    final sv = mod.generateSynth();
+    expect(sv.contains('#'), isFalse);
+  });
 }