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