From 12822ad0d01ff58b3ce9aa23ff73a106ee869c02 Mon Sep 17 00:00:00 2001 From: Hideto Ueno Date: Thu, 8 Aug 2024 15:40:35 +0900 Subject: [PATCH] [SimToSV] Add include guards to DPI import (#7459) This adds include guards `__CIRCT_DPI_IMPORT_*` to DPI import statements generated in SimToSV. Fix https://github.com/llvm/circt/issues/7458. --- lib/Conversion/SimToSV/SimToSV.cpp | 11 ++++++++++- test/Conversion/SimToSV/dpi.mlir | 7 ++++++- test/firtool/dpi.fir | 16 +++++++++++++--- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/Conversion/SimToSV/SimToSV.cpp b/lib/Conversion/SimToSV/SimToSV.cpp index a1d0af51ab42..bcdef4e024ec 100644 --- a/lib/Conversion/SimToSV/SimToSV.cpp +++ b/lib/Conversion/SimToSV/SimToSV.cpp @@ -268,8 +268,17 @@ void LowerDPIFunc::lower(sim::DPIFuncOp func) { auto name = builder.getStringAttr(nameSpace.newName( func.getSymNameAttr().getValue(), "dpi_import_fragument")); + // Add include guards to avoid duplicate declarations. See Issue 7458. + auto macroDecl = builder.create(nameSpace.newName( + "__CIRCT_DPI_IMPORT", func.getSymNameAttr().getValue().upper())); builder.create(name, [&]() { - builder.create(func.getSymNameAttr(), StringAttr()); + builder.create( + macroDecl.getSymNameAttr(), []() {}, + [&]() { + builder.create(func.getSymNameAttr(), + StringAttr()); + builder.create(macroDecl.getSymNameAttr(), ""); + }); }); symbolToFragment.insert({func.getSymNameAttr(), name}); diff --git a/test/Conversion/SimToSV/dpi.mlir b/test/Conversion/SimToSV/dpi.mlir index c352d5907ade..959e5152e2ef 100644 --- a/test/Conversion/SimToSV/dpi.mlir +++ b/test/Conversion/SimToSV/dpi.mlir @@ -3,8 +3,13 @@ sim.func.dpi @dpi(out arg0: i1, in %arg1: i1, out arg2: i1) // CHECK: sv.func private @dpi(out arg0 : i1, in %arg1 : i1, out arg2 : i1) +// CHECK-NEXT: sv.macro.decl @__CIRCT_DPI_IMPORT_DPI // CHECK-NEXT: emit.fragment @dpi_dpi_import_fragument { -// CHECK-NEXT: sv.func.dpi.import @dpi +// CHECK-NEXT: sv.ifdef @__CIRCT_DPI_IMPORT_DPI { +// CHECK-NEXT: } else { +// CHECK-NEXT: sv.func.dpi.import @dpi +// CHECK-NEXT: sv.macro.def @__CIRCT_DPI_IMPORT_DPI "" +// CHECK-NEXT: } // CHECK-NEXT: } // VERILOG: import "DPI-C" context function void dpi( diff --git a/test/firtool/dpi.fir b/test/firtool/dpi.fir index b7a353b2c77c..ce47feb2529e 100644 --- a/test/firtool/dpi.fir +++ b/test/firtool/dpi.fir @@ -2,23 +2,33 @@ FIRRTL version 4.0.0 circuit DPI: -; CHECK-LABEL: import "DPI-C" context function void clocked_result( +; CHECK-LABEL: `ifndef __CIRCT_DPI_IMPORT_CLOCKED_RESULT +; CHECK-NEXT: import "DPI-C" context function void clocked_result( ; CHECK-NEXT: input byte foo, ; CHECK-NEXT: bar, ; CHECK-NEXT: output byte baz ; CHECK-NEXT: ); +; CHECK: `define __CIRCT_DPI_IMPORT_CLOCKED_RESULT +; CHECK-NEXT: `endif -; CHECK-LABEL: import "DPI-C" context function void clocked_void( +; CHECK-LABEL: `ifndef __CIRCT_DPI_IMPORT_CLOCKED_VOID +; CHECK-NEXT: import "DPI-C" context function void clocked_void( ; CHECK-NEXT: input byte in_0, ; CHECK-NEXT: in_1, ; CHECK-NEXT: in_2[] ; CHECK-NEXT: ); +; CHECK: `define __CIRCT_DPI_IMPORT_CLOCKED_VOID +; CHECK-NEXT: `endif -; CHECK-LABEL: import "DPI-C" context function void unclocked_result( + +; CHECK-LABEL: `ifndef __CIRCT_DPI_IMPORT_UNCLOCKED_RESULT +; CHECK-NEXT: import "DPI-C" context function void unclocked_result( ; CHECK-NEXT: input byte in_0, ; CHECK-NEXT: in_1, ; CHECK-NEXT: output byte out_0 ; CHECK-NEXT: ); +; CHECK: `define __CIRCT_DPI_IMPORT_UNCLOCKED_RESULT +; CHECK-NEXT: `endif ; CHECK-LABEL: module DPI( ; CHECK: logic [7:0] [[TMP:_.+]];