diff --git a/integration_test/Dialect/FIRRTL/instance-choice.fir b/integration_test/Dialect/FIRRTL/instance-choice.fir index ab37de1728ea..93984f09cb7d 100644 --- a/integration_test/Dialect/FIRRTL/instance-choice.fir +++ b/integration_test/Dialect/FIRRTL/instance-choice.fir @@ -25,6 +25,11 @@ ; RUN: %t.default.exe --cycles 1 2>&1 | FileCheck %s --check-prefix=DEFAULT ; DEFAULT: result: 0 +; -------------------------------------- Test 5: Configuration file +; RUN: echo '`include "targets-top-Platform-FPGA.svh"' > %t/user-config.svh +; RUN: verilator %driver %t/top.sv %t/ASICTarget.sv %t/FPGATarget.sv %t/DefaultTarget.sv --cc --sv --exe --build -o %t.config.exe --top-module top -DFIRRTL_CONFIGURATION_FILE=user-config.svh -I%t +; RUN: %t.config.exe --cycles 1 2>&1 | FileCheck %s --check-prefix=CONFIGFILE +; CONFIGFILE: result: 20 FIRRTL version 5.1.0 circuit top: diff --git a/lib/Conversion/FIRRTLToHW/LowerToHW.cpp b/lib/Conversion/FIRRTLToHW/LowerToHW.cpp index 47dbd13202b4..c6bbe31221c2 100644 --- a/lib/Conversion/FIRRTLToHW/LowerToHW.cpp +++ b/lib/Conversion/FIRRTLToHW/LowerToHW.cpp @@ -221,6 +221,7 @@ struct CircuitLoweringState { std::atomic usedAssertVerboseCond{false}; std::atomic usedStopCond{false}; std::atomic usedFileDescriptorLib{false}; + std::atomic usedConfiguration{false}; CircuitLoweringState(CircuitOp circuitOp, bool enableAnnotationWarning, firrtl::VerificationFlavor verificationFlavor, @@ -1022,6 +1023,28 @@ endpackage }); }); } + + // Create a fragment for FIRRTL configuration file include. It enables users + // to manage all options through single file. + // (e.g. -DFIRRTL_CONFIGURATION_FILE=configuration.svh) + if (state.usedConfiguration) { + sv::MacroDeclOp::create(b, "FIRRTL_CONFIGURATION_FILE"); + sv::MacroDeclOp::create(b, "FIRRTL_CONFIGURATION_FILE_"); + emit::FragmentOp::create(b, "FIRRTL_CONFIGURATION_FRAGMENT", [&] { + sv::IfDefOp::create(b, "FIRRTL_CONFIGURATION_FILE", [&]() { + sv::IfDefOp::create( + b, "FIRRTL_CONFIGURATION_FILE_", [] {}, + [&]() { + StringRef body = R"(`define FIRRTL_CONFIGURATION_INCLUDED +`define _STRINGIFY(x) `"x`" +`include `_STRINGIFY(`FIRRTL_CONFIGURATION_FILE) +`undef _STRINGIFY)"; + sv::MacroDefOp::create(b, "FIRRTL_CONFIGURATION_FILE_", ""); + sv::VerbatimOp::create(b, body); + }); + }); + }); + } } /// Helper function to emit a single instance choice include file for a given @@ -4130,6 +4153,11 @@ LogicalResult FIRRTLLowering::visitDecl(InstanceChoiceOp oldInstanceChoice) { "must have instance_macro attribute set before " "lowering"); + // Mark that we're using configuration and add the fragment to the module + // containing this instance choice. + circuitState.usedConfiguration = true; + circuitState.addFragment(theModule, "FIRRTL_CONFIGURATION_FRAGMENT"); + // Get all the target modules auto moduleNames = oldInstanceChoice.getModuleNamesAttr(); auto caseNames = oldInstanceChoice.getCaseNamesAttr();