CIRCT 24.0.0git
Loading...
Searching...
No Matches
Firtool.cpp
Go to the documentation of this file.
1//===- Firtool.cpp - Definitions for the firtool pipeline setup -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
20#include "mlir/Transforms/Passes.h"
21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/Path.h"
23#include "llvm/Support/raw_ostream.h"
24
25using namespace circt;
26
27LogicalResult firtool::populatePreprocessTransforms(mlir::PassManager &pm,
28 const FirtoolOptions &opt) {
29 pm.nest<firrtl::CircuitOp>().addPass(
30 firrtl::createCheckRecursiveInstantiation());
31 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createCheckLayers());
32 // Legalize away "open" aggregates to hw-only versions.
33 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerOpenAggs());
34
35 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createResolvePaths());
36
37 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerFIRRTLAnnotations(
38 {/*ignoreAnnotationClassless=*/opt.shouldDisableClasslessAnnotations(),
39 /*ignoreAnnotationUnknown=*/opt.shouldDisableUnknownAnnotations(),
40 /*noRefTypePorts=*/opt.shouldLowerNoRefTypePortAnnotations()}));
41
42 if (opt.shouldEnableDebugInfo())
43 pm.nest<firrtl::CircuitOp>().addNestedPass<firrtl::FModuleOp>(
44 firrtl::createMaterializeDebugInfo());
45
46 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerIntmodules(
47 {/*fixupEICGWrapper=*/opt.shouldFixupEICGWrapper()}));
48 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
49 firrtl::createLowerIntrinsics());
50
51 return success();
52}
53
54LogicalResult firtool::populateCHIRRTLToLowFIRRTL(mlir::PassManager &pm,
55 const FirtoolOptions &opt) {
56 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerSignatures());
57
58 // This pass is _not_ idempotent. It preserves its controlling annotation for
59 // use by ExtractInstances. This pass should be run before ExtractInstances.
60 //
61 // TODO: This pass should be deleted.
62 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createInjectDUTHierarchy());
63
64 if (!opt.shouldDisableOptimization()) {
66 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
67 mlir::createCSEPass());
68 else
69 pm.nest<firrtl::CircuitOp>().nestAny().addPass(mlir::createCSEPass());
70 }
71
72 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
73 firrtl::createPassiveWires());
74
75 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
76 firrtl::createDropName({/*preserveMode=*/opt.getPreserveMode()}));
77
78 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
79 firrtl::createLowerCHIRRTLPass());
80
81 // Run LowerMatches before InferWidths, as the latter does not support the
82 // match statement, but it does support what they lower to.
83 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
84 firrtl::createLowerMatches());
85
86 // Width inference creates canonicalization opportunities.
87 firrtl::InferWidthsOptions inferWidthsOptions;
88 inferWidthsOptions.warnOnTruncation = opt.shouldWarnOnTruncation();
89 pm.nest<firrtl::CircuitOp>().addPass(
90 firrtl::createInferWidths(inferWidthsOptions));
91 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
92 firrtl::createLowerSizeOf());
93
94 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createInferResets());
95 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createFullReset());
96
97 // TODO: Move this to the same location as SpecializeLayers.
98 pm.addNestedPass<firrtl::CircuitOp>(firrtl::createSpecializeOption(
99 {/*selectDefaultInstanceChoice*/ opt
101
102 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createDropConst());
103
104 if (opt.shouldDedup())
105 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createDedup());
106
107 if (opt.shouldConvertVecOfBundle()) {
108 pm.addNestedPass<firrtl::CircuitOp>(firrtl::createLowerFIRRTLTypes(
109 {/*preserveAggregate=*/firrtl::PreserveAggregate::All,
110 /*preserveMemories*/ firrtl::PreserveAggregate::All}));
111 pm.addNestedPass<firrtl::CircuitOp>(firrtl::createVBToBV());
112 }
113
114 if (!opt.shouldLowerMemories())
115 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
116 firrtl::createFlattenMemory());
117
118 // The input mlir file could be firrtl dialect so we might need to clean
119 // things up.
120 // pm.addNestedPass<firrtl::CircuitOp>(firrtl::createLowerSignaturesPass());
121 pm.addNestedPass<firrtl::CircuitOp>(firrtl::createLowerFIRRTLTypes(
122 {/*preserveAggregate=*/opt.getPreserveAggregate(),
123 /*preserveMemory=*/firrtl::PreserveAggregate::None}));
124
125 {
126 auto &modulePM = pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>();
127 modulePM.addPass(firrtl::createExpandWhens());
128 modulePM.addPass(firrtl::createSFCCompat());
129 }
130
131 // InferDomains runs after ExpandWhens because FIRRTL allows for last-connect
132 // semantics and users have historically relied on this behavior to set
133 // default connections that are then overridden later. If this pass is run
134 // before ExpandWhens, then users can get errors if they rely on last-connect
135 // semantics.
137 firrtl::InferDomainsOptions passOptions;
138 passOptions.mode = *mode;
139 passOptions.skippedDomains.assign(opt.getSkippedDomains().begin(),
140 opt.getSkippedDomains().end());
141 pm.nest<firrtl::CircuitOp>().addPass(
142 firrtl::createInferDomains(passOptions));
143 }
144
145 if (opt.shouldStripDomain())
146 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createStripDomains());
147
148 pm.addNestedPass<firrtl::CircuitOp>(firrtl::createCheckCombLoops());
149
150 // Must run this pass after all diagnostic passes have run, otherwise it can
151 // hide errors.
152 pm.addNestedPass<firrtl::CircuitOp>(firrtl::createSpecializeLayers());
153
154 // Run after inference, layer specialization.
156 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createProbesToSignals());
157
158 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createInliner());
159
160 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
161 firrtl::createLayerMerge());
162
163 // Preset the random initialization parameters for each module. The current
164 // implementation assumes it can run at a time where every register is
165 // currently in the final module it will be emitted in, all registers have
166 // been created, and no registers have yet been removed.
168 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
169 firrtl::createRandomizeRegisterInit());
170
171 // If we parsed a FIRRTL file and have optimizations enabled, clean it up.
172 if (!opt.shouldDisableOptimization())
173 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
175
176 // Run the infer-rw pass, which merges read and write ports of a memory with
177 // mutually exclusive enables.
178 if (!opt.shouldDisableOptimization())
179 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
180 firrtl::createInferReadWrite());
181
183 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerMemory());
184
185 if (!opt.shouldDisableOptimization())
186 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createIMConstProp());
187
188 pm.addNestedPass<firrtl::CircuitOp>(firrtl::createAddSeqMemPorts());
189
190 pm.addPass(firrtl::createCreateSiFiveMetadata(
191 {/*replSeqMem=*/opt.shouldReplaceSequentialMemories(),
192 /*replSeqMemFile=*/opt.getReplaceSequentialMemoriesFile().str()}));
193
194 // This pass must be run after InjectDUTHierarchy.
195 //
196 // TODO: This pass should be deleted along with InjectDUTHierarchy.
197 pm.addNestedPass<firrtl::CircuitOp>(firrtl::createExtractInstances());
198
199 // Run SymbolDCE as late as possible, but before InnerSymbolDCE. This is for
200 // hierpathop's and just for general cleanup.
201 pm.addNestedPass<firrtl::CircuitOp>(mlir::createSymbolDCEPass());
202
203 // Run InnerSymbolDCE as late as possible, but before IMDCE.
204 pm.addPass(firrtl::createInnerSymbolDCE());
205
206 // The above passes, IMConstProp in particular, introduce additional
207 // canonicalization opportunities that we should pick up here before we
208 // proceed to output-specific pipelines.
209 if (!opt.shouldDisableOptimization()) {
211 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
212 circt::firrtl::createEliminateWires());
213 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
215 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
216 circt::firrtl::createRegisterOptimizer());
217 // Re-run IMConstProp to propagate constants produced by register
218 // optimizations.
219 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createIMConstProp());
220 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
222 pm.addPass(firrtl::createIMDeadCodeElim());
224 pm.nest<firrtl::CircuitOp>().addPass(
225 firrtl::createAnnotateInputOnlyModules());
226 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createInliner());
227 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
229 }
230 }
231
232 // Always run this, required for legalization.
233 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
234 firrtl::createMergeConnections(
235 {/*enableAggressiveMergin=*/!opt
237
238 return success();
239}
240
241LogicalResult firtool::populateLowFIRRTLToHW(mlir::PassManager &pm,
242 const FirtoolOptions &opt,
243 StringRef inputFilename) {
244 // Populate instance macros for instance choice operations before lowering to
245 // HW.
246 pm.nest<firrtl::CircuitOp>().addPass(
247 firrtl::createPopulateInstanceChoiceSymbols());
248
249 // Run layersink immediately before LowerXMR. LowerXMR will "freeze" the
250 // location of probed objects by placing symbols on them. Run layersink first
251 // so that probed objects can be sunk if possible.
253 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLayerSink());
254
255 // Lower the ref.resolve and ref.send ops and remove the RefType ports.
256 // LowerToHW cannot handle RefType so, this pass must be run to remove all
257 // RefType ports and ops.
258 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerXMR());
259
260 // Layer lowering passes. Move operations into layers when possible and
261 // remove layers by converting them to other constructs. This lowering
262 // process can create a few optimization opportunities.
263 //
264 // TODO: Improve LowerLayers to avoid the need for canonicalization. See:
265 // https://github.com/llvm/circt/issues/7896
266
267 pm.nest<firrtl::CircuitOp>().addPass(
268 firrtl::createLowerLayers({opt.getEmitAllBindFiles()}));
269 if (!opt.shouldDisableOptimization())
270 pm.nest<firrtl::CircuitOp>().nest<firrtl::FModuleOp>().addPass(
272
273 auto outputFilename = opt.getOutputFilename();
274 if (outputFilename == "-")
275 outputFilename = "";
276
277 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createAssignOutputDirs(
278 {/*outputDirOption=*/outputFilename.str()}));
279
280 // Run passes to resolve Grand Central features. This should run before
281 // BlackBoxReader because Grand Central needs to inform BlackBoxReader where
282 // certain black boxes should be placed. Note: all Grand Central Taps related
283 // collateral is resolved entirely by LowerAnnotations.
284 // Run this after output directories are (otherwise) assigned,
285 // so generated interfaces can be appropriately marked.
286 pm.addNestedPass<firrtl::CircuitOp>(
287 firrtl::createGrandCentral({/*companionMode=*/opt.getCompanionMode(),
288 /*noViews*/ opt.getNoViews()}));
289
290 // Read black box source files into the IR.
291 StringRef blackBoxRoot = opt.getBlackBoxRootPath().empty()
292 ? llvm::sys::path::parent_path(inputFilename)
293 : opt.getBlackBoxRootPath();
294 pm.nest<firrtl::CircuitOp>().addPass(
295 firrtl::createBlackBoxReader({/*inputPrefix=*/blackBoxRoot.str()}));
296
297 // Remove TraceAnnotations and write their updated paths to an output
298 // annotation file.
299 pm.nest<firrtl::CircuitOp>().addPass(
300 firrtl::createResolveTraces({opt.getOutputAnnotationFilename().str()}));
301
302 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerDPI());
303 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerDomains());
304 pm.nest<firrtl::CircuitOp>().addPass(firrtl::createLowerClasses());
305
306 // Check for static asserts.
307 pm.nest<firrtl::CircuitOp>().addPass(circt::firrtl::createLint(
308 {/*lintStaticAsserts=*/opt.getLintStaticAsserts(),
309 /*lintXmrsInDesign=*/opt.getLintXmrsInDesign()}));
310
313 opt.shouldLowerToCore()));
314
315 if (!opt.shouldDisableOptimization()) {
316 auto &modulePM = pm.nest<hw::HWModuleOp>();
317 modulePM.addPass(mlir::createCSEPass());
318 modulePM.addPass(createSimpleCanonicalizerPass());
319 }
320
321 // Check inner symbols and inner refs.
322 pm.addPass(hw::createVerifyInnerRefNamespace());
323
324 // Run the verif op verification pass
325 pm.addNestedPass<hw::HWModuleOp>(verif::createVerifyClockedAssertLikePass());
326
327 return success();
328}
329
330LogicalResult firtool::populateHWToSV(mlir::PassManager &pm,
331 const FirtoolOptions &opt) {
332 pm.nestAny().addPass(verif::createStripContractsPass());
333 pm.addPass(verif::createLowerTestsPass());
334 pm.addPass(
335 verif::createLowerSymbolicValuesPass({opt.getSymbolicValueLowering()}));
336
337 pm.addPass(seq::createExternalizeClockGate(opt.getClockGateOptions()));
338 pm.addPass(circt::createLowerSimToSVPass());
340 {/*disableRegRandomization=*/!opt.isRandomEnabled(
342 /*disableMemRandomization=*/
344 /*emitSeparateAlwaysBlocks=*/
346 pm.addNestedPass<hw::HWModuleOp>(createLowerVerifToSVPass());
347 pm.addPass(seq::createHWMemSimImpl(
348 {/*disableMemRandomization=*/!opt.isRandomEnabled(
350 /*disableRegRandomization=*/
352 /*replSeqMem=*/opt.shouldReplaceSequentialMemories(),
353 /*readEnableMode=*/opt.shouldIgnoreReadEnableMemories()
356 /*addMuxPragmas=*/opt.shouldAddMuxPragmas(),
357 /*addVivadoRAMAddressConflictSynthesisBugWorkaround=*/
359
360 // If enabled, run the optimizer.
361 if (!opt.shouldDisableOptimization()) {
362 auto &modulePM = pm.nest<hw::HWModuleOp>();
363 modulePM.addPass(mlir::createCSEPass());
364 modulePM.addPass(createSimpleCanonicalizerPass());
365 modulePM.addPass(mlir::createCSEPass());
366 modulePM.addPass(sv::createHWCleanup(
367 {/*mergeAlwaysBlocks=*/!opt.shouldEmitSeparateAlwaysBlocks()}));
368 }
369
370 // Check inner symbols and inner refs.
371 pm.addPass(hw::createVerifyInnerRefNamespace());
372
373 return success();
374}
375
376namespace detail {
377LogicalResult
379 const firtool::FirtoolOptions &opt) {
380
381 // Run the verif op verification pass
382 pm.addNestedPass<hw::HWModuleOp>(verif::createVerifyClockedAssertLikePass());
383
384 // Legalize unsupported operations within the modules.
385 pm.nest<hw::HWModuleOp>().addPass(sv::createHWLegalizeModules());
386
387 // Tidy up the IR to improve verilog emission quality.
388 if (!opt.shouldDisableOptimization())
389 pm.nest<hw::HWModuleOp>().addPass(sv::createPrettifyVerilog());
390
391 if (opt.shouldStripFirDebugInfo())
392 pm.addPass(circt::createStripDebugInfoWithPredPass([](mlir::Location loc) {
393 if (auto fileLoc = dyn_cast<FileLineColLoc>(loc))
394 return fileLoc.getFilename().getValue().ends_with(".fir");
395 return false;
396 }));
397
398 if (opt.shouldStripDebugInfo())
400 [](mlir::Location loc) { return true; }));
401
402 // Emit module and testbench hierarchy JSON files.
404 pm.addPass(sv::createHWExportModuleHierarchy());
405
406 // Check inner symbols and inner refs.
407 pm.addPass(hw::createVerifyInnerRefNamespace());
408
409 return success();
410}
411} // namespace detail
412
413LogicalResult
414firtool::populateExportVerilog(mlir::PassManager &pm, const FirtoolOptions &opt,
415 std::unique_ptr<llvm::raw_ostream> os) {
417 return failure();
418
419 pm.addPass(createExportVerilogPass(std::move(os)));
420 return success();
421}
422
423LogicalResult firtool::populateExportVerilog(mlir::PassManager &pm,
424 const FirtoolOptions &opt,
425 llvm::raw_ostream &os) {
427 return failure();
428
429 pm.addPass(createExportVerilogPass(os));
430 return success();
431}
432
433LogicalResult firtool::populateExportSplitVerilog(mlir::PassManager &pm,
434 const FirtoolOptions &opt,
435 llvm::StringRef directory) {
437 return failure();
438
439 pm.addPass(createExportSplitVerilogPass(directory));
440 return success();
441}
442
443LogicalResult firtool::populateFinalizeIR(mlir::PassManager &pm,
444 const FirtoolOptions &opt) {
445 pm.addPass(firrtl::createFinalizeIR());
446 pm.addPass(om::createFreezePathsPass());
447 om::ElaborateObjectOptions options;
448 options.allPublicClasses = true;
449 options.allowUnevaluated = true;
450 pm.addPass(om::createElaborateObject(options));
451 // TODO: Add SymbolDCE to elimiate unused private classes once after we
452 // stopped using private classes.
453
454 return success();
455}
456
457/// BTOR2 emission pipeline, triggered with `--btor2` flag.
458LogicalResult firtool::populateHWToBTOR2(mlir::PassManager &pm,
459 const FirtoolOptions &opt,
460 llvm::raw_ostream &os) {
461 auto &mpm = pm.nest<hw::HWModuleOp>();
462 // Lower all supported `ltl` ops
463 mpm.addPass(circt::createLowerLTLToCorePass());
464 // LTLToCore can generate shiftreg which should be lowered before emission
465 mpm.addPass(circt::seq::createLowerSeqShiftReg());
466 // ShiftReg Lowering generates compreg.ce, which we don't support, so lower
467 mpm.addPass(circt::seq::createLowerSeqCompRegCE());
468 // Do final formal specific lowerings, e.g. inline wires eagerly
469 mpm.addPass(circt::verif::createPrepareForFormalPass());
470 pm.addPass(circt::hw::createFlattenModules());
471 pm.addPass(circt::createConvertHWToBTOR2Pass(os));
472 return success();
473}
474
475//===----------------------------------------------------------------------===//
476// FIRTOOL CommandLine Options
477//===----------------------------------------------------------------------===//
478
479namespace {
480/// This class contains command line options that can be used to initialize
481/// various bits of a Firtool pipeline. This uses a class wrapper to avoid the
482/// need for global command line options.
483class FirtoolCmdOptions {
484public:
485 llvm::cl::opt<std::string> outputFilename{
486 "o",
487 llvm::cl::desc("Output filename, or directory for split output"),
488 llvm::cl::value_desc("filename"),
489 llvm::cl::init("-"),
490 };
491
492 llvm::cl::opt<bool> disableAnnotationsUnknown{
493 "disable-annotation-unknown",
494 llvm::cl::desc("Ignore unknown annotations when parsing"),
495 llvm::cl::init(false)};
496
497 llvm::cl::opt<bool> disableAnnotationsClassless{
498 "disable-annotation-classless",
499 llvm::cl::desc("Ignore annotations without a class when parsing"),
500 llvm::cl::init(false)};
501
502 llvm::cl::opt<bool> lowerAnnotationsNoRefTypePorts{
503 "lower-annotations-no-ref-type-ports",
504 llvm::cl::desc(
505 "Create real ports instead of ref type ports when resolving "
506 "wiring problems inside the LowerAnnotations pass"),
507 llvm::cl::init(false), llvm::cl::Hidden};
508
509 llvm::cl::opt<bool> probesToSignals{
510 "probes-to-signals",
511 llvm::cl::desc("Convert probes to non-probe signals"),
512 llvm::cl::init(false), llvm::cl::Hidden};
513
514 llvm::cl::opt<circt::firrtl::PreserveAggregate::PreserveMode>
515 preserveAggregate{
516 "preserve-aggregate",
517 llvm::cl::desc("Specify input file format:"),
518 llvm::cl::values(
520 "Preserve no aggregate"),
522 "Preserve only 1d vectors of ground type"),
524 "Preserve only vectors"),
526 "Preserve vectors and bundles")),
528 };
529
530 llvm::cl::opt<firrtl::PreserveValues::PreserveMode> preserveMode{
531 "preserve-values",
532 llvm::cl::desc("Specify the values which can be optimized away"),
533 llvm::cl::values(
534 clEnumValN(firrtl::PreserveValues::Strip, "strip",
535 "Strip all names. No name is preserved"),
536 clEnumValN(firrtl::PreserveValues::None, "none",
537 "Names could be preserved by best-effort unlike `strip`"),
538 clEnumValN(firrtl::PreserveValues::Named, "named",
539 "Preserve values with meaningful names"),
540 clEnumValN(firrtl::PreserveValues::All, "all",
541 "Preserve all values")),
542 llvm::cl::init(firrtl::PreserveValues::None)};
543
544 llvm::cl::opt<bool> enableDebugInfo{
545 "g", llvm::cl::desc("Enable the generation of debug information"),
546 llvm::cl::init(false)};
547
548 // Build mode options.
549 llvm::cl::opt<firtool::FirtoolOptions::BuildMode> buildMode{
550 "O", llvm::cl::desc("Controls how much optimization should be performed"),
551 llvm::cl::values(clEnumValN(firtool::FirtoolOptions::BuildModeDebug,
552 "debug",
553 "Compile with only necessary optimizations"),
555 "release", "Compile with optimizations")),
557
558 llvm::cl::opt<bool> disableLayerSink{"disable-layer-sink",
559 llvm::cl::desc("Disable layer sink"),
560 llvm::cl::init(false)};
561
562 llvm::cl::opt<bool> disableOptimization{
563 "disable-opt",
564 llvm::cl::desc("Disable optimizations"),
565 };
566
567 llvm::cl::opt<bool> vbToBV{
568 "vb-to-bv",
569 llvm::cl::desc("Transform vectors of bundles to bundles of vectors"),
570 llvm::cl::init(false)};
571
572 llvm::cl::opt<bool> noDedup{
573 "no-dedup",
574 llvm::cl::desc("Disable deduplication of structurally identical modules"),
575 llvm::cl::init(false)};
576
577 llvm::cl::opt<bool> dedupClasses{
578 "dedup-classes",
579 llvm::cl::desc("Deprecated; classes are never deduplicated"),
580 llvm::cl::init(false), llvm::cl::callback([](const bool &value) {
581 if (value)
582 llvm::errs() << "warning: --dedup-classes is deprecated and ignored; "
583 "classes are never deduplicated\n";
584 })};
585
586 llvm::cl::opt<firrtl::CompanionMode> companionMode{
587 "grand-central-companion-mode",
588 llvm::cl::desc("Specifies the handling of Grand Central companions"),
589 ::llvm::cl::values(
590 clEnumValN(firrtl::CompanionMode::Bind, "bind",
591 "Lower companion instances to SystemVerilog binds"),
592 clEnumValN(firrtl::CompanionMode::Instantiate, "instantiate",
593 "Instantiate companions in the design"),
594 clEnumValN(firrtl::CompanionMode::Drop, "drop",
595 "Remove companions from the design")),
596 llvm::cl::init(firrtl::CompanionMode::Bind),
597 llvm::cl::Hidden,
598 };
599
600 llvm::cl::opt<bool> noViews{
601 "no-views",
602 llvm::cl::desc(
603 "Disable lowering of FIRRTL view intrinsics (delete them instead)"),
604 llvm::cl::init(false),
605 };
606
607 llvm::cl::opt<bool> disableAggressiveMergeConnections{
608 "disable-aggressive-merge-connections",
609 llvm::cl::desc(
610 "Disable aggressive merge connections (i.e. merge all field-level "
611 "connections into bulk connections)"),
612 llvm::cl::init(false)};
613
614 llvm::cl::opt<bool> lowerMemories{
615 "lower-memories",
616 llvm::cl::desc("Lower memories to have memories with masks as an "
617 "array with one memory per ground type"),
618 llvm::cl::init(false)};
619
620 llvm::cl::opt<std::string> blackBoxRootPath{
621 "blackbox-path",
622 llvm::cl::desc(
623 "Optional path to use as the root of black box annotations"),
624 llvm::cl::value_desc("path"),
625 llvm::cl::init(""),
626 };
627
628 llvm::cl::opt<bool> replSeqMem{
629 "repl-seq-mem",
630 llvm::cl::desc("Replace the seq mem for macro replacement and emit "
631 "relevant metadata"),
632 llvm::cl::init(false)};
633
634 llvm::cl::opt<std::string> replSeqMemFile{
635 "repl-seq-mem-file", llvm::cl::desc("File name for seq mem metadata"),
636 llvm::cl::init("")};
637
638 llvm::cl::opt<bool> ignoreReadEnableMem{
639 "ignore-read-enable-mem",
640 llvm::cl::desc("Ignore the read enable signal, instead of "
641 "assigning X on read disable"),
642 llvm::cl::init(false)};
643
644 firtool::FirtoolOptions::RandomKind disableRandomValue =
645 firtool::FirtoolOptions::RandomKind::None;
646
647 // Make these options (and their grouping category) inaccessible as their
648 // values are not intended to be used directly. These change a lattice of
649 // randomization disable settings and directly accessing the command line
650 // option the user provided is not useful.
651private:
652 llvm::cl::OptionCategory randomizationCategory{
653 "Disable random initialization code (may break semantics!)"};
654
655 llvm::cl::opt<bool> disableMemRandom{
656 "disable-mem-randomization",
657 llvm::cl::desc("Disable emission of memory randomization code"),
658 llvm::cl::cat(randomizationCategory), llvm::cl::ValueDisallowed,
659 llvm::cl::callback([&](const bool &) {
660 disableRandomValue = firtool::FirtoolOptions::mergeRandomKind(
661 disableRandomValue, firtool::FirtoolOptions::RandomKind::Mem);
662 })};
663
664 llvm::cl::opt<bool> disableRegRandom{
665 "disable-reg-randomization",
666 llvm::cl::desc("Disable emission of register randomization code"),
667 llvm::cl::cat(randomizationCategory), llvm::cl::ValueDisallowed,
668 llvm::cl::callback([&](const bool &) {
669 disableRandomValue = firtool::FirtoolOptions::mergeRandomKind(
670 disableRandomValue, firtool::FirtoolOptions::RandomKind::Reg);
671 })};
672
673 llvm::cl::opt<bool> disableAllRandom{
674 "disable-all-randomization",
675 llvm::cl::desc("Disable emission of all randomization code"),
676 llvm::cl::cat(randomizationCategory), llvm::cl::ValueDisallowed,
677 llvm::cl::callback([&](const bool &) {
678 disableRandomValue = firtool::FirtoolOptions::RandomKind::All;
679 })};
680
681public:
682 llvm::cl::opt<std::string> outputAnnotationFilename{
683 "output-annotation-file",
684 llvm::cl::desc("Optional output annotation file"),
685 llvm::cl::CommaSeparated, llvm::cl::value_desc("filename")};
686
687 llvm::cl::opt<bool> enableAnnotationWarning{
688 "warn-on-unprocessed-annotations",
689 llvm::cl::desc(
690 "Warn about annotations that were not removed by lower-to-hw"),
691 llvm::cl::init(false)};
692
693 llvm::cl::opt<bool> warnOnTruncation{
694 "warn-on-implicit-truncation",
695 llvm::cl::desc("Warn when connects require implicit truncation"),
696 llvm::cl::init(false)};
697
698 llvm::cl::opt<bool> lowerToCore{
699 "lower-to-core",
700 llvm::cl::desc("Prefer core dialects over direct SV lowering for FIRRTL "
701 "verification and printf operations"),
702 llvm::cl::init(false)};
703
704 llvm::cl::opt<bool> addMuxPragmas{
705 "add-mux-pragmas",
706 llvm::cl::desc("Annotate mux pragmas for memory array access"),
707 llvm::cl::init(false)};
708
709 llvm::cl::opt<firrtl::VerificationFlavor> verificationFlavor{
710 "verification-flavor",
711 llvm::cl::desc("Specify a verification flavor used in LowerFIRRTLToHW"),
712 llvm::cl::values(
713 clEnumValN(firrtl::VerificationFlavor::None, "none",
714 "Use the flavor specified by the op"),
715 clEnumValN(firrtl::VerificationFlavor::IfElseFatal, "if-else-fatal",
716 "Use Use `if(cond) else $fatal(..)` format"),
717 clEnumValN(firrtl::VerificationFlavor::Immediate, "immediate",
718 "Use immediate verif statements"),
719 clEnumValN(firrtl::VerificationFlavor::SVA, "sva", "Use SVA")),
720 llvm::cl::init(firrtl::VerificationFlavor::None)};
721
722 llvm::cl::opt<bool> emitSeparateAlwaysBlocks{
723 "emit-separate-always-blocks",
724 llvm::cl::desc(
725 "Prevent always blocks from being merged and emit constructs into "
726 "separate always blocks whenever possible"),
727 llvm::cl::init(false)};
728
729 llvm::cl::opt<bool> addVivadoRAMAddressConflictSynthesisBugWorkaround{
730 "add-vivado-ram-address-conflict-synthesis-bug-workaround",
731 llvm::cl::desc(
732 "Add a vivado specific SV attribute (* ram_style = "
733 "\"distributed\" *) to unpacked array registers as a workaronud "
734 "for a vivado synthesis bug that incorrectly modifies "
735 "address conflict behavivor of combinational memories"),
736 llvm::cl::init(false)};
737
738 //===----------------------------------------------------------------------===
739 // External Clock Gate Options
740 //===----------------------------------------------------------------------===
741
742 llvm::cl::opt<std::string> ckgModuleName{
743 "ckg-name", llvm::cl::desc("Clock gate module name"),
744 llvm::cl::init("EICG_wrapper")};
745
746 llvm::cl::opt<std::string> ckgInputName{
747 "ckg-input", llvm::cl::desc("Clock gate input port name"),
748 llvm::cl::init("in")};
749
750 llvm::cl::opt<std::string> ckgOutputName{
751 "ckg-output", llvm::cl::desc("Clock gate output port name"),
752 llvm::cl::init("out")};
753
754 llvm::cl::opt<std::string> ckgEnableName{
755 "ckg-enable", llvm::cl::desc("Clock gate enable port name"),
756 llvm::cl::init("en")};
757
758 llvm::cl::opt<std::string> ckgTestEnableName{
759 "ckg-test-enable",
760 llvm::cl::desc("Clock gate test enable port name (optional)"),
761 llvm::cl::init("test_en")};
762
763 llvm::cl::opt<bool> exportModuleHierarchy{
764 "export-module-hierarchy",
765 llvm::cl::desc("Export module and instance hierarchy as JSON"),
766 llvm::cl::init(false)};
767
768 llvm::cl::opt<bool> stripFirDebugInfo{
769 "strip-fir-debug-info",
770 llvm::cl::desc(
771 "Disable source fir locator information in output Verilog"),
772 llvm::cl::init(true)};
773
774 llvm::cl::opt<bool> stripDebugInfo{
775 "strip-debug-info",
776 llvm::cl::desc("Disable source locator information in output Verilog"),
777 llvm::cl::init(false)};
778
779 llvm::cl::opt<bool> fixupEICGWrapper{
780 "fixup-eicg-wrapper",
781 llvm::cl::desc("Lower `EICG_wrapper` modules into clock gate intrinsics"),
782 llvm::cl::init(false)};
783
784 llvm::cl::opt<bool> selectDefaultInstanceChoice{
785 "select-default-for-unspecified-instance-choice",
786 llvm::cl::desc(
787 "Specialize instance choice to default, if no option selected"),
788 llvm::cl::init(false)};
789
790 llvm::cl::opt<verif::SymbolicValueLowering> symbolicValueLowering{
791 "symbolic-values",
792 llvm::cl::desc("Control how symbolic values are lowered"),
793 llvm::cl::init(verif::SymbolicValueLowering::ExtModule),
794 verif::symbolicValueLoweringCLValues()};
795
796 llvm::cl::opt<bool> disableWireElimination{
797 "disable-wire-elimination", llvm::cl::desc("Disable wire elimination"),
798 llvm::cl::init(false)};
799
800 llvm::cl::opt<bool> emitAllBindFiles{
801 "emit-all-bind-files",
802 llvm::cl::desc("Emit bindfiles for private modules"),
803 llvm::cl::init(false)};
804
805 llvm::cl::opt<bool> inlineInputOnlyModules{
806 "inline-input-only-modules", llvm::cl::desc("Inline input-only modules"),
807 llvm::cl::init(false)};
808
809 llvm::cl::opt<firtool::FirtoolOptions::DomainMode> domainMode{
810 "domain-mode", llvm::cl::desc("Enable domain inference and checking"),
811 llvm::cl::init(firtool::FirtoolOptions::DomainMode::Disable),
812 llvm::cl::values(
813 clEnumValN(firtool::FirtoolOptions::DomainMode::Check, "check",
814 "Check domains without inference"),
815 clEnumValN(firtool::FirtoolOptions::DomainMode::Disable, "disable",
816 "Disable domain checking"),
817 clEnumValN(firtool::FirtoolOptions::DomainMode::Infer, "infer",
818 "Check domains with inference for private modules"),
819 clEnumValN(firtool::FirtoolOptions::DomainMode::InferAll, "infer-all",
820 "Check domains with inference for both public and private "
821 "modules"))};
822
823 llvm::cl::opt<bool> stripDomain{
824 "strip-domain",
825 llvm::cl::desc(
826 "Erase all domain information after inference and checking"),
827 llvm::cl::init(true)};
828
829 llvm::cl::list<std::string> skippedDomains{
830 "skip-domain",
831 llvm::cl::desc("Names of domains (e.g. \"ClockDomain\") to exclude from "
832 "domain checking. Skipped domains will be erased from the "
833 "circuit after inference")};
834
835 //===----------------------------------------------------------------------===
836 // Lint options
837 //===----------------------------------------------------------------------===
838
839 llvm::cl::opt<bool> lintStaticAsserts{
840 "lint-static-asserts", llvm::cl::desc("Lint static assertions"),
841 llvm::cl::init(true)};
842 // TODO: Change this default to 'true' once this has been better tested and
843 // `-sv-extract-test-code` has been removed.
844 llvm::cl::opt<bool> lintXmrsInDesign{
845 "lint-xmrs-in-design", llvm::cl::desc("Lint XMRs in the design"),
846 llvm::cl::init(false)};
847};
848} // namespace
849
850static llvm::ManagedStatic<FirtoolCmdOptions> clOptions;
851
852/// Register a set of useful command-line options that can be used to configure
853/// various flags within the MLIRContext. These flags are used when constructing
854/// an MLIR context for initialization.
856 // Make sure that the options struct has been initialized.
857 *clOptions;
858}
859
860// Initialize the firtool options with defaults supplied by the cl::opts above.
864 probesToSignals(false),
865 preserveAggregate(firrtl::PreserveAggregate::None),
866 preserveMode(firrtl::PreserveValues::None), enableDebugInfo(false),
868 disableOptimization(false), vbToBV(false), noDedup(false),
869 companionMode(firrtl::CompanionMode::Bind), noViews(false),
874 warnOnTruncation(false), lowerToCore(false), addMuxPragmas(false),
875 verificationFlavor(firrtl::VerificationFlavor::None),
878 ckgModuleName("EICG_wrapper"), ckgInputName("in"), ckgOutputName("out"),
879 ckgEnableName("en"), ckgTestEnableName("test_en"), ckgInstName("ckg"),
881 stripDebugInfo(false), fixupEICGWrapper(false),
883 symbolicValueLowering(verif::SymbolicValueLowering::ExtModule),
887 stripDomain(true) {
888 if (!clOptions.isConstructed())
889 return;
890 outputFilename = clOptions->outputFilename;
891 disableAnnotationsUnknown = clOptions->disableAnnotationsUnknown;
892 disableAnnotationsClassless = clOptions->disableAnnotationsClassless;
893 lowerAnnotationsNoRefTypePorts = clOptions->lowerAnnotationsNoRefTypePorts;
894 probesToSignals = clOptions->probesToSignals;
895 preserveAggregate = clOptions->preserveAggregate;
896 preserveMode = clOptions->preserveMode;
897 enableDebugInfo = clOptions->enableDebugInfo;
898 buildMode = clOptions->buildMode;
899 disableLayerSink = clOptions->disableLayerSink;
900 disableOptimization = clOptions->disableOptimization;
901 vbToBV = clOptions->vbToBV;
902 noDedup = clOptions->noDedup;
903 companionMode = clOptions->companionMode;
904 noViews = clOptions->noViews;
906 clOptions->disableAggressiveMergeConnections;
907 lowerMemories = clOptions->lowerMemories;
908 blackBoxRootPath = clOptions->blackBoxRootPath;
909 replSeqMem = clOptions->replSeqMem;
910 replSeqMemFile = clOptions->replSeqMemFile;
911 ignoreReadEnableMem = clOptions->ignoreReadEnableMem;
912 disableRandom = clOptions->disableRandomValue;
913 outputAnnotationFilename = clOptions->outputAnnotationFilename;
914 enableAnnotationWarning = clOptions->enableAnnotationWarning;
915 warnOnTruncation = clOptions->warnOnTruncation;
916 lowerToCore = clOptions->lowerToCore;
917 addMuxPragmas = clOptions->addMuxPragmas;
918 verificationFlavor = clOptions->verificationFlavor;
919 emitSeparateAlwaysBlocks = clOptions->emitSeparateAlwaysBlocks;
921 clOptions->addVivadoRAMAddressConflictSynthesisBugWorkaround;
922 ckgModuleName = clOptions->ckgModuleName;
923 ckgInputName = clOptions->ckgInputName;
924 ckgOutputName = clOptions->ckgOutputName;
925 ckgEnableName = clOptions->ckgEnableName;
926 ckgTestEnableName = clOptions->ckgTestEnableName;
927 exportModuleHierarchy = clOptions->exportModuleHierarchy;
928 stripFirDebugInfo = clOptions->stripFirDebugInfo;
929 stripDebugInfo = clOptions->stripDebugInfo;
930 fixupEICGWrapper = clOptions->fixupEICGWrapper;
931 selectDefaultInstanceChoice = clOptions->selectDefaultInstanceChoice;
932 symbolicValueLowering = clOptions->symbolicValueLowering;
933 disableWireElimination = clOptions->disableWireElimination;
934 lintStaticAsserts = clOptions->lintStaticAsserts;
935 lintXmrsInDesign = clOptions->lintXmrsInDesign;
936 emitAllBindFiles = clOptions->emitAllBindFiles;
937 inlineInputOnlyModules = clOptions->inlineInputOnlyModules;
938 domainMode = clOptions->domainMode;
939 stripDomain = clOptions->stripDomain;
940 skippedDomains.assign(clOptions->skippedDomains.begin(),
941 clOptions->skippedDomains.end());
942}
static llvm::ManagedStatic< FirtoolCmdOptions > clOptions
Definition Firtool.cpp:850
false return failure()
Parse an optional keyword or string and set instance into 'result'.
return success()
Set of options used to control the behavior of the firtool pipeline.
Definition Firtool.h:32
bool shouldStripDebugInfo() const
Definition Firtool.h:146
firrtl::PreserveAggregate::PreserveMode getPreserveAggregate() const
Definition Firtool.h:105
bool shouldAddVivadoRAMAddressConflictSynthesisBugWorkaround() const
Definition Firtool.h:160
bool shouldDisableLayerSink() const
Definition Firtool.h:139
firrtl::PreserveValues::PreserveMode preserveMode
Definition Firtool.h:442
auto getVerificationFlavor() const
Definition Firtool.h:155
StringRef getOutputFilename() const
Definition Firtool.h:98
bool shouldDisableAggressiveMergeConnections() const
Definition Firtool.h:149
bool shouldWarnOnTruncation() const
Definition Firtool.h:153
StringRef getReplaceSequentialMemoriesFile() const
Definition Firtool.h:100
bool addVivadoRAMAddressConflictSynthesisBugWorkaround
Definition Firtool.h:465
SmallVector< std::string > skippedDomains
Definition Firtool.h:486
bool shouldFixupEICGWrapper() const
Definition Firtool.h:163
bool shouldConvertProbesToSignals() const
Definition Firtool.h:137
firrtl::PreserveValues::PreserveMode getPreserveMode() const
Definition Firtool.h:86
StringRef getBlackBoxRootPath() const
Definition Firtool.h:99
bool shouldDisableCSEinClasses() const
Definition Firtool.h:164
bool shouldDisableOptimization() const
Definition Firtool.h:140
firrtl::CompanionMode getCompanionMode() const
Definition Firtool.h:108
bool shouldDisableClasslessAnnotations() const
Definition Firtool.h:131
bool getEmitAllBindFiles() const
Definition Firtool.h:178
bool shouldReplaceSequentialMemories() const
Definition Firtool.h:138
bool shouldIgnoreReadEnableMemories() const
Definition Firtool.h:144
bool isRandomEnabled(RandomKind kind) const
Definition Firtool.h:67
bool shouldDisableUnknownAnnotations() const
Definition Firtool.h:128
static RandomKind mergeRandomKind(RandomKind current, RandomKind incoming)
Advance the disabled-randomization lattice.
Definition Firtool.h:73
bool shouldAddMuxPragmas() const
Definition Firtool.h:159
bool shouldEnableAnnotationWarning() const
Definition Firtool.h:152
bool shouldConvertVecOfBundle() const
Definition Firtool.h:145
StringRef getOutputAnnotationFilename() const
Definition Firtool.h:101
bool shouldStripFirDebugInfo() const
Definition Firtool.h:147
std::string outputAnnotationFilename
Definition Firtool.h:458
firrtl::VerificationFlavor verificationFlavor
Definition Firtool.h:463
firrtl::PreserveAggregate::PreserveMode preserveAggregate
Definition Firtool.h:441
bool shouldLowerMemories() const
Definition Firtool.h:141
DomainMode getDomainMode() const
Definition Firtool.h:182
bool getLintStaticAsserts() const
Definition Firtool.h:174
bool shouldLowerNoRefTypePortAnnotations() const
Definition Firtool.h:134
verif::SymbolicValueLowering getSymbolicValueLowering() const
Definition Firtool.h:169
bool shouldExportModuleHierarchy() const
Definition Firtool.h:148
firrtl::CompanionMode companionMode
Definition Firtool.h:449
bool shouldDisableWireElimination() const
Definition Firtool.h:172
bool shouldSelectDefaultInstanceChoice() const
Definition Firtool.h:165
bool shouldInlineInputOnlyModules() const
Definition Firtool.h:180
verif::SymbolicValueLowering symbolicValueLowering
Definition Firtool.h:478
bool getLintXmrsInDesign() const
Definition Firtool.h:176
seq::ExternalizeClockGateOptions getClockGateOptions() const
Definition Firtool.h:112
bool shouldEnableDebugInfo() const
Definition Firtool.h:143
bool shouldEmitSeparateAlwaysBlocks() const
Definition Firtool.h:156
static constexpr std::optional< firrtl::InferDomainsMode > toInferDomainsPassMode(DomainMode mode)
Convert the "domain mode" firtool option to a "firrtl::InferDomainsMode", the configuration for a pas...
Definition Firtool.h:54
ArrayRef< std::string > getSkippedDomains() const
Definition Firtool.h:186
@ All
Preserve all aggregate values.
Definition Passes.h:46
@ OneDimVec
Preserve only 1d vectors of ground type (e.g. UInt<2>[3]).
Definition Passes.h:40
@ Vec
Preserve only vectors (e.g. UInt<2>[3][3]).
Definition Passes.h:43
@ None
Don't preserve aggregate at all.
Definition Passes.h:37
@ None
Don't explicitly preserve any named values.
Definition Passes.h:58
@ Strip
Strip all names. No name on declaration is preserved.
Definition Passes.h:54
LogicalResult populateLowFIRRTLToHW(mlir::PassManager &pm, const FirtoolOptions &opt, StringRef inputFilename)
Definition Firtool.cpp:241
LogicalResult populateHWToBTOR2(mlir::PassManager &pm, const FirtoolOptions &opt, llvm::raw_ostream &os)
BTOR2 emission pipeline, triggered with --btor2 flag.
Definition Firtool.cpp:458
LogicalResult populateExportSplitVerilog(mlir::PassManager &pm, const FirtoolOptions &opt, llvm::StringRef directory)
Definition Firtool.cpp:433
LogicalResult populateHWToSV(mlir::PassManager &pm, const FirtoolOptions &opt)
Definition Firtool.cpp:330
LogicalResult populateExportVerilog(mlir::PassManager &pm, const FirtoolOptions &opt, std::unique_ptr< llvm::raw_ostream > os)
Definition Firtool.cpp:414
LogicalResult populatePreprocessTransforms(mlir::PassManager &pm, const FirtoolOptions &opt)
Definition Firtool.cpp:27
void registerFirtoolCLOptions()
Register a set of useful command-line options that can be used to configure various flags within the ...
Definition Firtool.cpp:855
LogicalResult populateFinalizeIR(mlir::PassManager &pm, const FirtoolOptions &opt)
Definition Firtool.cpp:443
LogicalResult populateCHIRRTLToLowFIRRTL(mlir::PassManager &pm, const FirtoolOptions &opt)
Definition Firtool.cpp:54
std::unique_ptr< mlir::Pass > createFreezePathsPass(std::function< StringAttr(Operation *)> getOpNameFallback={})
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< mlir::Pass > createExportSplitVerilogPass(llvm::StringRef directory="./")
std::unique_ptr< mlir::Pass > createLowerFIRRTLToHWPass(bool enableAnnotationWarning=false, firrtl::VerificationFlavor assertionFlavor=firrtl::VerificationFlavor::None, bool lowerToCore=false)
This is the pass constructor.
std::unique_ptr< mlir::Pass > createConvertHWToBTOR2Pass(llvm::raw_ostream &os)
std::unique_ptr< OperationPass< hw::HWModuleOp > > createLowerVerifToSVPass()
Create the Verif to SV conversion pass.
std::unique_ptr< mlir::Pass > createLowerSeqToSVPass(const LowerSeqToSVOptions &options={})
Definition SeqToSV.cpp:858
std::unique_ptr< mlir::Pass > createLowerLTLToCorePass()
std::unique_ptr< mlir::Pass > createLowerSimToSVPass()
Definition SimToSV.cpp:1050
std::unique_ptr< Pass > createSimpleCanonicalizerPass()
Create a simple canonicalizer pass.
Definition Passes.cpp:15
std::unique_ptr< mlir::Pass > createExportVerilogPass()
std::unique_ptr< mlir::Pass > createStripDebugInfoWithPredPass(const std::function< bool(mlir::Location)> &pred)
Creates a pass to strip debug information from a function.
LogicalResult populatePrepareForExportVerilog(mlir::PassManager &pm, const firtool::FirtoolOptions &opt)
Definition Firtool.cpp:378
Definition verif.py:1