11 #include "mlir/Pass/Pass.h"
12 #include "llvm/ADT/APSInt.h"
16 #define GEN_PASS_DEF_LINT
17 #include "circt/Dialect/FIRRTL/Passes.h.inc"
22 using namespace circt;
23 using namespace firrtl;
26 struct LintPass :
public circt::firrtl::impl::LintBase<LintPass> {
27 void runOnOperation()
override {
28 auto fModule = getOperation();
29 auto walkResult = fModule.walk<WalkOrder::PreOrder>([&](Operation *op) {
31 return WalkResult::skip();
32 if (isa<AssertOp, VerifAssertIntrinsicOp>(op))
33 if (checkAssert(op).failed())
34 return WalkResult::interrupt();
36 return WalkResult::advance();
38 if (walkResult.wasInterrupted())
39 return signalPassFailure();
41 markAllAnalysesPreserved();
44 LogicalResult checkAssert(Operation *op) {
46 if (
auto a = dyn_cast<AssertOp>(op)) {
47 if (
auto constant = a.getEnable().getDefiningOp<firrtl::ConstantOp>())
48 if (constant.getValue().isOne()) {
49 predicate = a.getPredicate();
51 }
else if (
auto a = dyn_cast<VerifAssertIntrinsicOp>(op))
52 predicate = a.getProperty();
56 if (
auto constant = predicate.getDefiningOp<firrtl::ConstantOp>())
57 if (constant.getValue().isZero())
58 return op->emitOpError(
59 "is guaranteed to fail simulation, as the predicate is "
61 .attachNote(constant.getLoc())
62 <<
"constant defined here";
64 if (
auto reset = predicate.getDefiningOp<firrtl::AsUIntPrimOp>())
65 if (firrtl::type_isa<ResetType, AsyncResetType>(
66 reset.getInput().getType()))
67 return op->emitOpError(
"is guaranteed to fail simulation, as the "
68 "predicate is a reset signal")
69 .attachNote(reset.getInput().getLoc())
70 <<
"reset signal defined here";
78 return std::make_unique<LintPass>();
std::unique_ptr< mlir::Pass > createLintingPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.